SQL Injection için Kayıt İlerletme

22-8-2007

Bir sonraki kayıda geçme SQL Injectionlardaki en kilit noktalardan biridir. Bunun çeşitli yollar var ve manual testlerde keyfe kader bunlardan uygun olanı seçilebilir ancak genel olarak bir metodoloji oluşturmak istiyorsanız iş biraz daha karışıklaşıyor.

İki - üç sene önce kadar bir Blind SQL Injection programı yazmıştım özellikle Full Blind - Benchmark() veya WAITFOR DELAY ile data çıkarma amacı için. Altı ay önce kadarda bu programı baştan tekrar yazmaya başladım ve inşallah bir hafta içerisinde ilk versiyonu yayınlayacağım. İşte bu program için SQL Server' da kayıt ilerletme üzerine çalışırken bunlar başıma geldi.

Mevcut bilinen ve kullanılan kayıt ilerletme metodlarının bir kısmı SQL Injection Cheat Sheet' te Moving Records başlığı altında var.

.. WHERE users NOT IN ('First User', 'Second User')

Bu klasik bir yöntem ancak pek verimli değil. Verimli olmamasının bir çok nedeni var. İlk nedeni ntext' lerde, binary datalarda vs. sorun çıkaracak, ikincisi kayıt sayısı çoğaldıkça uzayacak. Dolayısıyla bu işimizi görmüyor.

Select p.name from (SELECT (SELECT COUNT(i.id) AS rid FROM sysobjects i WHERE i.id<=o.id) AS x, name from sysobjects o) as p where p.x=3

Bu aslında güzel bir versiyon. Basit şekilde kayıt ilerletebiliyorsunuz ancak otomatiğe bağlamayı zorlaştıran bir yöntem çünkü "primary key" i bulmanızı gerektiriyor. Aslında buna katlanabilirseniz gayet güzel gibi.

SELECT TOP 1 name FROM members WHERE NOT IN(SELECT TOP 0 name FROM members)

Bu pek bilinen bir yöntem değil ama dehşet bir çözüm. Normalde ben bunu kullanıyorum ancak bugünkü testlerimde bir sorun ortaya çıktı. Meğersem IN operatörü text ve benzeri datalarda kullanılmıyormuş.

Bütün bu maceralardan sonra şu şekilde bir çözümle ulaştım

SELECT TOP 1 [description]
FROM [Products]
WHERE SUBSTRING(description,1,8000) NOT IN(
    SELECT TOP 0 SUBSTRING(description,1,8000) FROM [Products]
)

Aynı mantık, ama bu sefer basit şekilde datanın soldan ilk 8000 karakterini alarak onu otomatik olarak text' e çevirip kullanıyoruz bu sayede tuhaf sorunlar çıkmıyor. Tabii ki eğer iki datanında ilk 8000 karakteri aynı ise sorun çıkabilir ama siz bahtsız deveyseniz ben ne yapabilirim ki?

Bu arada SQL Server 2005' de aynı ORACLE benzeri ROW_NUMBER() fonksiyonu var. Henüz test etme fırsatım olmadı ancak basitçe kayıtları ilerletebilmenizi sağlıyor. Maalesef henüz SQL Server 2005 o kadar popüler değil...

Recent Blog Posts

See all of the blog posts