Selamunlar. Dün apar topar Balıkesir’e dönmek zorunda kalmıştım yaptığım bi yazılım işi için. Bu saate kadar onunla uğraşıyodum, kafam dağılsın diye wp-admin’e girdim. Aylardır yuvarlak top içinde beni bekleyen 6 adet güncelleme işini hallettim. Sonra baktım cidden WordPress aşmış kendini Yeni haliyle cezbetti beni. Aslında boş vaktimde video olarak çekmeyi düşündüğüm bir konuyu yazı olarak yazmak istedim. Gelelim konumuza; SQL Injection saldırılarında mysql_real_escape_string veya addslashes fonksiyonları ile filtrelenmiş verilerinizin nasıl bypass edilebileceği ve bypass edilişinin nasıl engelleneceği.
Başlamadan önce şu videomda sarfettiğim, sonrasında Nebi Sarıgül’ün beni aydınlatmasıyla doğruyu öğrendiğim bir yanlıştan bahsedeyim. Videoda “mysql_real_escape_string bypass edilemiyor” demiştim. Yazılım dünyası bu, hergün yeni şeyler öğreniyoruz. Fazla büyük konuşmuşum, ki şuan nasıl bypass edildiğine dair blog yazıyorum.
Şimdi anlatacağım bug, MySQL’in 4.1.x versiyonundan 4.1.20’ye kadar olan aralığında, 5.0.x versiyonları ve 5.1.11 versiyonlarında geçerlidir. Versiyonlar kısmını atlattıktan sonra; addslashes’in bypass edilebilmesi için charset’in GBK, mysql_real_escape_string’in bypass edilebilmesi için charset’in BIG5 veya GBK olması lazım. Buyrun bunlarda bugs.mysql.com’da yayınlanan buglara ait dökümanlar;
https://bugs.mysql.com/bug.php?id=8378
https://bugs.mysql.com/bug.php?id=8317
Öncelikle; bug nasıl işliyor?
Hex karşılığı 0xbf5c olan “¿\” karakteri, utf8 charsetinde 2 karakter, GBK charsetinde 1 karakter olarak algılanıyor. Injection saldırısında sorguya tek tırnak, yani 0x27 gönderdiğiniz vakit mysql_real_escape_string veya addslashes fonksiyonlarımız bizim tırnağımızı “\’” haline çeviriyor. Tırnaktan önce “¿” (0xbf) karakterini gönderdiğimizde yani “¿’” (0xbf27) karakterini gönderdiğimizde, tırnaktan önce \ ekleneceğinden gönderdiğimiz karakter “¿\’” (0xbf5c27) halini alıyor. GBK charseti “¿\” karakterini tek karakter olarak aldıladığından sondaki tırnağımız boşa çıkıyor, böylece sorgunun gidişatını değiştirmiş oluyorunuz. Sonrasında injection ile sorguyu istediğimiz şekle sokabiliyoruz.
Kısaca bir örnek gösterecek olursak; sorgumuz
SELECT * FROM uyeler WHERE id='$id'
Şimdi injecion işlemini gerçekleştirelim;
omercitak.net/uye.php?id=1%bf%27 UNION SELECT sifre FROM uyeler WHERE id='2
Hemen bakalım sorgumuz nasıl bir hale geldi?
SELECT * FROM uyeler WHERE id='1¿\' UNION SELECT sifre FROM uyeler WHERE id='2'
Gördüğünüz gibi mysql_real_escape_string ve addslashes fonksiyonları bu şekil bypass edilebiliyor.
Peki bypass işleminden nasıl korunurum?
Aslında bunun cevabını en başka vermiş gibi olduk.
1- Bu bug “MySQL’in 4.1.x versiyonundan 4.1.20’ye kadar olan aralığında, 5.0.x versiyonları ve 5.1.11 versiyonlarında geçerlidir” demiştik. Şuan MySQL’in son olarak 5.6.15 sürümü yayınlandı diye biliyorum. MySQL’inizi güncelleyerek korunmuş olursunuz.
2- Fonksiyonların bypass edilebilmesi için “charset’in BIG5 veya GBK olması lazım” demiştik. Bu ikisi dışında herhangi bi charset kullanırsanız yine bypass işleminden korunmuş olursunuz.
Bu yazım da bukadar. Yine bilmediğim, eksik bildiğim, yanlış bildiğim yerler olabilir; beni uyarın. Hayırlı akşamlar…
Comments on this post