首页
论坛
专栏
课程

[原创]SMM Rootkit初步 - 读写SMRAM(带你迈入CPU级Rootkit之门)

木桩 2009-3-29 14:37 43633
好吧,我承认标题有点夸大,不介意的都进来BS我把
就像 qihoocom 大侠说的,“SMM XX早就几万年前就不是什么秘密了”,不过国内讨论这个的到是鲜见,希望这篇文章能抛砖引玉吧。

之前看到rootkit.com上 Implementing SMM PS/2 Keyboard sniffer 那个代码,狠狠震撼了一把。于是开始研究SMM,半月下来总算有些收获。这里将如何读写SMRAM的方法拿出来科普一下,希望更多人能迈入编写SMM Rootkit的大门。
文章后面提供可以在VPC和VMware两大虚拟机中运行的代码,将演示如何在WinXP(SP2)中读写SMRAM。(本文只考虑最简单的系统环境,不涉及 SMM Space Locked(D_LCK)=1 时无法读写SMRAM的情况)另外,按 Ivanov 大牛的说法,这种方法局限性很大,只能在没有执行 Intel 修补方案的主板上运用(感谢两大VM模拟的都是I440BX )。

对硬件方面接触尚浅,文中若有疏漏之处,欢迎指正。

--------------------------------------------------------------------------------------------------------

首先放下PCI相关的诸多知识,我用最短的篇幅叙述读写SMRAM的过程。希望这篇文章能带你迈出SMM Rootkit的第一步。
首先说说什么是SMM(System Management Mode)。System Management Mode Hack中说:SMM是专门为电源管理设计的执行规则。当进入SMM后,系统的各个部件可以被关闭或者使用最低的功耗。SMM独立于其他的系统软件,也可以被用在其他目的...  该文章中文版点这里

了解SMM是什么东西就够了,这篇文章不会涉及太多SMM的东西。相反,读写SMRAM更需要的是PCI配置空间(PCI Configuration Space)方面的知识。
先讲讲两个访问PCI配置空间的I/O端口:CF8hCFCh
通过向 CF8h 端口写一个特殊的地址,我们就可以在 CFCh 端口上读写指定寄存器的值。这里要读的寄存器是位于配置空间偏移为 72h 的8bit寄存器——SMRAM (System Management RAM Control Register)

首先要介绍一下 CF8h 这个I/O端口。实际上 I/O CF8h 写的是CONFIG_ADDRESS寄存器,所以 CF8h又叫CONFIG_ADDRESS。其布局如下[1]:

按上图格式,31位置1(enable),假设I440BX的北桥82443BX位于Bus: 0, Device:0, Func:0(后面将教你如何确定芯片类型以及取得这几个值),这样配置空间的基址就是0x80000000。

通过I/O指令向CF8h写入0x80000000,就可以从 CFCh(CONFIG_DATA)中读出82443BX配置空间偏移为0的一个DWORD值了。而这个DWORD的高低16位分别是VendorIDDeviceID,如图:


下面在我们去读配置空间偏移为72h的SMRAM前,首先注意一个特性。不知道你注意到没有,回头看看CONFIG_ADDRESS的低2位,它们被定义为0。且不谈PCI规范上的大道理,说白了这个地方为0是为了限制你给出的地址——必须为4的整数倍。了解到这一点再看那个Register Number就比较好理解了,原来这个寄存器编号和偏移是这么对应的。

好了,那么偏移为72h (01110010) 的SMRAM,最后两位置零是70h (01110000),即位于编号为1C (11100)的寄存器上。所以只要向 CF8h 里写入0x80000070这个地址,此时从 CFCh 端口读出的数据就是包含SMRAM的一个DWORD了。



假设读出来的数据为DWORD 380A0000h (00 00 0A 38),对照上面82443BX寄存器表可知:
70h    00
71h    00
72h    [COLOR="red"]0A    SMRAM
73h    38    ESMRAMC


好了,SMRAM寄存器读出来了,下面进入正题:如何将SMRAM内容映射到0xA0000
从文献[2]中了解到,只要D_OPEN=1时,对物理内存0xA0000的访问会变成这样:


D_OPEN位在哪?SMRAM = 0Ah又代表什么?根据文献[1]记载,SMRAM的各位意义如下(关于SMRAM更详细解释,见文章末尾补充资料不部分):
   7    [COLOR="red"]6      5     4       3      2 - 0
   0  [COLOR="Red"]D_OPEN D_CLS D_LCK [COLOR="Indigo"]G_SMRAME C_BASE_SEG
        |                    [COLOR="indigo"]1       010
        |-> 我们就是要设置 D_OPEN = 1


