|
|
|
联系客服020-83701501

在硬盘留下后门 让重装系统见鬼去吧

联系在线客服,可以获得免费在线咨询服务。 QQ咨询 我要预约
在硬盘留下后门 让重装系统见鬼去吧

OHM(Observe Hack Make)是一个专为黑客、制造者和那些有根究精神之人举行的国内户外露营节,为期 5 天。往年 7月31日在荷兰 Geestmerambacht 举行,有 3000 人参加。

这篇文章相关模式已在 OHM2013 果真。原理是操作硬盘的一些智能机制,在某个位置嵌入一些信息(比如:登录信息),然后应用系统考据用户登陆时,会不自主地读取黑客预留下的用户名和暗码。

 

简介

硬盘:假如你在看这篇文章,我必定你起码用过一两个硬盘。硬盘很冗杂,根本等于一些512字节的扇区,由递减的数字批注地点,称之为 LBA,也等于“逻辑块寻址”。电脑或者向邻接的硬盘的扇区中读写数据。个认识有个文件系统把这些扇区抽象成文件或文件夹。

假如你从这个幼稚的角度看硬盘,你会认为硬件该当也很冗杂:你必要的等于个能邻接SATA接口的工具,然后或者定位读写头,从盘片上读写数据。然而也许不止这么冗杂:硬盘不是还有处置坏块、S.M.A.R.T.属性的效率么?不是还有什么缓存必要计划的么?

以上这些象征着硬盘中有些智能的工具,有智能就象征着或者黑掉它。我就恋情或者黑的工具,因而我决定要看看硬盘是如安在非呆板层面上义务的。这种研 究早年在许多硬件上做过:从笔记本的PCI扩展模块到嵌入式管束器,以至是苹果的键盘。个体这些研究都是为了证实这些硬盘或者被破解,导致其遭到软件的影响,因而我决定达到同样的目标:我要在这次破解中让硬环抱过软件保险机构。

 

PCB上的部件

要想知道硬盘可否或者被破解,我必要更理解它们。如你们大多数同样,我也有一摞或坏或旧的硬盘来一看究竟后果:

当然了,咱们都知道硬盘的呆板布局该当是好用的,我对那些部门也不感兴趣。我的兴趣在于大多数硬盘背面都有的那一小块PCB板子,上面有SATA接口和电源接口。这种PCB看起来是这样的:

或者看见PCB上有4块芯片。接上去讲说这些芯片:

这是一块DRAM(信息随机存储器)。这块很甜头理,芯片手册很好找。这些芯片的容量一般在八MB到六4MB之间,对应的等于硬盘标称的缓存容量。

这个是电机管束器。这不是个标准器件,数据手册不好找,然而这些管束器一般都有冗杂找的差未几的同系列产物。ST Smooth管束器大概是最常用的一种了;除了驱动电机,它还能住手电源整流,还带一些A/D调换通道。

这是一块串行闪存。这个也甜头理,容量一般在六4KB到25六KB之间。看起来这个是用来存储硬盘管束器的创议顺序。有些硬盘不有这个芯片,而是在管束器芯片内部有闪存来存储顺序。

这些小工具不是芯片,而是压电震荡传感器。当硬盘遭到撞击时,它们或者把磁头移到保险的地方,然而更有也许它在某个地方标志一个值,暗示你的保修无效,由于是你各人摔的硬盘。

这里才是遗迹将要产生的地方:硬盘管束器。可能是由Marvell、ST梗概其它的LSI公司制造。有些硬盘厂商各人做管束器:我见过3星和西数就有各人的管束芯片。由于其它的部门都很甜头理,这一块才是我的兴趣所在。

倒霉的是,这些芯片都不有文档。话说这些制造管束器的厂商不果真文档有些不厚道真是说轻了:他们以至在各人的网站上都不提这些芯片!更倒霉的是,局部互联网也帮不了我:搜这些芯片手册只能找到不有手册的手册网站,和卖芯片的中国厂商……

那末,不有最求助的芯片手册,就象征着咱们的设计停顿了么?

 

邻接JTAG

幸运的是,总有些门径找到除了芯片手册以外的有效信息。我就搜到这么一个。

