
CVE-2025-8088
Disclaimer: Questo contenuto ha esclusivamente scopo didattico e di ricerca. Non utilizzare queste informazioni per attività dannose.
Oggi facciamo un'analisi approfondita di un'affascinante vulnerabilità di path traversal, tracciata come CVE-2025-8088. Questa vulnerabilità consente a un attaccante di scrivere un file arbitrario in qualsiasi posizione sul sistema della vittima quando questa estrae un archivio RAR appositamente creato. Ciò che rende interessante questo particolare exploit è il suo approccio "a mitraglia" per garantire la consegna del payload, indipendentemente da dove l'utente estrae l'archivio.
Questo post analizzerà la tecnica utilizzata nel Proof-of-Concept (PoC) Python fornito per creare il file .rar dannoso.
L'obiettivo finale di questo PoC è classico ed efficace: persistenza. Sfruttando la vulnerabilità di path traversal, l'exploit mira a rilasciare un payload (payload.bat) nella cartella di avvio di Windows (AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup). Qualsiasi eseguibile o script inserito qui verrà eseguito automaticamente al prossimo accesso dell'utente, garantendo all'attaccante un accesso persistente.
Lo script Python automatizza un processo in più fasi per costruire il exploit.rar finale. Esaminiamo la sua logica.
La prima cosa che fa lo script è preparare i componenti:
payload.bat. Questo è il file dannoso che vogliamo rilasciare sulla macchina della vittima.PAYLOAD = "@echo off\necho Payload executed!\npause\n"
file1.txt, file2.txt, ecc.). Questi file servono a due scopi: rendono l'archivio legittimo e, soprattutto, fungono da veicoli per il nostro payload nascosto.def create_files() -> Tuple[List[Path], Path]:
# ...
for i in range(NUM_DEPTHS):
decoy = Path(f"{DECOY_FILE_PREFIX}{i+1}.txt")
" X " * 200). Questo segnaposto verrà incorporato nei metadati dell'archivio e successivamente sostituito con il nostro percorso dannoso.Questa è una parte fondamentale della tecnica. Invece di nominare un file con un percorso di traversal, lo script utilizza una funzionalità del file system NTFS chiamata Flussi di Dati Alternativi (ADS). Gli ADS consentono di "nascondere" dati all'interno di un file esistente.
Lo script associa payload.bat come ADS a ciascun file esca. Il nome di questo flusso è dove viene utilizzato il segnaposto. In sostanza, crea percorsi di file che appaiono così al file system:
file1.txt:XXXXXXXXXXXXXXXXXXXX...
Il contenuto di payload.bat è ora segretamente memorizzato all'interno di file1.txt.
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())
Successivamente, lo script individua lo strumento da riga di comando Rar.exe sul sistema e lo utilizza per creare un archivio base legittimo (base.rar). Questo archivio contiene tutti i file esca, che ora trasportano segretamente il payload nei loro Flussi di Dati Alternativi.
A questo punto, base.rar è un archivio perfettamente valido e non dannoso. WinRAR può estrarlo senza alcun problema e creerà i file esca con i loro nomi ADS lunghi e strani.
def create_base_rar(rar_exe: str, decoys: List[Path]) -> Path:
# ...
subprocess.run(
f'"{rar_exe}" a -ep -os "{base_rar}" {files}',
# ...
)
È qui che l'exploit diventa astuto e resiliente. L'attaccante non sa dove la vittima estrarrà l'archivio. Sarà C:\Users\victim\Downloads? C:\? D:\Temp?
Per superare questa incertezza, lo script genera un elenco di diverse stringhe di path traversal, ciascuna con una profondità diversa:
..\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.batL'idea è che fornendo più profondità, almeno una di esse riuscirà a navigare dalla directory di estrazione fino alla radice del file system (come C:\) e poi nella cartella di avvio target.
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
Questo è il cuore dell'exploit. Lo script apre base.rar in modalità binaria ed esegue un intervento chirurgico su di esso.
Itera attraverso la struttura interna dell'archivio, cercando l'intestazione di ciascun file (file1.txt, file2.txt, ecc.). All'interno di ogni intestazione, trova il nome ADS segnaposto (:XXXXXXXXXXXXXXXXXXXX...) e lo sostituisce con uno dei percorsi di traversal dannosi generati nel passaggio precedente.
file1.txt riceve il percorso con ..\.file2.txt riceve il percorso con ..\..\.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)
# ...
Semplicemente modificare i dati dell'intestazione corromperebbe l'archivio. WinRAR utilizza un checksum CRC32 per verificare l'integrità di ogni blocco di intestazione. Se il checksum non corrisponde al contenuto dell'intestazione, verrà generato un errore.
Il PoC anticipa questo problema. Dopo aver applicato la patch a un'intestazione con il percorso dannoso, ricalcola il corretto checksum CRC32 per l'intero blocco di intestazione modificato e riscrive il nuovo checksum nel file. Questo fa sì che l'archivio manomesso appaia perfettamente valido a WinRAR.
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)
# ...