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

2017-08-26 221470人围观 ,发现 8 个不明物体 系统安全

前不久,360安全中心率先发布了MBR木马——“隐魂”的预警,对木马入侵过程分析《史上反侦察力最强木马“隐魂”:撑起色情播放器百万推广陷阱》后发现,“隐魂”的反侦察能力极高,堪称迄今最复杂的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部分

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

1.png

图1

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

位置是由bp指定的。

2.png

图2

读取:

3.png

图3

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

4.png

图4

跳转:

5.png

图5

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

6.png

图6

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

7.png图7

定位位置:

8.png

图8

读取20个扇区:

9.png

图9

然后将代码拷贝到 0×101000 大小为0×1400。

10.png

图10

而后跳转到 0×10100处执行:

11.png

图11

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

12.png

图12

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

13.png

图13

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

14.png

图14

然后挂钩int13中断:

15.png

图15

挂钩后:

16.png

图16

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

17.png

图17

2.2 Int13挂钩部分

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

18.png

图18

挂钩函数为:

19.png

图19

挂钩后函数被修改为:

20.png

图20

2.3 BootMgr部分

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

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

相关函数为:

21.png

图21

跳转:

然后直接搜0×400000 地址并挂钩

22.png

图22

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

挂钩前该处调用为:

23.png

图23

特征码为:

24.png

图24

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

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

25.png

图25

后挂钩:

26.png

图26

挂钩后调用为:

27.png

图27

Winload挂钩函数为:

28.png

图28

2.4 WinLoad部分

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

挂钩函数HookWinLoad被执行。

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

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

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

29.png

图29

调用为:

30.png

图30

按系统分别挂钩:

31.png

图31

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

挂钩后函数为:

32.png

图32

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

33.png

图33

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

34.png

图34

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

35.png

图35

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

36.png

图36

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

37.png

图37

3 NT系统加载后

3.1 加载ShellCode部分

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

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

38.png

图38

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

39.png

图39

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

40.png

图40

校验代码并执行。

3.2 ShellCode1部分

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

先获取相关函数地址,

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

41.png

图41

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

申请后执行:

42.png

图42

3.3 ShellCode2部分

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

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

43.png

图43

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

44.png

图44

3.4 ShellCode3部分

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

45.png

图45

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

46.png

图46

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

47.png

图47

3.5 ShellCode4部分

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

入口出先断开内核调试:

48.png

图48

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

49.png

图49

创建设备跟应用层交互:

50.png

图50

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

51.png

图51

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

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

52.png

图52

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

53.png

图53

拷贝代码:

54.png

图54

代码为:

55.png

图55

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

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

56.png

图56

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

57.png

图57

挂钩函数为:

58.png

图58

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

59.png

图59

如果是svchost.exe进程创建:

60.png

图60

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

61.png

图 61

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

62.png

图62

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

63.png

图63

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

64.png

图64

Exploer注入代码:

65.png

图65

3.6 ShellCode5部分

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

获取签名公司列表信息:

66.png

图66

代码:

67.png

图67

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

68.png

图68

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

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

69.png

图69

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

70.png

图70

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

71.png

图71

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

ZwCreateFile:

72.png

图72

IofCallDriver:

73.png

图73

防止文件簇读取方式:

74.png

图74

获取文件保护列表函数:

75.png

图75

Patch函数:

76.png

图76

77.png

图 77

4 篡改主页部分

4.1 ShellCode1部分

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

78.png

图78

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

高端地址执行:

79.png

图79

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

80.png

图 80

执行入口点函数:

81.png

图81

4.2 ShellCode2部分

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

82.png

图82

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

83.png

图83

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

84.png

图84

然后打开首页页面地址:

85.png

图 85

其中共享内存区数据为:

86.png

图86

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

87.png

图87

挂钩回调函数为:

88.png

图88

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

89.png

图89

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

90.png

图90

浏览器列表为:

91.png

图91

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

92.png

图92

而后创建傀儡进程:

93.png

图93

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

94.png

图94

4.3 ShellCode3部分

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

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

95.png

图95

然后Patch傀儡进程入口点。

96.png

图96

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

97.png101.png

图97

完成修改主页:

1111.png

图98

svshost部分

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

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

创建:

99.png

图99

给驱动发送命令写入:

100.png

图100

5 尾声

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

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

98.png

图101

*本文作者:360安全卫士,转载请注明FreeBuf.COM

这些评论亮了

  • ynefen (3级) 这家伙太懒了,还未填写个人描述! 回复
    7654和360是现在体验最差、最恶心的两个网址导航。
    )10( 亮了
  • 周鸿伟 回复
    还有谁?能像我司这么牛逼?
    )9( 亮了
发表评论

已有 8 条评论

取消
Loading...
css.php