利用StrongOD漏洞反调试
/**************************************
/* 作者:半斤八兩
/* 博客: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下载地址: