*本文作者:tahf,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。
前言
作为一名沉迷于安全技术的小白,近期在对公司一台Win7客户主机进行安全应急响应时,捕获到一个64位dll形式的恶意程序,于是对其展开分析,收获很多。下面想结合取证分析的过程,从取证经过、动静态分析、破解加密等角度入手,与大家分享一些综合性的恶意程序分析方法,相互启发,相互学习。也许有些方法比较基础,望各位大佬勿喷~
提供dll样本以便大家茶余饭后分析着玩玩~
取证经过
某用户向SRC反映最近自己的邮箱账号被盗,作为应急中心的一员,我与团队成员一起对该用户的电脑进行了初步的取证和排查。
个人对个人主机排查的常用思路是:
可疑进程
网络流量
启动项
文件比对
但为了达到攻击持久化的目的,恶意程序往往会对系统进行驻留,因此对启动项进行检测排查是一个非常重要的环节。下面先推荐一款比较好用的常规自启动检测工具。
autoruns.exe
是一款出色的启动项目管理工具,作用就是检查开机自动加载的所有程序,例如硬件驱动程序,windows核心启动程序和应用程序。它比windows自带的msconfig.exe还要强大,通过它我们还可以看到一些在msconfig里面无法查看到的病毒和木马以及恶意插件程序,还能够详细的把启动项目加载的所有程序列出来。比如logon、explorer还有IE上加载的dll跟其它组件。
但autotuns也不是万能的,比如dll劫持等部分特殊的启动方式也无法检测到。作为取证人员,平时应该多多搜集和积累攻击者使用的奇淫巧技。
由于个人在对dll劫持方式有较多的了解和实践,同时结合文件比对,终于发现主机` C:\windows\` 目录下多了一个叫midimap.dll的动态库,基本可以断定为可疑程序,便对其展开分析。
动静态分析
首先我们对加载该dll的进程做了监控和分析。
dll劫持技术分析:
根据以往经验,可以利用工具和相关命令迅速确定是哪些进程加载了这个midimap.dll,推荐2种简便方法。
tasklist /m XXX.dll
以管理员权限运行` tasklist /m` 命令,可以获得所有进程中加载的动态链接库,也可以具体到某一个dll对应的进程,见下图。
Process Explorer
非常好用的一款增强型任务管理器软件,让使用者能了解看不到的在后台执行的处理程序,能显示目前已经载入哪些模块,分别是正在被哪些程序使用着,还可显示这些程序所调用的 DLL进程,以及他们所打开的句柄。
综上,可确定是explorer.exe进程加载了midimap.dll。
同时,我们利用一台干净的win7虚拟机对explorer.exe加载midimap.dll的过程进行了分析。使用Process Monitor软件对explorer.exe进程的行为进行了监控并设置了过滤条件,如下图。
可发现正常情况下,explorer.exe应加载位于` C:\windows\system32\` 目录下的midimap.dll,但由于exe加载dll有一定的搜索顺序,会首先在同目录下查找对应的dll文件。因此将恶意的midimap.dll文件放置在` C:\windows\ ` 目录下即可实现dll劫持。
行为分析
除了对恶意程序进行直接的静态分析和动态跟踪调试,我们还常使用其他工具和手段对恶意程序的行为进行监控和分析,尤其在对一些较难逆向的复杂程序进行分析时,结合行为监控将大大提高分析效率。这里也简单介绍2款工具。
Procmon
Process Monitor是一款能够实时显示文件系统、注册表与进程活动的高级工具,是微软推荐的一个系统监视工具。增加了进程ID、用户、进程可靠度、等等监视项,可以记录到文件中。它的强大功能足以让其成为你系统中的核心组件以及病毒探测工具。
文件监控软件
利用文件监控软件往往能对恶意程序的读写的文件的路径进行快速定位。
在对该恶意动态库进行分析时,我们使用Procmon工具对explorer.exe(加载恶意dll)进程的行为进行了监控,在敲击键盘和移动鼠标时,会伴有文件读写的行为,定位到` C:\Users\Windows\Appdata\Local\Microsoft\Windows\Caches\caches_version.db` 疑似为恶意程序产生的记录文件。
使用010editor打开caches_version,疑似加密的记录文件。
静态分析
用IDA对正常路径` C:\windows\system32\` 下的midimap.dll与在` C:\windows\` 下的恶意midimap.dll进行对比。可见恶意dll导出函数与正常dll的完全相同。
但对恶意程序进行初步分析后,可发现其实现了函数转发,将功能的调用转至正常路径下的动态库。
下图是从恶意dll中提取的字符串信息,根据经验,再结合函数导入表中调用` GetKeyState,GetClipboardData,GetWindowsTextA` 等函数,基本可以确定该恶意dll的大致功能,即为键盘记录工具。
目前,恶意dll的功能基本有了大致的判断,下面我们希望通过动态调试的方式来尝试将加密的记录文件caches_version中的内容进行解密。
破解记录加密算法
下一步我们希望通过静态分析+动态调试该dll的方式来破解记录的加密算法。
由于它是一个x64的dll,可使用x64dbg工具来调试(可切换至中文)。
分析发现恶意dll在dll被加载后,在DllMainCRTStartup中创建了一个线程,该线程为键盘记录运行的线程。
由于新创建的线程是恶意功能运转的线程,应跳入该线程中进行调试。这里遇到个小坑,一开始想通过x64dbg跳入新创建的线程中进行调试,在新线程地址设置了软硬件断点,但调试过程中总是异常退出,怀疑与x64dbg的Dllload64.exe有关。所以我自己用VS2010写了一个x64的exe使用loadlibrary来加载这个恶意dll。用x64dbg来调试该exe,在dll被load后,可在内存模块中找到这个dll,并在dll中搜索跨模块调用函数,在线程地址处下硬件断点,即可成功跳入线程中调试。
同时,可以搜索当前模块中的所有字符串,来找到其记录的路径。或者调试下CreateFile也可以。
该路径下caches_version.db文件就是记录击键结果的加密文件,与前期行为监控的结果一致。
我们若想还原出加密文件的内容,便可以对恶意程序中调用读写文件函数的上文进行分析。一般都是对信息加密后再写入文件。因此容易找出加密写入文件的函数,sub_180001820(LPCVOID lpBuffer),通过F5转换为伪代码,经过分析,对伪代码的功能进行了注释。
注意到一个长度为6的字符串,而且在代码中为引用了3次,后面两次均为生成加密表用。
重点看sub_1800025B0和sub_1800026B0两个函数(在sub_180001820被调用),动态调试下,可以发现sub_1800025B0函数每次生成的东西都是一样的。
再分析调试sub_1800026B0函数。
一样的问题,sub_1800026B0函数中每次生成的变换表也是一成不变的。也就是说我们通过动态调试得到的第2个表总是不变的,那么我们就可以直接将其提取出来,而不必分析前面生成它的算法,大大节省了时间!然后我从生成完这个表的之后开始调试,思路是用C语言来记录各个寄存器的操作,在栈中被加密和地址和加密用的表可以当作数组处理。
最终整理发现,所以被加密的字节永远都是异或0xE7来实现加密。所以解密其记录文件时,只要异或一个0xE7即可。之前看似复杂的加密过程,没想到完全没有加入随机性,最终其只不过是简单异或加密而已,这应该是攻击者在设计加密算法时的重大失误。解密后的文件如下图。
同时也说明在做加密时,一定要增加算法的随机性,比如可以根据前一个输入来生成加密的表,让前后有关联性。否则只是单字节一对一的加密,都可以不分析算法,直接试验一些输入再分析下输出即可搞定!(比如:在分析记录路径时,可以使用文件监控程序,然后不断敲击键盘,由于其程序需要不断想某文件中写入数据,所以文件监控很容易抓到这种频繁的改动,从而得出路径。在加密方面,可以先判断其是否是单字节一对一变换,这种可以通过连续敲入10个字母a,10个字母b来验证,如果加密记录结果中有连续出现10个同样的字节,说明其加密很有可能是单字节一对一变换。那么就很容易绕过其加密算法实现解密。)
感悟
这次是自己第一次分析并调试x64的dll,既积累了分析dll劫持的方法手段,又对x64dbg工具有了更多的实践,并填补了跳入线程调试的小坑。作为一名踏上安全之路的技术小白,在低头忙于手头工作的间隙,抬头眺望远方,深感安全之路漫长曲折。虽然在学习和实践技术时总会跳入各种坑,也常常被难题卡住,一路艰难困苦。但只要不放弃,不忘初心,总有一天当你蓦然回首,会发现之前挖过的坑,熬过的夜,吃得的苦,受过的寂寞都是一名安全从业者路途中最动人的风景~ 共勉~
*本文作者:tahf,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。