首页
社区
课程
招聘
[原创] 默默无闻·恶意代码分析Lab7
发表于: 2021-4-10 02:44 5580

[原创] 默默无闻·恶意代码分析Lab7

2021-4-10 02:44
5580

[原创]默默无闻·恶意代码分析Lab1

[原创] 默默无闻·恶意代码分析Lab5

[原创]默默无闻·恶意代码分析Lab6

[原创]默默无闻·恶意代码分析第七章

参照书籍:《恶意代码分析实战》;

文件来源:文件来源:官网随书文件、或者附件中(文件密码:apebro);;

使用工具:WinHex、CFF、StudyPE+、Exeinfo PE、Resource Hacker、Depends Walker、OD、IDA、MSDN;

分析在文件Lab07-01.exe中发现的恶意代码;

1、习惯性查壳;

image-20210408204205847

没壳,继续做题目;

2、使用Depends或者直接使用IDA Pro检查导入表,导入表能够透露出很多关键信息;

这里要提一句,使用Depends查看会出现一下问题。

image-20210409134240921

缺失的dll,可以在一个文件查找网站(有广告,别乱点)中找到,里面提供了如何下载的路径;

找到Options->Configure Module Search Order;

image-20210409135433371

添加下载后的文件保存在文件夹内;

image-20210409135633192

通过装载我们下载的文件,就可以查找到了;(延迟加载的警告可以暂时可以无视,或者使用相同的方式找到缺失文件并添加进去);

为了省事,我们就直接使用IDA Pro来查看了,界面有点广阔,就不截图了;

3、查看完导入表,再看看String窗口;

image-20210409141451620

收集到的信息还是蛮多的,下一步就开始分析代码了;

问题:

1、当计算机重启后,这个程序如何确保它继续运行(如何持久化驻留)?

image-20210409143533113

从主函数开始,第一个是StartServiceCtrlDispatcher函数,我们先假装不认识,找MSDN看看这个函数是干嘛的;

这个函数是被程序用来实现一个服务,且立即调用;

书中对这段代码的描述叫做流水账式代码,说明这段代码是一个标准的格式,可以司死记硬背关键点

这个程序创建一个名叫MalService的服务,保证每次系统启动后运行;

2、为什么这个程序会使用一个互斥量?

image-20210409144743056

图中显示了调用链;

image-20210409145417138

根据调用链发现,OpenMutexA打开互斥量,然后通过loc_401064函数创建互斥量,互斥量名叫HGL345;

根据本章知识总结,可知互斥量组合调用,是保证这个可执行程序任意给定时刻只有一份实例再系统上运行。
如果有一个实例已经在运行了,则OpenMutexA的第一次调用成功,程序就会退出;

可以理解成:

image-20210409151034832

否则就会创建一个互斥量CreateMutexA

下面一堆调用看着有点唬人,为了理清思绪,我们先简单反汇编一下;

CreateService创建一个叫做Malservice的服务;

关于CreateService的参数类型问题,详情请查看MSDN

这里直接给出结论,这个程序的dwStartType字段传入的是0x02,对应的是SERVICE_AUTO_ATART字段,说明这个服务在系统启动时自动运行;

其实到这里,这题已经解决了。如果觉得有些意兴阑珊,那么就继续往下看完这个程序

image-20210409153940952

image-20210409154746451

同样为了理清思路,可以简单反汇编一下;

关于SystemTimeToFileTime这个函数中的参数,详情查看MSDN,这里只讨论这个程序的情况;

年的设置是0x0834,其它被设置为0x0,所以设置的时间是2100年1月1日的午夜;

随后使用的WaitForSingleObject函数进入等待,直到2100年1月1日;

最后是一个循环20次创建线程;
StartAddress是线程开始的地址,我们双击进去可以看到线程每次在做的工作;

image-20210409160651852

可以看到跳转的函数;

可以看到,首先打开网络InternetOpenA,然后调用InternetOpenUrlA下载www.malwareanalysisbook.com的主页。

由于CreateThread被调用20次,所以会有20个线程一直调用InternetOpenurlA;
参考这个程序被安装成服务,这是一个DDos攻击
所有被感染的机器在同一时间(2100年1月1日)连接到服务器,使服务器过载;

通常,一个服务必须实现用来停止或暂停的函数,并且它必须能够改变它的状态,来使用户和操作系统知道这个服务已经启动
很显然,这个程序并没有做这些,它的服务状态一直显示为START_PENDING

