Was passiert, wenn das Netzwerk aufgeht?
Eine PDF, die plötzlich als Crontab dient. Eine Webanwendung in XeLaTeX. Und ein Exploit, der zwar Flags findet, aber zunächst vor allem abgelaufene. Unser erstes FAUST CTF hatte einiges zu bieten.
Am 26. September 2026 trat unser Team am Technologietransferzentrum Würzburg (TTZ-WUE) erstmals in diesem Format an. Nach acht Stunden erreichten wir Platz 107 in der Gesamtwertung und Platz 47 in der Low-LLM-Wertung. Dazwischen lagen viel Analyse, einige Umwege und die Erkenntnis, dass eine gefundene Schwachstelle noch lange keine sicheren Punkte bedeutet.
Bei einem Attack/Defense-CTF betreiben alle Teams dieselben absichtlich verwundbaren Services auf ihrer eigenen sogenannten Vulnbox. Der Gameserver hinterlegt dort regelmäßig Flags, also Zeichenfolgen, die als Nachweis eines erfolgreichen Angriffs eingereicht werden. Gleichzeitig müssen die Teams fremde Flags erbeuten, ihre eigenen schützen und ihre Services funktionsfähig halten.
Bei FAUST dauert ein Tick drei Minuten; Flags können innerhalb von fünf Ticks nach ihrer Erzeugung eingereicht werden. Nach einer Stunde zur Analyse der Services wird das Netzwerk zwischen den Teams geöffnet. Dann beginnen acht Stunden Wettbewerb. Die Details erklären die FAUST-Regeln.
Die erste Stunde: Wo sind eigentlich unsere Services?
Einige Tage vorher hatten wir bereits MOTH entwickelt, unser eigenes System zur zentralen Verarbeitung und Übermittlung erbeuteter Flags. Technisch waren wir also vorbereitet. Zumindest auf einen Teil dessen, was uns erwartete.
Die erste Stunde sollte der Reconnaissance gehören: Services verstehen, Angriffsflächen finden und erste Patches vorbereiten. Stattdessen beschäftigten uns zunächst IPv6, VPN, DNS und die Frage, wo einzelne Services überhaupt erreichbar waren.
Auch die Aufgabenverteilung lief noch nicht rund. Teilweise untersuchten mehrere Personen dieselbe Schwachstelle, während andere Bereiche liegen blieben. Uns fehlten außerdem feste Blue-Team-Rollen und eine zentrale Übersicht über die Aktivitäten auf unserer Vulnbox. Wenn ein Service Probleme machte, war deshalb nicht immer klar, ob ein eigener Patch, ein fremder Angriff oder die Verbindung dafür verantwortlich war.
Während wir uns noch sortierten, wurde das Netzwerk geöffnet.
ALF: Die PDF war plötzlich ein Crontab
Einer der ersten Services, mit denen wir uns intensiver beschäftigten, war ALF. Er kombinierte Flask und PostgreSQL mit einer Dokumentkonvertierung durch Typst und einer nativen Bibliothek zur Verarbeitung von Übersetzungen.
Im Upload von Typst-Projekten fanden wir einen unsicheren Umgang mit symbolischen Links. Dadurch ließen sich Dateien außerhalb des vorgesehenen Projektverzeichnisses lesen. Auch das Ziel der PDF-Ausgabe konnte beeinflusst werden. Unter bestimmten Bedingungen ließ sich das erzeugte Dokument dadurch als Datei für einen Cron-Dienst missbrauchen.
Die PDF war plötzlich ein Crontab.
Über die Dateilesemöglichkeit sahen wir außerdem, wie andere Teams ihre ALF-Instanzen veränderten. Dabei stießen wir auf eine ausgefeilte Persistenzstrategie mit PostgreSQL-Triggern, durch die neue Flags automatisch in einen eigenen Benutzerkontext kopiert wurden. Weitere Änderungen sollten diesen Zugriff erhalten und konkurrierende Persistenz entfernen.
Damit untersuchten wir längst nicht mehr nur den ursprünglichen Service. Wir mussten auch verstehen, welche Änderungen andere Teams eingebaut hatten und wie diese miteinander interagierten.
Später führte die Analyse zu einer weiteren Schwachstelle in der nativen Bibliothek libparser.so: Bestimmte Eingaben konnten ältere Heap-Inhalte in die Antwort übernehmen. Diese Speicherpreisgabe konnten wir lokal reproduzieren und über HTTP beobachten. Einen zuverlässigen Exploit, der daraus gültige FAUST-Flags extrahierte, entwickelten wir während des Wettbewerbs allerdings nicht mehr.
Nach ungefähr vier Stunden steckten wir tief in fremden Patches, Persistenzmechanismen und Reverse Engineering. Nach einer kurzen Zusammenfassung im Team entschieden wir uns, zunächst einen anderen Service anzusehen.
LAMP: LaTeX, Apache, MariaDB, Pain
Der nächste Service hieß LAMP. Für uns stand das ziemlich schnell für LaTeX, Apache, MariaDB, Pain.
Teile der Webanwendung waren tatsächlich in XeLaTeX implementiert. HTTP-Informationen wurden in TeX-Makros überführt, Daten aus MariaDB später erneut als TeX verarbeitet. An diesen Übergängen fanden wir mehrere Fehler, die sich zu einer Angriffskette verbinden ließen.
Eine manipulierte HTTP-Eingabe ermöglichte zunächst das Lesen von Dateien im Container. Ein unzureichend validiertes Datenbankfeld führte außerdem zu einer persistenten TeX-Injection. Weil XeLaTeX mit aktivierter Shell-Ausführung lief, konnten darüber Betriebssystembefehle ausgeführt werden, mit Root-Rechten innerhalb des LAMP-Containers. Die darunterliegende Vulnbox war damit noch nicht übernommen.
Eine besondere Einschränkung blieb: Für den entscheidenden Payload standen ungefähr 32 Bytes zur Verfügung. Für einen Testbefehl genügte das, für einen vollständigen Flag-Harvester nicht. Wir mussten deshalb einen längeren Befehl getrennt hinterlegen und ihn über den kurzen Payload aufrufen.
Damit hatten wir eine funktionierende Angriffskette. Die vollständige technische Analyse und die Proof of Concepts haben wir nach dem Wettbewerb in unserem LAMP-Repository auf GitHub dokumentiert.
Im laufenden Wettbewerb wartete aber schon das nächste Problem.
Flags finden ist nicht gleich Punkte bekommen
Die erste Version unseres Harvesters suchte großzügig nach FAUST-Flags. Sie lieferte eine beeindruckende Sammlung, allerdings waren viele davon bereits abgelaufen.
Wir schränkten die Suche deshalb auf aktuelle Checker-Dateien ein, also Dateien, die bei den Prüfungen des Gameservers entstanden. Zusätzlich entwickelten wir Werkzeuge, um erreichbare und noch verwundbare Targets zu erkennen, sie regelmäßig erneut zu prüfen und bereits bekannte Flags auszusortieren.
Hier zahlte sich MOTH aus. Unsere Skripte konnten gefundene Flags direkt an die vorbereitete Infrastruktur übergeben. Deduplizierung und Kommunikation mit dem Gameserver mussten wir dadurch nicht für jeden Exploit neu implementieren.
Währenddessen patchten andere Teams ihre Services. Manche Targets verschwanden, kamen zurück oder verhielten sich plötzlich anders. Unsere Werkzeuge mussten mit diesen Veränderungen umgehen können.
Ein Proof of Concept muss nur einmal funktionieren. Ein Attack/Defense-Exploit muss immer wieder funktionieren, während sich seine Umgebung verändert.
Mit der vollständigen LAMP-Kette gelang uns schließlich genau das: Wir extrahierten gültige Flags und übermittelten sie erfolgreich an den Gameserver.
KI und das Tempo des Wettbewerbs
FAUST 2026 erlaubte KI-gestützte Werkzeuge und bot zugleich eine freiwillige Low-LLM-Kategorie mit Einschränkungen bei deren Einsatz an. Die Bedingungen sind in der LLM Policy beschrieben.
Für uns wirft diese Entwicklung vor allem eine Frage auf: Was wird wichtiger, wenn Analyse und Code-Erzeugung immer schneller werden? Unsere Erfahrung spricht für Systemverständnis und gute Entscheidungen unter Zeitdruck. Ein Exploit muss verstanden, ein Fehler richtig eingeordnet und ein Patch überprüft werden. Vor allem muss das Team entscheiden, welches Problem gerade seine Aufmerksamkeit verdient.
Was wir beim nächsten Mal anders machen
Am Ende standen Platz 107 von 223 Teams in der Gesamtwertung und Platz 47 in der Low-LLM-Wertung. Die Gesamtwertung ist auf CTFtime dokumentiert. Für unseren ersten Attack/Defense-CTF sind wir darauf stolz.
Für den nächsten Wettbewerb haben wir drei konkrete Verbesserungen mitgenommen: die Erreichbarkeit der Infrastruktur vorher durchtesten, feste Verantwortlichkeiten pro Service vereinbaren und Monitoring sowie defensive Aufgaben von Anfang an besetzen.
Auch den Wechsel zwischen Services würden wir bewusster entscheiden. ALF war technisch spannend, band aber viel Zeit. LAMP zeigte uns anschließend, wie viel Arbeit zwischen einer gefundenen Schwachstelle und einem Werkzeug liegt, das tatsächlich Punkte bringt.
FAUST hat uns acht Stunden lang gleichzeitig als Angreifer, Verteidiger, Entwickler und Team gefordert. Wir haben uns festgebissen, umgedacht und am Ende gemeinsam funktionierende Angriffe auf die Beine gestellt.
Wir würden definitiv wieder antreten.
