【木马分析】“隐魂”木马篡改主页分析:史上反侦察力最强木马的犯罪素描

https://p1.ssl.qhimg.com/t013357723e403f1fdd.jpg

前不久,360安全中心率先发布了MBR木马——“隐魂”的预警,对木马入侵过程分析(史上反侦察力最强木马“隐魂”:撑起色情播放器百万推广陷阱http://bobao.360.cn/learning/detail/4238.html)后发现,“隐魂”的反侦察能力极高,堪称迄今最复杂的MBR木马。360安全中心随即对该木马展开了持续追踪,本篇是对其篡改主页的行为详细介绍。


1 摘要

首先,我们来进一步了解“隐魂”木马的反侦察能力和复杂性。

(1)隐蔽性极高:“隐魂”木马会通过挂钩磁盘底层驱动实现自我保护,普通的ARK工具或查杀类工具无法深入磁盘底层,难以有效检测到MBR被修改;同时,应用层代码在TimerQueue中调度,目前除了利用调试器进行反复测试外,根本没有其他方法能检测该系统触发机制;另外,内核LoadImage挂钩代码在Nt节的空白区域,这部分在未知内存区域执行的代码也是检测工具的一大盲区。

(2)对抗性极强:为了与检测工具及杀软对抗,“隐魂”使用签名和PDB文件名方式,禁止一系列驱动加载,即使加载成功相关功能函数也会被IAT挂钩。

(3)兼容性极高:“隐魂”是目前支持系统范围最广的MBR木马,从Windows XP到Win10X64位最新系统的均支持,兼容性远远超过2016年开始活跃的暗云Ⅲ木马。

其次,我们再来说一下“隐魂”木马在篡改主页时是如何清理犯罪现场的。

(1)声东击西:不同于直接在浏览器进程中添加参数的劫持方式,“隐魂”为了躲避查杀,采取了结束原浏览器进程——创建新的系统进程——再创建新浏览器进程的方式绕了个大圈才完成主页篡改。

(2)釜底抽薪:“隐魂”会把大多数杀软的正常挂钩全部抹掉,使得浏览器主页失去安全类软件的保护。

接下来,将从WindowsNt系统加载前 (BootKit) 、系统加载后(RootKit)、注入桌面进程explorer

改首页共三部分对木马的执行流程进行详细分析。


2 NT系统加载前

2.1 MBR部分

将自身代码拷贝到 0x600处执行。

https://p5.ssl.qhimg.com/t01fdd3a33cb3a95d8a.png

图1

而后使用int 13 42扩展读功能读取0x1个扇区 到 0x7c00,

位置是由bp指定的。

https://p1.ssl.qhimg.com/t014d6bc52af0803246.png

图2

读取:

https://p5.ssl.qhimg.com/t01d0644bc8d0cba978.png

图3

而后跳转到 0x7c00处继续执行。

https://p4.ssl.qhimg.com/t016756dbe2af03d2f3.png

图4

跳转:

https://p5.ssl.qhimg.com/t0105d48389b951d808.png

图5

并将自身代码再次拷贝到0x600处执行:

https://p5.ssl.qhimg.com/t01eb65f759e9f17f58.png

图6

这次相同位置连续读取 0x20个扇区:

https://p0.ssl.qhimg.com/t01d0c093f7217b0715.png

图7

定位位置:

https://p5.ssl.qhimg.com/t01e4c044bd72259b9b.png

图8

读取20个扇区:

https://p4.ssl.qhimg.com/t016ca4ec6724e30b9e.png

图9

然后将代码拷贝到 0x101000 大小为0x1400。

https://p2.ssl.qhimg.com/t01ac8c7efbc5aeb10a.png

图10

而后跳转到 0x10100处执行:

https://p4.ssl.qhimg.com/t01455383bfee5a6203.png

图11

然后预留高端地址0x14 = 20KB页面  用来存放代码。

https://p2.ssl.qhimg.com/t013fa3fbe38c3f5597.png

图12

将自身代码拷贝到高端地址:

https://p5.ssl.qhimg.com/t0100a271f1864714d6.png

图13

跳转到 0x9a400 处执行挂钩代码。

https://p4.ssl.qhimg.com/t01e2b804967dcf136e.png

图14

然后挂钩int13中断:

https://p1.ssl.qhimg.com/t01b4fc0279e41f4964.png

图15

挂钩后:

https://p3.ssl.qhimg.com/t01a5a80dd5bf41d4df.png

图16

挂钩处代码为 0x9a400 +  45 = 0x9a445。

https://p5.ssl.qhimg.com/t01aa2e5cf4d960dbab.png

图17

2.2 Int13挂钩部分

Int13挂钩中断被执行,搜索硬编码并挂钩:

https://p4.ssl.qhimg.com/t012295bc13d7fd551e.png

图18

挂钩函数为:

https://p4.ssl.qhimg.com/t01e76228e6471db768.png

图19

挂钩后函数被修改为:

https://p2.ssl.qhimg.com/t015d67cee7478e0bd7.png

图20

2.3 BootMgr部分

当系统控制权交给BootMgr 16位代码后,

准备转移给32位代码执行时挂钩中断被执行。

相关函数为:

 https://p5.ssl.qhimg.com/t019761d7b7613803e2.png

图21

跳转:

然后直接搜0x400000 地址 并挂钩

https://p2.ssl.qhimg.com/t01a2737b3199fca69e.png

图22

从BootMgr PE节信息中搜可执行代码,自带反汇编引擎搜索ImgpLoadPEImage对  LdrRelocateImageWithBias的调用,然后Patch对该函数调用。

挂钩前该处调用为:

https://p4.ssl.qhimg.com/t0130d914044b06a601.png

图23

特征码为:

https://p0.ssl.qhimg.com/t01c21f805818b02631.png

图24

搜到后 特征码 0xc0000221 及 0x20B后,

找到下一个Call调用 机器码为0xE8且指令长度为5即为搜索成功。

https://p1.ssl.qhimg.com/t01db33c9668f92fd91.png

图25

后挂钩 :

https://p2.ssl.qhimg.com/t0169b9df41568098dc.png

图26

挂钩后调用为:

https://p2.ssl.qhimg.com/t01d904470f5f753b5a.png

图27

Winload挂钩函数为:

https://p4.ssl.qhimg.com/t0110af46dd6616d3fd.png

图28

2.4 WinLoad部分

当系统执行到bootmgr!BmpTransferExecution  将控制权转移给Winload时候,

挂钩函数HookWinLoad被执行。

先将 LdrRelocateImageWithBias 函数地址放置在堆栈上,等挂钩Winload函数执行完毕后就

调用LdrRelocateImageWithBias 接着执行原来的流程。

后续的挂钩执行都是如此,并未恢复原先代码。

https://p2.ssl.qhimg.com/t0135d21ebfec62dbe8.png

图29

调用为:

https://p0.ssl.qhimg.com/t018838ab1daba10165.png

图30

按系统分别挂钩:

https://p0.ssl.qhimg.com/t014436b26666b9092a.png

图31

然后同样是搜索ImgpLoadPEImage对  LdrRelocateImageWithBias的调用,然后Patch对该函数调用,该部分代码同BootMgr一样。

挂钩后函数为:

https://p2.ssl.qhimg.com/t01222f5b219e206941.png

图32

先将恢复对函数LdrRelocateImageWithBias的调用:

https://p1.ssl.qhimg.com/t01a81153a4c1f6aed9.png

图33

而后将 0x9aa9a函数放置在堆栈上等待被调用:

https://p5.ssl.qhimg.com/t0141f15f39b7308fa3.png

图34

LdrRelocateImageWithBias调用完成后 HooNt函数被执行(0x9aa9a):

https://p1.ssl.qhimg.com/t017af7b9b5576f3a15.png

图35

先恢复堆栈 后续执行流程 将winload!ImgpLoadPEImage+0x67d 放置在返回地址处:

https://p1.ssl.qhimg.com/t01f8d73a76dbd85e2c.png

图36

通过反汇编引擎搜调用代码 搜IoInitSystem 对 IopInitializeBootDrivers的调用。

https://p5.ssl.qhimg.com/t01b692e3a3e8aecd80.png

图37


3 NT系统加载后

3.1 加载ShellCode部分

当系统执行到 Nt 中 IoInitSystem  对 IopInitializeBootDrivers调用时候,恶意代码被执行。

先将函数 IopInitializeBootDrivers 放置堆栈上,然后关闭写保护恢复原始挂钩处代码,而后将后续加载木马代码函数地址(LoadTheShellCode)放置堆栈上。

https://p1.ssl.qhimg.com/t01a8746b432d57af3f.png

图38

当函数IopInitializeBootDrivers 调用完成后, 再次将Nt正确函数返回地址放置堆栈上。

https://p0.ssl.qhimg.com/t01bfd541ce7417b5e3.png

图39

而后将ShllCode1代码映射, 大小为0xca0。

https://p3.ssl.qhimg.com/t0171d4f05ed3654f7b.png

图40

校验代码并执行。

3.2 ShellCode1部分

该部分功能为读取磁盘指定位置代码并加载ShellCode2。

先获取相关函数地址,

后读取磁盘数据 检测完整并获取大小, 大小为0x4a000。

https://p4.ssl.qhimg.com/t0156fb9f686784c27f.png

图41

然后为第二块ShellCode申请内存 大小为 0x4c08。

申请后执行:

https://p5.ssl.qhimg.com/t017ec6038aebb83ae6.png

图42

3.3 ShellCode2部分

该部分主要为解压之前读取的资源数据并查找加载其中/bin/i386/bootmgr NE文件并加载。

校验完整性 ,并解压数据:

https://p0.ssl.qhimg.com/t01bc2feb8d4e818845.png

图43

然后为第三块NE 格式ShellCode申请空间 大小为0x1f00,准备执行,并将资源作为参数传入。

https://p3.ssl.qhimg.com/t0192fcc5bd2feff048.png

图44

3.4 ShellCode3部分

主要为加载 /bin/i386/kernel 到内存并执行,Kenel部分为内核关键代码部分。

https://p3.ssl.qhimg.com/t015128411edd4b6b95.png

图45

拷贝NE文件资源,大小为0x10380:

https://p1.ssl.qhimg.com/t01a0b92656e25f703d.png

图46

而后帮第四块ShellCode修正导入表重定位并执行。

https://p1.ssl.qhimg.com/t017262b9f1a5a5152e.png

图47

3.5 ShellCode4部分

该部分为内核关键代码,包含注入代码挂钩LoadImage 反内核调试代码。

入口出先断开内核调试:

https://p2.ssl.qhimg.com/t011aeb0c65d5623d14.png

图48

而后读取磁盘数据并保存:

https://p0.ssl.qhimg.com/t01858ca5f805e450a8.png

图49

创建设备跟应用层交互:

https://p0.ssl.qhimg.com/t014d5c22e381c74e91.png

图50

而后重载内核获取一些导出符号,占满情况下,用于清理挂钩回调:

https://p4.ssl.qhimg.com/t019c5123fbcbbfd77d.png

图51

设置LoadImage回调 主要后续用于APC注入svchost跟explorer用来修改用户主页。

将真正函数地址LoadImageNotify作为参数传入。

https://p5.ssl.qhimg.com/t01e1abcf179237cd03.png

图52

查找节后面空闲区域 ,将自身挂钩代码拷贝过去。

https://p2.ssl.qhimg.com/t01221907207f135250.png

图53

拷贝代码:

https://p3.ssl.qhimg.com/t01b0476ef9968fc494.png

图54

代码为:

https://p0.ssl.qhimg.com/t019a2568d740fa7710.png

图55

其中AAAAAAAA 为占位后续将填入实际地址。

然后加载第五块ShellCode,并且挂钩:

https://p4.ssl.qhimg.com/t01a3fdfc8fe22f04b0.png

图56

而该挂钩会反复被检测执行:

https://p5.ssl.qhimg.com/t0133113ac79046e7a8.png

图57

挂钩函数为:

https://p2.ssl.qhimg.com/t01bb4d02e609b93193.png

图58

LoadImage中判断svchost.exe进程创建:

https://p2.ssl.qhimg.com/t01c74b808353643856.png

图59

如果是svchost.exe进程创建:

https://p2.ssl.qhimg.com/t01dbd8035068b7ab67.png

图60

判断是否为指定的svchost.exe:

https://p3.ssl.qhimg.com/t01f67d497a1117a0b6.png

图 61

主要通过命令行方式判断:

https://p3.ssl.qhimg.com/t0100084646c1a844ed.png

图62

匹配命令行后准备注入代码:

https://p5.ssl.qhimg.com/t01c0f827165cd99379.png

图63

将APC  NormalRoutine设置为Ne 入口点 得到执行:

https://p5.ssl.qhimg.com/t01a36cff72bb8e5da9.png

图64

Exploer注入代码:

https://p3.ssl.qhimg.com/t010b31adee49ed30bc.png

图65

3.6 ShellCode5部分

该内核块功能主要为防止被检出查杀。

获取签名公司列表信息:

https://p1.ssl.qhimg.com/t0118e7eedf35a26c61.png

图66

代码:

https://p0.ssl.qhimg.com/t019626790aa3a9ba04.png

图67

而后调用ShellCode4中设置LoadImage回调函数。 

https://p2.ssl.qhimg.com/t0109a909cd9887f9aa.png

图68

在回调中判断驱动是否有PDB信息,分三种情况Patch

1 如果没有PDB符号信息且匹配签名 则直接Patch入口点。

https://p3.ssl.qhimg.com/t01255ae6e5c36b8fb3.png

图69

2 如果有PDB信息,一些常见的工具,也Patch入口点,如gmer.pdb ,Win64AST.pdb。

https://p0.ssl.qhimg.com/t019561ac66318950a9.png

图70

3 如果Pdb有 且hash 比对一致则导入表 Hook:

https://p0.ssl.qhimg.com/t01e0ca029709ca0e3c.png

图71

还会IAT Hook文件操作函数,防止查杀类驱动读取文件恢复钩子。

ZwCreateFile:

https://p2.ssl.qhimg.com/t0161302834567e010a.png

图72

IofCallDriver:

https://p0.ssl.qhimg.com/t0182363747170f3dcc.png

图73

防止文件簇读取方式:

https://p0.ssl.qhimg.com/t013ee4373afcecd191.png

图74

获取文件保护列表函数:

https://p5.ssl.qhimg.com/t01239eaf7216f71960.png

图75

Patch函数:

https://p3.ssl.qhimg.com/t01ffef3d15701da62b.png

图76

https://p2.ssl.qhimg.com/t010b7d198680327c02.png

图 77


4 篡改主页部分

4.1 ShellCode1部分

APC注入Explorer.exe后,入口点修正导入表 ,创建线程并加载改首页模块。

https://p1.ssl.qhimg.com/t01ae7a6d1a10b476dd.png

图78

线程函数中申请执行空间,并将代码拷贝。

高端地址执行:

https://p0.ssl.qhimg.com/t0124f2ef4c8da177c2.png

图79

然后修正导入表,重定位:

https://p2.ssl.qhimg.com/t011127b81c4fabf525.png

图 80

执行入口点函数:

https://p1.ssl.qhimg.com/t016a87ccf3b349489b.png

图81

4.2 ShellCode2部分

初始化系统模块名字,挂钩时候使用:

https://p5.ssl.qhimg.com/t01d03bd0f456523b6b.png

图82

初始化恢复钩子列表,发现这些函数一旦被挂钩就直接恢复。

https://p2.ssl.qhimg.com/t011027017ed99a302c.png

图83

将原始代码备份,并保存到链表中,头部指令最多长度为0x20。

https://p4.ssl.qhimg.com/t01e18a42086aa0a1f5.png

图84

然后打开首页页面地址:

https://p2.ssl.qhimg.com/t0104d2b1eba7750c02.png

图 85

其中共享内存区数据为:

https://p3.ssl.qhimg.com/t0100c718ec926d38a5.png

图86

然后枚举所有加载模块 IAT挂钩CreateProcessW函数。

https://p2.ssl.qhimg.com/t01e1796dc13eeb2a23.png

图87

挂钩回调函数为:

https://p2.ssl.qhimg.com/t01bd40cc7ba4089244.png

图88

主要挂钩Shell32.dll对CreateProcessW函数调用。而后检测之前的初始化的系统函数是否被Hook,进行恢复。

https://p5.ssl.qhimg.com/t0173b28eace6f65795.png

图89

CreateProcessW挂钩中判断创建进程是否为浏览器列表之一:

https://p5.ssl.qhimg.com/t01430d228681946c22.png

图90

浏览器列表为:

https://p5.ssl.qhimg.com/t019f0581de21dc07b8.png

图91

而后创建verclsid.exe 为傀儡进程,修改主页:

https://p2.ssl.qhimg.com/t016b90f3b02840dd55.png

图92

而后创建傀儡进程:

https://p2.ssl.qhimg.com/t015c78a3c01af6c61a.png

图93

将代码映射到傀儡进程QueueUserAPC APC函数:

https://p4.ssl.qhimg.com/t01c5d697b9dbe58996.png

图94

4.3 ShellCode3部分

该部分代码为QueueUserAPC 注入到 verclsid.exe 中执行。

入口点为从PEB LDR中获取信息,修正重定位修正导入表:

https://p1.ssl.qhimg.com/t0126d6ef05562b667d.png

图95

然后Patch傀儡进程入口点。

https://p5.ssl.qhimg.com/t01f00b7559deddf68c.png

图96

而后在调用CreateProcessW创建带有命令行的浏览器进程

https://p0.ssl.qhimg.com/t0171a07dddd7d82a8a.png

图97

完成修改主页:

https://p2.ssl.qhimg.com/t01f73f6da047a2bdeb.png

图98

svshost部分

主要为创建TimerQueue中 回写LoadImage回调并回写MBR:

该部分代码难以有效检出。

创建:

https://p2.ssl.qhimg.com/t01194f5ed979c27dd6.png

图99

给驱动发送命令写入:

https://p3.ssl.qhimg.com/t01b8ebe0840dd43193.png

图100


5 尾声

“隐魂”木马创下了两周内攻击量上百万次的记录,可谓迄今传播速度最快的MBR木马。其高超的反侦察能力及复杂的利用技巧让不少检测手段力不从心,如今其攻势虽然放缓但远不曾停止,被推广利益驱使的作者很有可能继续兴风作浪,通过远程控制的方式实施对个人数据及财物的大规模攻击。

 

不过网民们也不用过分担心,360安全卫士不仅率先对“隐魂”木马展开了查杀,还可以完美拦截各类MBR顽固木马的攻击。目前,360安全中心也正在对“隐魂”木马进行持续追踪,如有新成果将第一时间与大家分享。

 

https://p3.ssl.qhimg.com/t01f3d778f819aba9ec.png

图101

(完)