3、可以用来检测这个程序的基于主机特征是什么?

一个名叫HGL345的互斥量,以及MalService服务;

4、检测这个恶意代码的基于网络特征是什么?

image-20210409162142561

线程创建函数中,用户代理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工具查壳;

image-20210409162802923

显然无壳;

2、进入IDA Pro查看导入表;

image-20210409163018482

CoCreateInstance函数和OleInitialize函数熟悉不在上一节第七章知识总结中有详细说明,这里简单说明这个程序使用了组件对象模型(COM);

CoCreateInstanceSysFreeStringSysAllocStringVariantInitOleInitializeOleUninitialize函数都是COM相关类型;

3、再来看看字符串;

image-20210409164225901

有个网址,下面开始反汇编一探究竟;

梳理逻辑:

image-20210409203356191

这个算是COM的标准结构了(COM方面知识我了解不多,不求甚解的朋友可以看看《COM编程原理》和《COM原理与应用》):
第一步先是初始化COM(OlenInitialize);
第二步获得一个COM对象(CoCreateInstance),标记为ppv
第三步VariantInit函数初始化一个VARIANT数据类型;

image-20210409200959207

image-20210409201506070

image-20210409204017512

edx保存的是COM对象的地址,那么2ch是什么呢?
把这想象成一个虚表,里面挨个存放着属于COM对象的函数地址(书上说是.h文件中的第12个函数,对应偏移0x2C处,经过查证是IWebBrowser2.Navigate())。

IWebBrowser2.Navigate()被调用,Internet Explorer将导航网址http://malwareanalysisbook.com/ad.html

image-20210409213715727

SysFreeString函数和OleUninitiialize函数都是清理函数,然后程序终止;

综上分析,这个程序不会持久化安装,也没有做出别的修改,知识简单显示一个网页(书上说是广告,我并没有连接上);

问题:

1、这个程序如何完成持久化驻留?

没有持久驻留,运行一次然后退出;

2、这个程序的目的是什么?

显示一个网页(广告);

3、这个程序是什么时候完成执行?

显示完网页(广告)后完成执行;

对于这个实验,我们在执行前获取到恶意的可执行程序,Lab07-03.exe,以及DLL,Lab07-03.dll。声明这一点很重要,这是因为恶意代码一旦运行可能发生改变。两个文件在受害者机器上的同一目录下被发现。如果你运行这个程序,你应该确保两个文件在分析机器上的同一个目录中。一个以127开始的IP字符串(回环地址)连接到了本地机器。(在这个恶意代码的实际版本中,这个地址会连接到一个台远程机器,但是我们已经将它设置成连接本地主机来保护你。)

警告:
这个实验可能对你的计算机引起某些损坏,并且可能一旦安装就很难清除。不要再一个没有事先做快照的虚拟机中运行这个文件。

这个实验可能比前面那些有更大的挑战。你将需要使用静态和动态方法的组合,并聚焦再全局视图上,避免陷入细节。

1、首先我们要查壳;

image-20210409214946585

无壳;

2、因为是DLL,所以查看导入表的同时还要看看导出表,直接使用IDA

image-20210409215447244

根据导入表可以看见有网络操作和进程操作;

image-20210409215552321

导出表就一个,没啥好说的,直接看代码吧;

3、然后再看看字符串;

image-20210409220005522

可以看到IP(127.26.152.13);还有一些函数名;

梳理逻辑:

image-20210409222021604

首先我们来看一下_alloca_probe函数,在空间中分配,使用了0x11F8大小的空间;

然后再看看:

image-20210409220552762

image-20210409221421171

简单的梳理一下功能:

虽然我们并不确定到底是什么数据被发送或接收了,或者哪个进程被创建了;

看到connect函数的上面,使用了固定IP地址127.26.152.13

image-20210409222841968

可以看到,还有hosthort也就是端口是0x50也就是熟悉的80端口,这是个Web常用端口;

image-20210409223142124

在这里我们可以看到,send发送了hello

image-20210409223822928

首先lea eax, [esp+120Ch+buf]lea ecx,[esp+1208h+buf]可能看着比较奇怪,其实往上看就都还是buf的位置;出现这个情况是IDA Pro标记的结果,是因为栈被修改的原因

还有一个不算知识点的小常识吧,debug版的程序都是根据ebp来找参数,而Release版本是根据esp;