原来的0Ah就是 0000 1010。只要第四位的D_LCK不为1,好了,向SMRAM写入4Ah (0100 1010),于是飞跃光明之巅!

附带程序中整个映射SMRAM过如下:
1. 首先遍历PCI设备,找到I440BX的82443BX Host Bridge Controller。
    (VMware Workstation 6.0.x中82443BX 的VendorID: 8086h  DeviceID: 7190h)
    (Virtual PC 2007 6.0.x 中82443BX 的VendorID: 8086h  DeviceID: 7192h)

    很幸运,这两个虚拟机中,82443BX都位于Bus:0, Device:0, Func:0,所以PCI配置空间基址都是0x80000000。
2. 以I/O伪代码为例,读SMRAM:
    out( CF8h, 80000070h )   // 还记得0x80000070怎么来的吗?
    in( CFCh, eax )          // 读出包含SMRAM的一个DWORD,如 380A0000h
    shr eax, 10h             // SMRAM的8bit在第三个字节处,右移16位(2字节)
    // 此时AL中就是SMRAM内容了(0Ah)
3. 置D_OPEN为1,并且C_BASE_SEG设为010
    (C_BASE_SEG在初始化时就是010了,不过为了防止意外,最好重设一下)
    out( CF8h, 80000070h )
    mov eax, 384A0000h       // 写回D_OPEN置1后的SMRAM(4Ah)
    out( CFCh, eax )
4. 此时对物理内存0xA0000-0xBFFFF读写,就是在SMRAM中了。写完试试D_OPEN=0隐藏看看,读0xA0000是不是又回到显存了?
注意:当SMM Space Lock(D_LCK)为1时,这种方法是无法修改SMRAM的,只能另辟蹊径。

另外,关于读出的SMRAM内容,一定会有人质疑0xA0000处真的是SMRAM?关于这点,可以去看看SMRAM的布局http://www.sandpile.org/ia32/smm.htm
我一般是通过7FF0h (EIP) 和7FF4h (EFLAGS) 这两个DWORD判断的(SMBASE默认是0xA0000):
> dump [000A7FC0 - 000A8000]
000A7FC0   00 00 00 00 28 00 00 00 00 04 00 00 F0 0F FF FF
000A7FD0   E1 BB 7E 81 83 A0 00 00 B2 00 00 00 00 00 00 00
000A7FE0   20 42 E6 F9 20 42 E6 F9 80 C2 A1 F9 E0 E0 6E 80
000A7FF0   47 8B A1 F9 46 02 00 00 00 90 03 00 31 00 01 80
               EIP       EFLAGS

补充资料:
这里是 Intel 440BX AGPset: 82443BX Host Bridge Controller[1] 中关于SMRAM的详细解释:



还有些相关知识,有时间再补上...


参考文献:
[1] Intel 440BX AGPset: 82443BX Host Bridge Controller
    http://download.intel.com/design/chipsets/datashts/29063301.pdf
[2] Shawn Embleton, Sherri Sparks, Cliff Zou.
    SMM Rootkits: A New Breed of OS Independent Malware
[3] Loic Duflot, Daniel Etiemble, Olivier Grumelard.
    Using CPU System Management Mode to Circumvent Operating System Security Functions
[4] Intel 64 and IA-32 Architectures Software Developer's Manual Volume 3B: System Programming Guide
    http://www.intel.com/products/processor/manuals/
[5] A tool for FreeBSD to discover SMRAM on i440BX based motherboards
    http://unix.derkeiler.com/Mailing-Lists/FreeBSD/hackers/2004-03/att-0448/smm.c

测试环境:
Intel Pentium D 3.0GHz 双核 + Virtual PC 2007(6.0.192.0) + WinXP(SP2)
Intel Pentium D 3.0GHz 双核 + VMware Workstation (6.0.4-93057) + WinXP(SP2)
AMD Athlon 64 X2 Dual 4000+ + Virtual PC 2007(6.0.192.0) + WinXP(SP2)

Virtual PC 2007下的运行截图:


由于手头没有I440BX的主板,无法使用真实机器测试。另外 AMD64 Architecture Programmer's Manual Volume 2: System Programming 也提及了SMM的相关细节,目前还没有仔细看。
如果你在其他芯片组上测试成功,欢迎给我来信:upbit@126.com

