Deutschlands Bester Hacker - Blinde Flecken (OT) - 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 OTOperational TechnologyHardware und Software zur Überwachung oder Steuerung physischer Anlagen, Maschinen und industrieller Prozesse.
Punkte 465
Angriffsklasse Unvollständige EnumerationEnumerationErmittelt Benutzer, Dienste, Freigaben oder andere Ressourcen eines Zielsystems. — UDP-Dienste im Leitnetz
Flag DBH{UDP_UNT3R_D3M_RADAR_1M_LEITNETZ_XXX}

Die Challenge

Die Challenge dreht sich um einen typischen blinden Fleck bei interner Enumeration: UDP-Dienste werden oft übersehen, wenn nur TCP gescannt wird. Die Flag ist in drei Teile zerlegt, verteilt über drei UDP-Dienste — der Weg dorthin führt aber über TCP.

Aufklärung

Zuerst die lokalen Listener:

ss -lun
ss -ltn

Ergebnis:

  • UDP: 69 (TFTPTFTPMinimales Dateiübertragungsprotokoll über UDP, ohne Authentisierung und ohne Verzeichnisauflistung.), 161 (SNMPSNMPProtokoll zur Abfrage und Konfiguration von Netz- und Infrastrukturgeräten über UDP.), 8080 (UDP-basiertes Pseudo-HTTP)
  • TCP: 22, 80, 199

Damit war klar, dass der Fokus auf den UDP-Diensten liegen muss. 80/tcp und 199/tcp lieferten nur Hinweise beziehungsweise Nebenspuren — allerdings die entscheidenden.

Die Schwachstelle

Der TCP-Webserver auf Port 80 zeigt zunächst nur eine harmlose interne Portal-Seite. Interessant wird die robots.txt:

curl -i http://127.0.0.1/robots.txt
User-agent: *
Disallow: /it-administration.bak/

Der Pfad war erreichbar und enthielt Notiz.txt und backup.log.

Notiz.txt enthielt den klaren Hinweis auf UDP-Scanning:

Liebe Kollegen,

als Reminder: -sU

-- M.

backup.log war der entscheidende Hinweis für den TFTP-Dateinamen:

# Backup-Sammeljob "GLT-Wochenlauf"

[Di 02:14:07]  Trafostation Ost               -> trafostation_backup.cfg       4108 B   OK, uebernommen
[Di 02:14:41]  Notstromaggregat B             -> notstromaggregat_backup.cfg   3742 B   OK, uebernommen
[Di 02:15:02]  Zugangskontrolle Aussenstelle  -> zugangskontrolle_backup.cfg   2916 B   OK, uebernommen
[Di 02:15:33]  Leitstelle (LS-FR-07)          -> FEHLER: Zielhost antwortet nicht

# TODO (M.): LS-FR-07 haengt seit Firmware 3.4.1.

Da die Leitstelle im Log explizit genannt wird, ließ sich der fehlende TFTP-Dateiname sauber ableiten: leitstelle_backup.cfg.

Der Angriff

Teil 2/3 — UDP-HTTP auf 8080/udp. Der Dienst antwortet auf einen simplen HTTP-Request per UDP:

printf 'GET / HTTP/1.0\r\n\r\n' | nc -u -w2 127.0.0.1 8080
HTTP/0.9 200 OK
X-Hinweis: Kein echtes HTTP -- diese Antwort kam per UDP, nicht TCP.

Teil 2/3: UNT3R_D3M_RADAR_

Teil 3/3 — SNMP auf 161/udp. Zuerst die Community prüfen:

onesixtyone 127.0.0.1
127.0.0.1 [public] Leitstellen-Aussenstelle -- Gebaeudetechnik-Segment

Dann den NET-SNMP-Extend-Bereich abfragen:

snmpwalk -v2c -c public 127.0.0.1 1.3.6.1.4.1.8072.1.3

Der Extend-Eintrag fragment3 gibt den dritten Teil direkt aus:

Teil 3/3: 1M_LEITNETZ_XXX}

Teil 1/3 — TFTP auf 69/udp. Mit dem aus dem Log abgeleiteten Namen:

atftp --trace -g -r leitstelle_backup.cfg -l /tmp/tftp-hit 127.0.0.1 69
cat /tmp/tftp-hit
# Leitstellen-Backup -- Netzwerk-Konfiguration (auto-generiert)
# Nicht manuell bearbeiten.

device.id = LS-FR-07
device.location = Landratsamt Bayreuth, Gebaeudetechnik
device.firmware = 3.4.1
device.protocol = TFTP (RFC 1350, kein Auth)

# TODO: dieses Kommentarfeld vor Produktivbetrieb entfernen
# Teil 1/3: DBH{UDP_

Die Flag

Zusammengesetzt aus allen drei Teilen:

DBH{UDP_UNT3R_D3M_RADAR_1M_LEITNETZ_XXX}

Was ich mitnehme

  • Ein reiner TCP-Scan hätte die eigentlich relevanten Dienste komplett verpasst. In OT-Umgebungen sind TFTP und SNMP ohne Auth eher Regel als Ausnahme.
  • robots.txt und ein versehentlich offen liegendes Backup-Verzeichnis lieferten den entscheidenden Kontext — der Weg zur UDP-Flag lief über TCP.
  • Der Ablauf war am Ende geradlinig: UDP-Dienste identifizieren → 8080/udp für Teil 2 → 161/udp für Teil 3 → 80/tcp als Hinweisgeber auf backup.log → 69/udp mit dem dort abgeleiteten Dateinamen für Teil 1.