Umut Tosun

I love low level stuffs and cyber security

Web For Pentester I – SQL Injections Çözümleri

05 Feb 2017 » Cyber Security, Pentest

Bu yazımda “Web For Pentester I” ın SQL Injection çözümlerini sizlerle paylaşacağım.

Example 1

Karşımızda “192.168.1.4/sqli/example1.php?name=root” şeklinde bir url beliriyor ve sayfada kullanıcı adı root olan kişi listeleniyor. Burada yapmamız gereken şey başarılı bir şekilde injection yapıp bütün kullanıcıların bilgilerini ekrana bastırmak.

Url’in sonunda gördüğümüz gibi name, string bir değişken alıyor. Zaten ilk örnek olduğu basit bir payload işimizi görecektir: ‘ or ‘1’=’1

192.168.1.4/sqli/example1.php?name=root' or '1'='1

Example 2

Bu örnek bir önceki örnek ile neredeyse aynı. Yapmamız gereken şey bir önceki örnek gibi bütün kullanıcıları listeletmek.

Bir önceki payloadı denediğimizde bize “Error, no space” gibi bir uyarı veriyor (Eğer siz bir websitesi yapıyorsanız, hataları kullanıcılara olabildiğince göstermemeye çalışın. Örneğin “Boşluk kullanmayın” yerine “Bir hata oluştu” tarzı bir mesaj verebilirsiniz). Yapmamız gereken boşluklardan bir şekilde kurtulmak. Bunun için iki yöntem kullanılabilir:

  • 1.si bütün boşlukları silmek yani: ‘or’1’=’1
  • 2.si boşluk yerlerine yorum eklemek: ‘/**/or/**/’1’=’1

Example 3

Example 3, Example 2 ile aynı (Sadece boşluk bırakmanıza yarayan 1-2 karakter daha filtrelenmiş). Yine bizden boşluk bırakmamamızı istiyor. Example 2 deki payloadları kullanarak yine bütün kullanıcıları listeleyebiliyoruz.

Example 4

Bu sefer “192.168.1.4/sqli/example4.php?id=2” şeklinde bir url imiz var. İstenilen yine aynı.

Burada dikkat edilmesi gereken şey şu ana kadar name parametresi bizden string bir ifade alıyordu, bu yüzden tırnaklı bir biçimde ‘1’=’1′ yazıyorduk. Fakat id parametresi int bir değer alıyor. Bu yüzden payloadımızı tırnaksız bir biçimde yazarsak sorun ortadan kalkar:

192.168.1.4/sqli/example4.php?id=2 or 1=1

Example 5

Önceki örnek ile aynı şekilde bir url imiz var. Fakat bu sefer tırnaklıda denesek tırnaksızda denesek olmuyor. Çünkü arka tarafta id parametresi int bir değer mi değil mi kontrol ediliyor. Eğer id parametresi int türünden farkı bir tür ise ekranda bir şey göstermiyor.

Fakat buradaki önemli nokta ise bu int kontrolü sadece 1. satır için yapılıyor. Yani biz payloadımızı 2.satırdan itibaren yazmaya başlarsak sorun olmayacaktır. Bunuda şu şekilde yapabiliyoruz: %0a

192.168.1.4/sqli/example5.php?id=2%0a or 1=1

Example 6

Bu örnektede int tür kontrolü yapılıyor, fakat bu sefer değerin ilk ve sonu kontrol ediliyor. Yani ilk ve son karakterler int ise sorgu çalışıyor.

Bu örnekte bir aşağı satıra geçmeye bile gerek yok. Örnek 4 teki payload burada da çalışıyor.

192.168.1.4/sqli/example6.php?id=2 or 1=1

Example 7

Bu örnektede int kontrolü yapılıyor. Yine %0a ile bu örneği de geçebiliriz kolaylıkla:

192.168.1.4/sqli/example7.php?id=2%0a or 1=1

Example 8

Karşımıza şu şekilde bir url çıkıyor : “192.168.1.4/sqli/example8.php?order=name”

Bunu gördüğümüz anda_ ORDER BY_ ifadesinin kullanıldığını anlıyoruz ( Sıralama yapmak için kullanılır). Url in sonundaki name yerine age yazarsak bunu doğrulamış oluruz.

Bu örnekte yapabileceğimiz pek bir şey yok çünkü ORDER BY ifadesi sorguların sonunda kullanılıyor. Yani şu şekilde gözüküyor: “SELECT * FROM table ORDER BY name ASC”

ORDER BY sorgunun sonunda kullanıldığından biz sadece sıralama şeklini değiştirebiliriz. Evet bu sayfada sql injection açığı var fakat yapabileceğimiz fazla bir şey yok.

Example 9

Example 9 da Example 8 gibi. ORDER BY ifadesi kullanılmış. SQL injection açığı var fakat yapabileceğimiz fazla bir şey yok.

 

Biz sql injection açıklarını kullanarak kullanıcıları listeledik fakat sadece kullanıcıların yaşı,adı ve id si listelendi. Bu kullanıcıların parolalarını da alabiliriz. Bunun için payloadımızı değiştirmemiz gerekecek.

İlk önce yapmamız gereken şey kullanıcıların tutulduğu tablonun ismini almak. Tabloların isimleri information_schema.tables da tutuluyor. UNION, farklı bir sql sorgusu yapabilmemize ve sonucu ilk sonuçla birleştirebilmemize olanak sağlıyor. Payloadımızı şu şekilde değiştirirsek tabloların isimlerini görebiliriz:

' union select table_name, null, null, null, null from information_schema.tables %23

Payload daki null ifadeleri açıklamak gerekirse: UNION ın çalışabilmesi için ilk sorgu ile ikinci sorgunun kolon sayısı aynı olmalı bu yüzden table_name den farklı 4 adet kolon seçildi ve aynı zamanda yine UNION ın çalışabilmesi için kolonlardaki verilerin türlerinin aynı olması gerekiyor. Biz türleri hakkında detaylı bir bilgiye sahip olamadığımızdan null kullandık, çünkü null diğer veri türlerine dönüşebiliyor.

Bu şekilde değiştirirsek payloadımızı ekranda bütün tabloların isimlerini görebilirsiniz. Tablo adını bulduktan sonra, “users”, sıra tablodaki verileri ekrana yazdırmaya geldi.

Bunun için yine UNION ifadesini kullanacağız. Payloadı aşağıdaki şekilde değiştirirsek kullanıcıların şifrelerini de almış oluruz.

' union select id,name, passwd,null,null from users %23

Sondaki %23 ifadesi # karakterinin encode hali. Yani %23 den sonrasını MySql yorum satırı olarak algılıyor ve geride kalan sorgu önemsiz kalıyor.