加壳与解包
加壳软件可以帮助你对可执行文件进行压缩,就跟zip文件差不多。一般来说,当你在使用zip文件时,需要手动进行解压缩。但是对于加壳来说,它会在可执行文件的代码中添加一部分不会被压缩的“运行时封装器”代码。当你运行这个可执行文件时,这部分未被封装的代码将会对可执行文件中其他已被封装的恶意代码进行解包并运行。
识别加壳
如何识别这种加壳的恶意软件呢?其中一种方法就是检查其中的字符串信息,但是加壳后的可执行文件中并没有大量字符串可以查看。你也可以对代码中import的类和库进行分析,但加了壳的可执行文件并不会显示这部分内容,这样可以增加逆向分析的难度。因此,为了对加壳的恶意软件成功进行逆向分析,我们需要对其一直调试直到发现了未压缩的代码为止,然后对导出的可执行文件代码进行分析。
这里可以使用“ESP技巧”,也就是ESP寄存器。我们可以利用这种技术在ESP寄存器中设置硬件断点,当我们转移到改断点时,也就是到达了程序的入口点(OEP)。接下来,我们就可以将剩下的可执行文件导出,并得到解包后的可执行文件代码了。
解包夺旗游戏
我们专门开发了一个小程序来演示如何手动解包可执行文件,你可以点击【这里】获取。其实这就是一个夺旗小游戏,当你找到了正确的密码之后,你需要输入并尝试拿到Flag。你可以在Radare2中通过比对字符串数据来寻找到密码,或者你也可以直接使用“strings”命令来搜索,但如果程序加了壳的话,又该怎么办呢?因此,我们这里使用了免费的UPX封装器来对代码进行封装加壳,它的解包过程也比较简单,所以它是一款非常适合学习的工具。祝大家好运!
过程分析
当我们使用rabin2运行封装的可执行程序并查看import信息时,我们可以看到这里几乎没有什么信息,而且字符串也看不出什么字面意思:

很明显,这是一个经过封装的程序。我们可以PEiD工具来查看它所使用的封装器信息:

你可以看到,这里使用的是UPX封装器。当然了,这种封装器拆封起来非常简单,你也可以直接下载UPX拆封程序来进行解包。但我们这里要演示的是如何手动实现这个过程,所以接下来我们在x64dbg中启动程序,然后按下F9,直到我们到达应用程序的入口点位置。X64dbg会直接用“EntryPoint”对入口点进行标记,这里我们使用了pushal指令对入口点设置识别符。

下一步,我们需要按下F8或F7键,或者按下“step over”或“step into”按钮。然后需要右键点击右侧的ESP寄存器,并选择“Follow in Dump”。

接下来,我们需要选择x64dbg底部导出数据的前四个字节,然后在DWord中设置一个硬件访问断点。

接下来,我们就可以按下F9键来重新运行应用程序了,当运行到硬件端点位置时,程序将暂停运行。我们在断点后设置了一个popal指令,并用它来表示我们仍在正确的执行路径上。我们还可以看到,结尾部分跳转到的0x0040c483就是解包后可执行文件的结尾部分。

跳过jmp指令之后,我们就到达了程序的入口点位置。

下一步就是要对导出的应用程序进行分析了,按下CTRL+A键并开始分析汇编代码,这样可以确保到处的汇编代码不会出现错误。现在,我们可以按下CTRL+I键或在插件栏选择Scylla来开始导出程序。

现在,点击“IAT Autosearch”按钮来让程序自动帮我们找出可执行程序的导入地址表(IAT)。点击了“Get Imports”按钮之后,我们将会得到这个可执行文件引用的第三方库。

现在,点击“Dump”按钮并保存导出的可执行程序。但是当我们运行这个可执行文件时,却出现了下图所示的错误:

这是因为解包后的可执行文件中不包含之前可执行文件中的IAT,所以我们还需要对其进行修复。返回Scylla界面,点击“Fix Dump”按钮,选择刚才导出的可执行文件,并点击确定。修复成功后,可执行文件的文件名后面会加上一个“SCY”,现在它就可以正常运行了。



然后重新在Rabin2中打开这个解包后的可执行程序,并尝试导出其中的设置信息。

如果你使用密码“this_is_password”来运行我们的应用程序,你将会看到如下所示的界面:

恭喜你成功拿到了Flag!
资源获取
UPX_Proj_Packed.exe:【点击阅读原文获取】
* 参考来源:goggleheadedhacker,FB小编Alpha_h4ck编译,转载请注明来自FreeBuf.COM