样本概况
样本基本信息
利用VirusTotal扫描
漏洞分析
使用notepad++打开病毒文件:
bp kernel32!Winexec
breakpoint 0 redefined
0:000> bl
0 e 7748e695 0001 (0001) 0:**** kernel32!WinExec0:000> bp kernel32!CreateProcessA0:000> bp kernel32!CreateProcessW0:000> bl
0 e 7748e695 0001 (0001) 0:**** kernel32!WinExec1 e 774020620001 (0001) 0:**** kernel32!CreateProcessA2 e 7740202d 0001 (0001) 0:**** kernel32!CreateProcessW0:000> g
Breakpoint0 hit
eax=00000001 ebx=0691c40a ecx=00120fbc edx=776f64f4 esi=001220cc edi=001215b8
eip=7748e695 esp=00120fdc ebp=00121568 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
kernel32!WinExec:7748e695 8bff mov edi,edi
运行后发现是在加载了MSCOMCTL.OCX后执行WinExec断了下来,并且WinExex的第一参数就是发现的隐藏hkcmd.exe,这一点与OD里的操作遥相呼应!
但是查看WinExec返回地址,发现这个堆栈看不懂(被破坏了),如下图所示:
为了分析出这个漏洞的溢出点,从网上找到它的POC(真是坑啊!-!)
POC分析
下面来分析它的POC:
在上图中关键信息已经标注出来,当利用kb命令查看堆栈的时候,发现堆栈已经被破坏掉,利用 dps 查看详细的栈信息,根据上图的栈信息 0x001215ec = 41414141 而0x1215b8 = 275c8a0a 此处的值,直接在查看0x275c8a0a地址处的反汇编代码如下如所示:
从上图中可以获取获取到 0x275c8a0a 是函数的返回地址,地址0x275c8a05处的函数调用极可能就是溢出函数,根据函数的信息可知道,
MSCOMCTL!DLLGetClassObject+0x41a29 ,此函数调用发生在mscomctl.ocx中,此组件是打开doc文件时动态加载的,所以只在下bp断点是断不下来的。
接下来再上图的基础上持续向上查找,查找到0x275c8a0a 函数调用的起始处,如下图所示:
调试此函数方法:
利用sxe ld mscomctl.ocx在动态加载的时候断下来;(此时直接将恶意样本拖进word.exe进程,Windbg会让其在加载mscomctl.ocx的时候断下来)
断下来之后直接在 地址0x275c89c7的地址处下int3 断点即可(对应指令: bp 0x275c89c7),然后直接g指令即可;
重新加载poc文件,如下图所示:
此时程序已经来到了溢出函数的被调函数处,同时此时用ida 打开mscomctl.ocx 文件 (此文件在system32文件目录下 ) ,直接在函数窗口中打开 sub 0x275c89c7函数地址如图所示:
从上图中我们可以直接获取到函数参数,以及函数的调用信息。 这里我们先主要依靠windbg进行分析,
接下来直接利用 u 0x275c89c7 L64命令 查看100条反汇编指令如下图所示:
如图所示 重点部分已经标注,接下来直接使用命令 uf MSCOMCTL!DllGetClassObject+0x41a29 进行查看函数完整的反汇编指令。
其实仔细观察会发现,在溢出的被调用函数中,总共发生过两次相同的函数调用如下图所示:
下面对溢出函数进行分析:
单步运行到0x275c8a05 然后dd esp查看函数参数值。如图:
如上图,函数三个参数分别是001215e0,0c7308e8,00008282;进入溢出函数前ebp为001215e8,进入函数后的ebp为001215b4,接下来继续单步运行程序直接来到地址275c87cb地址处如图所示:
如图所示当执行到地址275c87cb地址处的时候,可以观察esi 内存中包含41414141 而ecx = ox20a0 因此当执行 此指令时后,即可表明程序的执行已经被用户控制啦
具体要追根溯源的话,请看下边这个帖子:
下面直接用IDA进行分析,直接将mscomctl.ocx拖进ida 查找到 0x2785c89c7地址出的函数,如图所示:
查看伪代码:
直接进入溢出函数查看伪代码:
由此可以知道这里漏洞产生的原因就是if里面的判断条件,应该是
dwBytes<8
而不是大于等于8
分析shellcode
回归主线,上面说到了在Winexec处断了下来:
由这里可以知道,Winexec释放了一个hkcmd.exe,而这样一个行为肯定是发生于Shellcode 里面的,所以通过Winexec的栈回溯是可以定位到Shellcode的,
上图中,0x121602执行了从0x0012161B开始的shellcode解密过程;
在0x1215F8处设置硬件执行断点即可追踪shellcode逻辑:
貌似上面已经没有必要了,其实通过上面的POC分析,可以直接找到0x275c89C7这个地址就是溢出函数附近:
跟进函数sub_275c876d:
发现这个函数里面有memorycopy(memcpy)这个函数,这个函数也最为可疑,下面我们要验证这个猜想:
选取shellcode的一处位置0x127C00为中断点,
使用命令 ba w 4 0x127C00 “r eip;gc” 记录程序运行到中断处为止的EIP变化情况:
发现程序在 0x275c87cb 处出现问题被引导向Shellcode中,果然验证了此前的猜测;
另一方面,跟踪发现程序循环多次执行了此命令, 其中一次执行时eax值为8181
此处esi所在处为一个以0与返回地址 0x27583C30 为起始的数据块, edi为栈空间地址,而 0地址x27583C30 处恰好是一个JMP ESP指令
显然这里是要跳往shellcode执行恶意代码的!
到这里为止,我们利用WinDbg和OD都证明了0x275c87cb 这个地址确实是存在问题的,在这个地址处,由于没有对写入的数据大小进行校验,从而导致恶意代码可以淹没函数返回地址,进而实现漏洞利用!
小结
回顾一下Shellcode的总分析过程:
a.使用refobj.py工具提取ole对象,而后用OLE分析工具offvis来分析提取出的ole对象,发现跟mscomctl.ocx模块相关;
b.另外一方面,用WinDbg分析其(CVE2012-0158)POC,找到溢出函数附近,打开IDA,用IDA分析出是具体在哪个地址发生栈溢出的;
c.最后利用WinDbg和OD验证上面IDA得出的溢出地址的结论;
恶意代码分析
在上边分析Shellcode的时候我们已经知道在栈溢出之后,会通过调用Winexec释放出一个hkcmd.exe;
发现一个可疑的服务,注册了一个动态服务库
doc文档释放的hkcmd文件主要释放了一个类似于系统的dll: datac1en.dll(原为dataclen.dll);
将此dll以服务的形式写入注册表,验证了上面的注册了一个动态服务库;
结合之前检测到的程序行为, 可以判定这个hkcmd将此dll注册为服务,通过导入的这几个dll来实现主要恶意行为,通过其导出的ServiceMain来执行主要的恶意行为;
将此dll拖入IDA中:
这个关键函数里面又有许多函数,其中大部分都是加载dll,获取函数地址,然后解密 拼接字符串等操作
获取系统路径,判断系统
跟进10003A7B函数:
用loadlibrary加载了ws2_32.dll与wininet.dll模块, 并获取了字节顺序转换函数与Internet系列函数地址;
解析url链接,读取数据,连接服务器,打开文件
然后根据上面读取到的信息,判断操作的类型
创建线程一,线程一应该为把本地文件发送到服务器
创建线程二,并从服务器获取文件然后写入本地
创建线程三,创建批处理文件和msacm16.dll文件,并发送到服务器
结束指定线程
运行服务器指令
遍历文件
加密数据,传送数据到指定服务器


发布评论