VulnHub – Brain-1 CTF Çözümü

Merhaba

VulHub’da yayınlanan CTF serilerinden birisi olan Brain-1’in çözümlerinin anlatıldığı yazıya hoş geldiniz. İlgili CTF imajını https://www.vulnhub.com/entry/brainpan-1,51/ adresinden indirebilirsiniz. Size tavsiyem yazının kalan kısımlarını okumadan önce imajı indirip kendi bilgilerinizi sınamanızdır. İlerleyen günlerde Brain-2 ve Brain-3 bölümlerini ele alacağız.

Her şeyin başı Nmap

Kali ve Brain sanal sunucularını aynı NAT networküne aldıktan sonra her zaman gib gibi -sn parametresi ile live host’ları tespit ediyoruz.

Görüldüğü üzer 10.0.0.140 hedef makinamız olan Brain’in ip adresidir. 10.0.0.138 ile Kali 2.0’ımıza ait. Hızlıca top 1000 port’u taradığımızda aşağıdak sonuç çıkmakta.

Simple Fuzzing

9999 portuna netcat ile bağlanıldığında aşağıdaki gibi bir çıktı karşımıza gelmekte.

Girdi olarak hi kelimesini yolladığımda ise ACCESS DENIED kelimesinin geri dönüş yaptığını görmekteyiz. Bu andan itibaren ilk akla gelen fikir, basit bir Buffer Overflow zafiyetinin olabileceğidir. Bunu anlamak adına aşağıdaki gibi basit bir fuzzer yazarak çalıştırabiliriz.

Fuzzing işlemi tamamlandığında aşağıdaki gibi bir çıktı bizi karşılamakta.

Gördüğünüz üzere 519 adet karakter gönderdikten sonra bir şeyler ters gitmekte ve servis crash olmakta. Bir süre bekledikten sonra servis tekrardan çalışacak şekilde bir cron job tanımladığını söyleyebiliriz.

Hedef’te buffer overflow zafiyetinin varlığı, offset değerinin hesaplanması vb gibi aşamalar kolay kısım ama hedef programa ve işletim sistemine özel RET adresini, JMP instructer’larının adresini bilebilmemiz çok zor. Bu nedenle başka bir bilgiye daha ihtiyacımızın olduğu aşikar. Bunun için Nmap çıktısına dönerek 10.000 TCP portuna bakıyoruz.

10.000 portunda Python SimpleHTTPServer’ın çalıştığını görebiliriz. Burada yapacağınız ufak bir dirbuster hareketi ile doğrudan /bin/ dini altında ki http://10.0.0.140:10000/bin/brainpan.exe dosyasının varlığını bulabilirsiniz.

Harika, şimdi her şey tamam oldu. Bu .exe dosyasını analiz edeceğiz. Hedef sistemde ASLR, DEP vb gibi koruma mekanizmalarının devre dışı olduğunu düşünerek .exe içerisinden doğrudan işe yarar bir adres bulmayı umuyoruz.

Reverse 101

İndirdiğimiz EXE’yi Windows makinada açtıktan sonra Ollydbg yada Immunity Debugger araçları ile analiz etmeye başlıyoruz. Önce işin kolay kısmı, “Offset değeri tam olarak kaç ?” sorusuna cevap vermek üzere metasploit pattern_create’i kullanıyoruz.

Bu çıktıyı basit bir netcat komutu ile hedef yönlendirdikten sonra offset değerini hesaplamak adına pattern_create komutunu kullanabiliriz. Debugger’dan aldığımız bilgiye göre EIP 35724134 değerindeydi.

Şimdi sıra ikinci suale geldi, “Acaba binary içerisinde JMP ESP komutu var mı ?” eğer doğrudan binary içerisinde bunu görebilirsek bizim için harika ve son derece basit bir exploitation olacak. Bu soruya cevap vermek için tek bir komut yeterli.

Harika..! 311712f3 adresini 524 karakter sonra tersten yazarak çok basit bir stack overflow zafiyetini exploit etmiş olacağız.

Shellcode

Shellcode için basit bir reverse_shell oluşturabiliriz. Bunun için msfvenom’u aşağıdaki şekilde kullanabilirsiniz.

Böylece doğrudan python kodu olarak shellcode üretmiş oluyoruz. \x00 karakterini blacklist’e alarak herhangi bir NULL BYTE karakter yüzünden shellcode’umuzun çalışmasının durdurulmasına engel oluyoruz.

Exploit ve Ters Bağlantı

Ve son olarak exploit saldırımız ve reverse_shell üzerinden CTF’i tamamlayımışız şu şekilde olacaktır.

Yukarıda ki exploit 10.0.0.138 ip adresinin 4444 portuna bağlantı açacaktır. Bu bağlantı üzerinden hedef sisteme erişim gerçekleştirmiş olacağız.

İlgili python komutu ile direk pty interactive shell’e geçiş yapabilirsiniz.

Post Exploitation

Kendi prensiplerim olarak hedef sisteme erişim sağladıktan sonra aşağıda ki adımlara tek tek kontrol ederek daha fazla bilgi elde etmeye çalışırım.

  • Diğer kullanıcıların listesini oluştur
  • Erişim yetkin olan dizinler altında chown’u senin kullanıcına ait olan dosyaları bul
  • bash_history dosyasına göz at

