写在前边
1.1 识别oep
在本节中,我们将了解识别打包二进制文件中的oep的技术。在下面的截图中,在pestudio中检查打包的二进制文件,显示了许多表明该文件是打包的指标。包装好的二进制文件包含三个部分:upx0、upx1和.rsrc。
pestudio网址:
https://www.winitor.com/
从截图中,我们可以看到打包二进制文件的入口在upx1部分,所以执行从这里开始,这部分包含解压存根,将在运行时解压原始可执行文件。
一个指标是upx0部分的原始大小为0,但虚拟大小为0x1f000;这表明upx0部分不占用磁盘上的任何空间,但它占用了内存空间;具体而言,它占用了0x1f000字节的大小(这是因为恶意软件在内存中解压了可执行文件,并在运行时将其储存在upx0部分)。另外,upx0部分具有读、写、执行权限,很可能是因为在解压原始二进制文件后,恶意代码将在upx0中开始执行。
另一个指标是打包的二进制文件包含混淆的字符串,当在ida中加载二进制文件时,ida识别出导入地址表(iat)在一个非标准的位置,并显示以下警告;这是由于upx打包了所有的部分和iat。
该二进制文件仅由一个内置函数和5个导入函数组成;所有这些指标都表明,该二进制文件是打包的。
为了找到oep,你需要在打包的程序中找到将控制权转移到oep的指令。根据打包程序的不同,这可能很简单,也可能很有挑战性;通常我们会关注那些将控制权转移到一个不明确目的地的指令。检查打包的二进制文件中的函数流程图,可以看到跳转到一个位置,这个位置被ida用红色标出。
红色是ida表示它不能分析,因为跳转目的地不明确。下面的屏幕截图显示了跳转指令。
双击跳转目的地(byte_40259b)显示,跳转将被带到upx0(从upx1)。换句话说,执行时,恶意软件在upx1中执行解压存根,解开原始二进制文件,复制upx0中的解压代码,而跳转指令很可能将控制权转移到upx0中的解压代码(从upx1)。
在这一点上,我们已经找到了我们认为会跳转到oep的指令。下一步是在调试器中加载二进制文件,在执行跳转的指令处设置断点,并执行到该指令为止。为了做到这一点,二进制文件被加载到x64dbg中(你也可以使用ida调试器并遵循同样的步骤),并设置断点,执行到跳转指令。如下面的截图所示,在该跳转指令处暂停执行。
现在我们可以假设恶意软件已经完成了解包;可以按一次f7(步入),这将到地址0x0040259b的原始入口点。在这一点上,我们是在恶意软件的第一个指令(解包后)。
现在我们已经找到了oep,下一步是将进程内存转储到磁盘。为了转储进程,我们将使用一个名为scylla的工具;它是一个转储进程内存和重建导入地址表的伟大工具。
scylla网址:
https://github.com/ntquery/scylla
x64dbg的一大特点是它集成了scylla,可以通过点击插件|scylla(或ctrl i)启动scylla。要转储进程内存,当执行在oep处暂停时,启动scylla,确保oep字段被设置为正确的地址,如下图所示;如果没有则需要手动设置,并点击转储按钮,将转储的可执行文件保存到磁盘(在这个例子中,它被保存为packed_dump.exe)。
当把转储的可执行文件加载到ida时,我们会看到整个内置函数列表(之前在打包的程序中是看不到的),函数代码也不再被混淆,但仍然看不到导入,api调用显示的是地址而不是名字。为了克服这个问题,需要重建打包后的二进制文件的导入表。
要修复导入表,回到scylla,并点击iat自动搜索按钮,它将扫描进程的内存以找到进口表;如果找到,它将用适当的值填充va和大小字段。要获得导入的列表,请点击get imports按钮。使用这种方法确定的导入函数的列表显示在这里。有时,我们可能会注意到结果中的无效条目(条目旁边没有勾号);在这种情况下,右击这些条目,选择cut thunk来删除它们。
在使用上一步确定导入的功能后,我们需要将补丁应用到转储的可执行文件(packed_dump.exe)中。要做到这一点,点击fix dump按钮,这将启动文件浏览器,可以选择之前转储的文件。scylla将用确定的导入函数修补二进制文件,并将创建一个新的文件,文件名在末尾含有_scy(例如packed_dumped_scy.exe)。现在,当在ida中加载打过补丁的文件时,我们会看到对导入函数的引用,如图所示。
当我们处理一些打包器时,scylla中的iat自动搜索按钮可能无法找到模块的导入表;在这种情况下可能需要手动确定导入表的开始和导入表的大小,并在va和大小字段中输入。
02
自动拆包
有各种工具可以让我们解开用upx、fsg和aspack等常见打包器打包的恶意软件。自动工具对于已知的打包器是很好的,可以节省时间,但请记住,它可能并不总是有效的;这时,手动解包技能将有所帮助。
reversinglabs的titanmist是一个伟大的工具,由各种打包器签名和解包脚本组成。
titanmist网址:
https://www.reversinglabs.com/open-source/titanmist.html
*左右滑动查看更多
在下载并解压后,我们可以使用这里显示的命令针对打包的二进制文件运行它:
-i 指定输入文件(打包文件)
-o 指定输出文件名
-t 指定解包器的类型
在后面提到的命令中,titanmist是针对用upx打包的二进制文件运行的;注意它是如何自动识别打包器并执行解包过程的。该工具自动识别了oep和导入表,转储了进程,修正了导入,并将补丁应用到转储的进程中。
c:\titanmist>titanmist.exe -i packed.exe -o unpacked.exe -t python
match found!
│ name: upx
│ version: 0.8x - 3.x
│ author: markus and laszlo
│ wiki url: http://kbase.reversinglabs.com/index.php/upx │ description:
unpacker for upx 1.x - 3.x packed files
reversinglabs corporation / www.reversinglabs.com
[ ] debugger initialized.
[set. ] hardware breakpoint
[00407000. ] import at
[00407004. ] import at
[00407008.[removed] [x] import at 00407118. ] import at
[0x0040259b. ] oep found:
[ ] process dumped.
[0x00407000, size 00000118. [x] imports fixed. ] iat begin at
[ ] no overlay found.
[ ] file has been realigned.
[0. ] file has been unpacked to unpacked.exe. [x] exit code:
█ unpacking succeeded!
*左右滑动查看更多
另一个选择是使用ida pro的通用pe解包器插件。这个插件依赖于对恶意软件的调试,以确定代码何时跳转到oep。要调用这个插件,将二进制文件加载到ida,并选择edit | plugins | universal pe 解包器。
关于该插件的详细信息,请参见:
https://www.hex-rays.com/products/ida/support/tutorials/unpack_pe/unpacking.pdf
*左右滑动查看更多
运行该插件可以在调试器中启动程序,并且它试图暂停程序,只要打包器完成解包。在ida中加载upx打包的恶意软件(与手动解包中使用的样本相同)并启动插件后,会显示以下对话框。
在下面的截图中,ida将开始地址和结束地址设置为upx0部分的范围;这个范围被视为oep范围。换句话说,当执行到这一段时(从upx1开始,它包含解压存根),ida将暂停程序的执行,给你一个机会采取进一步的行动。
在下面的截图中,注意ida是如何自动确定oep地址,然后显示以下对话框的。
如果点击 "是 "按钮,执行将被停止,进程将被退出,但在此之前,ida将自动确定导入地址表(iat),它将创建一个新段来重建程序的导入部分。在这一点上,我们可以分析解压后的代码。下面的屏幕截图显示了新重建的导入地址表。
如果不点击yes按钮,而是点击no按钮,那么ida将在oep处暂停调试器的执行,在这一点上可以调试已解压的代码或手动转储可执行文件,通过输入适当的oep(如前边提到的手动解压),使用scylla等工具修复导入。
在x64dbg中可以使用解包脚本执行自动解包。
获取网址:
https://github.com/x64dbg/scripts
要解包,需确保二进制文件被加载并在入口点暂停。根据所处理的打包器,需要在脚本窗格上点击右键,然后选择加载脚本|打开(或ctrl o)来加载相应的解包脚本。下面的屏幕截图显示了upx解包器脚本的内容。
加载完脚本后,通过右键点击脚本窗格并选择运行来运行该脚本。如果脚本成功解压,就会弹出一个消息框说脚本完成了,执行将在oep处暂停。下面的截图显示了运行upx解包脚本后,在oep处自动设置的断点(在cpu窗格中)。现在,我们可以开始调试解压后的代码,或使用scylla来转储进程并修复导入的代码(如前文的手动解压中所述)。
除了前面提到的工具外,还有其他各种资源可以帮助我们进行自动解包。详情请参见:
ether unpack service:
http://ether.gtisc.gatech.edu/web_unpack/
fuu(faster universal unpacker):
https://github.com/crackinglandia/fuu
*左右滑动查看更多
四
总结
恶意软件作者使用混淆技术来掩盖数据,并从安全分析人员那里隐藏信息。在这一章中,我们研究了恶意软件作者常用的各种编码、加密和打包技术,我们还研究了不同的策略来消除数据的混淆。后续我们将会继续在公众号上介绍内存取证的概念,你将了解如何使用内存取证来调查恶意软件的能力。欢迎关注安恒信息安全服务,精彩内容不走丢~