-
1 概述
2015年2月16,国外安全厂商卡巴斯基披露了一个可能是目前世界上最复杂的网络攻击组织—“方程式”组织(Equation Group)。并同时披露了该组织所使用的恶意攻击程序。其中包含一个名为nls_933w.dll的模块,该模块的独特之处在于可修改各类硬盘固件,这应该是迄今为止发现的第一种可修改硬盘固件的恶意程序。硬盘固件作为硬盘最为重要的组成部分,相当于硬盘的中枢神经,负责驱动、控制、解码、传送、检测等工作。
恶意代码一旦隐藏在硬盘固件中,将具有极高的隐蔽性且难以检测。被恶意代码修改的固件程序,可屏蔽厂商原有的ATA指令达到不可被清除的目的。在查阅相关资料时,我们发现国外某硬件安全研究人员就通过修改硬盘固件的方式替换Linux的Root密码,从而达到入侵目标机器的目的。
尽管这种攻击方式十分隐蔽,难以被检测,但我们仍希望通过本文与大家共同探讨一种可行的检测方式。
2 受影响的硬盘厂商或型号
我们通过分析发现该模块提供了应用层操作硬盘控制器的接口功能,通过释放的驱动将应用层的ATA指令发送到硬盘控制器,从而实现对指定厂商(WDC WD、SAMSUNG、Maxtor、Maxtor STM、ST)的硬盘控制器固件的烧录、硬盘日志空间读写等操作。
该插件在进行磁盘固件操作前,会首先判断当前硬盘的厂商类型,针对不同的厂商,一些厂商自定义的ATA指令会有所差异,如ATA指令0x80 VENDOR SPEC等。
受影响厂商列表如下:
受影响硬盘厂商 厂商简介 WDC WD 西部数据,全球知名硬盘厂商 SAMSUNG 三星电子,2011年向希捷出售旗下硬盘事业部 ST 希捷,全球领先的硬盘及存储解决方案提供商之一 Maxtor / Maxtor STM 迈拓,2006年被希捷收购这些厂商名称均加密硬编码在程序内:
3 操作硬盘控制器的过程
当恶意程序释放并完成驱动程序的安装后,开始进行一系列的初始化工作,这些初始化操作包括初始化硬盘控制器、查询硬盘设备序列号、硬盘当前固件版本,以及对一些全局变量的初始化。
当完成这些初始化工作后,恶意程序会查询调用的参数信息并根据参数去调用不同的接口,执行完成后删除服务和释放的驱动程序,返回执行结果:
恶意程序的dll模块通过DeviceIoControl与驱动程序win32m.sys通信,这个过程中用到的IOCTL_CODE如下:
IOCTL_CODE 功能 0x870021C0 返回版本号 0x870021C4 初始化函数虚表、映射I/O端口、创建系统线程 0x870021C8 0x870021CC 返回一些数据到Ring3层 0x870021D4 初始化某些变量 0x870021D0 操作硬盘控制器其中最为重要的IOCTL_CODE 0x870021D0负责将构造好的ATA Command通过InBuf传递给win32m.sys。根据硬盘厂商的不同,恶意程序会选取不同的ATA命令进行操作, 所使用的ATA指令见章节4“所使用的ATA指令”。
4 所使用的ATA指令
ATA(Advanced Technology Attachment)也称作高级技术配置,是一种硬盘控制技术,兼容IDE和STAT接口的硬盘均可以通过ATA控制技术实现对硬盘控制器的操作。
ATA控制技术规范指定了一系列的ATA命令,这些命令包括一些标准命令如IDENTIFY DEVICE,还有一些命令是由硬盘控制器制造商自己指定,通过这些ATA控制命令,可以实现对硬盘控制器的一系列操作,如获取硬盘序列号、固件版本、硬盘厂商,甚至可以修改硬盘的固件等。
该插件模块所使用的ATA指令列表如下:
ATA指令 指令编码 说明 READ SECTORS WITHOUT RETIRIES 0x21 读取扇区 READ LOG EXT 0x2F 从指定的地址读取LOG WRITE LOG EXT 0x3F 将LOG写入指定的地址 VENDOR SPEC 0x80 厂商自定义,被用于“SAMSUNG” VENDOR SPEC 0x82 厂商自定义,被用于“SAMSUNG” VENDOR SPEC 0x8A 厂商自定义,被用于“WDC WD” VENDOR SPEC 0x8F 厂商自定义,被用于“SAMSUNG” INIT DEBICE PARAS 0x91 初始化设备参数 DOWNLOAD MICROCODE 0x92 下载微码 VENDOR SPEC 0x9A 厂商自定义,被用于“Maxtor STM”、“ST” SMART READLOG 0xB0 (0xD5) 实现SMART的 READLOG SMART WRITELOG 0xB0 (0xD6) 实现SMART的 WRITELOG CFA ERASE SECTORS 0xC0 删除扇区数据(需要支持CFA特性的硬盘) VENDOR SPEC 0xC1 厂商自定义,被用于“Maxtor” SET MULT MODE 0xC6 在读取DBQ数据块时开启批量读写 STANDBY IMMEDIATE 0xE0 强制磁头进入STANDBY模式(电源管理) FLUSH CACHE 0xE7 刷新缓存 IDNTIFY DEVICE 0xEC 鉴别硬盘控制器,返回相关信息 SET FEATURES 0xEF 设置设备特性 VENDOR SPEC 0xF7 厂商自定义,被用于“Maxtor STM”、“ST” VENDOR SPEC 0xFC 厂商自定义,被用于“Maxtor STM”、“ST”
5 对硬盘固件内容操作的部分逻辑
5.1 获取固件的入口地址
该模块会针对WDC WD厂商的硬盘控制器,匹配固件加载部分的指令,从而获取固件程序的入口地址,一共有两种方式:
方式1
1) 判断Loader程序偏移0x14是否为ARM指令 MOV R0, R0,如果是,则继续判断下一条指令 。
2) 判断Loader程序偏移0x1C是否为ARM指令 LDR PC, [PC, #0x0018],如果是,则返回偏移0x34存储的固件入口地址。方式2
1) 判断Loader程序偏移0x14是否为ARM指令 MOV R1, R1,如果是,则直接返回偏移0x3C存储的固件入口地址。
2) 判断Loader程序偏移0x14是否为ARM指令 MOV R2, R2,如果是,则直接返回偏移0xB4存储的固件入口地址。
3) 判断Loader程序偏移0x14是否为ARM指令 MOV R3, R3,如果是,则直接返回偏移0x5C存储的固件入口地址。对应代码如下:
5.2 验证固件的文件格式
该模块会针对WDC WD厂商的硬盘控制器,会检测是否满足WDC WD固件的文件头格式,推测可能是用于在烧录固件前,对固件格式进行验证确认。通过依次检测固件头是否为“ROYL”、“00020000”或“0001000”,代码逻辑如下:
我们通过从网上下载到的WDC固件进行对比,发现字段特征,正好符合WDC固件的某个版本文件格式。
6 API指令接口分析
为了正常到达释放和安装驱动部分代码,需要先执行完导出函数0x100013DD对驱动名、注册表键值等进行解密,解密后程序会获取自身文件中名为”BINARY”的二进制资源,该资源会被写入到系统目录%SYSTEM32%drivers\win32m.sys中:
当恶意程序释放并安装完成驱动程序后,便可以通过该dll提供的接口来实现对物理硬盘的一系列操作,实现包括获取硬盘序列号、固件版本、硬盘厂商、修改固件等。
接口的调用在函数0x10001148中实现,该函数接收一个特定的结构体指针以及该结构体的大小做为参数,通过逆向分析,我们得出两种不同的结构在该接口的调用过程中。
12345678910111213141516171819struct API_Interface_A
{
byte
command_num;
//每个接口都包含一个特定的id号
byte
command_type;
//该字段标识结构体类型(传入、传出)
word checksum;
//结构体数据校验和
dword args_size;
//可选参数
char
*args;
//可选参数
}
struct API_Interface_B
{
byte
command_ num;
byte
command_type;
word checksum;
char
*DriverNum;
//长度为20个字节的硬盘盘序列号
dword Unknow;
//可选参数
dword args_size;
//可选参数
char
*args;
//可选参数
}
接口A和接口B在调用时唯一的不同之处在于接口B会作用于特定的硬盘物理序列号,关于程序如何获取到硬盘的序列号会在后面分析关于ATA指令部分分析中进行描述。
在每个接口被调用的过程中均会对传递参数进行多次校验和检查,当发现校验和与checksum字段不符时立即终止并返回错误代码。下面是该恶意程序中用到的参数校验和检测函数:
除了一些未知功能的接口,我们分析得出了以下的接口编号及功能:
command_ num 解释 0x51 安装驱动程序并启动服务 0x52 卸载驱动程序删除服务 0x53 获取版本号(本次分析中为3.0.1) 0x54 获取硬盘信息(序列号、固件版本等) 0x55 对指定序列号的硬盘进行写加密文件操作 0x56 对指定序列号的硬盘进行读解密文件操作 0x5F 驱动程序、初始化ATA指令操作 0x63 对指定序列号的硬盘执行ATA操作 0x60 清空并释放在内存中的一些全局指针结果
下面是通过接口编号0x53获取dll版本例子:
接口传入的参数构造如下:
command_num:0x53
command_type:0x00
checksum:0xFFAD传出的数据如下:
command_num:0x53
command_type:0x01
checksum:0xA213
args_size:0x00000006
args:”3.0.1”7 驱动操作硬盘控制器分析
样本在Ring3层会释放并安装对硬盘进行操作的驱动,该驱动为Ring3层提供了操作硬盘的接口。主要作用是接收Ring3传入的参数,参数中包含对硬盘的控制指令。驱动通过对I/O端口进行读写操作。
Ring3与Ring0通过DeviceIoControl进行交互,Ring3层将硬盘控制指令发送至Ring0层,Ring0层再将硬盘控制指令发送到相应的I/O端口,并从对应的端口上读取数据,判断操作是否成功。在完成与AHCI的操作后再将数据返回至Ring3。
7.1 IDE I/O Port
IDE接口是目前PC机普遍采用的一种硬盘接口,现在大多数的主板都内置了两个IDE控制器,分别为主IDE控制器和次IDE控制器。通常情况下,主IDE控制器占用的I/O PORT地址是1F0H~1F7H、3F6H~3F7H。次IDE控制器占用的I/O PORT地址为170h~177h、376H~377H。下面以主IDE控制器的I/O PORT为例:
1) 1F0是数据读写端口,分析的程序中就是通过读取1F0端口的内容,来获取硬盘的状态信息。
2) 1F1在读写状态下表示不同的作用,在Read状态下表示错误寄存器,在Write状态下表示功能寄存器。
3) 1F2 是扇区计数寄存器。
4) 1F3~1F5分别表示的是LBA(逻辑区块地址)的低中高地址。
5) 1F6 驱动或磁头寄存器
6) 1F7在读写状态下表示不同的作用,在Read状态下表示状态寄存器,在Write状态下表示命令寄存器。
7) 3F6在读写状态下表示不同的作用,在Read状态下表示备用状态,在Write状态下表示设备控制寄存器。7.2 Ring0操作IDE控制器的流程
本次分析的操作流程,是依据程序中发送的0xEC指令进行动态跟踪。其他控制指令可能存在差异。Ring0与IDE控制器交互主要是通过READ_PORT_UCHAR、WRITE_PORT_UCHAR、READ_PORT_BUFFER_USHORT等函数完成的。
驱动首先对0x1F6端口进行操作选择主IDE控制器。接着读取备用硬盘状态寄存器来获取硬盘状态,随后对硬盘的状态进行一系列的判断。再读取硬盘的各种信息,完成这些操作后向IDE命令寄存器中写入读取硬盘信息的命令0xEC。从硬盘数据就拿起中读出硬盘信息至指定的Buffer中。随后进行一些状态检测操作。
8 接口函数发现REGIN关联痕迹
nls_933w.dll是一个工作在windows x86下的动态链接库程序,抹去了导出函数名称,可以通过序号隐式调用。
通过静态分析,得知该dll程序存在以下几个关键的导出函数
接口函数 功能 nls_933w_1 (0x100013F4) 获取实现硬盘操作功能的函数指针 nls_933w_2 (0x100013DD) 解密nls_933w_1中用到的部分字符串 nls_933w_3 (0x100013F0) 用于测试接口函数是否可正常调用,只是返回1 nls_933w_4 (0x10001408) 获取硬盘信息(序列号、固件版本等) nls_933w_4 (0x10001408) 获取文件的版本号 (0x30, 0x00, 0x01, 0x10000) nls_933w_5 (0x10001425) 获取插件的版本号 (0x80AB)
8.1 与REGIN关联的接口函数
该函数接收一个对象作为参数并在函数0x10001BB2中进行初始化,之后通过RC6算法解密一段大小为0x9C的二进制数据。标准的RC6算法中使用的两个算子分别为0xB7E15163和0x9E3779B9:
在该样本中对算子进行了一个修改:
程序中将+0x9E3779B9修改为-0x61C88647。根据卡巴斯基的报告,这两个经过修改的算子也曾在Regin恶意程序中出现。
解密后的缓冲区包含了注册表键值和几个文件名:9 最后
该恶意程序高端 之处是能够修改主流硬盘厂商的硬盘固件程序,而我们由于缺少硬盘产商的内部资料很难了解该硬盘固件后门真正的功能。根据国外媒体<<明镜周刊>>曝光的一封NSA(美国国家安全局)项目计划书指出,NSA其实早在2006年就已经开始研究如何通过修改硬盘固件,达到对一些敌对国家的重要目标进行信息窃取、破坏的目的:
号称只有产商可以升级的硬盘固件程序,已经被方程式组织的攻击者们掌握。联想到还有那么多有固件程序如网卡、鼠标键盘、路由器等,当黑手伸向设备固件程序的时候,作为安全从业人员我们突然觉得有种无力感。这是一场不对等的战争,还未开始防御者就已经输在了起跑线上 ,作为防御者我们更需要投入更多的资源来进行攻防的研究,这也是为什么在热点事件过后这么久时间里我们还一直在研究它的原因所在,意义所在。