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.
