首页
论坛
专栏
课程
9

[原创]windows 7下的病毒感染

AntBean 2010-11-26 17:58 24767
这个是在XFish的病毒专题的基础上进行的简单探索。Windows 7上面有很多有趣的地方,对安全研究有很大的意义。这两周有些心得,想跟大家分享一下,这里仅仅探讨一下Windows 7下面的病毒感染。

一、Kernel32基址的获得
XFish专题中提到了三种方式,具体参见:http://bbs.pediy.com/showthread.php?t=85910

这里直接引用XFish的帖子:
1. 通过线程初始化时, 获得esp堆栈指针中的ExitThread函数的地址,然后通过搜索获得kernel32.dll的基地址。   
2. 遍历seh异常链,然后获得EXCEPTION_REGISTRATION结构prev为-1的异常处理过程地址,这个异常处理过程地址是位于kernel32.dll,通过它搜索得到kernel32.dll的基地址。
3. 通过TEB获得PEB结构地址,然后再获得PEB_LDR_DATA结构地址,然后遍历模块列表,查找kernel32.dll模块的基地址。

我将讨论下,现实中如果要感染windows 7的做法。
第一种通过线程初始化的方式,一般来说,病毒代码很难在线程初始化的时候得到执行。你可能会说,直接修改PE入口点,指向你的病毒代码。据我所知,这样会直接被杀软干掉的。所以现实中不具有可行性。现实中的病毒代码会通过EPO技术,感染文件。即替换任意一个call的目标地址,让它调用自己的病毒代码,并在病毒代码的结尾跳转到被替换的目标代码中执行。这种技术对抗杀软非常有效。
第二种方法和第三种方法在windows xp下都是很好的查找kernel32基址的方法。而且在windows xp下我更偏爱第二种。因为第二种通过TEB,由fs:[0]指向,和windows的SEH机制非常相似。杀软很难通过特征码判断出来。而第三种通过PEB,由fs:[30h]指向,正常程序应该很少操作fs:[30h]。杀软很容易将其列为特征码。
但是,这些仅仅是在windows xp下。
在windows 7下,第二种方法是没有效果的。因为异常处理过程不再位于kernel32.dll当中,而是位于ntdll.dll中。你写一个程序用OD加载后查看下SEH链就明白了。
只能使用第三种方法。
XFish提供的第三种方式的代码如下:

这段代码十分简洁漂亮。
但是如果你尝试在windows 7下面直接用,你会很遗憾的发现你的病毒代码运行不是很正常。因为这段代码基于的假设是系统初始化dll的顺序是ntdll.dll-->kernel32.dll-->其他dll。
在windows 7下面系统初始化dll的顺序变成了ntdll.dll-->kernelBase.dll-->kernel32.dll-->其他dll。
我现在暂时未弄清楚kernelBase.dll的作用(听名字好像和ASLR有关??额,哪位大哥能指点一下?)。
如果你的病毒试图在windows xp和windows 7下都能正常感染,要么通过判断OS类型(但是你还没有GetProcAddress函数,所以你貌似没辙),要么使用第三种感染方式,只不过我们要弄清楚第三种的原理。
XFish的帖子中已经很详尽地解释了第三种得到基址的原理。这里我借用一下。总体思路是通过PEB,获得加载模块的链表。
涉及的数据结构如下:

Ldr是_PEB_LDR_DATA的指针。而_PEB_LDR_DATA就是加载模块链表的头节点。

你肯定知道_LIST_ENTRY就是链表结构体,将我们链表中的各个节点连接起来。
我们链表中的节点是啥样子的?如下:

怎么连的?那个_LIST_ENTRY结构如下:

整个链表的结构如下:

为了病毒能在windows xp和windows 7下面都能运行,只要将BaseDllName与kernel32.dll进行比较就行了。注意这里是进行unicode的字串比较。提供代码如下:


附件是可运行的代码:
VirusTest2.rar

快讯:[看雪招聘]十八年来,看雪平台输出了大量安全人才,影响三代安全人才!

上传的附件:
最新回复 (31)
leeonegor 2010-11-26 18:28
2
顶~~~~~~~~
傷遺忘 2010-11-26 19:23
3
图不错.很形象..

谢谢分享...
zyr零零发 2010-11-26 22:46
4
分析的不错。
熊猫正正 2010-11-26 23:46
5
谢谢分享
熊猫正正 2010-11-27 00:25
6
文章写的不错,有分享精神支持,但刚看了一下附件,给你提个建议,可以去网上下一个《汇编语言代码书写规范》读读~~还好代码不长,不然就是自己去读自己的代码也会很累的~~
AntBean 2010-11-27 09:21
7
汇编代码写得不多。。所以写得比较难看。。 。谢谢你的建议。。
Mx¢Xgt 2010-11-27 11:52
8
每个指令后按TAB 会对齐,对比较好看
jasonzhou 2010-11-27 13:05
9
表述得很清晰。谢谢分享。
水晶蜗牛 2010-11-28 11:02
10
图片花花绿绿的,很好看,有种unix下的感觉
寻梦小子 2010-11-28 12:17
11
感谢,学习了。。。
王晓松 2010-11-29 21:12
12
有一点需要强调,也许看起来更容易,我们现在找的是_LDR_MODULE中baseaddress的地址,所以才会有esi+0x1c,esi+4,(合并为esi+0x20),的出现,因为baseaddress为0x18,再加上链表头的长度8,则为0x20
hackjack 2010-11-29 23:37
13
路过路过路过路过路过路过路过
antime 2010-11-30 10:55
14
Kernelbase.dll 是 ALSR 技术的一部分。
zuoyefeng 2010-12-1 10:32
15
路过~~~
win7确实增加了难度
AntBean 2010-12-1 21:52
16
谢谢antime,学习了。。。
gjden 2010-12-1 22:56
17
谢谢分享!!!
wufenjack 2010-12-2 11:26
18
学习了,支持下,代码是汇编写的,将就能看懂,但是写不出来,呵呵!
riusksk 2010-12-3 10:56
19
写错了吧,应该是ASLR(地址空间分布随机化)
cscncllf 2010-12-3 12:24
20
分析的不错。
bluecode 2010-12-3 20:28
21
不顶都不行的好文。。。
licyong 2010-12-3 23:30
22
好强的~~~
guxinyi 2010-12-8 18:28
23
作记号,以备查验
guxinyi 2010-12-8 21:58
24
通过TEB获得PEB结构地址,然后再获得PEB_LDR_DATA结构地址,然后遍历模块列表,查找kernel32.dll模块的基地址

标记备查
孤行有你 2011-2-21 08:57
25
MARK 。。。。。
孤行有你 2011-5-23 10:38
26
需要..谢谢...
boystones 2011-5-23 15:08
27
顶一顶。。。
风逐天 2011-5-23 15:38
28
病毒感染不是很在行。。。看看。。
robey 2011-5-23 15:41
29
看看。。路过。。
busy 2011-5-23 17:31
30
我修改了一下代码,改成在C++里内嵌,用vs2010编译运行发现esi可能会为0(我是的操作系统是win7 64位)导致 repe cmpsw 这个直接抛违规访问的异常,可以在repe指令前面加一个esi的判断,另外还有个小问题就是大小写,比较最好能忽略大小写,不过这些都是些没有技术含量的体力活 呵呵
hittimes 2011-5-23 19:03
31
顶一个!!!
wyyzy 2011-6-17 10:03
32
路过,好贴:)
~~~~~~~~~~``
返回