Bu bağlamda yaptığım araştırmalar gösterdi ki hedefte sahipliği bizim user’ımıza ait OLMAYAN aşağıdaki binary dosya bulunmaktaydı.

Bu executable dosyanın adı validate ve ne iş yaptığına dair hiçbir fikrimiz yok. Fark ettiğimiz tek şey ise ls -al çıktısında bulunan rwsr yetkileri. Bu sticky bit adı verilen özel bir permission bit’idir ve bizim çok işimize yarayacaktır. Çünkü anansi kullanıcısına ait bir binary’de bulacağımız zafiyeti exploit ederek sistemde ki bir başka kullanıcı yetkilerine geçiş yapabiliriz.

Validate dosyası üzerinde basit bir test gerçekleştirdiğimizde aşağıdaki şekilde segmentation fault almaktayız.

Bu binary dosyayı ister nc ile isterseniz doğrudan web/bin altına kopyalıyarak Kali makinamıza indiriyoruz. Eğer Kali’niz benim gibi x64 bit ise indirdiğiniz binary dosya çalışmayacaktır. Bu problemi çözmek için şu komutları kullanabilirsiniz.

Reversing Validate

Hedef sunucu üzerinde yaptığımız basit test ile segfault hatası aldığımız için gene basit bir stack based buffer overflow zafiyeti beklemekteyiz. Öncelikle offset’i hesaplayalım. Bu sefer Ollydbg yerine gdb kullanacağız.

Gene pattern_create ile oluşturduğumuz input’u vererek crash aldığımızda EIP’in 0x39644138 değeri aldığı gözlemlenmektedir. Bu değer üzerinden offset’i hesapladığımızda ise 116 çıkmaktadır.

Her şey hazır. Şimdi sıra JMP ESP komutunu bulmakta… Şanslıysak

Görüldüğü üzere JMP ESP komutunun olduğu herhangi bir instruction malesef yok..! Stack üzerine veri yazabiliyoruz, EIP’i kontrol edebiliyoruz ama JMP ESP veya herhangi bir CPU register’ını parametre olarak kullanan JMP komutu yok..!

Stack üzerinde analiz yapmaya devam etmek için gdb aşağıdaki komutlar ile analiz ediyoruz. EIP öncesi 116 karakterimiz A, EIP için B yazdıktan sonra dönüp kalan diğer cpu registerlarını ve stack’in durumunu kontrol edeceğiz.

0x41414141 değerlerimiz tam olarak 0xffffd328 adresinden başlıyor…Register’ların durumuna baktığımızda ise karşımıza çok ilginç bir şey çıkacak.

EAX registerı’nın deperi 0x414141’lerimizin başladığı adresin ta kendisini göstermekte. JMP ESP olarak bulamadığımız komut yerine CALL EAX bulabilirsek bu durumda EIP’i kontrol ettiğimiz BBBB yerine CALL EAX’ın adresini yazarız. Oda doğrudan shellcode’umuzun başlayacağı adrese zıplamış olur.

Harika..! Her şey hazır. Şimdi sıra 116 karakterden kısa /bin/sh çalıştıran bir shellcode yaratmakta..!

Shellcode -> Exploit -> Anansi User

Bir kez daha msfvenom kullanıyoruz ve shellcode’umuzu hazırlayabiliriz. 116 byte her ne kadar yetip artacak olsada ben genede minimal bir shellcode seçmeyi uygun görüyorum ve 28 byte uzunluğunda ki http://shell-storm.org/shellcode/files/shellcode-811.php shellcode örneğini kullanıyorum.

Fark ettiğiniz üzere shellcode’umuz 28 byte uzunluğunda. 116 – 28 = 88 byte doldurmamız gereken alan sonra EIP’e gelmiş olacağız. EIP adresini de call eax’lardan bir tanesi ile ( ben 80484af kullanacağım ) ezeceğiz ve shellcode’umuza erişmiş olacağız.

Gördüğünüz üzere puck user’ından anansi user’ına geçişi tamamlamış olduk. Şimdi sıra geldi son aşamaya.

Anansi_utils

sudo -l komutu ile NOPASSWD ile erişilebilir linux komutlarını görüyoruz.

Bu bizim için son derece kolay bir exploitation yöntemi olacak. Çünkü görünen o ki /home/anansi/bin/anansi_util ‘yi herkes root hakları ile çalıştırabilmekte. Ufak bir symlink ile doğrudan root haklarına kalıcı olarka geçiş yapabiliriz.

  • Robin Dimyanoğlu

    Hocam elinize sağlık, ctf’lere sarmışsınız bu sıralar belli. İlginizi çekerse Vulnhub’ın Persistence’ını öneririm.

    • Selam,

      Öncelikle Brain-2 ve 3’ü bitirelim. Bu sırada Nullbyte’a yeni level gelmez ise direk Persistence’a göz atarım :-) Öneri için teşekkür ederim.

  • taner

    merhaba mehmet bey bu konu hakkında kurs seminer vb. uygulamalarınız olucakma katılmayı çok isterim teşekkürler

    • Kısa vadede malesef hayır, uzun vadede ise evet, hemde bomba gibi! :-)

  • Mustafa Irann

    Güzel bir çalışma olmuş elinize sağlık. Fuzzer kodunda indentation problemleri var bilginize.