Syzkaller(Google团队开发的一款针对Linux内核进行模糊测试的开源工具),最近开始支持USB模糊测试,并且已经在Linux内核中发现了80多个漏洞。目前,鉴于USB本身的复杂性导致的安全性的影响和潜在的大量漏洞,几乎所有模糊测试专家都开始将他们的模糊测试技术应用于USB的模糊测试中。
什么是USB协议栈?
按着协议,USB分为USB host(USB主机) 和 USB device/gadget(USB从机),USB主机能够主动发起会话而USB从机则不能发起会话。HOST是主机,好比电脑端那个USB,简而言之,主机好比电脑端那个USB接口,从机好比就是连接到USB接口的U盘。当我们谈论USB时,通常说的是USB主机,例如带有标准USB端口的笔记本电脑。下图是Linux USB主机栈。从下到上,分为硬件、内核空间和用户空间。
USB主机控制器设备(又名HCD)是连接到系统PCI总线的PCI设备,通过USB端口提供USB连接支持。根据USB技术的发展,它也被称为USB 1.x的UHCI / OHCI,USB 2.x的EHCI和USB 3.x控制器的XHCI。要使内核使用此控制器,我们需要一个USB主机控制器驱动程序,它可以设置PCI配置和DMA。上面是USB内核,实现底层USB协议栈,并使用通用内核API(submit /recv URB)抽象发送/接收USB数据包的方式。上面是不同的USB从机驱动程序,例如USB HID驱动程序和USB大容量存储驱动程序。这些驱动程序会实现不同的USB类协议(例如,HID,大容量存储),为内核中的其他子系统(例如输入和数据块)提供粘合层,方便用户空间(例如创建/dev节点)。
由于Linux也广泛用于嵌入式系统,例如一些USB软件保护器(USB Dongle),USB从机指的是Linux内的USB软件保护器硬件和USB模式。 USB从机与USB主机模式完全不同。下图显示了Linux内核中的USB从机协议栈。
底部是USB从机控制器(又名UDC),与HCD一样,UDC也在PHY层内实现特定版本的USB标准。但是,与英特尔最常用的HCD不同,UDC IP来自不同的硬件供应商,例如DWC2/3,OMAP,TUSB和FUSB。这些控制器通常具有其自己的设计规范,并且当它们支持USB On-The-Go(又名OTG)模式时也可遵循HCD规范(例如XHCI规范)。 OTG允许UDC在USB主机和USB从机模式之间切换。例如,当Android设备以MTP的形式与笔记本连接时,Android USB从机控制器处于USB从机模式。如果USB闪存驱动程序插入Android设备,UDC将在USB主机模式下工作。支持OTG的UDC也被USB 3.x标准中的双角色设备(Dual-Role Device,DRD)控制器取代。因此,不需要OTG数据线来切换UDC的角色,因为角色切换是在DRD控制器的软件中完成的。
要使用UDC,你需要在内核中使用UDC驱动程序,通过行业标准总线((包括 AMBA™ AHB和AXI接口))提供连接和配置,并为更高层设置DMA。与USB主机协议栈中的USB内核一样,USB从机协议栈中的USB从机内核也提供API,通过回调和配置来注册和实现USB从机函数。例如,我们可以通过请求现有的大容量存储函数(f_mass_storage)将USB描述符传递到USB从机内核并实现典型的USB大容量存储设备。对于诸如MTP的更复杂的协议,用户空间守护进程或库提供协议逻辑并通过例如configfs或usbfs与从机函数通信。
USB主机控制器(Host Controller)
USB的拓扑结构决定了主机控制器就是最高统帅,没有主机控制器的要求,从机永远不能主动发数据。所以主机控制器在USB的世界里扮演着重要的角色,它是幕后操纵者。
比如说USB主机发送Setup数据包获取设备描述符是怎么发出去的?这个过程包含很多信息,比如:如何在D+和D-这两根线上传过去的、又传过来的。 这一切的工作都是主机控制器给我们做的,USB主机控制器的规范有很多种,比如UHCI/OHCI。
什么是USB controller?
USB 设备和主机的接口就是host controller,一个主机可以支持多个host controller,比如分别属于不同厂商的。那么USB host controller 本身是做什么的? 很简单用于控制,控制所有的USB从机的通信。 CPU把要做的事情分配给主机控制器,然后自己想干什么就干什么去,主机控制器替他去完成剩下的事情,事情办完了再通知CPU。否则让CPU去盯着每一个从机做每一件事情,那是不现实的。
控制器的主要工作是什么? 把数扔出去,把数拿回来。绝对不应该偷偷加工数据。
主机控制器控制总线上包的传输, 使用1ms或125us的帧。在每帧的开始时,主机控制器产生一个帧开始包(SOF: Start of Frame)。
SOF包用于同步帧的开始和跟踪帧的数目,包在帧中被传输,或由主机到从机(输入事务),或由从机到主机(输出事务)。传输总是由 主机发起的(轮询传输)。回此每条USB总线只能有一个 主机。每个数据包的传输都有一个状态阶段同(同步传输除外),数据接收者可以在其中返回ACK(应答接收),NAK(重试),STALL(错误条件)或什么也没有(混乱数据阶段,设备不可用或已经断开)。
USB模糊测试的历史
FaceDancer
由于可编程USB硬件模糊测试工具——FaceDancer的出现,USB模糊测试开始吸引更多的关注。它支持USB主机和从机模式模拟,并允许发送预先形成带有漏洞的USB请求和响应。 Umap/Umap2提供了一个用Python编写的模糊测试框架,它具有面向FaceDancer的不同USB从机和响应模板。TTWE框架通过使用两个FaceDancer分别模拟USB主机和USB从机来实现USB主机和USB从机之间的MitM,此MitM允许两个方向的USB数据包突变,从而实现双方的模糊测试。
目前所有这些解决方案都集中在USB主机协议栈上,其原因是人们假设恶意USB从机不是恶意的USB主机(例如笔记本电脑),并且大多数USB从机固件都是闭源的,因此很难被分析。这意味着,大多数漏洞/错误存在于USB内核(用于解析USB响应)和一些常见的USB驱动程序(例如键盘)中。这些解决方案的优点是能够完全模拟USB从机。但是,在我看来,却有两方面不足:
1.过于依赖硬件;
2.目标反馈有限。
由于FaceDancer速度很慢,这使得任何基于它构建的解决方案都无法扩展测试功能。由于在实践中,经常需要将FaceDancer和目标设备作为模糊测试的基本要素,所以,这也对FaceDancer的可扩展性带来了更多挑战。反馈是另一个重要问题,模糊输入的突变是基于模板和随机化的,除了系统日志记录之外,没有来自目标的实时反馈(例如代码覆盖率)。因此,模糊测试的准确率是非常不可信的。
为了摆脱硬件依赖性,使用虚拟化(例如QEMU)来进行保存。vUSBf使用QEMU/KVM运行内核映像,并利用QEMU中的USB重定向协议将对USB从机的访问重定向到由模糊测试工具控制的USB模拟工具,如下所示:
虽然vUSBf提供了一个很好的编排体系结构来并行运行多个QEMU实例,以此解决可扩展性问题,但模糊测试工具本质上是基于模板的,而反馈也还仍然依赖于系统日志记录。
POTUS
为此,有研究人员开发了POTUS 项目,POTUS 项目也可以发现位于 Linux USB 驱动程序的漏洞。
2017年,伦敦大学的安全研究人员发布了 POTUS工具,这是一种可以发现 Linux USB 设备驱动程序漏洞的工具。该工具通过设置虚拟机,通用 USB 设备以及故障注入,发送模糊符号等技术来测试 USB 驱动程序继而查找漏洞。
研究人员通过 POTUS 测试 USB 驱动程序发现了两个 Linux 内核漏洞。一个是 CVE-2016-5400,USB 设备驱动程序中用于与 Airspy 软件定义无线电(SDR)通信的内存泄漏漏洞,而另一个是自 2003 年以来已存在的 Linux 内核的乐高 USB 塔驱动器使用后释放漏洞(无 CVE 标识符)。
POTUS的工作原理如下所示:
systemtap是一个诊断linux系统性能和功能问题的开源软件,并且允许开发人员编写和重用简单的脚本深入探查linux系统的活动,可以快速安全的提取过滤总结数据,以便能够诊断复杂的性能或功能问题。
在USB模糊测试中,SystemTap用于检测内核存在的漏洞,并将漏洞数量记录下来。基于不同状态下的故障数量的路径优先级排序算法可以控制“分叉(fork)”的数量。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者输入的变量不同,两个进程也可以做不同的事。一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同,相当于克隆了一个自己。
给定路径的故障数量表示代码覆盖率,因此,故障数量越大则代码覆盖率越高。另外,POTUS还在QEMU中实现了一个通用的USB虚拟从机,以使用可配置的设备描述符和数据传输来模拟不同的USB从机。 虚拟从机中的USB 驱动程序(USB 驱动程序)使用系统调用来使用暴露在虚拟从机的不同设备节点。与vUSBf相比,POTUS就具有模糊测试反馈机制(通过计算路径内的故障数量),从而支持更多USB从机模拟。但是,在USB 驱动程序中模拟某些USB从机操作的手动进程、符号执行的基本限制——路径爆炸( path explosion),以及依赖于路径故障数量的未知有效性和局限性,使得POTUS很难被广泛使用。
本文我们先从什么是USB协议栈开始讲起,然后再讲到USB模糊测试的历史,其中讲到了一些过去的常用技术和工具,不过它们都存在着一些问题。下文,我们将介绍最新的USB模糊测试的解决方案。