/**************************************/* 作者:半斤八兩/* 博客:http://cnblogs.com/bjblcracked/* 日期:2014-06-18 21:01/**************************************

只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!

环境:我只测试了xp x86 win7 x64 其它平台未测试.

插件:Strongod 0.4.5 (感谢海风前辈写了一个这么优秀的免费插件.)

今天J师傅又发来一个好玩的东西了.只要用OD加载,就会报错.

一看到这个提示,我第一反映是这个PE损坏的? 不能运行? 但是我双击是可以运行的,只是没有GUI.

双击是可以运行,我尝试attach 上去,也是可以的.那么就可能是运行时检测调试器?我就再想会不会是tls在捣鬼?

1 004001C8 00000000 DD 00000000 ; TLS Table address = 0

2 004001CC 00000000 DD 00000000 ; TLS Table size = 0

再查看了tls后,全为0. 这时候我就想,可能是系统的漏洞? 要么就是ollydbg自身的漏洞?

首先要来排除是ollydbg的漏洞, 我就换了几个ollydbg尝试. 结果都是一样的,都会弹错误.

这时候我就开始以为是系统的PE相关的漏洞.因为我是在xp下的,我最后又拿ntsd 调试了一下.

用ntsd 调试,发现可以正常加载.并运行.并没有发现什么异常 :(

那么我们就能除非系统漏洞了,那么就是ollydbg的漏洞.

Ollydbg加载时有错误码,我们不知道错误码的意思,可以在网上搜索一下.

C0000142 STATUS_DLL_INIT_FAILED

从字面意思上大概能猜出意思,是在DLL初始化时的错误.

不过我比较迟钝,当时没有反映过来.它的意思. 后面又在一个俄国人的论坛上看到了也有遇到类似情况的贴子.

就算这篇贴子是英文写的我也不一定知道意思,更何况是英文的.但是, 我就正好看到 Plugin 这个单词. 正好还认识..

然后我就想到错误码的意思,瞬间就反映过来了.

我把ollydbg的插件目录改名,然后再加载,就可以正常运行了. 那么这样就知道也不是ollydbg的漏洞,而是ollydbg的某个插件有问题.

剩下的就是排除了.我运气比较好,试了第二下,就找到是strongod 的问题.

知道是strongod 的问题后,就要确定是哪个功能有问题. 剩下的就是一个个排除. 这个漏洞,程序并没有得到执行.就产生了. 自然就会想到应该是PE相关的漏洞. 而strongod 上面,和PE相关的,好像就一个 !*Kill BadPE Bug. 于是我把这个勾去掉. 再重新加载. 果然就没有异常了.

现在程序可以正常执行了.

现在我们已经知道漏洞根源了.现在我们要搞清楚,漏洞是如何产生的.

Strongod 是做为ollydbg 的模块运行起来的. 也就是被调试的父进程. 我们想要分析它的话,只能双开ollydbg.

调试Ollydbg 我们简称 父od. 被调试Ollydbg 我们简称 子od.

运行子od. 用子od 加载那个病毒体.(记得勾上 !*Kill BadPe Bug 选项.) 刚加载,就报错.那就是正常的了.

因为我们要分析的是Strongod , 而Strongod 是做为插件运行的,所以调用的地方相对来说比较少. 所以我们可以尝试直接在代码段下断点.

多断几次.我们可以来到 .004AEFBE 这个地址.

1 004AEFA6 jmp dword ptr ds:[<&ADVAPI32.RegOpenKeyA>] ; ADVAPI32.RegOpenKeyA

2 004AEFAC jmp dword ptr ds:[<&ADVAPI32.RegQueryValueExA>] ; ADVAPI32.RegQueryValueExA

3 004AEFB2 jmp dword ptr ds:[<&ADVAPI32.RegSetValueExA>] ; ADVAPI32.RegSetValueExA

4 004AEFB8 jmp dword ptr ds:[<&KERNEL32.CloseHandle>] ; KERNEL32.CloseHandle

5 004AEFBE jmp dword ptr ds:[<&KERNEL32.ContinueDebugEvent>] ; StrongOD.7084EE50

6 004AEFC4 jmp dword ptr ds:[<&KERNEL32.CreateDirectoryA>] ; KERNEL32.CreateDirectoryA

7 004AEFCA jmp dword ptr ds:[<&KERNEL32.CreateFileA>] ; KERNEL32.CreateFileA

8 004AEFD0 jmp dword ptr ds:[<&KERNEL32.CreateProcessA>] ; StrongOD.70844340

9 004AEFD6 jmp dword ptr ds:[<&KERNEL32.DebugActiveProcess>] ; StrongOD.7084B250

不难看出这里是一片IAT ,其中 004AEFBE 处被Strongod hook 了. 而被HOOK的函数,正是 Kernel32.ContinueDebugEvent.

写过调试器的,或者对调试程序熟悉的童鞋应该都知道这个函数的意思.

ContinueDebugEvent

The ContinueDebugEvent function enables a debugger to continue a thread that previously reported a debugging event.

BOOL ContinueDebugEvent(

DWORD dwProcessId, // process to continue

DWORD dwThreadId, // thread to continue

DWORD dwContinueStatus // continuation status

);

我们回车跟进Strongod 代码. 跟进去后可以发现里面已经加入类似虚拟机东西. 我们就没有必要继续分析了.

到此,我们该知道的,差不多都知道了.

下面我们来构造一个这样的”畸形PE”. 我们就拿xp系统自带的计算器来做一个吧.

因为没有分析漏洞产生的代码.所以也只能”猜测”. 我猜测是因为开启 Strongod 的 !*Kill BadPe Bug 功能后,会对PE头做一些 ”保护”.

而这个”保护”做的并不是很细腻. 就有点像我前段时间写的 win7 漏洞一样.

而那个”病毒程序” 正好他的AddressOfEntryPoint 是0.

01000118 00000000 DD 00000000 ; AddressOfEntryPoint = 0

Oep为0 那也就是可以理解成 oep 为 imagebase. 也就是可以理解成. “病毒” 的第一行代码是从 PE的 “MZ” 开始的.

代码如下:

1 00400000 4D dec ebp

2 00400001 5A pop edx

3 00400002 52 push edx

4 00400003 - FF25 1A004000 jmp dword ptr ds:[40001A] ; AntiArp.00404F47

5 00400009 90 nop

6 0040000A 0000 add byte ptr ds:[eax],al

7 0040000C FFFF ??? ; 未知命令

8 0040000E 0000 add byte ptr ds:[eax],al

9 00400010 B8 00000000 mov eax,0

10 00400015 0000 add byte ptr ds:[eax],al

11 00400017 0040 00 add byte ptr ds:[eax],al

12 0040001A 47 inc edi

13 0040001B 4F dec edi

14 0040001C 40 inc eax

15 0040001D 0000 add byte ptr ds:[eax],al

第一行就是 ”M” 对应的 机器码 0x4d 对应的汇编代码 dec ebp ,

第二行就是 “Z” 对应的机器码 0x5a 对应的汇编代码 pop edx.

第三行 机器码是 0x52 对应的汇编代码 push edx

第三行可能是为了堆栈平衡, 也可能是为了代码对齐什么的, 我们就不要在意这些细节了.

第四行就开始跳到原来的EIP了. 就是这简单的4行. 让程序无法调试了.

这也有可能不是Strongod程序的漏洞, 也可能是我”猜”错了. 因为毕竟没有看代码实现细节.

但是有一点可以肯定的是绝对是因为Strongod 导致出错了 :)

最后感谢J师傅发的bin. 要不然也不会有此发现.

PDF和畸形PE下载地址:

<<看雪学院>>