用于测试在 LPC55S69 和 K82 系列 Revision A2 中发现的 BootROM 漏洞的 POC。该漏洞已在更新的设备中修复,LPC55S69 使用新的 Revision A3。
受影响设备:
已确认: LPC55S69 和 K82 系列 MCU
疑似: 其他具有类似 USB ISP 堆栈的 NXP 系列 MCU——Kinetis K 系列和 RT 系列
在 NXP LPC55s69 和 Kinetis K82 微控制器系列的 USB 系统内编程 (ISP) 模式下发现了一个缓冲区过度读取漏洞。利用该漏洞,攻击者可以从受保护的闪存中读取 16KB(LPC55S69)和 64KB(K82)的数据。
NXP LPC55S69 和 K82 MCU 提供系统内编程 (ISP) 模式,用于通过 USB、SPI、UART 和 I2C 等外设现场更新 MCU 固件。USB ISP 模式提供了一个嵌入主机,用于通过 NXP 文档化的更新命令更新固件。
ISP 是 LPC55S69 和 K82 BootROM 的一部分,根据某些寄存器位、ISP 引脚和映像头定义的值触发。对于 LPC55S69,使用 USB HID 类下载 USB0/1 端口的映像;类似地,对于 K82,ROM 中的 Kinetis 引导加载程序支持通过 USB 外设以 USB HID 类将数据加载到闪存中。
LPC55S69 和 K82 系列 IC 的 USB ISP 均使用三个端点,如下所示:
缓冲区过度读取漏洞是在 USB 控制端点 0 上观察到的,该端点用于 USB 主机枚举。
目标 1:LPC55S69
缓冲区过度读取漏洞在嵌入式 USB 主机的 GET 描述符配置请求中观察到。攻击者可以构造一个 USB 请求以发送 GET 描述符配置,通过将“wlength”值修改为 65535 字节,请求最多 16KB 的响应数据。LPC556S9 会限制并在将 16KB 数据复制到 USB TX 缓冲区并成功传输到主机时重置。
设备详情:
目标开发板:LPC55S69 – EVK RevA2 USB 主机:Ubuntu 20.04 或 Raspberry-pi 4 Model B
重现漏洞的步骤:
图 1:Ubuntu dmesg 工具显示 USB 设备详细信息
[43295.318228] usb 1-1.4: USB disconnect, device number 95
[43296.175536] usb 1-1.4: new full-speed USB device number 96 using xhci_hcd
[43296.397315] usb 1-1.4: New USB device found, idVendor=1fc9, idProduct=0021, bcdDevice= 3.00
[43296.397331] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[43296.397337] usb 1-1.4: Product: USB COMPOSITE DEVICE
[43296.397342] usb 1-1.4: Manufacturer: NXP SEMICONDUCTOR INC.
[43296.400768] hid-generic 0003:1FC9:0021.0055: hiddev0,hidraw4: USB HID v1.00 Device [NXP SEMICONDUCTOR INC. USB COMPOSITE DEVICE] on usb-0000:00:14.0-1.4/input0
在目标板和 PC 之间连接一个 USB 分析器,或使用 Linux 内核模块“usbmon”捕获 USB 数据包:
在 Wireshark 中,根据“lsusb”中的总线号过滤 USB 设备地址。
在 Ubuntu 中运行概念验证 (PoC)“sudo python3 LPC_USB.py”。为成功执行 Python 脚本,USB 主机 PC 需要以下条件: a. 安装 Python 3+ b. 安装“pyusb”模块
sudo python3 LPC_USB.py


注意 1: 在 Ubuntu 系统中,由于 Libusb 的“MAX_CTRL_BUFFER_LENGTH”限制,只能请求 4KB 的缓冲区过度读取。可以在 Raspberry-pi 系统中修改此限制并请求 16KB。附件固件“LPC.bin”是使用 Raspberry-pi 4 Model B 从 LPC55s69-EVK 板上检索到的。
如果您希望发出大于 4KB 的请求,请在树莓派上使用 Horac 创建的优秀脚本,并将 wlength 改为 65535(0xffff)运行 PoC。
目标 2:Kinetis K82
缓冲区过度读取漏洞在嵌入式 USB 主机的 GET Status-Other 请求中观察到。攻击者可以构造一个 USB 请求以发送 GET status-Other,通过将“wlength”值修改为 65535 字节,请求最多 64KB 的响应数据。K82 USB 设备成功发送了 64KB 的数据。
设备详情:
目标开发板:FRDM-K82F USB 主机:Ubuntu 笔记本电脑或 Raspberry-pi
sudo python3 K82_USB.py
注意 1: 在 Ubuntu 系统中,由于 Libusb 的“MAX_CTRL_BUFFER_LENGTH”限制,只能请求 4KB 的缓冲区过度读取。可以在 Raspberry-pi 中修改此限制并请求 64KB。
注意 2: K82 中的漏洞仅在 USB 请求 GET status-Device、Interface、Endpoint 和其他请求按顺序发生才能触发。可以通过多次 ISP 复位后运行开发的 PoC 脚本实现。
如果您希望发出大于 4KB 的请求,请在树莓派上使用 Horac 创建的优秀脚本,并将 wlength 改为 65535(0xffff)运行 PoC。