2023年7月4日发(作者:)
恶意代码分析实战11-2本次实验我们将会分析⽂件。先来看看求解答的问题Q1.这个恶意DLL导出了什么?Q2.使⽤安装这个恶意代码后,发⽣了什么?Q3.为了使这个恶意代码正确安装,Labl 必须放置在何处?Q4.这个安装的恶意代码如何驻留?Q5.这个恶意代码采⽤的⽤户态Rootkit技术是什么?代码做了什么?Q7.哪个或者哪些进程执⾏这个恶意攻击,为什么?Q8. .ini ⽂件的意义是什么?Q9.你怎样⽤Wireshark动态抓获这个恶意代码的⾏为?先使⽤dependency walker载⼊dll⽂件可以看到有⼀个名为installer的导出函数Q1.这个恶意DLL导出了什么? 包含⼀个名为installer的导出函数在⾥看到⼀些⽂件操作、快照相关的函数在中看到与注册表相关的操作查看字符串的内容注意到了AppinitDlls和SOFTWAREMicrosoftWindows NTCurrentVersionWindows,这⾥简单提⼀下AppinitDllsAppInit_Dlls键值位于注册表 HKLMMicrosoftWindows NTCurrentVersionWindows下⾯,相对于其他的注册表启动项来说,这个键值的特殊之处在于任何使⽤到 的EXE、DLL、OCX等类型的PE⽂件都会读取这个地⽅,并且根据约定的规范将这个键值下指向的DLL⽂件进⾏加载,加载的⽅式是调⽤ LoadLibrary。可见其键值是⾮常危险的。这⾥出现了,就值得我们警惕。另外还出现了,表明恶意代码会使⽤此时提供的ini⽂件因为我们这是的⽂件是dll⽂件,使⽤process monitor是不能直接监控的,所以这⾥进⾏监控时设置的过滤条件是然后⽤如下命令启动注意后⾯跟的是逗号,然后是刚才发现的导出函数installer来到process monitor此时在process monitor发现很多信息了先看⽂件⽅⾯的监控,注意到在系统⽬录下⽣成了⼀个dll我们找到它计算md5看看是否就是该dll本⾝可以看到md5是⼀样的继续观察,可以看到恶意代码将添加到AppInit_dll列表中(结合前⾯的扩展知识,我么知道这样就可以到导致恶意代码被加载到所有装载的进程中)还可以看到访问时是不成功的,因为在系统⽬录下不存在该⽂件,所以我们这⾥将其复制到该⽬录,便于进⼀步的分析Q3.为了使这个恶意代码正确安装,必须放置在何处?A3.为了恶意代码的正常运⾏,必须位于%SystemRoot% System32⽬录下这⾥可以先查看的字符串可以看到似乎是加密或者混淆过的内容Q2.使⽤安装这个恶意代码后,发⽣了什么?A2.使⽤命令rund1132. exe Lab11-02.d11, installer 从命令⾏启动恶意代码,恶意代码会作为 将⾃⾝复制到系统⽬录中,并且在AppInit_ DLLS 键值下永久安装。另外,恶意代码尝试着从系统⽬录中打开,但是它在那⾥并没有发现这个⽂件Q4.这个安装的恶意代码如何驻留?A4.恶意代码将⾃⾝安装到AppInit_ _DLLS 的注册表键值中,这可以使恶意代码加载到所有装载的进程中接下来使⽤ida进⾏分析先看⼀下installer这个导出函数查看交叉引⽤的图view-grpash-xrefs from可以看到调⽤了regsetvalue,copytfile等,这些函数的作⽤⾏为在之前我们已经看到了。Installer函数的唯⼀⽬的就是复制恶意代码到并设置它为Appinit_dlls值在view-a⾥也可以详细看到这⼀点接下来回到dllmain继续分析调⽤了sub_1000105b跟进去可以看到是调⽤getsystemdirectiry获取系统路径,所以可以将这个函数改名为getdirectory接着往下通过strncat将系统⽬录与字符串进⾏拼接组成新的路径接着调⽤createfile试图打开该ini⽂件如果不能打开往左⾛,直接返回,如果可以打开则往右⾛,如下图所⽰如果可以打开ini⽂件, 接下来会调⽤readfile。将其读到⼀个缓冲区lpbuffer⾥,读取之后会通过cmp [ebp+numberofbyteread],0来判断读取过来的是否⼤于0接下来是push offset byte_100044a0,是将缓冲区的内容⼊栈,作为sub_100010b3的参数因为sub_100010b3是打开可以加密⽂件句柄后调⽤的第⼀个函数,所以我们推测这可能是解密函数接下来我们使⽤od动态分析(在动态分析前,注意先将ini⽂件和dll⽂件复制到系统⽬录并将dll重命名为)然后跳到ida中那个调⽤那个函数的地址在这⾥下断点,然后执⾏过来这时其上⽅的push的内容已经⼊栈了,可以在数据窗⼝中跟随可以看到此时的数据还是⽆法识别的接下来单步,看看eax保存的返回值可以看到解密出的数据是⼀个邮箱的地址Q8. .ini ⽂件的意义是什么? ⽂件中包含⼀个加密的邮件地址。 解密Labl 之后,我们看到它包含billy@所以可以给ida识别出的全局变量byte_100034a0命名为emailaddress,将这个函数命名为decoder接下来回到ida继续分析往下可以看到调⽤了sub_100014b6这个函数安装了内联钩⼦(inline hook),所以这⾥将其重命名为hook_installerQ5.这个恶意代码采⽤的⽤户态Rootkit技术是什么?A5.这个恶意代码针对send函数安装了⼀个 inline 挂钩(hook)这⼀块⽐较复杂,在深⼊分析之前,我们先学习相关知识左侧是ws32_中正常的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.恶意代码的攻击⽬标仅针对、 和,之所以这样,是因为它们都是电⼦邮件客户端软件。除⾮恶意代码运⾏在这些进程空间中,否则它不会安装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获取句柄,回到上⼀个函数看看是谁的句柄所以获取的是的句柄之后通过loadlibrary,getprocaddress就能获取send函数的地址获得的send函数地址被保存在lpaddress之后是⼀系列的Push,push arg_c,arg_8以及lpadress,作为参数传给sub_10001203arg_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.后续是为内联钩⼦创建trampolinecall 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,最后以>rn结束这么也就总结出来了,这段代码的作⽤就是向所有的发出的邮件中添加了⼀个收件⼈⾄此,来总结下钩⼦函数的操作:程序调⽤send函数send函数的第⼀个指令转换到sub_1000113d当外传缓冲区存在RCPT TO时,sub——1000113d操作外传的缓冲区sub_1000113d调⽤dword_10003484指向的trampoline代码trampoline代码运⾏send函数的前三条原始指令(它被覆盖来安装钩⼦)trampoline跳回send函数第五个字节,从⽽使sned函数可以正常运⾏代码做了什么: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@的邮箱地址说明恶意⽂件确实如我们分析的那样起作⽤了A9.怎样⽤Wireshark动态抓获这个恶意代码的⾏为?A9.不许特别设置,直接抓包即可。通过Wireshark抓取的⽹络数据,可以看到⼀个假冒的邮件服务器以及Outlook Express客户端来总结下:lab11-2是⼀个到处installer函数的恶意dll。使⽤appinit_dll来永久安装恶意代码,⼤多数进程都会加载这个恶意代码。会通过预设的⽬标进程列表进⾏⽐较,如果运⾏在⼀个邮件客户端中,则在send函数安装内联钩⼦,实现⽤户态rootkit。(其实现⽅式是在send函数开始放置 ⼀个jmp指令,钩⼦运⾏⼀个函数,它会扫描send的发送的数据缓冲区,如果其中存在字符串RCPT TO,则会插⼊⼀个额外的RCPT TO,包含从解密后的中提取出的邮件地址,其⽬的是从⽬标邮件程序中复制所有邮件发送给恶意代码编写者)。参考:1.《恶意代码分析实战》
发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1688472819a141756.html
评论列表(0条)