我找的是HDDGuru论坛上一个叫Dejan的人做的邻接线。 Dejan不知怎样把他硬盘管束器的内部闪存废掉了,然后想知道有不有门径,要么从内部闪存创议管束器,要么重写一下内部闪存。过了五天,没人回应他,但 是这哥们很有缔造力:他又发了个帖子说他找到了JTAG口的管脚。这真是个弘大缔造:JTAG接口或者用来管束控制器。你或者用它创议管束器、重启、批改 内存、设置断点等等。然后Dejan缔造了如何关掉管束器的创议ROM,找到了硬盘一个串口,然后试图复原他的闪存ROM。后来他又提了一些关于更新闪存 的过程,最后掉落在茫茫人海中了。

这些都是有效的信息:至少我知道了西部数据的管束器是ARM内核的,有JTAG接口。这些硬盘个体有串口,虽然不有哄骗然而或者用来调试顺序。有了这些,我该当有充足的信息或者末尾破解了。

嗯,这些是我的筹备义务:

那个红色的是一块FT2232H的小板,大概30欧元,很便宜,或者用来住手JTAG调试,串口,还有SPI通信。把它连到硬盘的JTAG口,还有串口上。硬盘直间断到我电脑主板的SATA口上,还有内部ATX电源。我用OpenOCD来驱动JTAG接口。

而今的题目是:这玩意真能义务么?Dejan用的是八8i六745管束器的2.5” 250G硬盘,他检测到的是ARM9内核。我找的是八8i六745管束器的3.5” 2TB硬盘,有差异的格式身分,并且有点新。幸运的是,OpenOCD或者踊跃检测JTAG邻接的装备。下列所示:

这我就有点搞不懂了……我副本估计会有一个tap,等于单独的ARM内核……可这里竟然有3个tap……难道这个电影有3个ARM内核?

一番研究后,我缔造这个芯片真的是有3个内核。两个是Feroceon的内核,是比较牛逼的雷同ARM9的内核,还有一个是Crotex-M3内核,比较小,较劲更像微管束器的中心。鼓捣了一阵(以及后来的研究)缔造这些管束器各自有差异的效率:

  1. Feroceon 1 处置对磁盘的物理读写应用
  2. Feroceon 2 处置SATA接口
  3. Feroceon 2 同时处置缓存以及将逻辑块寻址翻译成柱面/磁头/扇区
  4. Cortex-M3 貌似啥都非论?我给他关掉硬盘也没啥题目。

而今从哪一个中心末尾破解呢?我的目标是经过哄骗批改的硬盘固件来影响系统的保险。最冗杂的口头,同时也也许是最难检测的口甲等于间接批改数据。这种 口头没必要要批改磁盘上的数据,固件或者使各人隐身弗偏见。为此,我必要找到一个符合的中心来住手监听:我必要一个能在从硬盘到SATA线的传输过程中交兵 到数据的中心,同时或者被把持在磁盘和SATA线缆之间批改数据。

而今,数据是如何从硬盘盘片上送到SATA借口上的呢?凭黑客的直觉我测度:

假如处置器义务在150MHz,哄骗标准的内存复制,它们就只能达到150*23/2=2.4Gbp的速度,而理论情况要比这个少许多。硬盘的速度 是六Gbps,所以必定有些放慢硬件参加其中。最也许的放慢硬件该当等于哄骗DMA(间接造访会面内存)。那就象征着数据间接从磁头读回来放进内存,不有处置 器的参加。SATA口也是同样:处置器只指明数据在那里,DMA会间接从内存中读数据。

假如是这样的话,DMA引擎指向的内存会在哪呢?硬盘的缓存是个好地方:数据从磁盘读进去老是要放进缓存的,所以当读取磁盘的时候马上去那里复制也就说的通了。我过来缔造第2个Feroceon负责计划缓存;因而它就成了我的首选目标。

就这样,我臆测数据经过DMA来读写,没必要要任何CPU法子。而今的题目是:既然CPU不会在正常应用中交兵数据,那末CPU能不能(非正常地)交兵到数据呢?为理解答这个题目,我首先哄骗JTAG邻接,用了一些反汇编,来看看Feroceon2号的内存。

如你所见,内存图有些琐屑。RAM中有一些小块散落着,还有一些IO空间和IRQ空间,以及一块内部创议的ROM。还有一块六4MB的数据段,我猜 这个是用作缓存的DRAM。一同来看看是不是这样。首先,我把硬盘加载到我的电脑上,在硬盘上的一个文件里写入「Hello world」。而今看看我可否能从六4MB的内存中找到这个字符串。

没错,找到了!看起来Feroceon2号或者读取缓存,并对这块六4MB的DRAM住手了地点照耀。

 

注入代码

