[TR] TryHackMe — Mindgames Write-Up

Anıl Çelik
6 min readJun 15, 2020

--

Herkese merhaba, ben Anıl Çelik. Bu yazımda, sizlerle geçtiğimiz günlerde TryHackMe platformu üzerinde yayınlanan Mindgames isimli makinenin çözümünü paylaşacağım.

İlk olarak nmap ile başlayalım:

Gördüğümüz gibi, 2 adet açık portumuz var. SSH’ın sahip olduğu versiyonda herhangi bir zafiyet bulunmadığı için, HTTP servisi üzerinde enumeration işlemine başlayabiliriz:

80 numaralı porta gittiğimizde, yukarıdaki gibi bir sayfayla karşılaşıyoruz. Sayfayı gördüğüm an Brainfuck isimli bir scripting dili ile alakalı olduğunu anladım çünkü TryHackMe üzerinde aynı tarz bir encodingi daha önce de görmüştüm. Bahsettiğim oda: THM — Year of the Rabbit, bu odaya ait yayınladığım write-up: THM — Year of the Rabbit — Write-Up. Şimdi devam edelim; öncelikle burada bulunan encode edilmiş verileri Brainfuck üzerinden decode ederek clear-text haline getirmeyi deneyebilirsiniz (benim ilk yaklaşımım buydu), veya bu verileri aşağıda bulunan kutucuğa girerek çalıştırmayı deneyebilirsiniz.

Öncelikle sayfanın kaynak kodlarına göz atalım:

Pek de heyecanlanmamızı gerektirecek bir şey yokmuş..

Şimdi de encode edilmiş verileri kutucuğa girerek çalıştırmaya çalışalım:

Hello, world” ün altında verilen kod, burada yazdığı gibi gerçekten de “Hello, world” yazısını bastırıyor. Şimdi de “Fibonacci” altında yer alan kodu deneyelim:

Görünüşe göre bu kod da üzerinde yazan şeyi aynen yapıyor; yani bir Fibonacci algoritması çalıştırıyor ve görünene göre bu algoritma Fibonacci Serisinin ilk 10 sayısını bastırıyor. Şimdi elimizde olanları gördüğümüze göre, ikinci adım olarak bu kodları decode edebiliriz:

Göründüğü gibi, sadece “Hello, World” yazdırılmasına yarayan bir Python print fonksiyonu.

İkinci parçayı decode ettiğimizde ise tanımlanmış bir fonksiyon ve bu fonksiyona 1'den 10'a kadar veri gönderen bir for döngüsü olduğunu görüyoruz. Eğer algoritmayı anlamakta zorluk çektiyseniz buradaki örnekleri incelemenizi öneririm.

Şimdi devam edelim. Göründüğü üzere, Brainfuck ile encode edilen veriler Python dilinde yazılmış kod parçaları. Belki de bunu tersine çevirebilir; yani yazdığımız bir Python kod parçasını encode edip sayfa üzerindeki interpreter üzerinde çalıştırabiliriz. Fakat öncelikle, unutmadan directory brute-force işlemini gerçekleştirelim:

Bir sonuç çıkmadı (İlk çözümü yaparken bütün wordlistler ile denedim, herhangi bir sonuç çıkmamakta.)

Şimdi ise daha önce bahsettiğimiz şeyi yapıp, direkt olarak reverse shell almayı deneyelim:

İlk olarak Python Reverse Shell payloadumu kendi yazmış olduğum bir toolu kullanarak oluşturdum. Eğer ilginizi çekerse, tool’a buradan ulaşabilirsiniz. (bu yazıyı okumakta olan bütün Bash gurularına saygılarımla belirtmek isterim ki, bu tool’u Bash programlamayı birkaç saat içerisinde öğrenip sadece kendime bir tool yazıp yazamayacağımla ilgili bir challenge oluşturup yaptım; so, nothing biggie ;) )

Elimizdeki payloadu buradan encode edelim:

Şimdi kodu çalıştırmaya çalışalım:

Beğenmediği şeyler var, belki de ufak birkaç kısmı çıkartıp tekrar deneyebiliriz:

Tekrar deneyelim:

Shell’i almayı başardık. Şimdi enumeration işlemine devam edebiliriz:

Shell’i almış olduğumuz directory içerisinde server adında ilgimizi çeken bir dosya var ancak root aşamasına geldiğimizde göreceğiz ki, bu dosya Capabilities içerisinde kafa karıştırmak için konulmuş bir rabbit hole’dan başka bir şey değil.

