假冒和未经许可的产品的制造在视频游戏控制台的世界中很普遍。这是一个价值数十亿美元的行业,需求创造了供给。您现在可以找到几乎所有的现有控制台的设备,这些控制台允许您从闪存驱动器,假冒游戏手柄和配件,各种适配器中播放许可视频游戏“备份”的副本,其中一些还适用于其他播放器,以及在在线和离线视频游戏中使用作弊。甚至有一些服务可以让您直接购买在视频游戏上的战绩,而无需花费数个小时去通关。当然,这些都是在未经视频游戏机制造商同意的情况下销售的。
与20年前一样,现代视频游戏控制台是专有的系统,其规则由硬件制造商设定,而不是由使用这些设备的数百万游戏玩家设定。他们的设计中包含各种保护措施,以确保这些控制台只运行有授权的代码,因此他们只玩有执照和合法获得的视频游戏,所有玩家享有平等的权利,只能玩官方授权的配件。在某些国家,试图破解自己的视频游戏机甚至是非法的。
但与此同时,如此严苛的保护模式反而使得这些控制台成为一个有吸引力的攻击目标,也是对信息安全和逆向工程感兴趣的爱好者的一大'裂缝'。因为,对他们来说,越难的拼图,解决起来就越县挑战性,也越有趣。特别是对那些从小到大一直对电子游戏很痴迷的玩家。
关注我的推特账号的读者可能知道我是逆向工程视频游戏机及其相关内容的长期粉丝,包括非官方游戏设备。在PlayStation 4的早期,FreeBSD内核(PlayStation 4所基于的)中的一个众所周知的漏洞让我和许多其他研究人员得以了解索尼新游戏机的架构和内部工作原理。我进行了很多不同的研究,其中一些研究包括了解USB认证在PlayStation4中的工作原理,以及它如何区分许可设备和阻止未经授权的设备。这个研究很有意思,因为我以前曾对其他游戏机做过类似的研究。PlayStation 4的身份验证方案比Xbox 360中使用的方案简单得多,但同样有效。
图:PlayStation4 USB配件的授权方案
PS4向DualShock 4发送0x100随机字节,作为响应,游戏手柄创建RSASSA-PSS SHA-256签名,并将其发送回验证它所需的加密常数N和E(公钥)。这些常量对于所有制造的DualShock 4游戏手柄都是独一无二的。游戏手柄还发送验证N和E所需的签名。它使用相同的RSASSA-PSS SHA-256算法,但加密常数对于所有PlayStation 4控制台是相同的,并存储在内核中。
这意味着如果您想要验证自己的USB设备,那么攻击PlayStation4内核是不够的,您还需要有存储在游戏手柄中的私钥。即使有人设法破解游戏手柄并获得私钥,索尼仍然可以通过固件更新将密钥列入黑名单。如果八分钟后游戏控制台没有收到验证响应,它将停止与游戏手柄的通信,您需要将手柄从USB端口移除并再次插入以使其工作。这就是早期的假冒游戏手柄需要通过每8分钟模拟USB端口拔出/插拔过程来使其工作,这对于购买它们的人来说非常烦人。
一段时间,我都没有听到任何关于破解这种认证方案的事件,直到我听到市场上有在销售看起来像原版一样的新假冒游戏手柄的传闻时,我真的很想研究一下他们,所以我从中国商店订购了一些。
在我等待包裹到达时之前,我决定尝试收集有关假冒游戏手柄的更多信息。经过不少搜索,我找到了一个名为Gator Claw的游戏手柄。
未经授权的Gator Claw游戏手柄
在Reddit上,有一个有趣的讨论,人们说它的工作方式与其他未经授权的游戏手柄一样——只有8分钟,但是开发人员已经设法通过固件更新解决了这个问题。购买商店包括固件更新的链接和手册。
GatorClaw的固件更新手册
我做的第一件事是看一下固件更新程序可执行文件的资源部分。
在Gator Claw的固件更新程序资源中找到的固件
熟悉为嵌入式设备编写代码的读者很可能会了解这种文件格式。这是Intel HEX文件格式,通常用于编码微控制器,许多编译器(例如GNU Compiler)可以输出这种格式的编译代码。此外,我们可以看到固件的开头的信息熵并没有很高,字节序列也很容易识别。这意味着固件未加密或压缩。从英特尔HEX格式解码这个固件,并以十六进制编辑器加载(010编辑器能够以该格式直接打开文件)后,我们就可以查看它编译的架构是什么?由于ARM Cortex-M被广泛采用,我一下子就认出了它。
GatorClaw的固件(左)和ARM Cortex-M的矢量表(右)
根据规范,第一个双字是初始堆栈指针,然后是异常向量表。该表中的第一个双字是复位向量(Reset Vector),用作固件入口点。其他异常处理程序的高地址(high address)可以了解固件的基址(base address)。
除固件外,固件更新程序的资源部分还包含一个配置文件,其中包含不同微控制器的描述。固件更新程序的开发人员很有可能使用的是来自微控制器制造商的公开可用源代码,这可以解释为什么这个配置文件带有源代码。
配置文件,包含不同微控制器的描述
从配置文件中搜索微控制器识别器后,我们找到了制造商的网站— Nuvoton。技术文档和SDK中的产品信息可免费下载,无需任何许可协议。
Nuvoton微控制器制造商的网站
此时我们已经有固件,我们知道它的架构和微控制器制造商,我们有关于基地址,初始堆栈指针和入口点的信息。因此,我们有很多信息,有超过在IDA Pro中加载固件并开始分析它所需要的信息。
ARM处理器有两种不同的指令集:ARM(32位指令)和Thumb(使用Thumb-2 32位指令扩展的16位指令)。Cortex-M0仅支持Thumb模式,因此我们将在IDA Pro中加载固件时将“处理器选项 - 编辑ARM体系结构选项 - 设置ARM指令”中的单选按钮切换为“NO”。
之后,我们可以看到固件已经加载到基址0,自动分析几乎可以识别每个功能。现在的问题是如何推进固件的逆向工程?
多固件功能之一的示例
如果我们分析固件,我们会看到它在整个存储器中对基本地址为0x40000000的存储器执行读写操作。这是存储器映射输入输出(MMIO)寄存器的基址。这些MMIO寄存器允许您访问和控制所有微控制器的外围组件。固件所做的一切都是通过访问它们来实现的。
外围控制器的存储器映射
通过搜索地址0x40000000的技术文档,我们发现该微控制器属于M451系列。现在我们已经了解了微控制器系列,我们可以下载该平台的SDK和代码示例。在SDK中,我们找到一个头文件,其中包含所有MMIO地址,位字段和结构的定义。我们还可以使用所有库编译代码示例并将它们与IDB中的函数进行比较,或者我们可以在源代码中查找MMIO地址的名称并将其与我们的反汇编进行比较。这使得逆向工程的过程变得简单。那是因为我们知道微控制器的架构和模型,我们对所有MMIO寄存器进行了定义。如果我们没有这些信息,分析就会复杂得多。
在固件中查找库函数
我在等待我的假游戏手柄到达时研究了Gator Claw的固件,其内部没有太多使人感兴趣的地方—认证数据被发送到可通过I2C访问的另一个微控制器,并且响应被发送回控制台。这款未经许可的游戏手柄的开发人员知道这种固件可能是逆向工程的,而且更多的假冒游戏手柄的存在可能会损害他们的业务。为了防止这种情况,使用另一个微控制器的唯一目的是安全。这是常见的做法。黑客在他们的产品上付出了很多努力,也不想被黑客入侵。在这个固件中真正引起我注意的是存在一些看起来未使用的字符串。它很可能是USB设备描述符的一部分,但该特定描述符未被使用。这个字符串是故意留下的吗?这是某种签名吗?很可能,因为这个字符串是以逻辑分析仪而闻名的主要硬件制造商的名称。但事实证明,他们还有一个游戏部门,旨在成为原始设备制造商(OEM),甚至拥有许多与游戏配件生产相关的专利。除此之外,他们还拥有子公司,他们的网站上有各种各样的游戏配件。在售的产品中有二十几个适配器,允许一个控制台的游戏手柄与另一个控制台一起使用。例如,有一种产品可以让你将Xbox 360的游戏手柄连接到PlayStation 4,另一种产品可以让你将PlayStation 3游戏手柄连接到Xbox One等等,包括通用的“一体机”。产品列表还包括适配器,允许您将PC鼠标和键盘连接到PS4,Xbox One和Nintendo Switch视频游戏控制台,各种游戏手柄和印刷电路板,为游戏控制台创建自己的街机控制器。所有产品都带有类似于为Gator Claw提供的固件更新器,但有一个显着的区别—所有固件都是加密的。
其中一个产品的资源的手动和加密固件示例
用于创建自己的街机控制器的印刷电路板让您可以在不购买设备的情况下查看PCB设计并将其拆开,他们的设计很可能非常接近Gator Claw的设计。我们可以看到两个微控制器:其中一个应该是Nuvoton M451,另一个是存储机密的额外微控制器。所有迹线都在黑色环氧树脂下进入微控制器,因此应该是主微控制器,带有四个黄色引脚的微控制器似乎具有通过I2C工作所需的功能。
产品PCB设计的例子
这时我终于收到了深圳的包裹,这就是我在里面找到的。我想你也同意假冒游戏手柄看起来和原来的DualShock 4一模一样,感觉就是正牌的手柄。这是一款采用优质材料制成的无线游戏手柄,具有工作触摸板,扬声器和耳机端口。
假冒DualShock 4(来自外部)
我按下更新说明中的其中一个组合并打开电源。游戏手柄启动进入DFU模式!在此模式下将游戏手柄连接到PC后,它被识别为具有不同标识符和特征的另一个设备。我已经知道我会在里面看到什么......
假冒DualShock 4(主PCB视图)
我将几根导线焊接到看起来像JTAG点的地方并将其连接到JTAG编程器,编程工具可以识别微控制器,但设置了安全锁。
编程工具识别微控制器但启用了安全锁
经过这个相当冗长的介绍,现在是时候回到本文的主题。USB(通用串行总线)是外围设备的行业标准。它的设计非常灵活,可以广泛应用。USB协议定义了两个实体,一个主机与其他设备连接。USB设备分为集线器,人机界面,打印机,成像,大容量存储设备等类。
USB设备的连接方案
设备与主机之间的数据和控制交换通过一组单向或双向管道进行。通过管道,我们考虑主机软件和USB设备上的特定端点之间的数据传输。一个设备可以具有许多不同的端点以交换不同类型的数据。
数据传输类型
有四种不同类型的数据传输:
1.控制传输(用于配置设备)
2.批量数据传输(以相对较大和突发的数量生成或使用)
3.中断数据传输(用于及时但可靠地传输数据)
4.同步数据传输(通过预先协商的传输延迟占用预先协商的USB带宽量)
所有USB设备必须支持端点零处的特殊指定管道,USB设备的控制管道将连接到该管道。这些类型的数据传输是使用根据以下方案提供的分组来实现。USB协议中使用的数据包
事实上,USB协议是一个状态机,在本文中我们不会检查所有这些数据包。您可以在下面看到控制传输中使用的数据包示例。
控制转移
USB设备在实施批量传输,中断传输,同步传输时可能包含漏洞,但这些类型的数据传输是可选的,它们的存在和使用将因目标而异。但是所有USB设备都支持控制传输。它们的格式很常见,这使得这种类型的数据传输对于分析漏洞最具吸引力。
下面的方案显示了用于执行控制传输的SETUP数据包的格式。
SETUP包的格式
SETUP包占用8个字节,可以根据请求的类型用于获取不同类型的数据。某些请求对所有设备都是通用的(例如GET DESCRIPTOR);其他请求依赖于设备类别和制造商许可。要发送或接收的数据长度是SETUP数据包中提供的16位字。
标准和特定于类的请求的示例
总结:“控制传输”使用所有USB设备支持的非常简单的协议,它可以有很多额外的请求,我们可以控制数据的大小。所有这一切使Control Transfers成为模糊和毛刺的完美目标。
为了破解我的假冒游戏手柄,我不必模糊它,因为我在查看Gator Claw代码时发现了漏洞。
HID类请求处理程序中的弱代码
函数HID_ClassRequest()用于模拟原始DualShock 4游戏手柄的工作,并实现最少的所需请求,以使其与PlayStation 4一起使用. USBD_GetSetupPacket()获取SETUP数据包,并根据报告类型,它将发送具有USBD_PrepareCntrlIn()功能的数据或将使用函数USBD_PrepareCntrlOut()接收。此功能不检查所请求数据的长度,这应该允许我们读取固件所在的内部闪存的一部分,并且还可以读取和写入SRAM存储器的开头。
控制传输期间缓冲区溢出
DATA数据包的大小在USB设备描述符中定义(也通过控制传输接收),但似乎未被注意的是这个大小定义了单个数据包的长度,并且可能有很多数据包依赖在SETUP包中设置的长度。
值得注意的是,Nuvoton网站上提供的代码示例也没有长度检查,并且这可能导致在使用此代码作为参考的所有产品中传播类似的错误。
利用SRAM存储器中的缓冲区溢出
SRAM(静态随机存取存储器)是一种存储器,其中包括堆栈占用的存储器。SRAM通常也是可执行存储器(这是可配置的)。这通常是为了通过将经常调用的代码片段(例如,实时操作系统)复制到SRAM来提高性能。不能保证堆栈的顶部可以通过缓冲区溢出来访问,但是它的可能性仍然很高。
令人惊讶的是,利用USB固件的主要障碍是操作系统。我在使用Windows时观察到以下内容,但我认为大部分内容也适用于没有特殊补丁的Linux。
首先,操作系统不允许您在控制传输期间读取超过4 kb的数据。其次,根据我的经验,操作系统不允许您在控制传输期间写入多个DATA数据包。第三,USB设备可能具有隐藏请求,并且OS将阻止所有使用它们的尝试。
这很容易用人机接口设备(HID)演示,包括游戏手柄。HID附带了其他描述符(HID描述符,报告描述符,物理描述符)。报告描述符与其他描述符完全不同,由描述支持的报告的不同项组成。如果报告描述符中缺少报告,则操作系统将拒绝完成报告,即使它已在设备中处理。这基本上减损了USB设备固件中漏洞的发现和利用,这些细微差别最有可能阻止发现漏洞。
为了解决这个问题而不必阅读和重新编译Linux内核的源代码,我只使用了我手边的低端仪器:Arduino Mega板和USB Host Shield(总计<$ 30)。
连接方案
在使用上述方案连接设备后,我使用Arduino板执行控制传输,不受操作系统的任何干扰。
ArduinoMega 和 USB 主盾
假冒游戏手柄与Gator Claw具有相同的漏洞,我做的第一件事就是转储部分固件。
部分转储固件
查找固件转储基址的最简单方法是查找包含指向已知数据的指针的结构。之后,我们可以计算地址的增量并将固件的部分转储加载到IDA Pro。
具有指向已知数据的指针的结构
固件转储允许我们找出printf()函数的地址,该函数输出工厂质量保证所需的UART信息。更重要的是,我能够在转储中找到hexdump()函数,这意味着我甚至不需要编写shellcode。
寻找有助于开发的功能
在游戏手柄的印刷电路板上找到UART点,焊接导线并将它们连接到TTL2USB适配器后,我们可以在串行终端中看到输出。
游戏手柄启动期间的标准UART输出
Nuvoton微控制器的标准库带有一个非常方便的硬故障异常处理程序,可输出寄存器转储。这极大地方便了开发并允许调试漏洞。
堆栈覆盖导致硬故障异常后的UART输出
转储固件的最终漏洞可以在下面的屏幕截图中看到。
利用shellcode和shellcode通过UART转储固件
但这种转储固件的方式并不完美,因为Nuvoton M451系列的微控制器可能有两种不同类型的固件,主固件(APROM)和用于设备固件更新的迷你固件(LDROM)。
不同模式下闪存和系统内存的存储器映射
APROM和LDROM映射到相同的内存地址,因此只能转储其中一个。要获得LDROM固件转储,我们需要禁用安全锁并使用编程工具读取闪存。
Shellcode禁用安全锁
对负责更新的固件(LDROM)的分析显示,它主要是来自Nuvoton的标准代码,但增加了代码来解密固件更新。
用于解密固件更新的加密算法方案
用于解密固件更新的加密算法是自定义分组密码。它以密码块链接模式执行,但块大小仅为32位。该算法采用密钥作为产品的文本(ascii)标识符和指令数组,用于定义应对当前块执行的转换。在遇到键和数组的末尾后,它们的当前位置被设置为初始位置。转换列表包括六个操作:xor(异或),减法,减法(反向)和相同的操作,但交换了字节。由于固件包含填充零的大区域,因此可以轻松计算此算法的秘密部分。
显示固件更新加密密钥
将从伪造游戏手柄的固件中提取的算法应用到主要OEM制造商生产的固件上,可以揭露所有这些固件都用此加密算法。此算法的弱点是允许我们计算适用于所有设备的加密密钥,并解密其固件更新程序。换句话说,在假冒产品中使用的算法导致该制造商开发的所有产品的安全性受到损害。
这个博客内容虽然很多,我很想让广大观众理解这个原理。我已经分析了嵌入式固件的分析,发现漏洞并利用它们来获取固件转储并在USB设备上执行代码执行。
故障攻击的主题不包括在本文的范围内,但此类攻击对USB设备也非常有效。对于那些想要了解更多相关信息的人,我建议您观看此视频。对于那些想知道盗版如何设法从DualShock 4获取算法和密钥以制作自己的设备的人,我建议阅读这篇文章。
至于用于保密的辅助微控制器之谜,我发现它并没有应用在所有设备中,只是为了增加复杂性而添加。该微控制器不保留任何秘密,仅用于SHA1和SHA256。这项研究还帮助爱好者创建自己的开源项目,用于游戏控制台。
至于假冒游戏手柄的购买者,他们并不处于令人羡慕的位置,因为制造商阻止非法使用的密钥,而且这些购买者最终还是没有工作的游戏手柄,也没有提示在哪里可以获得固件更新。
翻译:何跃鹰、孙中豪