Selamlar dostlar yeni bir makine çözümüyle sizlerle beraberim. Bu seferki makinemiz Hack The Box üzerinde bulunan BountyHunter makinesi. Lafı çok uzatmadan çözümüne geçelim.
USER FLAG
Öncelikle her makinemizde olduğu gibi nmap sorgusu ile açık portlarımızı görelim.
Açık 2 adet portumuz var birisi 80 diğeri 22. Alışık olduğumuz şeyler :D. O zaman gelin bakalım 80 portu üzerinde ne çalışıyormuş.
Bizi böyle bir web sayfası karşılıyor. Dirbuster kullanıp farklı hangi dizinler var onu kontrol edelim.
Dikkatimi çeken iki sayfa var birisi portal.php diğeri ise log_submit.php şimdi gidip ikisininde içinde ne var bakalım.
Portalımızda, bize portalın geliştirme aşamasında olduğunu bounty tracker’ı test sayfasını kullanarak test edebileceğimizi söylüyor. Test sayfası da dirbusterda gördüğümüz log_submit.php sayfası. Gelin orayı kontrol edelim.
Bu sayfada bir form var ve buraya bilgileri girdikten sonra submit butonuna tıkladığımızda bize aşağıdaki gibi bir çıktı veriyor.
Mesajdan anladığımız üzere bu script veritabanına bir şey girmiyor. Sadece yazdıklarımızı bize geri döndürüyor. Araya burpsuite ile girip isteği kontrol edelim.
İsteğimize baktığımızda /tracker_diRbPr00f314.php adresine POST ile istek atıldığını görüyoruz. Ve data adında bir adet parametremiz var. Bu parametreye girilen değeri seçerek inspector kısmını açtığımda benim için decode ediyor ve sağ tarafta decode edilmiş halini veriyor.
<?xml version="1.0" encodinISO-8859-1"?>
<bugreport>
<title>test</title>
<cwe>test</cwe>
<cvss>test</cvss>
<reward>test</reward>
</bugreport>
Yukarıda gördüğünüz xml verisi data parametresi ile /tracker_diRbPr00f314.php adresine giden veri. Bunu görünce aklımıza XML External Entity (XXE) gelmeli. XXE zafiyetini https://portswigger.net/web-security/xxe adresinden inceleyebilirsiniz. XXE kullanarak bir sorgu deniyorum. Yani yukarıdaki xml verisini aşağıdaki gibi değiştiriyorum.
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<bugreport>
<title>test</title>
<cwe>test</cwe>
<cvss>test</cvss>
<reward>&xxe;</reward>
</bugreport>
Bu veri sayesinde makinemizin /etc/passwd dosyasını okuyup ekrana yazdırabiliriz. Gelin deneyelim. Öncelikle yapmamız gereken şey bu veriyi base64 formatına çevirip ardından url encode işlemi yapmak. Bu işlemleri yaptıktan sonra verimiz aşağıdaki gibi oldu.
PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KPCFET0NUWVBFIGZvbyBbIDwhRU5USVRZIHh4ZSBTWVNURU0gImZpbGU6Ly8vZXRjL3Bhc3N3ZCI%2BIF0%2BCjxidWdyZXBvcnQ%2BCjx0aXRsZT50ZXN0PC90aXRsZT4KPGN3ZT50ZXN0PC9jd2U%2BCjxjdnNzPnRlc3Q8L2N2c3M%2BCjxyZXdhcmQ%2BJnh4ZTs8L3Jld2FyZD4KPC9idWdyZXBvcnQ%2B
Gelin bu veriyi data parametresine verelim ve isteği devam ettirelim bakalım xxe zafiyetinden faydalanabilecekmiyiz.
Data parametremizi değiştirdik şimdi sorguyu devam ettirelim. Ve sonucu görelim.
Sonuç tam tahmin ettiğimiz gibi xxe ile makinemizin /etc/passwd dosyasını okuyabildik. Şimdi yapacağımız şey şu dirbuster taramasında bir dosya görmüştük. /resource/README.txt adında orayı okuduğumuzda görevler arasında log_submit.php scriptini veritabanına bağlamaktan bahsediyordu. Hemen orayı da sizlere göstereyim.
Buradan yola çıkarak sistemde bir config.php dosyası olabileceğini çıkarabiliriz. Ancak config.php dosyasını okumayı denediğimizde öyle bir dosya olmadığını görüyoruz. Ve farklı varyasyonlar deniyoruz. En son log_submit.php dosyasındaki “If DB were ready, would have added:” ifadesinden yola çıkıyoruz ve db.php dosyasını kontrol ediyoruz. Ancak burada php dosyasını doğrudan okuyamıyoruz. Bu yüzden sorgumuzu değiştirmek zorundayız. /etc/passwd dosyasını çekerken “file:///etc/passwd” komutunu kullanmıştık. Burada ise “php://filter/convert.base64-encode/resource=db.php” şeklinde çağırmak zorundayız. Yani xml şablonumuz aşağıdaki gibi oldu.
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=db.php"> ]>
<bugreport>
<title>test</title>
<cwe>test</cwe>
<cvss>test</cvss>
<reward>&xxe;</reward>
</bugreport>
Şimdi bu şablonla db.php dosyasını okumayı deneyelim.
Denediğimizde karşımıza veritabanı bağlantı bilgileri geliyor. Hatırlıyorsanız /etc/passwd dosyasını okumuştuk. Orada development adında bir kullanıcı vardı. Şimdi bu bulduğumuz parolayı development kullanıcısına ssh ile bağlanmayı denerken kullanabiliriz.
Parolayı kabul etti ve user.txt dosyasını okuyarak BountyHunter makinesinin User Flag kısmını başarıyla tamamlamış olduk.
ROOT FLAG
BountyHunter makinesinin user tarafını hallettiğimize göre root tarafına şöyle bir bakalım. Öncelikle yapmak istediğim development kullanıcısının dizinini listelemek. Hemen bakalım ne varmış.
Contract.txt adında bir dosyamız var ve bu dosyanın içine yönetici bir mesaj bırakmış. Mesajda bilet doğrulayıcı bir yazılım olduğunu ve bunu kullanabilmemiz için yetki ayarlarını değiştirdiğini söylemiş. Yetki ayarları dediğinde aklımıza gelen ilk şey “sudo –l” komutu ile sudoyu hangi komutlar için kullanabileceğimizi öğrenmeye çalışmak. Hemen bakalım ne yapabiliyormuşuz.
“/usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py” komutunu sudo ile şifre istemeden kullanabiliyormuşuz. Artık yazılımın da hangi dizinde olduğunu biliyoruz. O dizine gidip python ile yazılmış programın işlevinin ne olduğuna bakalım.
Bilet doğrulayıcı yazılımımızın kodları bunlar. Buraya ilk baktığımızda bir şey göremesekte biraz daha düşününce eval fonksiyonunu görüyoruz. Eval fonksiyonunu kullanarak bir şeyler yapabiliriz. Bunun dışında dizinde hatalı biletlerin olduğu bir klasörde var. Oradaki bir bileti alıp test edebiliriz. Hemen yapalım.
Denediğimiz ticket için invalid hatası aldık. Yukarıdaki python kodlarına göre ticketi düzenleyebiliriz. Ancak ben doğrudan aklıma gelen eval fonksiyonuna oynamayı tercih edeceğim. Bunun için öncelikle bir ticketi development kullanıcısının dizinine kopyalıyorum. Amacım ticketi düzenlemek.
Artık kopyaladığım ticketi düzenleyebilirim. Hemen eklemek istediğim satırı ekleyip çalıştırmak istiyorum.
Bu bizim biletimizin son hali. Ancak bunu çalıştırmadan önce neden doğrudan eval fonksiyonuna yöneldiğimi size açıklayayım. Eval fonksiyonu ona verilen parametreyi nasıl anlarsa öyle çalıştırır. Amacı dinamik kod üretebilmektir. Yani diyelim ki bir değişkene kod yazdınız yine bir python kodu. Bu değişkeni eval fonksiyonuna verirseniz değişkenin içindeki kodları çalıştırmaya başlar. Burada yaptığımız işlem de aynı şekilde çalışıyor. Biz ticketValidator.py yazılımında eval ile çalıştırılan yeri bir komut haline getirmiş olduk yani orası çalıştığı anda amacımıza ulaşabileceğiz. Daha fazla uzatmadan düzenlediğimiz bilet ile root olabiliyor muyuz bakalım.
Başarıyla root kullanıcısının yetkilerine erişebildik ve BountyHunter makinesini tamamlamış olduk.
Bu yazım da buraya kadardı umarım yeterince açık anlatabilmişimdir. Hepinize iyi çalışmalar…