ps: 忘补上一个开发库了,程序里用到了WinIO,可以到这里http://www.internals.com/
    WinIO这个开发库附带C和VB的例子,理论上我这里给的代码都能翻译成C或VB的,有兴趣的不妨试试
.

[防守篇]2018看雪.TSRC CTF 挑战赛(团队赛)11月1日征题开启!

上传的附件:
最新回复 (79)
木桩 8 2009-3-29 14:38
2

0

使用附件中的程序枚举PCI设备,代码参考自 遍历PCI设备 这篇文章:
http://hengch.blog.163.com/blog/static/10780067200822893345451/

例如这是我在VPC里的结果:
[80000000] 01 VID:8086/D:7192 B:00 D:00 F:00 06-00-00 (V:03)
[80003800] 02 VID:8086/D:7110 B:00 D:07 F:00 06-01-00 (V:01)
[80003900] 03 VID:8086/D:7111 B:00 D:07 F:01 01-01-80 (V:01)
[80003A00] 04 VID:0000/D:0000 B:00 D:07 F:02 00-00-00 (V:00)
[80003B00] 05 VID:8086/D:7113 B:00 D:07 F:03 06-80-00 (V:02)
[80004000] 06 VID:5333/D:8811 B:00 D:08 F:00 03-00-00 (V:00)
[80005000] 07 VID:1011/D:0009 B:00 D:0A F:00 02-00-00 (V:20)


这里主要关注的是VendorID和DeviceID(VID:8086/D:7192),以及最前方的地址信息(80000000)。关于这两个ID所代表的意义,我们可以到 http://www.pcidatabase.com/ 上进行查询。

例如我VPC 2007的设备信息:
440BX/ZX chipset Host-to-PCI Bridge
[80000000] 01 VID:8086/D:7192 B:00 D:00 F:00 06-00-00 (V:03)
PIIX4/4E/4M ISBridgeA
[80003800] 02 VID:8086/D:7110 B:00 D:07 F:00 06-01-00 (V:01)
PIIX4/4E/4M IDE Controller
[80003900] 03 VID:8086/D:7111 B:00 D:07 F:01 01-01-80 (V:01)
-
[80003A00] 04 VID:0000/D:0000 B:00 D:07 F:02 00-00-00 (V:00)
PIIX4/4E/4M Power Management Controller
[80003B00] 05 VID:8086/D:7113 B:00 D:07 F:03 06-80-00 (V:02)
S3 Graphics Co., Ltd - Trio 64/64V
[80004000] 06 VID:5333/D:8811 B:00 D:08 F:00 03-00-00 (V:00)
Digital Equipment Corporation - Fast Ethernet Ctrlr
[80005000] 07 VID:1011/D:0009 B:00 D:0A F:00 02-00-00 (V:20)


VMware VMware Workstation 6.0的:
82443BX/ZX 440BX/ZX AGPset Host Bridge
[80000000] 01 VID:8086/D:7190 B:00 D:00 F:00 06-00-00 (V:01)
82443BX/ZX 440BX/ZX AGPset PCI-to-PCI bridge
[80000800] 02 VID:8086/D:7191 B:00 D:01 F:00 06-04-00 (V:01)
82371AB/EB/MB PIIX4/4E/4M ISBridgeA
[80003800] 03 VID:8086/D:7110 B:00 D:07 F:00 06-01-00 (V:08)
82371AB/EB/MB PIIX4/4E/4M IDE Controller
[80003900] 04 VID:8086/D:7111 B:00 D:07 F:01 01-01-8A (V:01)
82371AB/EB/MB PIIX4/4E/4M USB Interface
[80003A00] 05 VID:8086/D:7112 B:00 D:07 F:02 0C-03-00 (V:00)
82371AB/EB/MB PIIX4/4E/4M Power Management Controller
[80003B00] 06 VID:8086/D:7113 B:00 D:07 F:03 06-80-00 (V:08)
VMware Inc. - 9500MGS NVIDIA
[80007800] 07 VID:15AD/D:0405 B:00 D:0F F:00 03-00-00 (V:00)
BT958 SCSI Host Adaptor
[80008000] 08 VID:104B/D:1040 B:00 D:10 F:00 01-00-00 (V:01)
VMware Inc. - ??
[80008800] 09 VID:15AD/D:0790 B:00 D:11 F:00 06-04-01 (V:02)
Am79C970/1/2/3/5/6 PCnet LANCE PCI Ethernet Controller
[80020000] 10 VID:1022/D:2000 B:02 D:00 F:00 02-00-00 (V:10)
ES 1371 AudioPCI
[80020800] 11 VID:1274/D:1371 B:02 D:01 F:00 04-01-00 (V:02)
VMware Inc. - Standard Enhanced PCI to USB Host Controller
[80021000] 12 VID:15AD/D:0770 B:02 D:02 F:00 0C-03-20 (V:00)


