-
-
[原创] 默默无闻·恶意代码分析Lab7
-
发表于: 2021-4-10 02:44 5580
-
参照书籍:《恶意代码分析实战》;
文件来源:文件来源:官网随书文件、或者附件中(文件密码:apebro
);;
使用工具:WinHex、CFF、StudyPE+、Exeinfo PE、Resource Hacker、Depends Walker、OD、IDA、MSDN;
分析在文件Lab07-01.exe中发现的恶意代码;
1、习惯性查壳;
没壳,继续做题目;
2、使用Depends
或者直接使用IDA Pro
检查导入表,导入表能够透露出很多关键信息;
这里要提一句,使用Depends查看会出现一下问题。
缺失的dll,可以在一个文件查找网站(有广告,别乱点)中找到,里面提供了如何下载的路径;
找到Options
->Configure Module Search Order
;
添加下载后的文件保存在文件夹内;
通过装载我们下载的文件,就可以查找到了;(延迟加载的警告可以暂时可以无视,或者使用相同的方式找到缺失文件并添加进去);
为了省事,我们就直接使用IDA Pro
来查看了,界面有点广阔,就不截图了;
3、查看完导入表,再看看String
窗口;
收集到的信息还是蛮多的,下一步就开始分析代码了;
问题:
1、当计算机重启后,这个程序如何确保它继续运行(如何持久化驻留)?
从主函数开始,第一个是StartServiceCtrlDispatcher
函数,我们先假装不认识,找MSDN看看这个函数是干嘛的;
这个函数是被程序用来实现一个服务,且立即调用;
书中对这段代码的描述叫做流水账式代码
,说明这段代码是一个标准的格式,可以司死记硬背关键点
这个程序创建一个名叫MalService
的服务,保证每次系统启动后运行;
2、为什么这个程序会使用一个互斥量?
图中显示了被调用链;
根据调用链发现,OpenMutexA
打开互斥量,然后通过loc_401064
函数创建互斥量,互斥量名叫HGL345
;
根据本章知识总结,可知互斥量组合调用,是保证这个可执行程序任意给定时刻只有一份实例再系统上运行。
如果有一个实例已经在运行了,则OpenMutexA
的第一次调用成功,程序就会退出;
可以理解成:
否则就会创建一个互斥量CreateMutexA
;
下面一堆调用看着有点唬人,为了理清思绪,我们先简单反汇编一下;
CreateService
创建一个叫做Malservice
的服务;
关于CreateService
的参数类型问题,详情请查看MSDN
;
这里直接给出结论,这个程序的dwStartType
字段传入的是0x02
,对应的是SERVICE_AUTO_ATART
字段,说明这个服务在系统启动时自动运行;
其实到这里,这题已经解决了。如果觉得有些意兴阑珊,那么就继续往下看完这个程序
同样为了理清思路,可以简单反汇编一下;
关于SystemTimeToFileTime
这个函数中的参数,详情查看MSDN,这里只讨论这个程序的情况;
年的设置是0x0834
,其它被设置为0x0
,所以设置的时间是2100年1月1日的午夜;
随后使用的WaitForSingleObject
函数进入等待,直到2100年1月1日;
最后是一个循环20次创建线程;StartAddress
是线程开始的地址,我们双击进去可以看到线程每次在做的工作;
可以看到跳转的函数;
可以看到,首先打开网络InternetOpenA
,然后调用InternetOpenUrlA
下载www.malwareanalysisbook.com
的主页。
由于CreateThread
被调用20次,所以会有20个线程一直调用InternetOpenurlA
;
参考这个程序被安装成服务,这是一个DDos
攻击
所有被感染的机器在同一时间(2100年1月1日)连接到服务器,使服务器过载;
通常,一个服务必须实现用来停止或暂停的函数,并且它必须能够改变它的状态,来使用户和操作系统知道这个服务已经启动
很显然,这个程序并没有做这些,它的服务状态一直显示为START_PENDING
;
3、可以用来检测这个程序的基于主机特征是什么?
一个名叫HGL345
的互斥量,以及MalService
服务;
4、检测这个恶意代码的基于网络特征是什么?
线程创建函数中,用户代理Internet Explorer 8.0
,并和www.malwareanalysisbook.com
通信;
5、这个程序的目的是什么?
程序等待一直到2100年1月1日的半夜,发起对www.malwareanalysisbook.com
发起分布式拒接服务(DDos)攻击;
6、这个程序是什么时候完成执行?
注意的是如果不是在虚拟机中运行这个实验,可以通过命令行sc delete Malservice
可以移除这个服务;
分析在文件Lab07-02.exe中发现的恶意代码;
1、Exeinfo PE
工具查壳;
显然无壳;
2、进入IDA Pro
查看导入表;
CoCreateInstance
函数和OleInitialize
函数熟悉不在上一节第七章知识总结中
有详细说明,这里简单说明这个程序使用了组件对象模型(COM);
CoCreateInstance
、SysFreeString
、SysAllocString
、VariantInit
、OleInitialize
、OleUninitialize
函数都是COM相关类型;
3、再来看看字符串;
有个网址,下面开始反汇编一探究竟;
梳理逻辑:
这个算是COM的标准结构了(COM方面知识我了解不多,不求甚解的朋友可以看看《COM编程原理》和《COM原理与应用》):
第一步先是初始化COM(OlenInitialize
);
第二步获得一个COM对象(CoCreateInstance
),标记为ppv
;
第三步VariantInit
函数初始化一个VARIANT
数据类型;
edx
保存的是COM对象的地址,那么2ch
是什么呢?
把这想象成一个虚表,里面挨个存放着属于COM对象的函数地址(书上说是.h文件中的第12个函数,对应偏移0x2C
处,经过查证是IWebBrowser2.Navigate()
)。
当IWebBrowser2.Navigate()
被调用,Internet Explorer将导航网址http://malwareanalysisbook.com/ad.html
;
SysFreeString
函数和OleUninitiialize
函数都是清理函数,然后程序终止;
综上分析,这个程序不会持久化安装,也没有做出别的修改,知识简单显示一个网页(书上说是广告,我并没有连接上);
问题:
1、这个程序如何完成持久化驻留?
没有持久驻留,运行一次然后退出;
2、这个程序的目的是什么?
显示一个网页(广告);
3、这个程序是什么时候完成执行?
显示完网页(广告)后完成执行;
对于这个实验,我们在执行前获取到恶意的可执行程序,Lab07-03.exe,以及DLL,Lab07-03.dll。声明这一点很重要,这是因为恶意代码一旦运行可能发生改变。两个文件在受害者机器上的同一目录下被发现。如果你运行这个程序,你应该确保两个文件在分析机器上的同一个目录中。一个以127开始的IP字符串(回环地址)连接到了本地机器。(在这个恶意代码的实际版本中,这个地址会连接到一个台远程机器,但是我们已经将它设置成连接本地主机来保护你。)
警告:
这个实验可能对你的计算机引起某些损坏,并且可能一旦安装就很难清除。不要再一个没有事先做快照的虚拟机中运行这个文件。
这个实验可能比前面那些有更大的挑战。你将需要使用静态和动态方法的组合,并聚焦再全局视图上,避免陷入细节。
1、首先我们要查壳;
无壳;
2、因为是DLL,所以查看导入表的同时还要看看导出表,直接使用IDA
;
根据导入表可以看见有网络操作和进程操作;
导出表就一个,没啥好说的,直接看代码吧;
3、然后再看看字符串;
可以看到IP(127.26.152.13);还有一些函数名;
梳理逻辑:
首先我们来看一下_alloca_probe
函数,在空间中分配栈,使用了0x11F8
大小的空间;
然后再看看:
简单的梳理一下功能:
虽然我们并不确定到底是什么数据被发送或接收了,或者哪个进程被创建了;
看到connect
函数的上面,使用了固定IP
地址127.26.152.13
;
可以看到,还有hosthort也就是端口是0x50
也就是熟悉的80端口,这是个Web常用端口;
在这里我们可以看到,send
发送了hello
;
首先lea eax, [esp+120Ch+buf]
,lea ecx,[esp+1208h+buf]
可能看着比较奇怪,其实往上看就都还是buf
的位置;出现这个情况是IDA Pro标记的结果,是因为栈被修改的原因
还有一个不算知识点的小常识吧,debug版的程序都是根据ebp来找参数,而Release版本是根据esp;
可以看见recv
的调用将网络数据保存在了栈上也就是buf
位置上面;
根据上面的截图,可以看见call ebp;strncmp
,比较的是收到的字符串前五个字符是否是Sleep
。
如果是则休眠 60秒;
否则进入下一层;
可以理解成:
可以看到这段代码会检查接收的字符串是否是exec
,
如果是则创建进程,否则休眠60秒;
看看CreateProcessA
上面的,有个[esp+1224h+CommandLine]
值,这个值是保存在栈上面的,我们双击进去,并没有看到被改变;因为这是静态分析;
到这里,我们可以判断这个DLL实现的是后门功能;
1、查壳;
无壳;
2、查看导入表;
圈起来的函数告诉我们,这个程序可能打开文件并且映射到内存中;
在右侧一列可以明显的看出并没有导入DLL,其实在分析DLL的时候我们就知道并没有什么能用的函数被导出;
3、查看字符串;
可以看出添加了不少路径,还有一个kernel32.dll
,不禁让我想起第一章的模糊替换;
下面就直接看反汇编吧;
梳理逻辑:
首先我们一个一个跳转的看;
1.第一个跳转loc_401813
,看看跳转条件:
首先是cmp eax,2
,判断参数[esp+argc]
是否为2,也就是判断命令行参数是否为2;
如果不理解,百度关键字:main函数的三个参数详解;
如果是参数不是两个,则程序直接退出;
2.假设满足条件继续往下走。可以看到WARNING_THIS_WILL_DESTROY_YOUR_MACHINE
的首地址被传给了esi
,其后又把esi
截取赋给了bl
,最后比较是否满足;
通常命令行参数不会这么直白,多少都会更加私密
这里可以简单的看作:
Lab07-03.exe WARNING_THIS_WILL_DESTROY_YOUR_MACHINE
;
我们知道了调用方式就可以使用动态分析;
静态分析其实也不慢,就当看汇编练功了不是 ;
我们可以看到CreateFile
、CreateFileMapping
以及MapViewOfFile
的调用,打开了kernel32.dll
以及Lab07-03.dll
;
除了这些系统API,我们纵观整个程序,充满了内存微操,看着相当头疼,所以我们先理清函数的调用 ;
书中说:分析像这些消耗时间的内存微操函数是一个常见陷阱,除非绝对需要,应该避免这样做;
在这里我们可以发现,连续的调用了两次关闭句柄CloseHandle
,我们知道这时候Malware完成了文件编辑;
然后调用CopyFile
,而且是把Lab07-03.dll
复制到C:\Windows\System32\Kerner132.dll
;
这里有一个问题,就是明明是两个反斜杠我为什么在文件路径中只写了一个,这是因为它是转义字符呀,跟\n
不是n
而是换行一样的道理;
我们发现,传入的字符串最终传给了FindFirstFileA
;
经过查询MSDN,得知其功能是在一个目录中搜索文件名与指定文件名匹配的文件,也就是搜索C盘;
这一步可以理解成:
跳过malloc
函数,看最近的call
;
查看_stricmp
函数貌似没有传参,这个颇具迷惑气息,但是我们可以一路向上找push
;
是个比较两个字符串的检查,然后调用是sub_4010A0
;
在进入下一层函数之前,我们先向下省视这层的函数;
我们看到,这是一个向上调用的程序(暗指循环);
看到这里,我们可以确认的是这个函数是搜索C盘来查找.exe文件;(书中说这是一个递归调用搜索整个文件系统,最好的方式是使用进程监视器来进行动态分析;)
这个环节又出现了很多系统API,前面没有遇到过的简单描述一下功能;
继续往下走:
这里先是比较了字符串是否相等;
然后是两个寻常的遍历,根据上面的传参,我们判断可能是按位替换,但是是用什么替换的呢,我们只看到了最接近的字符dword_403010
;
(书中提到repne scasb
和rep movsd
功能上和strlen
以及memcpy
是等价的; )
在截图中,dword_403010
是个dword
类型,用一个dword
类型替换字符串,貌似不太正常;
我们选中dword_403010
摁a
键,然后就转换成字符串Kerne132.dll
;
由此可见,这个恶意代码修改可执行文件让它们访问kerne132.dll
,而不是kernel32.dll
;
简单的说就是用假的替换真的,而假的代替真的被这个exe文件加载;
书后答案中还有就是使用进程监视器进行Malware行为观察,我图省事并没有跟踪。看答案和我们的分析结果是一样的。
问题:
1、这个程序如何完成持久化驻留,来确保在计算机被重启后它能继续运行?
这个程序通过写一个叫做kerner132.dll
到C:\Windows\System32
,并修改系统上每一个导入它的.exe文件,来达到持久化驻留;
2、这个恶意代码的两个明显的基于主机特征是什么?
通过硬编码使用文件名kerne132.dll
。
3、这个程序的目的是什么?
创建一个后门,链接远程主机。后门又两个命令,一个是用来执行命令,一个是用来睡眠;
4、一旦这个恶意代码被安装,你如何移除它?
很难,因为每一个exe文件都被修改了,所以最简单的方法是直接还原备份系统;
本来想跳过这一章节的课后题目的,毕竟学习进度有些慢了。可是做起来却做了好久(包括要写帖子);
这一章节还是比较重要的,01是服务驻留,02是COM组件驻留,03就是直接替换系统文件更改exe文件导入表达到驻留目的,几乎包含了包含程序驻留的所有方式;
幸亏没有放弃这章,还是很有学习价值的;
以上内容如有疑误之处,还请大佬指正;
StartServiceCtrlDispatcher函数将服务进程的主线程连接到服务控制管理器,这将使线程成为调用进程的服务控制调度程序线程。
BOOL
StartServiceCtrlDispatcher(
LPSERVICE_TABLE_ENTRY lpServiceStartTable
/
/
address of service table
);
StartServiceCtrlDispatcher函数将服务进程的主线程连接到服务控制管理器,这将使线程成为调用进程的服务控制调度程序线程。
BOOL
StartServiceCtrlDispatcher(
LPSERVICE_TABLE_ENTRY lpServiceStartTable
/
/
address of service table
);
if
(OpenMutexA(...))
/
/
打开互斥量
loc_401064;
else
ExitProcess();
/
/
退出程序
if
(OpenMutexA(...))
/
/
打开互斥量
loc_401064;
else
ExitProcess();
/
/
退出程序
CreateMutex(...);
/
/
创建互斥量
esi
=
OpenSCManagerA(...);
/
/
打开一个服务控制管理器的句柄 返回值被赋给了esi
GetCurrentProcess(...);
/
/
返回当前程序句柄
GetModuleFileNameA(...);
/
/
返回当前正在运行的可执行程序或一个被加载的DLL路径名
CreateServiceA(...);
/
/
创建一个新的服务;
CreateMutex(...);
/
/
创建互斥量
esi
=
OpenSCManagerA(...);
/
/
打开一个服务控制管理器的句柄 返回值被赋给了esi
GetCurrentProcess(...);
/
/
返回当前程序句柄
GetModuleFileNameA(...);
/
/
返回当前正在运行的可执行程序或一个被加载的DLL路径名
CreateServiceA(...);
/
/
创建一个新的服务;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
- [原创]默默无闻·恶意代码分析Lab10 13506
- [原创] 默默无闻·恶意代码分析Lab9 15336
- [原创] 默默无闻·恶意代码分析Lab7 5581
- [原创]咬文嚼字·浅说OEP和EP 16506
- [原创]默默无闻·恶意代码分析第七章 7880