查壳
无壳
Thread32First和Thread32Next用来遍历一个进程的所有线程,CreateToolhelp32Snapshot用来创建一个进程,堆空间,模块和线程的快照,病毒常用这个函数在多个进程线程之间传播感染
CopyFileA ReadFile CreateFileA表名创建了一个文件然后将它复制到了别处
RegCloseKey RegSetValueExA RegOpenKEyExA 说明用到的注册表操作并设置了一个注册表键
VirtualProtect修改一个内存区域的保护机制,该病毒可能将一块只读的内存修改为可写可执行代码
send wsock32.dll表明该病毒使用了网络功能,AppInit_DLLs和SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows表明该病毒使用AppInit_DLLs来永久安装自身
这里有一些奇怪的字符串,猜测对网络传输的内容做了加密处理,结合上面的图看到的"RCPT TO:"可能对邮件进行了加密处理。
用PEView查看,该文件有三个导入库,但是没有资源节
查看依赖关系
该文件只有一个导出函数,installer
这里的导入函数前面用strings分析过了,这里用来验证一下
我们用procmon监视恶意代码
首先,从命令行运行DLL
在procmon中用进程名过滤rundll32.exe
这里,病毒在C:\WINDOWS\system32系统目录下创建了一个名为spoolvxx32.dll的文件,这里的创建时间就是我现在分析的时间。
查找注册表操作
该病毒将spoolvxx32.dll添加到了HKLM\SOFTWARE\Microsoft\WIndows NT\CurrentVersion\Windows\AppInit_DLLs目录下,这个位置是一个特殊位置,可以让DLL获得加载,AppInit_DLLs中的DLL程序会在进程加载User32.dll时被加载,很多进程都会加载User32.dll,这是全局dll注入的一种方式。
我们到C:\WINDOWS\system32目录下找到该文件
打开LoadPE比较一下这两个文件
LoadPE显示这两个文件相同,我们不需要对这个文件重新进行静态分析
载入IDA,首先定位installer导出函数
查看交叉引用
installer在注册表中设置了一个值,并将一个文件复制到了windows的系统目录,和我们用procmon中观察到的一致,这里证实了这一点,installer函数唯一的目的是复制恶意代码到spoolvxx32.dll并把它设置为一个APPInit_DLLs值
定位到DllMain
这里的fdwReason对应的值为1的时候表示的是DLL_PROCESS_ATTACH,该病毒仅在DLL_PROCESS_ATTACH状态时运行,如果不是DLL_PROCESS_ATTACH状态,DllMain不会做其他任何事情就会直接返回.
这里调用了sub_1000105b处的过程,enter跟进
程序提取Windows系统目录,10001667处的strncat将系统目录和1000165e处的字符串组合成一个路径,10001685处打开一个文件,如果打开成功则将该文件读入到一个全局变量缓冲区,即100034a0这个地址
接着判断文件的大小是否大于0,然后100016ca处将包含文件内容的缓冲区传递给sub_100010b3,enter跟进
这里是一个循环结构,100010e5处调用了sub_10001097,enter跟进
这里是一些算术运算,sub_100010b3是获取文件句柄后执行的第一个函数而且是一系列运算,所以它应该是一个解密器.
打开OD,加载文佳
断下后F8单步跳过,EAX的返回值是一个邮箱地址,回到IDA,将它重命名为emailaddress
IDA中100016e2处调用了另一个函数sub_100014b6,enter跟进
该函数直接调用了六个自定义函数,第一个只调用了GetModuleFileNameA
六个函数如下:
sub_10001075
sub_1000102d
sub_1000113d
sub_10001104
sub_10001499
sub_100013bd
先看第一个函数,双击查看
病毒在10001086处调用了GetModuleFileNameA函数,看一下MSDN的解释
因为参数hModule被设置为0所以该函数会返回加载该DLL的可执行文件的绝对路径,然后在arg_4中返回路径名,其实就是个字符串指针,然后这个指针作为后续函数的参数
看下10001104处的函数
可以看到,10001104这个函数有一个参数是10001075返回的字符串指针,即arg_4
10001104调用了两个函数,strrchr和strlen,strrchr用于查找一个字符在一个字符串中末次出现的位置,并返回该位置的地址,strlen用于返回字符串的长度,直到遇到第一个'\0'.
看下1000102d处的函数
该函数调用了toupper,该函数用于将字符串转变为大写
如图,接下来,将当前进程名的大写字母与THEBAT.EXE,OUTLOOK.EXE,MSIMN.EXE比较,如果进程名不等于其中的任何一个,恶意代码就会退出,如果病毒已经加载到这三个进程中的任意一个,则就会调用100013bd处的函数
双击跟进
该函数首先调用GetCurrentProcessId函数然后调用sub_100012fe函数
enter跟进
sub_100012fe调用了GetCurrentThreadId,返回当前线程的ID,接着调用了CreateToolhelp32Snapshot函数,接着调用Thread32First和Thread32Next遍历整个进程并调用SuspendThread将所有遍历的线程挂起.
然后关闭进程句柄,call sub_100013bd的作用就是挂起当前进程的所有线程
再看看100012a3处的函数
该函数有四个参数,enter跟进
GetModuleHandleA获得wsock32.dll的句柄,若失败则调用LoadLibraryA主动加载wsock32.dll,确保加载了wsock32.dll之后调用GetProcAddress加载send函数,
最终调用sub_10001203这个函数,它有三个参数,dword_10003484,sub_1000113d还有send函数的地址,双击进入
10001209处,用sub_1000113d的地址减去send函数的地址,再减去5个字节,然后移动到var_4变量中,
VirtualProtect用于在调用进程的虚拟地址空间中更改对提交页面区域的保护,看下MSDN的解释
这里的flNewProtect值为40
内存页的属性被修改为可读可写可执行,大小是5个字节,接着调用malloc分配0FFh大小的内存空间,返回的内存基址在eax中,
灰色标注出来的代码是这个函数的精髓
过程如下:eax返回malloc返回的地址指针,把这个指针给了var_8,send函数的地址给了ecx,malloc分配的内存的开头位置存储了send函数的指针(mov [eax],ecx),接着,把malloc的基址给edx,接着调用memcpy,第一个参数是5,然后将send的地址给eax,并压栈,第二个参数是send的地址,即源地址,这里IDA已经标注出来了(Src),接着将malloc的基址给ecx,ecx+5后压栈,memcpy的作用是将send函数复制到malloc返回地址的第六个字节的位置(前面要空五个字节)
如图
malloc开头空出的五个字节用来干嘛那?继续往下看
我们知道edx是指向malloc分配的内存地址的开头的,memcpy复制了5个字节,malloc基址的开头空了五个字节,所以这里是edx+A,这里复制过去的是0E9h,
是一个机器码,之前写过脱壳的文章(脱壳精讲1),其中一种方法叫一步直达发,壳程序运行结束后一般会有一个jmp或call指令跳到OEP,会脱壳的肯定对E9这个机器码很熟悉,它是jmp指令的机器码,接着将sned函数的地址给eax,eax-malloc基址-0Ah,(这里我卡了好久,一直没看懂啥意思,后来终于想明白了,eax存储的是VA,而不是RVA,如果eax中存储的是RVA,则这里就不需要减去malloc的基址了,因为这里是VA,所以要减去malloc的基址),eax-malloc基址-0Ah是什么意思呢,它表示的是send函数的剩余部分,接着,ecx指向malloc的基址,malloc的偏移0bh处是一个指向send函数剩余部分的指针
接着分析下面的代码
这里,将jmp的机器码复制到send函数的开头,接着将var_4复制到0xe9之后的内存,var_4保存的是sub_1000113d的地址,这段代码的功能是在send函数的开头放置一个jmp指令,让程序的执行流跳转到DLL中的sub_1000113d处的函数,
在函数的末尾,还有一个VirtualProtect调用,这个VirtualProtect调用是为了恢复原始的内存保护设置,最后几行代码的作用是设置dword_10003484为要执行的函数的地址
很明显,这里是一个inline hook,下面来分析hook函数,(var_4)
因为它hook的是send这个函数,所以它与send有相同的参数,
挂钩函数在Str中寻找字符串"RCPT T0:",如果没有发现这个字符串,则只调用dword_1000113d,这样的话send函数的操作与没有安装 inline hook前一样,否则下面这个模块的代码将被执行
该部分代码创建了一个添加到向外传输的缓冲区中的字符串.这个字符串以RCPT T0:<开头,随后是邮箱地址,最后以>\r\n结束.到这里,程序的流程图已经很明确了
这是一个inline hook
打开邮箱,OD附加到进程,这里看到进程中的所有线程都被终止了
Ctrl+G来到send函数
我们看到send函数的开头位置被一个jmp指令覆盖,这是一个inline hook,程序被重定向到1000113D这个函数,这个jmp指令的机器码"e9 11 c5 5d 9e"刚好是5个字节。
跟进
这里我们看到了之前用OD解密时出现的邮箱地址
接着调用10003484
跟进
5个字节之后是jmp指令,跳转到send函数的剩余部分,这和我们在IDA中分析的一样。
这个病毒会遍历进程列表查看它是否运行在一个右键客户端中,如果是邮件客户端则在send函数中安装一个inline挂钩,实现用户态Rootkit,目的是从受害者机器上的邮件程序中复制邮件内容发送给病毒作者.
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2020-11-6 09:51
被Golden_Boy编辑
,原因: