基于最近,我开始使用它Facedancer挖掘的工具USB主机堆栈中的漏洞。本文首先介绍了我的Fuzzing测试方法,然后给出完全更新Windows 8.1 x64漏洞的实际示例。本文的目的不是重新定义USB Fuzzing测试,不是对我的Fuzzing完整描述测试架构,但从Fuzzing测试漏洞报告的完整步骤。
0x01 Fuzzing 方法
我的Fuzzing结构基于Facedancer和Umap一些功能被添加到工具中:
- · 在PCAP中为仿真设备捕获流量;
- · 已记录PCAP重放流量;
- · 基于Radamsa数据包变异。
本文的目的不是详细描述USB但仍然需要一些知识来更好地理解工作原理USB Fuzzing。连接设备后,主机会向设备发出标准请求,以检索设备信息(供应商)ID,产品ID,可用功能等),这样做是为了对其进行配置并将适当的驱动程序加载到OS该信息称为 描述符。这些请求/描述符在特殊端点交换:每个连接的新标准设备必须响应发送给它的请求。端点是设备接口之间的逻辑链接USB主机堆栈由一个或多个端点组成,并提供类功能(HID,大容量存储等)或特定功能。
0x03 Fuzzing的实例示例
我模拟了USB大容量存储设备丢弃交换流量,然后我决定Fuzzing特别是配置描述符bNumEndpoints字段。
变异只是用随机字节代替这个字节。一段时间后,我Windows 8.1 x64上触发了BSOD。在这里,我的变异描述符以红色框的形式发送到主机。在使用变异描述符重放数据包序列几次后,我推测主机在发送设置配置请求后立即触发橙色框BSOD 。
在Wireshark变异描述如下:
崩溃转储分析几乎没用,因为内核池内存已经损坏:每次崩溃都在另一个位置。我继续在某个时候注入数据包Windows BSOD给我以下问题的位置:USBSTOR.sys。
驱动程序的名称是显式的:它是一个大容量存储驱动程序。
0x04 反向大容量存储驱动程序
下载完USBSTOR.sys我把符号加载到符号后IDA Pro中,幸运的是,这些符号很容易理解,我很快找到了有趣的函数: USBSTOR_SelectConfiguration()
第一个基本块显示正确usbd.sys调用导出: USBD_CreateConfigurationRequestEx()输出返回指向URB_FUNCTION_SELECT_CONFIGURATION结构指针 MSDN [6],此“例程分配和格式化URB以选择USB设备的配置”。URB用于描述客户端驱动程序发送到设备请求的结构[7]。
调用第二个基本块USBSTOR_SyncSendUsbRequest(),并将之前创建的(),URB作为第一个参数。调用此函数后,请求将通过USB堆栈发送,然后从主机控制器物理发送到设备。如果我中断USBSTOR_SyncSendUsbRequest()调用时,会观察到系统崩溃不是由此调用引起的。
USBD_CreateConfigurationRequestEx()函数中,我看到它被复制 bNumEndpoints(我设置为0Fuzzing 空间)从USB_INTERFACE_DESCRIPTOR结构的 NumberOfPipes基于USBD_INTERFACE_INFORMATION结构。该USB_INTERFACE_DESCRIPTOR本文不研究枚举过程结构的初始化。
现在,正在调用USBD_CreateConfigurationRequestEx()之后,我回来了USBSTOR.sys ,RDI指向:

现在,将_USBD_INTERFACE_INFORMATION结构复制到RCX,我把指针放回去RAX中。
这些指令的伪代码是:
Windows 8.1 32位
我在64位模式下看到了情况,但在32位模式下没有看到。我不会详细解释指令流,因为它是完全相同的。
以下代码段对应于之前代码段的32位等效:
在伪代码中,memset()大小如下:
0x05 参考文献