我只找到I440BX的设计手册,几台实际机器用的芯片乱七八糟(SIS、VIA、NVIDIA都有),网上又下不到相关的资料,实在是无法把程序写得更通用
如果哪位好心人有在其他芯片组的主板上找SMRAM的资料,也请拿出来分享一下。

抱歉,昨天忙中出错,已经把附件 PCI设备枚举.rar 传上来了
上传的附件:
AASSMM 2009-3-29 14:43
3

0

板凳观望·~
海风月影 17 2009-3-29 14:58
4

0

LZ很强大,只能学习
木桩 8 2009-3-29 15:04
5

0

没那回事,我也希望和大家讨论一下(哪怕不是SMM方面,我倒是觉得SMRAM中保存的那些寄存器值得仔细看看),也许有些新收获。
自己一个人看CPU、PCI手册实在是痛苦,今天另一个帖子里被qihoocom大侠提点了一下,感觉茅塞顿开。下周继续看如何越过“SMM LOCK这个叹息之壁”
dayed 1 2009-3-29 15:28
6

0

这个必须的顶
option 2009-3-29 16:03
7

0

业余爱好,看看而已
sudami 25 2009-3-29 16:20
8

0

这个还是很不错的. 都快到硬件层了. 多分享分享,哈哈
yingyue 2009-3-29 16:57
9

0

只能收藏,无法学习
玩命 31 2009-3-29 20:14
10

0

  标记 学习。。。
feezd 2009-3-29 20:23
11

0

有新东西了,谢谢分享。慢慢看。。
achillis 15 2009-3-29 20:32
12

0

太强大了!俺水平有限,不能学习,只能收藏了!
kmyc 4 2009-3-29 20:49
13

0

支持啊,很大的进步,希望继续深入下去,争取早日搞出一个简单的CPU Rootkit。
juniko 2009-3-29 22:51
14

0

真的不好学习
lixupeng 2009-3-29 22:57
15

0

望尘莫及学习下
azy 2009-3-29 23:03
16

0

对某些人无语了,辩不过就删帖,看雪啊。。。
weolar 10 2009-3-29 23:11
17

0

赶快膜拜,加强学习,对SMRAM这方面完全没有接触
heXer 3 2009-3-30 00:00
18

0

为什么前面那个讨论贴没有了?
heXer 3 2009-3-30 00:03
19

0

我觉得伊万大叔你可以删掉自己的观点,但别人的合法讨论是应该保留的
Ivanov 2009-3-30 10:06
20

0

此楼层已删除
sudami 25 2009-3-30 10:15
21

0

楼上很强大啊,讨论问题还能生气(╰_╯)#
Ivanov 2009-3-30 10:29
22

0

此楼层已删除
swzices 2009-3-30 10:33
23

0

我是来顶LZ的 太强大了
只有学习的份了...............
木桩 8 2009-3-30 10:45
24

0

关于TXT那篇论文我也下过,不过塞文件夹里忘看了 还是先把现在看的两篇吃透好了...
讨论而已,大家各抒己见。

不过,昨天听 Ivanov 大牛的一席话确实深有感触,之前都没注意到Intel新板子的补丁问题。
回头又翻了一下别人的文章,确实有提到在BIOS里做的补丁情况(2005年后的都给锁上了):


之前看文章太粗心了
上传的附件:
azy 2009-3-30 16:31
25

0

原来是喝高了。。。
QuanTa 2009-3-30 20:16
26

0

只要第四位的D_LCK不为1

=================================

这样的主板有多少?如果是我,我就一定lock。
QuanTa 2009-3-30 20:17
27

0

和那个cpu smm漏洞一样可笑。
居然还有这么多人狂吹
qihoocom 9 2009-3-30 20:24
28

0

老的很多没LOCK,即使SMM LOCK了,TOP_SWAP也有众多没LOCK~
deryope 1 2009-3-30 21:09
29

0

看Intel的说法,修补好像是要BIOS配合才行,也就是等BIOS完成SMRAM初始化后才D_LCK置1,个人感觉可以从BIOS下手。
另外,一般BIOS会比主板的生产时间更早,导致新的主板也可能没LOCK。
rhan 2009-3-30 21:27
30

0

望尘莫及啊!奋力追。。。
billh 1 2009-3-30 22:06
31