可以看见recv的调用将网络数据保存在了栈上也就是buf位置上面;

根据上面的截图,可以看见call ebp;strncmp,比较的是收到的字符串前五个字符是否是Sleep
如果是则休眠 60秒;
否则进入下一层;
可以理解成:

image-20210409230059930

可以看到这段代码会检查接收的字符串是否是exec

如果是则创建进程,否则休眠60秒;

看看CreateProcessA上面的,有个[esp+1224h+CommandLine]值,这个值是保存在栈上面的,我们双击进去,并没有看到被改变;因为这是静态分析;

到这里,我们可以判断这个DLL实现的是后门功能;

1、查壳;

image-20210409231345469

无壳;

2、查看导入表;

image-20210409231534463

圈起来的函数告诉我们,这个程序可能打开文件并且映射到内存中;

在右侧一列可以明显的看出并没有导入DLL,其实在分析DLL的时候我们就知道并没有什么能用的函数被导出;

3、查看字符串;

image-20210409231905410

可以看出添加了不少路径,还有一个kernel32.dll,不禁让我想起第一章的模糊替换;

下面就直接看反汇编吧;

梳理逻辑:

image-20210409232453231

首先我们一个一个跳转的看;

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

我们知道了调用方式就可以使用动态分析;

静态分析其实也不慢,就当看汇编练功了不是

image-20210410003727706

我们可以看到CreateFileCreateFileMapping以及MapViewOfFile的调用,打开了kernel32.dll以及Lab07-03.dll

除了这些系统API,我们纵观整个程序,充满了内存微操,看着相当头疼,所以我们先理清函数的调用

image-20210410004359261

书中说:分析像这些消耗时间的内存微操函数是一个常见陷阱,除非绝对需要,应该避免这样做;

image-20210410005352669

在这里我们可以发现,连续的调用了两次关闭句柄CloseHandle,我们知道这时候Malware完成了文件编辑;

然后调用CopyFile,而且是把Lab07-03.dll复制到C:\Windows\System32\Kerner132.dll
这里有一个问题,就是明明是两个反斜杠我为什么在文件路径中只写了一个,这是因为它是转义字符呀,跟\n不是n而是换行一样的道理;

image-20210410005853416

image-20210410010700633

我们发现,传入的字符串最终传给了FindFirstFileA

经过查询MSDN,得知其功能是在一个目录中搜索文件名与指定文件名匹配的文件,也就是搜索C盘;

image-20210410011617076

这一步可以理解成:

跳过malloc函数,看最近的call

image-20210410013028215

查看_stricmp函数貌似没有传参,这个颇具迷惑气息,但是我们可以一路向上找push;

image-20210410013334212

是个比较两个字符串的检查,然后调用是sub_4010A0;

在进入下一层函数之前,我们先向下省视这层的函数;

image-20210410013655170

我们看到,这是一个向上调用的程序(暗指循环);

看到这里,我们可以确认的是这个函数是搜索C盘来查找.exe文件;(书中说这是一个递归调用搜索整个文件系统,最好的方式是使用进程监视器来进行动态分析;)

这个环节又出现了很多系统API,前面没有遇到过的简单描述一下功能;

继续往下走:

image-20210410015538262

这里先是比较了字符串是否相等;

然后是两个寻常的遍历,根据上面的传参,我们判断可能是按位替换,但是是用什么替换的呢,我们只看到了最接近的字符dword_403010

(书中提到repne scasbrep movsd功能上和strlen以及memcpy是等价的; )

在截图中,dword_403010是个dword类型,用一个dword类型替换字符串,貌似不太正常;

我们选中dword_403010a键,然后就转换成字符串Kerne132.dll

由此可见,这个恶意代码修改可执行文件让它们访问kerne132.dll,而不是kernel32.dll
简单的说就是用假的替换真的,而假的代替真的被这个exe文件加载;

书后答案中还有就是使用进程监视器进行Malware行为观察,我图省事并没有跟踪。看答案和我们的分析结果是一样的。

问题:

1、这个程序如何完成持久化驻留,来确保在计算机被重启后它能继续运行?

这个程序通过写一个叫做kerner132.dllC:\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(...);        // 创建一个新的服务;
 
 
 
 

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2021-4-10 20:12 被平头猿小哥编辑 ,原因:
上传的附件:
收藏
免费 3
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//