Öncelikle kullanıcının home dizinine gidelim ve user flag’i bulmaya çalışalım:

User flag’i elde ettik. Buradan sonra kullanıcıya ait sudo komutlarını kontrol ettim ancak bir screenshot almayı unutmuşum, zaten herhangi bir şey de yoktu. Şimdi vakit kaybetmeden linPEAS çalıştıralım:

Bu komutla, linPEAS çıktımızı output.txt isimli dosyaya kaydedebiliriz. Çıktıda gelen “grep: write error: Broken pipe” hatasını görmezden gelebilirsiniz çünkü linPEAS çalışırken Looking for specific hashes… kısmından daha ileri gidemediği durumlarda böyle bir hata fırlatıyor. Şimdi sonuca bakalım:

Bir sürü SUID binary var fakat bunlardan hiç biriyle işimiz yok. Yetkilerimizi root seviyesine yükseltmek için bizim aradığımız şey; Capabilities. Capabilities kavramına dair detaylı açıklamayı ve başka bir örneği yayınlamış olduğum bir önceki write-up’da okuyabilirsiniz: THM — Wonderland Write-Up.

Capabilities kısmını kontrol ettiğimizde, ilgimizi çeken bazı binary dosyaları görüyoruz. Burada ilk olarak benim de makineyi ilk çözerken gitmiş olduğum gibi “/home/mindgames/webserver/server = cap_net_bind_service+ep” isimli binary ile saatlerinizi harcayabilirsiniz veya direkt olarak “/usr/bin/openssl = cap_setuid+ep” isimli dosyaya giderek direkt olarak root’a doğru yol alabilirsiniz.

Klasik bir hamle olarak, direkt olarak GTFOBins’e gidip openssl ile ilgili bir arama yapabilirsiniz. %100 doğru olmamakla birlikte, doğru yoldasınız ancak eksik bazı şeyler var.

Bu makinenin adını hakettiğini düşündüğüm asıl nokta burada başlıyor. İhtiyacımız olan ve bu binaryi exploit etmemize olanak sağlayacak kodu GTFOBins üzerinde openssl için açılmış bir Pull Request’de buldum:

Bu kod bize yardım edecek fakat nasıl? OpenSSL Engine nedir? gibi sorular soruyor olabilirsiniz. Basit olarak, OpenSSL Engine içerisinde built-in olarak OpenSSL fonksiyonlarını barındıran ve bizim olayımızda bize root shell’in spawn olması için gerekli mekanizmayı tetikleyecek araçtır. Ayrıca, OpenSSL içerisindeki kriptografik fonksiyonlar için de sıkça kullanılmaktadır.

Şimdi tek yapmamız gereken, bu kod parçasına ufak bir satır eklemek:

Eklediğimiz kod satırı: setuid(0); yani spawn olacak shell içerisinde sahip olacağımız effective user ID’mizi 0; yani root olarak ayarlıyoruz. Bunu yapabiliyor olmamızın sebebi, exploit etmeye çalıştığımız capability’nin bize olanak sağladığı şey, aslında User ID’mizi istediğimiz gibi ayarlayabiliyor olmamız. Bunun için gerekli bilgiyi aşağıda görebilirsiniz:

Şimdi kodumuzu compile edelim. Burada dikkat etmemiz gereken şey, bir engine kodu compile ettiğimiz için geleneksel gcc kullanımının yanında bazı ek parametrelere ihtiyacımız olduğudur:

Burada kullandığımız -fPIC parametresi, bize daha sonra -lcrypto parametresine verecek olduğumuz a.o dosyasını oluşturmamızı sağlıyor. Geriye kalan kısımda ise engine kodu oluşturuluyor. Dosya compile edildikten sonra, engine.so isimli dosyayı makineye aktaralım ve çalıştırarak root shell elde etmeye çalışalım:

req -engine parametresini bir engine kodu çalıştıracağımız için kullanıyoruz

Görüldüğü gibi, root shell’i ve root flag’i elde ettik.

Bu makineyle ilgili sizlerle paylaşmak istediklerim bu kadardı, umarım bir faydası olmuştur. Yazımı okuduğunuz için teşekkür ederim.

Bir sonraki yazımda görüşmek üzere.

Kaynaklar:

--

--

Anıl Çelik
Anıl Çelik

No responses yet