0

好强大 向lz学习 拿回家慢慢研究
cntrump 13 2009-3-30 22:16
32

0

占个位子,学习
三根火柴 4 2009-3-30 22:16
33

0

太强了,只有支持的份了
痞子辉 1 2009-3-30 23:29
34

0

楼主给我提供了有多学习的地方呀!!支持!!
suncloud 2009-3-31 08:50
35

0

楼主的动手能力很强啊
wwwst 2009-3-31 09:06
36

0

狂頂下。。。studying
Thinker 2009-3-31 09:27
37

0

hao!
Ivanov 2009-3-31 09:53
38

0

08年以后的主板还添加另一块芯片, 用于Intel提出的TXT计划
cyliu 1 2009-3-31 15:59
39

0

曾经看到一篇文章:Intel曾在2008年8月对SMM进行过一次BIOS升级修复,但问题依旧。

楼主很厉害啊。

从phrack中文章摘录的内容:

Intel处理器手册卷三说明说明的四种模式转换:

   -------------------                    SMI (interrupt)
      |->|Real Address Mode| -------------------------------------------|
      | ------------------- <----------------------------------|       |
      | | PE=1    ^ PE=0 (requires ring0) or                   |rsm or |
      | v         | reset                                      |reset V
      | -------------------                                    ---------
reset | | Protected Mode | -------> SMI (interrupt) ------> | SMM Mode |
      | ------------------- <------- rsm instruction <------   ---------
      | | VM=1    ^ VM=0                                       |       ^
      | v         |                                            |rsm    |
      | ------------------- <----------------------------------|       |
      |- |Virtual 8086 Mode| -------------------------------------------|
         -------------------                    SMI (interrupt)

(1) PE 和 VM是CR0里的标志位。
(2) 其他三中操作模式在SMI中断都可以切换到SMM模式。
(3) SMM模式通过发出一个rsm指令返回到前一个操作模式。
(4) rsm指令只有smm模式中使用。
(5) SMM里分页机制不可用, 但可以访问所有物理内存。
(6) SMRAM开始于SMBASE,占0x1FFFF 字节(如使用扩展的SMRAM,这个数值将更大). SMBASE默认为0x30000, 实际上是0xA0000(视频卡的I/端口也重定向到此地址)
(7) 内存控制Hub有一个称为SMRAM控制寄存器.

                -----------------
SMBASE+0x1FFFF  |                 |
                |                 |
                |                 |
                |                 |
SMBASE+0xFFFF    -----------------
                |                 |
                | State save area |
                |                 |
SMBASE+0xFE00    -----------------
                |                 |
                | Code,Heap,Stack |
                |                 |
SMBASE+0x8000    ----------------- ----> First SMI Handler instruction
                |                 |
                |                 |
                |                 |
SMBASE=0xA0000   -----------------

也上传一个pci管理库,开源的代码,可以支持windows,linux等。我在linux使用的,不知道windows支持怎么样,大家看看,还有源代码哦! 把zip 后缀改为tgz,然后解压缩。
上传的附件:
木桩 8 2009-3-31 20:21
40

0

libpci(pciutils)在Windows下其实也是用的WinIO库,具体怎么用没仔细看,不过想来用这个读写PCI配置空间会比较简单。
至于如何进入SMM模式我现在也没看懂,网上搜到N多触发SMI的方法,结果都没试出来...

看来我太浮躁了,回头要好好看看Intel IA-32处理器手册SMM相关部分
cooray 2009-3-31 23:34
41

0

winnip 1 2009-4-1 17:38
42

0

很遗憾。。:(
spman 2009-4-2 10:54
43

0

触发SMI的方法,不是这个吗?
asm("push %rax\n"
            "xor %rax, %rax\n"
            "outb %al, $0xb2\n"
            "pop %rax");
xss 4 2009-4-3 21:35
44

0

感觉很底层了,了解一下这方面的知识
myeanngg 2009-4-4 18:02
45

0

楼主挺牛的,这玩意对搞单片机的人应该相对容易一些
Fahrenheit 3 2009-4-4 19:49
46

0

dingaaaaa
Laona 2009-4-5 13:17
47

0

人才啊..
学习中..
swjtu 2009-4-23 11:16
48

0

学习 好强大哦 都做到CPU去了~
htsf110 2009-4-30 17:31
49

0

好好好好好好
isbluefish 2009-6-4 23:30
50

0

不错,读得很有感觉,学习.
另外,楼上的图不错.也很有感觉.
返回