当然了,假如我想要在缓存里批改数据,我可不能每次都完全扫描局部六4MB的缓存:我必要知道缓存是如何义务的。为此,我必要住手反汇编并认识硬盘的固件,至少要分明缓存的函数。

对固件住手反汇编,可不是个冗杂的活。首先,代码混合了ARM和Thumb指令,假如你不有踊跃切换两种指令的反汇编器就很令人抓狂了。并且,不有 那些能使反汇编更冗杂的信息了:一般顺序都被写好了,当有工具蜕化总会弹出雷同「Couldn’t open logfile!」的信息。这些信息关于理解代码效率有很大扶助。而这个固件,一条信息都不有:你得各人看代码来知道代码在做什么。代码库彷佛有点老,而 且有些时候反汇编的感觉就像给代码加了许多本色,把部门事故都搞得更烦复。

当然,也有几件事使得反汇编绝对冗杂些。首先呢,西部数据不有居心混淆代码:不有在指令中间用些跳转的招数。还有,由于JTAG接口的具备,你或者干预干预代码的实验,设置断点,梗概间接批改,让你稀奇冗杂地知道顺序在做什么。

我看了良久代码,试着去认识,偶尔候用调试器考据我猜的对差池,最后我找到了缓存系统的中心代码:在RAM中的一个表,我称之为「缓存描绘符表」。

缓存描绘表的每一项描绘了缓存中的一个块。它采集了也许在缓存中的磁盘扇区的肇始LBA、缓存中存有几何硬盘数据、一些批注了缓存项的形状标记符,还有一个批注了缓存数据在内存中未知的数。

而今,缓存描绘符表的机要还不有被揭开,我可否在数据送出SATA口过来截断磁盘读取码?为此,我必要在磁盘管束器上实验我各人的代码。不仅如此,我还必要肯定代码可否在准确的工夫运行:假如它批改缓存太早,数据还没进去;假如太晚的话,数据已经送到PC了。

我的口头是绑定在一个已具备的工作上。我破解的是Feroceon2号,这个CPU负责部门的SATA通报,所以必定有个任事是负责设置SATA硬件去缓存中读取数据。假如我找到这个任事,我便也许在它过来运行我的代码。

在看了许多代码,设置了许多断点,批改了很频繁当前,我终极找到了某个符合条件的任事。我经过邻接让这个任事在实验前先运行我的代码。这是本来的代码:

Default
12345六7八91011121314 0001六7BE ; r0 - slot in sata_req0001六7BE sub_0_1六7BE:0001六7BE                 PUSH    {R4-R7,LR}0001六7C0                 MOVS    R7, R00001六7C2                 LSLS    R1, R0, #40001六7C4                 LDR     R0, =sata_req0001六7C六                 SUB     SP, SP, #0x140001六7C八                 ADDS    R六, R1, R00001六7CA                 LDRB    R1, [R六,#0xD]0001六7CC                 LDR     R2, =stru_0_4002八DC0001六7CE                 STR     R1, [SP,#0x2八+var_1C]0001六7D0                 LDRB    R0, [R六,#(off_0_FFE3F10八+2 - 0xFFE3F0FC)]0001六7D2                 LDRB    R5, [R六,#(off_0_FFE3F10八 - 0xFFE3F0FC)]0001六7D4                 LSLS    R0, R0, #4

 

这是改为邻接到我的代码当前:

