恶意代码分析实战11-2

Posted Neil-Yale

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了恶意代码分析实战11-2相关的知识,希望对你有一定的参考价值。

本次实验我们将会分析lab11-02.exe文件。先来看看求解答的问题
Q1.这个恶意DLL导出了什么?
Q2.使用rundll32.exe安装这个恶意代码后,发生了什么?
Q3.为了使这个恶意代码正确安装,Labl 1-02.ini必须放置在何处?
Q4.这个安装的恶意代码如何驻留?
Q5.这个恶意代码采用的用户态Rootkit技术是什么?
Q6.hook代码做了什么?
Q7.哪个或者哪些进程执行这个恶意攻击,为什么?
Q8. .ini 文件的意义是什么?
Q9.你怎样用Wireshark动态抓获这个恶意代码的行为?

先使用dependency walker载入dll文件
在这里插入图片描述

可以看到有一个名为installer的导出函数
Q1.这个恶意DLL导出了什么?
A1.Labl 11-02.dll包含一个名为installer的导出函数

在kernel32.dll里看到一些文件操作、快照相关的函数
在这里插入图片描述

在adavpi32.dll中看到与注册表相关的操作
在这里插入图片描述

查看字符串的内容
在这里插入图片描述

注意到了AppinitDlls和SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows,这里简单提一下AppinitDlls
AppInit_Dlls键值位于注册表 HKLM\\Microsoft\\Windows NT\\CurrentVersion\\Windows下面,相对于其他的注册表启动项来说,这个键值的特殊之处在于任何使用到User32.dll 的EXE、DLL、OCX等类型的PE文件都会读取这个地方,并且根据约定的规范将这个键值下指向的DLL文件进行加载,加载的方式是调用 LoadLibrary。可见其键值是非常危险的。这里出现了,就值得我们警惕。
另外还出现了\\lab11-02.ini,表明恶意代码会使用此时提供的ini文件

因为我们这是的文件是dll文件,使用process monitor是不能直接监控的,所以这里进行监控时设置的过滤条件是rundll32.exe
在这里插入图片描述

然后用如下命令启动
在这里插入图片描述

注意lab11-02.dll后面跟的是逗号,然后是刚才发现的导出函数installer
来到process monitor
在这里插入图片描述

此时在process monitor发现很多信息了
先看文件方面的监控,注意到
在这里插入图片描述

在系统目录下生成了一个dll
我们找到它计算md5看看是否就是该dll本身
在这里插入图片描述

可以看到md5是一样的
继续观察,可以看到
在这里插入图片描述

恶意代码将spoolvxx32.dll添加到AppInit_dll列表中(结合前面的扩展知识,我么知道这样就可以到导致恶意代码被加载到所有装载user32.dll的进程中)
还可以看到
在这里插入图片描述

访问lab11-02.ini时是不成功的,因为在系统目录下不存在该文件,所以我们这里将其复制到该目录,便于进一步的分析
Q3.为了使这个恶意代码正确安装,Lab11-02.ini必须放置在何处?
A3.为了恶意代码的正常运行,Lab11-02.ini必须位于%SystemRoot% \\System32\\目录下
这里可以先查看lab11-02.ini的字符串
在这里插入图片描述

可以看到似乎是加密或者混淆过的内容
Q2.使用rundll32.exe安装这个恶意代码后,发生了什么?
A2.使用命令rund1132. exe Lab11-02.d11, installer 从命令行启动恶意代码,恶意代码会作为spoolxx32.dll 将自身复制到系统目录中,并且在AppInit_ DLLS 键值下永久安装。另外,恶意代码尝试着从系统目录中打开Lab11-02.ini,但是它在那里并没有发现这个文件
Q4.这个安装的恶意代码如何驻留?
A4.恶意代码将自身安装到AppInit_ _DLLS 的注册表键值中,这可以使恶意代码加载到所有装载User32.dll的进程中
接下来使用ida进行分析
先看一下installer这个导出函数
在这里插入图片描述

查看交叉引用的图view-grpash-xrefs from
在这里插入图片描述

可以看到调用了regsetvalue,copytfile等,这些函数的作用行为在之前我们已经看到了。Installer函数的唯一目的就是复制恶意代码到spoolvx32.dll并设置它为Appinit_dlls值
在view-a里也可以详细看到这一点
在这里插入图片描述

接下来回到dllmain继续分析
在这里插入图片描述

调用了sub_1000105b
跟进去
在这里插入图片描述

可以看到是调用getsystemdirectiry获取系统路径,所以可以将这个函数改名为
getdirectory
接着往下
在这里插入图片描述

通过strncat将系统目录与lab11-02.dll字符串进行拼接组成新的路径
在这里插入图片描述

接着调用createfile试图打开该ini文件
如果不能打开往左走,直接返回,如果可以打开则往右走,如下图所示
在这里插入图片描述

如果可以打开ini文件, 接下来会调用readfile。将其读到一个缓冲区lpbuffer里,读取之后会通过cmp [ebp+numberofbyteread],0来判断读取过来的是否大于0
接下来是push offset byte_100044a0,是将缓冲区的内容入栈,作为sub_100010b3的参数
因为sub_100010b3是打开可以加密文件句柄后调用的第一个函数,所以我们推测这可能是解密函数

