HackTheBox / Late

LinkDifficultyCreator
LateEasykavigihan

Scan / Enumeration

Makinedeki açık portları keşfedebilmek için nmap aracını kullanarak port taraması yapyıyorum. Araca -T4 parametresini vererek tarama hızını arttırıyorum. Tarama sırasında çıktı alabilmek için -vv parametresini, bütün portların taranması için -p- parametresini kullanarak taramayı başlatıyorum.

nmap -T4 -vv -p- $IP

Makinede 22 ve 80 portlarının açık olduğunu görüyorum. Bu portlar üzerinde çalışan servisleri ve versiyonları öğrenebilmek için bir nmap taraması daha yapıyorum. Script ve versiyon taraması için -sVC parametresini, portları belirtmek için -p parametresini ve tarama sonucunu bir dosyaya kaydetmek için -oN parametresini kullanıyorum.

nmap -sVC -p22,80 -oN late.nmap $IP

22 Portunda çalışan OpenSSH servisinin 7.6p1 versiyonu için yakın zamanda çözmüş olduğum Dogcat makinesinde bir exploit taraması gerçekleştirmiştim. Bu nedenle bu servis üzerinde kullanabileceğim bir user enumeration zafiyeti dışında herhangi bir zafiyet olmadığını biliyorum.

80 portunda çalışan nginx servisinin 1.14.0 versiyonu için searchsploit ve arama motorları aracılığıyla bir exploit taraması gerçekleştiriyorum fakat herhangi bir zafiyet bulamıyorum. Makinede bulunan websitesini el ile keşfetmeye başlamadan önce sitede bulunan dizinleri keşfetmek ve sitenin yapısını anlayabilmek için bir gobuster ve nikto taraması başlatıyorum.

Gobuster aracını dir parametresini vererek dizin taraması yapacağını anlatıyorum. Tarancak sitenin adresini -u parametresiyle, taramada kullanılacak wordlist’i -w parametresiyle belirtiyorum. Dizin taraması sırasında dosya taraması da yapması için -x parametresiyle dosya uzantısı belirtiyorum. Taramanın hızını -t parametresiyle belirliyorum ve taramanın çıktısını -o parametresiyle bir dosyaya kaydediyorum. Nikto aracına -h parametresiyle hedef siteyi belirterek taramayı başlatıyorum.

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

Siteyi incelemek için bir tarayıcı aracılığıyla siteye erişiyorum. Sitenin footer’ında late.htb domainini görüyorum ve hosts dosyama ekleyerek siteye bu domain üzerinden erişiyorum. Sitenin index sayfasında images.late.htb adresine referans verdiğini görüyorum ve bu adresi de hosts dosyama ekleyerek sayfayı incelemeye başlıyorum.


Gain Access

Sayfanın başlığında yer alan “with Flask” yazısından sayfada python‘un flask modülü kullanıldığı anlaşılabiliyor. Sayfaya bir resim yükleyerek normal bir şekilde kullanmayı deniyorum ve yüklediğim resimin içerisinde bulunan yazıları text olarak bana geri verdiğini görüyorum. Görsel içerisindekiler, text’e çevrilirken geçtikleri işlemlerin Server Side Template Injection zafiyeti içerebileceğini düşünerek flask’ın SSTI ile nasıl exploit edilebileceğini araştırıyorum.

HackTricks’in SSTI sayfasını incelerken zafiyetin tespitini kolaylaştıran bir görselle karşılaşıyorum.

Bu görselden hareketle buradaki payloadları içeren bir dosya oluşturuyorum ve ekran görüntüsünü alarak images.late.htb adresine yüklüyorum ve bir hata mesajı ile karşılaşıyorum.

Hata mesajından yüklediğim payloadlardan bir kaçının çalıştığını fakat integer çıktı verdikleri için uygulamaya hata verdirdiklerini tahmin ediyorum. HackTrick‘in sayfasındaki python bölümüne gidiyorum. Burada Tornado, Jinja2 ve Mako‘nun kullanılabilir olduklarını görüyorum. Flask üzerine biraz araştırma yaptıktan sonra Flask’ın Jinja’yı kullandığını öğreniyorum. Bu sefer yalnızca string çıktısı verecek olan {{7*'7'}} değerini yüklüyorum ve sayfanın bu değeri işleyip 7777777‘ye dönüştürdüğünü dolayısıyla SSTI zafiyeti içerdiğini görüyorum.

Payload’ı bir görsel üzerinde vermem gerektiği ve hedef sunucu üzerindeki app’in, görselin üzerindeki yazıyı hatasız okuması gerektiği için terminale komutları yazıp ekran görüntüsünü server’a yükleme sistemim tutarlı bir şekilde çalışmıyor. Tutarlı bir şekilde çalışıp, yüklediğim her görselde sunucudan çıktı alabilmek için girdiğim text’i görsele çevirecek bir python kodu yazıyorum. Görsel içerisinde sunucunun anlayabileceği bir fontu kullanabilmek için google fonts üzerindeki fontların bir çoğunu deniyorum ve sonunda Inconsolata fontunun çalıştığını görüyorum.

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

def getSize(txt, font):
    testImg = Image.new('RGB', (1, 1))
    testDraw = ImageDraw.Draw(testImg)
    return testDraw.textsize(txt, font)

if __name__ == '__main__':

    fontname = "Inconsolata-Regular.ttf"
    fontsize = 30
    text = "{{ config.__class__.__init__.__globals__['os'].popen(' uname -a && id ').read()}}"

    colorText = "black"
    colorBackground = "white"


    font = ImageFont.truetype(fontname, fontsize)
    width, height = getSize(text, font)
    img = Image.new('RGB', (width+20, height+30), colorBackground)
    d = ImageDraw.Draw(img)
    d.text((15, height/2), text, fill=colorText, font=font)

    img.save("<output_path>")

Yazdığım koddan verdiğim text’i görsel olarak alıyorum ve sunucuya yükleyerek istediğim çıktıyı elde ediyorum.

Sunucuda /home dizini altında bulunan kullanıcıları ve varsa kullanıcıların .ssh dizinlerini kontrol ederek bir id_rsa dosyası elde etmeyi ve sunucuya SSH üzerindne bağlanmayı hedefliyorum. Sunucu ls komutunu çalıştırmayı denediğim her seferinde boş cevap aldığımı görüyorum. Buna karşın ls komutu yerine echo komutunu kullanarak dosyaları listeliyorum ve /home/svc_acc/.ssh/ dizini içerisinde kullanabileceğimi düşündüğüm bir id_rsa dosyası buluyorum.

Buradan elde ettiğim id_rsa dosyasını kullanarak sunucuya SSH ile bağlanıyorum.


Privilege Escalation

İlk olarak bağlandığım kullanıcının yetkisinin sudo -l komutuyla kontrol etmeyi deniyorum fakat kullanıcının parolasını bilmediğim için herhangi bir şey göremiyorum. Kullanabileceğim bir SUID dosya olup olmadığını kontrol etmek için find komutunu kullanıyorum. Aranacak dizin olarak / dizinini veriyorum. SUID yetkisine sahip dosyaları aramak için -perm parametresine -4000 değerini veriyorum. Hataları ekrana basmak yerine /dev/null’a göndermek için 2>/dev/null‘u kullanıyorum.

find / -perm -4000 2>/dev/null

Fakat kullanabileceğimi düşündüğüm herhangi bir SUID dosyası görmüyorum. Kullanabileceğim cronjob’ları kontrol etmek için /etc/crontab dosyasını kontrol ediyorum ve crontab -l komutunu deniyorum fakat herhangi bir cronjob ile karşılaşmıyorum. Kullanabileceğim bir şey bulmak amacıyla makine hakkında daha fazla bilgi edinmek için linPEAS‘i kullanıyorum. Makinemde python ile bir server ayağa kaldırarak hedef makine üzerinde wget ile linpeas script’ini çekiyorum. Script’e çalıştırma yetkisi verdikten sonra çalıştırıyorum ve çıktısını incelemeye başlıyorum.

Çıktıda, /usr/local/sbin dizini PATH’te olduğu için uyarı verdiğini görüyorum. Yazabileceğim dosyalar içerisinde /usr/local/sbin dizini altında ssh-alert.sh isminde bir script olduğunu görüyorum.

Dosyayı okuduğumda giriş yapan her kullanıcının bilgilerini /usr/sbin/sendmail aracılığıyla root@late.htb adresini gönderildiğini görüyorum.

Dosyanın sahibi ben olduğum ve dosyaya yazma hakkım bulunduğu için dosyanın root tarafından çalıştırılması halinde yetki yükseltebileceğimi düşünüyorum. Dosyanın her kullanıcı girişi yapıldığında kim tarafından çalıştırıldığını anlamak için içerisine basitçe id >/tmp/bywho satırını eklemeyi düşünüyorum. Dosyayı vim ile açarak yazmaya çalıştığımda yazamadığımı görüyorum.

Dosyanın yetkilerini tekrar kontrol ediyorum ve yazma yetkisinde bir problem olmadığını gözlemliyorum. Dosyanın attribute’lerini lsattr komutu ile kontrol ettiğimde a -append only- ve e -block extents- attribute’lerine sahip olduğunu görüyorum. Dosyaya yazamama nedenim a attribute’u olduğu için bunu kaldırmak için chattr -a <file> komutunu kullanarak kaldırmaya çalışıyorum fakat yetkim olmadığı için yapamıyorum.

Dosyı açarak komut ekleyemesem de komut ile direkt olarak eklemeye çalışıyorum ve ekleyebiliyorum

Yeni bir terminal üzerinden tekrar SSH bağlantısı kuruyorum ve bağlantı sonrası /tmp dizinini kontrol ettiğimde istediğim dosyanın yazıldığını görüyorum.

Dosyayı root kullanıcısı çalıştırıyor dolayısıyla dosyanın içerisine bir reverse shell kodu yazarsam root kullanıcısı ile shell alabilirim. Aynı yöntemle dosyanın içerisine reverse shell kodunu yazıyorum. Bir terminalden makineye SSH ile bağlanırken başka bir terminalden nc ile portu dinliyorum ve shell’i alıyorum.

-Gev