
Exploit proof-of-concept per una heap over-read nel filtro RAR v4 di libarchive (CVE-2025-5915) con riproduzione ASan, encoder e dimostrazione su dispositivo iOS 18.5.
Un heap over-read / memory-disclosure controllato nel percorso del filtro RAR v4 di libarchive
(copy_from_lzss_window). Questa repo lo riproduce end-to-end: ASan locale, un encoder RAR v4
scritto da zero che regola la dimensione della leak, e una dimostrazione su dispositivo su iOS 18.5
usando la libarchive.2.dylib di sistema del telefono.
parse_filter() legge un blocklength del filtro (bytecode RAR-VM, fino a 32 bit)
e copy_from_lzss_window() esegue memcpy di altrettanti byte fuori dalla finestra LZSS senza
verificare che stiano in dictionary_size. La dimensione della finestra è rar_fls(unp_size) << 1 — l'attaccante
controlla entrambi. Dichiara unp_size=16 → finestra di 32 byte, chiedi blocklength=0x3C000 → leggi
~240 KB di heap adiacente dentro l'output decompresso.a612bf62 (libarchive 3.8.0) aggiunge if (blocklength > rar->dictionary_size) return 0;
(più una correzione per il wrap-around in copy_from_lzss_window).3.7.4 — la stringa di versione non le distingue (vedi write-up §7–8).Vedi il write-up completo: writeup/cve-2025-5915.en.md
(in italiano: writeup/cve-2025-5915.it.md).
Lo stesso blocklength non verificato è la lunghezza di una memcpy con due estremità:
Su iOS 18.5 il limite lato scrittura (26256) è già backportato ma la protezione lato lettura (5915)
non lo è — quindi su iOS questo è esclusivamente una read (analysis/two_cve_unification.md).
writeup/ articolo tecnico completo (EN + IT)
poc/
build_bigleak.py riduce unp_size in un archivio reale + ripara il CRC-16 dell'header
build_encoder.py encoder RAR v4 scritto da zero; regola blocklength (dimensione leak)
plant.c interpose realloc su macOS per piantare un segreto dopo la finestra
*.rar archivi proof-of-concept (vedi poc/README.md)
RARLeak/ harness iOS su dispositivo (progetto Xcode)
analysis/ log ASan, patch-diff iOS (disassembly), note, patch di isolamento della guardia
device-proof/ output dell'esecuzione su dispositivo (iPhone, iOS 18.5)
git clone https://github.com/libarchive/libarchive && cd libarchive && git checkout v3.7.4
CC=clang CFLAGS="-fsanitize=address -g -O1" LDFLAGS="-fsanitize=address" \
cmake -B build-asan -DENABLE_TEST=OFF . && cmake --build build-asan --target bsdtar
ASAN_OPTIONS=detect_leaks=0 build-asan/bin/bsdtar -xOf poc/enc_0x40000.rar >/dev/null
# -> AddressSanitizer: heap-buffer-overflow READ of size 262112
Creane uno tuo: python3 poc/build_encoder.py out.rar <unp_size> <blocklength> [e8e9].
poc/RARLeak è un'app iOS che spruzza il proprio heap, fa dlopen della libarchive di sistema, riceve un
RAR appositamente costruito e conta quanto del proprio heap torna indietro nell'output. Imposta il tuo
signing team e compila:
cd poc/RARLeak && ./build.sh <device-udid> # imposta prima DEVELOPMENT_TEAM (vedi build.sh)
Atteso: un file dichiarato come 16 byte produce ~196 KB di output, di cui ~150 KB sono il marcatore
LK5915!! piantato e letto fuori dai limiti. Il risultato viene scritto nella cartella Documents/ dell'app.
La libarchive.2.dylib di Apple (18.5 / 18.6) non è inclusa (proprietaria). Sono inclusi solo i loro
SHA-1 (analysis/SHA1SUMS.ios-dylibs) e gli estratti di disassembly pertinenti. Estrai la tua con
ipsw dyld extract <dyld_shared_cache> libarchive.2.dylib.
N-day, corretto in libarchive 3.8.0 / iOS 18.6. Tutto è stato testato sull'hardware dell'autore. Bug segnalato da JJLeo (issue #2565 di libarchive), ricerca di Yifan Zhang (PLL, Peking University), fix di Tobias Stoeckmann e Tim Kientzle. Fix di CVE-2024-26256 di Tobias Stoeckmann. Solo per uso di ricerca e difensivo.
| lato | bound mancante | CVE | fix |
|---|
| sorgente (finestra LZSS) | blocklength ≤ dictionary_size | CVE-2025-5915 (read) | a612bf62, v3.8.0 |
destinazione (vm->memory, 0x40000) | blocklength ≤ VM_MEMORY_SIZE | CVE-2024-26256 (write) | b7b0c7c4, v3.7.5 |