接下来我们使用od动态分析(在动态分析前,注意先将ini文件和dll文件复制到系统目录并将dll重命名为spoolvxx32.dll)
在这里插入图片描述

然后跳到ida中那个调用那个函数的地址
在这里插入图片描述

在这里下断点,然后执行过来
在这里插入图片描述

这时其上方的push的内容已经入栈了,可以在数据窗口中跟随
在这里插入图片描述

可以看到此时的数据还是无法识别的
在这里插入图片描述

接下来单步,看看eax保存的返回值
在这里插入图片描述

可以看到解密出的数据是一个邮箱的地址
Q8. .ini 文件的意义是什么?
A8.INI 文件中包含一个加密的邮件地址。 解密Labl 1-02.ini之后,我们看到它包含billy@malwareanalysisbook.com

所以可以给ida识别出的全局变量byte_100034a0命名为emailaddress,将这个函数命名为decoder
接下来回到ida继续分析
往下可以看到调用了sub_100014b6
在这里插入图片描述

这个函数安装了内联钩子(inline hook),所以这里将其重命名为hook_installer
Q5.这个恶意代码采用的用户态Rootkit技术是什么?
A5.这个恶意代码针对send函数安装了一个 inline 挂钩(hook)
这一块比较复杂,在深入分析之前,我们先学习相关知识
在这里插入图片描述

左侧是ws32_32.dll中正常的send函数调用的形式,右侧是hook_installer安装send函数的内联钩子的过程。可以看到send函数最开始通过jmp指令跳到了恶意代码起始处,执行恶意代码后,运行一小段send函数的头部代码,再通过jmp(这一部分的指令称之为trampoline)回到send函数的主体流程。从而实现了send正常的操作,仿佛与没被安装钩子之前的效果是一样的。
Hook_installer在安装钩子之前,会先检查恶意代码在哪个进程中运行。具体而言,可以跟入该函数
首先调用了sub_10001075
跟入
在这里插入图片描述

可以看到调用了getmodulefilename,因为在调用之前,参数hModule是0
在这里插入图片描述

所以函数会返回加载这个dll进程的绝对路径
接下来恶意代码在arg_4中返回路径名
接着调用sub_10001104
在这里插入图片描述

跟入
在这里插入图片描述

主要是用于将刚才获取的路径的名称提取出来
接着调用sub_1000102d
跟进去
在这里插入图片描述

可以看到,通过topper将小写改大写
之后就是一系列的比较
在这里插入图片描述

如果不是上图中待比较的exe中的任一个,则会退出,否则继续执行
Q7.哪个或者哪些进程执行这个恶意攻击,为什么?
A7.恶意代码的攻击目标仅针对MSIMN.exe、THEBAT.exe 和OUTLOOK.exe,之所以这样,是因为它们都是电子邮件客户端软件。除非恶意代码运行在这些进程空间中,否则它不会安装hook。

首先是调用sub_100013bd
跟入
在这里插入图片描述

首先调用了getcurrentprocessid,然后调用了sub_100012fe
跟入
在这里插入图片描述

一开始是通过getcurrentid获取当前运行线程的id(线程标识符)
接着调用createtoolhelp32snapshot为当前进程线程拍摄快照
然后通过thread32first,thread32next来循环遍历当前进程的所有线程标识符
如果遍历获取后的线程不是我们当前的线程,则调用suspendthread将其挂起
在这里插入图片描述

也就是说该函数的作用就是挂起了当前进程的所有运行线程
所以可以将sub_100012fe其改名为suspendthread,便于后续分析
回到dllmain,跟入sub_10001499
在这里插入图片描述

同样也是先调用getcurrentprocessid,我们直接跟入sub_100013da
在这里插入图片描述

可以看到它的基本结构和之前分析的那个是一样的,不同的是这里是resumethread
作用就是如果当前的线程不是我们获取的线程,则调用resumethread恢复线程
回到main
在这里插入图片描述

我们就知道这段的功能就是:首先是挂起线程,后面是恢复线程。这种行为模式常见于修改内核,或者安装内联钩子inline hook。当然,在我们这次的分析中就是用于安装内联钩子。
刚才还有一个函数没分析sub_100012a3
在这里插入图片描述

可以知道有4个参数
跟入
在这里插入图片描述

首先调用getmodulehandle获取句柄,回到上一个函数看看是谁的句柄
在这里插入图片描述

所以获取的是wsock32.dll的句柄
在这里插入图片描述

之后通过loadlibrary,getprocaddress就能获取send函数的地址
获得的send函数地址被保存在lpaddress
之后是一系列的Push,push arg_c,arg_8以及lpadress,作为参数传给sub_10001203
arg_8,argc可以看到分别是是第三,四个参数
在这里插入图片描述

分别是,sub_1000113d和dword_10003484,待会儿分析

接下来我们看看参数传入之后,这个函数实现了什么样的功能
在这里插入图片描述

