
Exploit de type preuve de concept pour une lecture hors limites du tas dans le filtre RAR v4 de libarchive (CVE-2025-5915), avec reproduction sous ASan, encodeur et démonstration sur appareil iOS 18.5.
Un heap over-read / divulgation mémoire contrôlé dans le chemin de filtrage RAR v4 de libarchive
(copy_from_lzss_window). Ce dépôt le reproduit de bout en bout : ASan local, un encodeur
RAR v4 écrit de zéro qui règle la taille de la fuite, et une démonstration sur appareil
sous iOS 18.5 utilisant le libarchive.2.dylib système du téléphone.
parse_filter() lit un blocklength de filtre (bytecode RAR-VM, jusqu'à 32 bits)
et copy_from_lzss_window() fait un memcpy de ce nombre d'octets hors de la fenêtre LZSS sans
vérifier qu'il tient dans dictionary_size. La taille de fenêtre est rar_fls(unp_size) << 1 —
l'attaquant contrôle les deux. Déclarez unp_size=16 → fenêtre de 32 octets, demandez
blocklength=0x3C000 → lecture d'environ 240 Ko de tas adjacent dans la sortie décompressée.a612bf62 (libarchive 3.8.0) ajoute
if (blocklength > rar->dictionary_size) return 0; (plus un correctif de dépassement dans
copy_from_lzss_window).3.7.4 — la chaîne de version ne les distingue pas (voir l'analyse §7–8).Voir l'analyse complète : writeup/cve-2025-5915.en.md
(italien : writeup/cve-2025-5915.it.md).
Le même blocklength non vérifié est la longueur d'un memcpy à deux extrémités :
Sous iOS 18.5, le plafond côté écriture (26256) est déjà backporté mais la protection côté lecture (5915)
ne l'est pas — donc sous iOS il s'agit d'une lecture uniquement (analysis/two_cve_unification.md).
writeup/ full technical article (EN + IT)
poc/
build_bigleak.py shrink unp_size in a real archive + repair header CRC-16
build_encoder.py from-scratch RAR v4 encoder; dials blocklength (leak size)
plant.c macOS realloc interpose to plant a secret after the window
*.rar proof-of-concept archives (see poc/README.md)
RARLeak/ on-device iOS harness (Xcode project)
analysis/ ASan logs, iOS patch-diff (disassembly), notes, isolated guard patch
device-proof/ output of the on-device run (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
Créez votre propre archive : python3 poc/build_encoder.py out.rar <unp_size> <blocklength> [e8e9].
poc/RARLeak est une application iOS qui arrose son tas, fait dlopen du libarchive système, lui fournit un
RAR forgé et compte combien de son propre tas revient dans la sortie. Définissez votre équipe de
signature et compilez :
cd poc/RARLeak && ./build.sh <device-udid> # set DEVELOPMENT_TEAM first (see build.sh)
Résultat attendu : un fichier déclaré sur 16 octets produit environ 196 Ko de sortie, dont environ
150 Ko proviennent du marqueur LK5915!! planté, lu hors limites. Le résultat est écrit dans le
Documents/ de l'application.
Le libarchive.2.dylib d'Apple (18.5 / 18.6) n'est pas inclus (propriétaire). Seuls leurs
SHA-1 (analysis/SHA1SUMS.ios-dylibs) et les extraits de désassemblage pertinents le sont. Extrayez
le vôtre avec ipsw dyld extract <dyld_shared_cache> libarchive.2.dylib.
N-day, corrigé dans libarchive 3.8.0 / iOS 18.6. Tout a été testé sur le matériel personnel de l'auteur. Bug signalé par JJLeo (issue libarchive #2565), recherche par Yifan Zhang (PLL, Université de Pékin), correctif par Tobias Stoeckmann et Tim Kientzle. Correctif de CVE-2024-26256 par Tobias Stoeckmann. Pour usage de recherche et défensif uniquement.
| côté | limite manquante | CVE | correctif |
|---|
| source (fenêtre LZSS) | blocklength ≤ dictionary_size | CVE-2025-5915 (lecture) | a612bf62, v3.8.0 |
dest (vm->memory, 0x40000) | blocklength ≤ VM_MEMORY_SIZE | CVE-2024-26256 (écriture) | b7b0c7c4, v3.7.5 |