导语:做安全研究的人都知道,有时候最大的障碍不是你不懂技术,而是你不知道怎么绕过一个问题。一位安全研究人员在开发Xbox 360漏洞利用工具时,遇到了一个竞态条件(Race Condition)问题——需要让硬盘在读取特定扇区时人为延迟几百毫秒,才能让漏洞成功触发。他的解决方案是:直接动手破解硬盘固件。
一、背景:一切从Xbox 360漏洞说起
去年某个时候,我正在为Xbox 360游戏机开发一个漏洞利用工具(后来演变成了备受期待的软改工具)。为了成功利用一个竞态条件漏洞,我需要在硬盘发出读请求后、硬盘回复数据之前,人为制造一个特定的时间差。
当时我对整个漏洞利用流程中涉及的变量还没完全搞清楚,所以在硬盘响应的那点时间内,很难精准地触发漏洞。我最初的想法是:修改硬盘固件,让它在读取某个特定扇区时,故意延迟几百毫秒——这样就能给漏洞触发留出足够的时间窗口。
说起来容易做起来难。虽然我知道修改硬盘固件这个概念早就有人玩过,但从来没有一份完整的攻略能让我拿来直接用。更重要的是,嵌入式设备的内部结构通常极其复杂,反向工程的投入巨大。
你真的了解硬盘内部是怎么工作的吗?宏观上讲,磁盘高速旋转,磁头读取数据——这我当然知道。但在微控制器层面,你真的理解它的工作原理吗?
我以前也不懂。但我知道,如果搞定这个漏洞是我唯一的选择,那这块硬盘就必须被拿下。
二、测试对象:四块硬盘的”解剖实验”
我挑选了四块硬盘作为实验对象:

测试对象清单:
- 三星 HM020GI(机械硬盘)
- 日立 HTS545032B9A300(机械硬盘)
- 西数 WD3200BEVT(机械硬盘)
- 三星 PM871a(固态硬盘SSD)
选择这几块硬盘的原因:一方面,它们是Xbox 360常用的型号;另一方面,西数硬盘有”后门Vendor命令”可以用来获取底层访问权限;三星SSD则是我手上刚好有的。
动手之前,我先去网上搜了大量资料。主要泡在HDD Guru论坛,读了无数帖子,还找到了一篇MalwareTech写的硬盘固件破解系列文章。其中一句话特别扎心:
“开始之前我决定先读读别人的研究成果,做点功课。事实证明,大部分我找到的资料要么是错的,要么根本不适合我用的这款硬盘。”
这基本就是我的真实经历——找到的信息大部分是15年前的老帖子,要么不正确,要么不适合我的型号。但别慌,我搜集了大量”碎片信息”,拼起来就能看到全貌了。
三、获取固件:三条路
对于每块硬盘,我的计划是这样的:
- 获取固件镜像:要么网上找到现成的,要么自己从硬盘里dump出来
- 导入IDA分析:包括解压缩/解密固件(如果加密了的话)
- 找到刷回固件的方法:不能写回去的固件毫无意义
- 定位DMA READ EXT命令处理函数:这是硬盘响应读请求的代码,需要找到它
- 写补丁:在读取特定扇区时人为加入几百毫秒延迟
- 刷回固件
途径一:PC-3000专业设备
我在HDD Guru论坛上发现,有人专门用专业数据恢复工具PC-3000上传了各种硬盘的固件镜像。PC-3000是一套专业级数据恢复设备,通过厂商专有命令来诊断、修复硬盘并dump固件。
我在论坛上找到了西数硬盘的固件dump。后来发推之后,有人主动联系了我,用他的PC-3000设备帮我dump了三星HM020GI的固件。
途径二:OEM官网固件更新工具
三星PM871a的固件,是我从联想官网的固件更新程序里找到的。这个方法意外地好用——不仅拿到了固件镜像,还顺带从固件更新程序里逆向出了刷固件所需的命令。
这条经验很重要:去各大OEM厂商官网搜索固件更新工具,往往能一次拿到两样东西:固件镜像 + 可以直接用的刷写工具。
固件格式大不同
西数(WD)硬盘:固件格式是扁平的二进制文件,包含多个静态链接的代码/数据段,每个段都有8位校验和。除第一段是加载器stub外,其余段全部是压缩的。压缩算法是基于LZHUF,但有两个小改动——N常量从2048改成了4096,游程计算也做了修改。



三星PM871a SSD:固件经过混淆处理,用了一种位操作算法,我把更新工具逆向出来之后才搞清楚了逻辑——对每个字节的高低半字节做位运算就能还原。更有意思的是,这个固件大概率没有用RSA或ECDSA强签名,因为对比两个不同型号的固件,除了开头28字节的差异外,其他部分几乎相同。28字节这个长度可能是SHA-224或截断的SHA-256。


三星HM020GI机械硬盘:最诡异的一块。固件镜像里全是明文字符串和机器码,但用任何已知架构都无法反汇编。最诡异的是,整个文件的数据是”字节翻转”的——这可能意味着用的是某种极其冷门的指令集架构(ISA),甚至可能是跑在MCU内部虚拟机上的自定义字节码。

四、刷固件:三条路可以走
想把修改后的固件写回硬盘,有三种主流方法:
方法一:DOWNLOAD MICROCODE命令
这是最通用的方式,ATA规范里的标准命令,所有现代硬盘都支持。固件更新工具本质上就是用这个命令把新固件流传输到硬盘里。不过,一旦刷固件失败,你就可能收获一块”镇纸”。普通用户基本上无法恢复。
方法二:后门Vendor命令
西数硬盘有个很有趣的特性:它们大量使用”服务区覆盖模块”来更新固件——而不是直接覆盖主固件区。这些覆盖模块存储在硬盘盘片的特殊”服务区”里,正常情况下完全不可访问。
这些模块可以通过SMART READ/WRITE LOG命令来访问。SMART命令本身是用来读写SMART状态数据的,但其中有个”厂商自定义”的范围(log address 0xBE),西数就用它来实现后门访问。
方法三:物理串行接口
很多硬盘在电路板上都有一个暴露的4针串口(就在SATA接口旁边),这是RS232串口,可以直接向硬盘发送修复/诊断命令。各厂商各型号支持的命令各有不同,有些能在网上找到文档,有些则需要自己逆向固件来摸索。
五、调试固件:Live JTAG调试硬盘
现在到了最硬核的部分——找到硬盘处理读请求的代码。
西数硬盘有一个很棒的特性:电路板上有个38针的MICTOR连接器(通常是空焊的),暴露了JTAG接口。这意味着我可以直接焊几根线,获得对硬盘MCU的硬件级调试访问权。
没错——我们要实时调试一块正在运行的硬盘。

用OpenOCD加上FT232适配器,我成功连上了JTAG并中断执行。
但有几个坑需要注意:
- 硬盘必须直连主板SATA,不能通过USB转接(USB适配器不支持ATA透传)
- 如果硬盘超时没响应,Windows会认为它”失联”,之后所有通信都会失败(某些Windows版本甚至会蓝屏)
- 调试时硬盘比较”娇气”,有时候会进入一种需要重新上电才能恢复的状态
用Vendor Specific Commands定位代码
西数的后门Vendor Specific Commands(VSC)里,最有趣的是”读取RAM”命令。我的计划是:
- 在内存地址
0x41414141上设置一个访问断点 - 发送VSC读RAM命令,指定读取这个地址
- 断点触发后,查看调用栈,找到处理读请求的函数
具体怎么发VSC?通过ATA透传结构,配置ATA端口寄存器,执行SMART WRITE LOG命令(log page设为0xBE),然后在额外数据区里放入VSC命令ID和参数。

断点触发后,我在调试器里dump寄存器,发现读取0x41414141的指令地址是0xFFE1D780,这段代码就在固件里。
然后顺着调用栈往上追,我找到了VSC命令的函数处理表——共67个条目,比我预想的多不少。
但当我用读扇区测试来触发断点时,却没有命中。我意识到:DMA READ EXT命令(读扇区用的命令)和SMART LOG命令走的是完全不同的代码路径。
真正的代码在覆盖模块里
折腾了半天之后,我终于发现:DMA READ EXT命令的处理器代码,不在主固件镜像里,而是藏在服务区的覆盖模块(Overlay Module)里。

这些覆盖模块可以通过VSC dump出来,但更简单的方法是:等硬盘完全启动后,直接把包含代码的那段RAM区域导出到文件。最终我确认了这个代码存在于模块编号0x11中。
现在,终于可以写补丁了。
六、写补丁:给硬盘注入200毫秒延迟
有了读请求处理函数的代码,我开始规划hook点。最终我选了一个合适的位置插入跳转指令,跳转到一段空闲RAM空间里执行我自己的代码:
Hook_SataDmaRead:
ldr r3, =(MS_DELAY * F_CPU / 1000) # 10MHz * 200ms / 1000
Hook_SataDmaRead_loop:
sub r3, r3, #1
bne Hook_SataDmaRead_loop
bx lr
这段代码会在每次读操作时,让硬盘CPU原地空转约200毫秒。

测试结果:
- 无补丁时:读扇区耗时约0毫秒(命中缓存)
- 打补丁后:读扇区耗时约450毫秒(延迟生效!数学计算不太精确,但够用了)
七、结果:任务”成功地失败了”
我准备好了一切:
- 一块完全未修改的硬盘,外接电源供电,预先在RAM里打好了补丁
- 硬盘通过SATA连接到Xbox 360(只有数据线)
- 主机启动时尝试读取特定扇区,同时后台进行”某种操作”
- 如果读操作延迟足够长,漏洞就会触发,机箱环点亮橙色灯光表示成功
但在正式测试之前,我想先做一次”对照组”测试——不动硬盘的任何代码,确保漏洞仍然失败。
结果:我打开电源,未做任何修改,漏洞成功触发了。
我以为是什么巧合,重启了好几次,漏洞几乎每次都能触发,尽管硬盘固件完全没有被动过。
后来我终于搞清楚了:其他变量都被我调好了,漏洞已经能在原版硬盘上稳定触发——我根本不需要修改硬盘固件。
这个.side quest,到此结束。
八、结论:硬盘固件比你想象的更有搞头
这次研究让我学到了很多关于嵌入式设备逆向工程的实战经验。虽然后来再也没机会深入研究更多细节,但我把这个领域的工具和脚本都开源了(GitHub: grimdoomer/HDDTools),希望更多人能参与进来。
这次研究还有一个意外收获:在后续用AI辅助做其他硬盘分析时,我发现AI在黑盒逆向嵌入式设备方面表现得相当出色——下篇文章里会详细介绍这个方向。
至于硬盘固件这个领域,其实一直有人在做,只是公开资料太少。Travis Goodspeed和Sprite这两位研究者在这个方向有不少有趣的成果。
现在想想,固件分析这个方向之所以不被广泛讨论,主要原因是大家担心这些技术会被坏人利用来制作硬盘木马。但话说回来,硬盘木马早就存在了(懂的都懂)。
原文链接:https://icode4.coffee/?p=1465 作者:grimdoomer(I Code 4 Coffee)
版权声明:本文由华盟网原创发布,保留所有权利。配图来自I Code 4 Coffee授权使用。














暂无评论内容