通过sub计算了send函数的内存地址(lpaddress)与sub_1000113d(这里的arg4,是传入的第二个参数,是上一个函数的第三个参数)开始的内存地址之间的差。将差值移到var_4之前,从中减去5个字节。这样子,后面的指令使用var_4变量时,加上0xe9(jmp的操作码),使这5个字节的指令能够跳转到sub_1000113d
继续往下看

在这里插入图片描述

调用virtualprotect函数。用于修改内存的运行、读、以及写等保护权限,因此可以使恶意代码修改send函数的执行。在下面还看到一个virtualprotect调用,是恢复原始的内存保护设置。
在调用第一个virtualprotect之后,可以看到通过malloc分配了0xff字节的内存,将结果保存在var_8中。
因为这一块malloc的内存作为一个前面扩展知识中提到的trampoline,所以可以将var_8重命名为trampoline.
后续是为内联钩子创建trampoline
在这里插入图片描述

call memcpy是复制send函数的前5个字节到trampoline.(这是因为恶意代码覆盖了send函数的前五个字节,所以需要保存原始指令)
接下来mov ptr[edx+0ah],0e9h,添加机器码0xe9,mov [ecx+0bh],eax 添加跳转的地址(这里就是通过从send函数的地址中减去trampoline的地址,来实现跳回send函数),来计算跳转地址
而这一段
在这里插入图片描述

将机器码0xe9复制到send函数的开头,之后通过mov [eax+1],e复制到var_4到0xe9之后的内存。
前面说过Var_4变量包含跳转的目的地址即sub_1000113d。
所以通过以上的指令,作用就是在send函数的开始部分放置了一个jmp,从而跳到sub_1000113d。
这个过程其实就是钩子功能的实现,所以给sub_1000113d重命名为hook_function
最后
在这里插入图片描述

通过一系列mov指令(注意,这里arg_8就是dword_10003484,var_8就是trampoline)将全局变量dword_10003484变量设置为trampoline的地址

接下来分析hook_function,跟入
在这里插入图片描述

可以看到首先会查找字符串”RCPT TO:”
如果没有则退出,那么表现出来则和没有按照挂钩前一样
如果存在的话继续往下走,功能是创建一个添加向外传输的缓冲区的中的字符串。
这个字符串以RCPT:<开头,随后是email_address,最后以>\\r\\n结束
这么也就总结出来了,这段代码的作用就是向所有的发出的邮件中添加了一个收件人
至此,来总结下钩子函数的操作:
程序调用send函数
send函数的第一个指令转换到sub_1000113d
当外传缓冲区存在RCPT TO时,sub——1000113d操作外传的缓冲区
sub_1000113d调用dword_10003484指向的trampoline代码
trampoline代码运行send函数的前三条原始指令(它被覆盖来安装钩子)
trampoline跳回send函数第五个字节,从而使sned函数可以正常运行
Q6.hook代码做了什么:
A6:检查向外发出的包,看外传的包是否是包含RCPT TO:的电子邮件信息,如果发现了这个字符串,则它会添加一个额外的RCPT TO行,来增加一个恶意的电子邮件账户

接下来od动态分析验证我们的结论:
首先打开outlook
在这里插入图片描述

然后od附加到outlook的进程msimn
在这里插入图片描述

点击M查看内存映射
在这里插入图片描述

可以看到spoolvxx被加载到内存中了
也就说明恶意程序开始工作了
接下来ctrl+g搜索send
在这里插入图片描述

可以看到函数此时已经被hook了,会跳到spoolvx.1000113d
在这里插入图片描述

尝试使用wireshark捕获,wireshark开启监控后打开outlook
在这里插入图片描述

发生成功之后
然后回到wireshark
找到smtp的数据之后跟踪tcp流
在这里插入图片描述

可以看到除了我们指定的发件人邮箱外,多了一个bill@malwareanalysisbook.com的邮箱地址
说明恶意文件确实如我们分析的那样起作用了
A9.怎样用Wireshark动态抓获这个恶意代码的行为?
A9.不许特别设置,直接抓包即可。通过Wireshark抓取的网络数据,可以看到一个假冒的邮件服务器以及Outlook Express客户端

来总结下:lab11-2是一个到处installer函数的恶意dll。使用appinit_dll来永久安装恶意代码,大多数进程都会加载这个恶意代码。会通过预设的目标进程列表进行比较,如果运行在一个邮件客户端中,则在send函数安装内联钩子,实现用户态rootkit。(其实现方式是在send函数开始放置 一个jmp指令,钩子运行一个函数,它会扫描send的发送的数据缓冲区,如果其中存在字符串RCPT TO,则会插入一个额外的RCPT TO,包含从解密后的lab11-02.ini中提取出的邮件地址,其目的是从目标邮件程序中复制所有邮件发送给恶意代码编写者)。

参考:
1.《恶意代码分析实战》

以上是关于恶意代码分析实战11-2的主要内容,如果未能解决你的问题,请参考以下文章

恶意代码分析实战3-2

恶意代码分析实战11-1

恶意代码分析实战9-1

恶意代码分析实战14-02

恶意代码分析实战15-3

恶意代码分析实战21-2