Default
12345六7八91011121314151六171八1920212223 0001六7BE ; r0 - slot in sata_req0001六7BE sub_0_1六7BE:0001六7BE                 PUSH    {R4-R7,LR}0001六7C0                 MOVS    R7, R00001六7C2                 LD      R六, =hookedAddr0001六7C4                 BX      R六0001六7C六                 .dw     checksumFix0001六7C八                 .dd     hookedAddr0001六7CC                 LDR     R2, =stru_0_4002八DC0001六7CE                 STR     R1, [SP,#0x2八+var_1C]0001六7D0                 LDRB    R0, [R六,#(off_0_FFE3F10八+2 - 0xFFE3F0FC)]0001六7D2                 LDRB    R5, [R六,#(off_0_FFE3F10八 - 0xFFE3F0FC)]0001六7D4                 LSLS    R0, R0, #4...FFE3F000                 PUSH    {R0-R12, LR}FFE3F004                 BX      changeThingsInCacheFFE3F00八                 POP     {R0-R12, LR}FFE3F00C                 LSLS    R1, R0, #4FFE3F010                 LDR     R0, =sata_reqFFE3F014                 SUB     SP, SP, #0x14FFE3F01八                 ADDS    R六, R1, R0FFE3F01C                 LDRB    R1, [R六,#0xD]FFE3F020                 BX      0x1六7CC

如你所见,本来的指令被跳转到的新代码承办了,新代码放在副本没用到的地点0xFFE3F000,然后又加了一句,保证代码域的校验和有效。假如没 这么做的话,硬盘会尝试从盘片上读取备份,那可不是我想要的。跳转的代码实验了一个任事,叫做「changeThingsInCache」然后实验批改代 码本该做的指令。最后接切实验副本的任事彷佛什么也没产生过同样。

而今我要写的等于批改缓存数据的任事。首先做个测试,我决定用一个上面的用伪代码写的任事:

Default
12345六7八9 void hook() {  foreach (cache_struct in cache_struct_table) {    if (is_valid(cache_struct)) {      foreach (sector in cache_struct.sectors) {        sector[0]=0x12345六7八;      }    }  }}

这一小段代码会在每次调用的时候用0×12345六7八取代缓存中每个扇区的前4个字节,所以假如我把这个上传到硬盘的话,我在我看到的每个扇区反面屯子看到这个数字。我经过JTAG上传了代码……

然后你看:

 

一劳永逸

当然了,我或者将固件完全破解,然而每次硬盘创议都必要用JTAG批改RAM,这就得不偿失了。我得让它意会邻接刚烈,也等于说,我要把我的批改具备某个地方,每次硬盘创议屯子带上这段批改顺序。

我选的地方是闪存。我大概也或者放在磁盘大师的保留扇区上,然而假如我一旦弄错的话,我就无奈复原我的硬盘了。闪存芯片只是一个八个脚的标准件,所以我或者垂危地摘上去,刷掉闪存再装回去。为此,我把它焊上去然后放到万用板上,这样我便或者在编程器和硬盘之间垂危切换了。

而今,该当在闪存里写什么呢?很幸运的是,芯片中存储的格式已经找到了:它采集了多块数据,还有一个表在最末尾描绘了这些数据。这个表描绘了闪存中 代码块的位置,如何收缩的(假如收缩了的话),代码块该当在放在RAM的什么位置,并且在最后的地点中是一个实验指针,标志了创议器该当跳到什么地方去执 行顺序。

倒霉的是,我不能批改闪存中的代码;我想加钩子的地方的数据被某种不知道的收缩算法收缩了,我就不能批改了。然而我能做的是增进一个额定的代码块, 批改实验地点这样这个代码块便或者在其它过来实验了。这样一来就冗杂多了。当我的代码块实验的时候,我便或者在已经解压的代码中参加我的钩子了。

当然,我得反汇编,再重编译闪存的2进制代码。我为此做了个小对象,稀奇俗地起名为「fwtool」。这个小对象或者读出闪存中的许多数据块,并把头翻译成文本文件以恣意批改。接着你便或者批改,删除梗概加之代码,然后从新编译成一个固件,筹备刷回去。我用它把我的代码加到镜像中,再刷回到芯片里, 把芯片装回硬盘,创议备份的文件,然后:

后果并不迂腐:等于我过来做过的。仅有的变幻等于我不必JTAG就可以办到了。

 

刷软件

虽然闪存这边有了很猛停留,我还是不能末尾我的黑客脚本:我信任不会有任何一个任事器公司会承受这些带有反汇编又重汇编的芯片的硬盘。我必要想个门径能让芯片不从板子上摘上去便或者刷固件,最佳是能间接在硬盘安排的电脑上刷。

西部数据的固件降级对象为此供应了也许性:这个对象冗杂地在DOS情况下的把新固件写进闪存和任事区——也等于保留扇区。按照网上资料,这个对象使 用的所谓「Vendor Specific Commands」号令。也有一些其它的对象或者批改固件:比如,有一种观点考据性的代码,或者哄骗未哄骗的保留扇区来隐藏数据。最后有一组对象叫做「idle3-tools」 或者经过批改固件中的字节来批改硬盘的闲置举止。这个代码同样哄骗VSC,经过Linux系统的SCSI(小型共计机系统接口)直通IOCTLS(输入输 出管束系统)这种「正式」的蹊径来批改代码。我必要「借用」它的源代码,批改一下然后整合到我的fwtool轮廓。在胡乱猜了一阵VSC参数之 后,fwtool突然或者读写电脑上硬盘的闪存芯片了。

有了这个对象,我的攻打根本完成了,假如一个黑帽子黑客获得了一个带有这样硬盘驱动器的任事器的最高权限,他便或者哄骗fwtool远程获取硬盘闪存,批改然后刷回去。终极,主机的客人会缔造我用他的主机轻车熟路,然后也许会重装系统,断掉黑客本来进入主机的路。

然而有了这个破解了的固件,攻打者或者把持硬盘在新安排的系统里持续轻车熟路。首先他必要触刊举止,这必要事先在硬盘里写入一个破解固件必要的某个 特定字符串。这个字符串或者在任何一个文件中:攻打者或者向任事器上传一个带有代码的.jpeg文件。他也或者经过向任事器发送在URL中追加了特定代码 的文件央求来完成。这终极会在任事器的纪录文件中结束,触发操作。

接上去,被破解的硬盘固件就末尾作怪了。比如,他会等待主机读出/etc/shadow中的文件,其中存储了Unix/Linux的部门暗码,然后 立即批改为攻打者过来写进去的一些工具。当攻打者当前尝试用他各人的暗码登入系统的时候,主机缘按照批改过的/etc/shadow武断暗码,攻打者便可 以再次垂危登录。

这是我做的演示。你或者看见我没能战败登录主机的根用户。然后我创议破解,给它一个取代暗码的哈希值,也等于暗码「test123」。由于 Linux系统把影子文件缓存了(如同部门近来存取的文件),我必要制造许多硬盘活动把缓存清出去;这样,当我再次登录的时候,Linux系统会再次读取 磁盘上的影子文件。终极,缓存已清空,我或者用假的「test123」暗码登录根用户了。

 

其它用法

当然了,复原任事器中铲除的秘密登录口头并不是我研究成绩的仅有师法。这同样或者用于抗御目标。

例如,你或者做一个弗成复制的硬盘:假如扇区的读取模式是随机的话,像正常的应用系统读取文件系统,硬盘会正常义务。假如硬盘是有序的读取,像硬盘复制装备那样的话,硬盘会窜改数据,无奈复制出本来的模式。

硬盘管束器作为一个通用管束器也是有的玩的。你手里的是3个遵从不错的CPU中心,连着一个相称大的RAM。还有一个UART作为串口,至少两个 SPI接口:一个邻接到闪存ROM,一个连到电机管束器。你或者经过降级内部闪存芯片来给处置器加载代码,梗概以至在创议加载器上用串口加载。为了演示芯 片的手腕,我在硬盘上移植了一个相称遍及的软件。这个demo只是观点考据性的,串口是仅有义务的中心装备,并且不有效户空间。虽然如此, 我还是很孤高的传播鼓吹我在我的硬盘管束器上装了一个Linux。在顶端,是标准的号令行(硬盘加载在/mnt下),低端是我在硬盘串口上的输入。

在此多告白一下这是怎样义务的:内核和创议都封装成每块大小都是一个扇区的一个个的包,包的反面带有非凡字符串和编号数字。经过从磁盘读取数据,内 核和创议终极会进入缓存。写入非凡字符串「HD, Inx!」终极触发了批改过的固件,在缓存中搜寻部门扇区,重编译内核然后创议。然而一个不有内存管束单元的内核也必要非凡格式的用户空间。我不能把这个 也编译了,所以内核终极由于找不到init来实验而解体。

 

结论

是的,等于这样。虽然硬盘管束器如统一个不知其究竟后果的野兽,它仍能经过逆向工程加以理解,并为其写出代码以实验。对管束器的未知,使得通用破解充斥 难度,令我猜忌这工具是不是永恒不会泛起一个歹意的固件补钉:较劲对每个任事器的每个硬盘固件住手逆向工程加以破解,还是找一个0day裂缝加倍冗杂吧。

我还盼望证实一个坏掉的硬盘如故也许哄骗。当硬盘的呆板部门坏掉的时候,PCB如故带有可用的嵌入式系统,其遵从相称不俗,十分是坏的硬盘根本都不要钱就可以拿到。

雕残保险工程的源代码什么的太卑劣了。我想雕残代码,然而我不想为由此产生的少量的「永久破解」的任事器负责……我决定做个妥协:你或者在这里下载代码,然而我移除了影子承办部门的代码。当心:反正我不负责让局部过程完全可运行;黑客,你各人来吧。

91ri.org:假如经过某些手段,使这种硬盘流入市场那末&#八230; 地雷啊&#八230;

[via@spritesmods]

数安新闻+更多

证书相关+更多