
CTF-Herausforderung, die einen Heap-Overflow in libpngs png_image_finish_read ausnutzt, um einen Funktionszeiger zu überschreiben und eine Shell zu starten, mit Build-Skripten und Exploit-Generator.
Diese Herausforderung basiert auf einer realen Pufferüberlauf-Schwachstelle in libpng (speziell im Umgang mit der vereinfachten API png_image_finish_read bei der Verarbeitung von 16-Bit-interlaced-Bildern).
Sie erhalten eine verwundbare Binärdatei victim, die eine statisch gelinkte, verwundbare Version von libpng verwendet. Die Anwendung liest eine PNG-Datei namens exploit.png in einen Puffer.
Ihr Ziel ist es, eine bösartige PNG-Datei zu erstellen, die einen Heap-Überlauf auslöst, um einen Funktionszeiger in der Logger-Struktur (unmittelbar nach dem Bildpuffer) zu überschreiben und die Ausführung zur win()-Funktion umzuleiten, um eine Shell zu starten.
Voraussetzungen: gcc, make, python3, git, autoconf, automake, libtool.
Repository klonen:
git clone --recursive https://github.com/bohemian-miser/CVE-2025-65018_Exploit_Challenge.git
cd CVE-2025-65018_Exploit_Challenge
Challenge erstellen (einschließlich verwundbarem libpng):
./build.sh
Dieses Skript wird:
libpng-Quellcode konfigurieren und patchen, um die Schwachstelle zu aktivieren.libpng-Bibliothek erstellen.victim-Binärdatei kompilieren.Die Schwachstelle besteht darin, wie libpng interlaced Bilder behandelt, wenn es von 16-Bit-Eingabe in 8-Bit-Ausgabe konvertiert.
PNG_FORMAT_RGBA). libpng weist eine Puffergröße zu, die für 8-Bit-Daten ausreicht.png_combine_row fälschlicherweise Daten mit der 16-Bit-Farbtiefe der Eingabe in den Ausgabepuffer.Die Binärdatei enthält eine Hilfsfunktion win(), die execl("/bin/sh", ...) aufruft. Wir benötigen ihre Adresse. Da die Binärdatei mit -no-pie kompiliert wurde, sind die Adressen statisch.
nm victim | grep win
# Output: 00000000004013e0 T win
Zieladresse: 0x4013e0
solve.py)Wir müssen ein gültiges PNG erstellen, das:
IHDR) mit 16-Bit-Farbtiefe hat.win) bilden.Das Skript solve.py macht Folgendes:
Logger-Struktur (die 4096 Bytes nach dem Start des Puffers liegt).win-Adresse in den Pixeldaten der letzten Zeile.IDAT-Chunk.Payload-Layout:
Die win-Adresse 0x4013e0 (Little Endian: E0 13 40 00 ...) muss in 16-Bit-RGB-Pixel codiert werden.
Generieren des bösartigen PNG:
python3 solve.py 4013e0
Dies erstellt exploit.png.
Ausführen des Opfers:
./victim
Erwartete Ausgabe:
[*] Win function is at: 0x4013e0
[*] Buffer at: 0x7ffd51353530
[*] Logger at: 0x7ffd51354530
[*] Offset from buffer start to logger: 4096 bytes
[*] Processing image...
[+] png_image_finish_read success
[*] Calling logger...
[*] Hacked! Spawning shell...
$
Um den Überlauf in Aktion zu sehen, können Sie GDB verwenden.
1. Breakpoint vor dem verwundbaren Aufruf setzen:
break 62
run
2. Überschreiben beobachten:
Die Logger-Struktur befindet sich bei Offset 4096. Beobachten wir den Ziel-Funktionszeiger.
print &ctx.logger.log_func
# $1 = (void (**)(const char *)) 0x7fffffffc8f0
watch *0x7fffffffc8f0
continue
3. Auslösen:
GDB wird anhalten, wenn png_combine_row in den Funktionszeiger schreibt.
Hardware watchpoint 2: *0x7fffffffc8f0
Old value = 4199366 (0x4013c6 <normal_log>)
New value = 4199392 (0x4013e0 <win>)
0x00007ffff7e024d9 in __memcpy_avx_unaligned_erms ()
Dies bestätigt, dass libpng unseren Zeiger mit der Adresse von win überschrieben hat!
victim.c: Verwundbarer Quellcode.solve.py: Exploit-Generator.libpng-src/: Quellcode für libpng (v1.6.37).build.sh: Skript zum Kompilieren aller Komponenten.Makefile: Build-System für die victim-Binärdatei.