导语:这篇文章的主题是Malwarebytes CrackMe——我最近创建的恶意软件分析挑战题。这个挑战最初是为了内部训练目的而设立的,通过Twitter发布后引发许多积极的响应。感谢所有发送Write Up的人!
这篇文章的主题是Malwarebytes CrackMe——我最近创建的恶意软件分析挑战题。这个挑战最初是为了内部训练目的而设立的,通过Twitter发布后引发许多积极的响应。感谢所有发送Write Up的人!
当然,在解决这个挑战题目的过程中,许多人也是举步维艰,所以需要更多的解释和指导。所以,在本文中,我们将手把手为读者详解如何解决这个CrackMe。尽管这里的介绍已经非常详尽了,但是如果缺乏逆向工程经验的话,做起来可能还是有一定的难度。不过不要紧,如果您还有弄不明白的地方,请不要犹豫,直接在评论中提问就好了。
虽然这个CrackMe相对来说比较简单,但是它仍然为读者展示了恶意软件通常使用的各种技术——这对于恶意软件分析的新手来说,仍不失为一个很好的练手机会。像往常一样,文中所演示的解决方案只是各种可能的方案之一。
本文涉及的技术
我们想通过该CrackMe砥砺读者的下列技术/技巧:
· 注意常见的免杀技巧(反调试、反vm等),以绕过防病毒检查
· 检测经过异或方式混淆过的payload,并对其进行解码
· 加深对RunPE技术的基本理解
· 寻找调试/加载shellcode的方法
使用的环境和工具
在分析环境方面,我使用的是安装在Virtual Box中的32位Windows 7系统,并连接了Internet。
在分析过程中,我使用了以下工具:
· 静态分析:IDA
· 动态分析:ImmunityDbg/OllyDbg/x64dbg
· PE-bear
· Fiddler
第一阶段
当我们运行CrackMe时,首先会看到如下所示的标语:
如果拿到一个下列格式的旗标,该CrackMe的破解就算成功了:
flag{…}
这里没有任何密码提示——我们只能看到屏幕上的失败提示。要想了解更多信息,唯一的方法就是查看其内部代码。为此,我将借助IDA软件来进行分析。
寻找关键变量
由于代码没有经过混淆处理,所以经过一番检查之后,我们可以很容易地找到这个信息:
这里的关键是要找到AL注册表的值(AL=0会导致失败)。这个值是在上面函数sub_4014F0中进行设置的。下面,让我们进入函数,看看它到底在哪里:
我们看到,这里有一个变量(IDA自动将其命名为szUrl,暗示它可能被用作URL),并且它会被传递给一个函数sub_403380。之后,这个函数的输出(就目前来说,我们可以猜测它是一些校验和数据)将与硬编码的输出进行比较。如果两者相匹配的话,AL被设置为1。所以,我们的目标是为szUrl填充一些适当的数据,以便使其校验和为0x3B47B2E6。
寻找相关的引用
首先,让我们来看看变量szUrl的外部引用(xref),从而了解其使用方式以及在哪里进行的设置。我们可以通过在IDA中按组合键CTRL+X来查找这些引用:
正如你所看到的那样,代码中的三个地方引用了这个变量。第二个(高亮显示的)引用来自我们当前所在的地方(szUrl被传递给校验和函数进行相应的计算的地方)。
该变量是如何使用的?
第三个外部引用可能会涉及到这个变量的用法。所以,让我们仔细看看:
进入函数sub_4033D0,会看到有一些与读取给定URL内容有关的API调用,例如:
以及:
我们现在可以肯定的是,变量szUrl(如果能正确填写其值的话)是用来从互联网上下载某些东西的。
变量是如何填充的?
现在,让我们考察第一个引用,并找出szUrl的值到底来自哪里:
我们可以看到,它是传递给函数sub_4031C0的参数之一。这个函数也需要用到一个DWORD数组。接下来,让我们来看看这个函数的内部代码。我们可以发现,它使用了Windows Crypto API:
就像您看到的那样,传递给它的内容将通过Windows API使用AES算法进行解密。
根据参数的传递顺序,我们很容易猜到这个函数是用于对传入的缓冲区(DWORD数组)数据进行解密的,而szUrl将被用来存储输出结果。所以,我们唯一需要关心的是获取用于解密的有效密钥。这样,我们就能得到一个校验和为0x3B47B2E6的相应URL了。
寻找解密密钥
该密钥来自于另一个缓冲区的哈希值,并作为函数参数之一进行传递。我们可以看到,这里的Windows Crypto API就是用来计算哈希值的。这里使用的哈希函数是SHA256(算法ID:0x800C = CALG_SHA_256(链接地址:https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx)):
这个哈希函数用来生成AES128密钥(算法ID:0x660E = CALG_AES_128(链接地址:https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx)):
我们的研究发现,作为密钥的基础的缓冲区是作为第四个参数传递给函数的:
我们把它命名为key_buf,并弄清楚了它是从哪里传递给这个函数的:
同样,通过这个外部引用,我们可以了解到它是在哪里进行设置的详细信息:
我们发现,整个缓冲区是由各种函数设置的DWORD所组成的。接下来,让我们来逐个考察这些函数。
现在,我们要做的事情变得越来越简单:我们进行各种环境检查,也就是恶意软件常常用来识别是否在受控环境中运行的那些检查。例如,检查是否在调试器下运行:
虽然恶意软件检测到在调试器下运行的时候通常会终止执行,但就本例来说,情况正好相反。因为,每通过一项检查,就会为缓冲区添加相应的一段数据,而我们需要捕获所有的数据!
我们可以通过跟踪每个检查并进行相应的修改(删除条件跳转)来达到这个目的,因为这样就能无条件地将相应的数据添加到缓冲区了。当然,你可以使用IDA完成修改任务(链接地址:http://resources.infosecinstitute.com/applied-cracking-byte-patching-ida-pro/#gref),但恕我直言,这样很不方便。所以,我通常会借助于一些其他的工具(如OllyDbg或PE-bear之类的调试器)来进行修改,而IDA只是用于查找分支。
例如:删除PE-bear中的条件检查:
根据检查的偏移量(CTRL+R)进行跳转:
选中十六进制视图中的相关字节,然后进行修改:
结果:
在跟踪并删除所有检查之后,我们可以将修补后的文件保存:
当部署这个修改后的版本(链接地址:https://www.hybrid-analysis.com/sample/71f4450d411d8d721f18e75713a5663299b3d770ffef61177e45b48cf3896d32?environmentId=100)的时候,我们会看到一些进度信息!例如,屏幕上将显示信息“You are on the right track!”。同时,我们还会看到有一些东西正在进行解压处理。
小结
在本文中,我们详细介绍了解决Malwarebytes CrackMe挑战第一阶段任务的相关方法,如查找关键变量和引用,如查找关键变量和引用,了解变量的用途和填充方式等。在下一篇文章中,我们将继续为读者详细介绍完成第二阶段任务的具体过程。