导语:本文将会为读者详细介绍如何根据勒索软件加密代码的弱点来设计相应的解密程序。
在本文的上篇中,我们通过静态分析和动态调试技术,深入考察了勒索软件样本中加密代码的内部工作机制,找出了其主要的弱点。在本文的下篇中,我们将会为读者详细介绍如何针对加密代码的弱点,来设计相应的解密程序。
加密代码弱点综述
目前,加密代码的分析阶段基本完成了。除了我们在函数10001CC0中提到的循环中之外,我们没有在别的地方看到对rand()或srand()的调用,所以我们主要把精力放到这个循环中就行了。正如我们所看到的,这个函数被调用了3次。
这是有道理的,因为在这个恶意软件中共生成了3组随机字符串。
· AES密钥
· 受害者ID
· 文件扩展名
第一次调用该函数,是用来生成随机字符串,该字符串将来会用于密钥。通过调试,我们发现该字符串所在内存区域被传入生成AES密钥的函数中,这说明前面的判断是正确的。第二次调用该函数,是生成受害人ID。如何确认这一点呢?主要是因为通过edx传入的参数的长度是0x0C或12。
实际上,如果我们仔细比较就会发现,该勒索软件对应的网站提供的受害者ID编号的长度,也是12位。
这个随机字符串生成器函数的最后一次调用,是用来生成文件扩展名。
这段代码生成的三组随机数种子之差非常小,由此可以假定,它们的执行时间可能只相差几秒。
深入理解加密代码的安全弱点
那么,上面所有这一切对我们意味着什么呢?该勒索软件的作者使用了相同的随机数生成逻辑来生成文件扩展名和受害者ID(其实这些就意味着AES密钥),这就是它的弱点所在,也是我们的突破口。如果情况并非如此,(如果他们使用固定的静态扩展名,而使用其他方式生成受害者ID的话),我们就很难破解这个加密系统了。
为什么这么说呢?因为如果采用生成AES密钥并测试加密文件的话,则需要进行数千次迭代(由潜在的种子值的数量决定),这明显是不可行的——计算时间太长了。 所以,我们必须找到与受害者ID匹配的字符串,好在这是一个相对较快的计算操作;找到后,我们就可以开始在这个基础上,以逐步递增的方式来生成和测试AES密钥,因为我们知道,受害者ID和AES密钥生成时间之差不超过100秒。所以,生成100次AES密钥的方式是可行的,所用时间也是可以接受的。
如果受害者ID和扩展名也不是随机字符串,那么只有在知道大致准确的感染时间的情况下,才能够顺利解密文件。
如果知道大致感染时间的话,可以按照上一篇文章中介绍的方法,以这段时间内的系统时间(以秒为单位)作为种子,进行有针对性的测试。不过,这要求每个受害者在受到感染时都必须能够在一两分钟内弄清情况,并采取相应的措施。对于被勒索软件袭击后能够编写解密程序的公司来说,这是一个非常好的解决方案;但是,若想为所有受害者提供通用工具的话,则需要借助于hasherezade提供的方法。
回到我们的例子,如果我们能够找到用于生成文件扩展名或受害者ID的种子值(以秒表示的系统时间),那么自然可以通过循环迭代,在这些种子值的基础上逐步往回找,就能在较短的时间内找到用于生成加密密钥的种子值。这种破解方法之所有效,同样是因为该软件会先调用time64和srand函数来生成AES密钥,不久之后,又调用了两次来生成另外两个随机字符串。
那么,接下来该咋办呢?现在,我们必须想出一种方法来找到生成受害者ID或扩展名的确切时间(以秒为单位)。
如何设计解密算法
作为算法头脑风暴的最后一部分,我将一步一步地介绍算法需要做什么,以及为什么要这么做。
1.通过以秒为单位的系统时间创建种子值,并以它为参数调用srand()。
2.从勒索信息中提取受害者ID、加密文件扩展名。
3.从现在调用srand()的时刻开始,不停递减计数器(就是说,每次减1秒),
· 每次迭代srand()时,都要像勒索软件那样调用rand()/在字符集中查找子字符串。
· 生成一个12个字符的字符串,并与提供给用户的受害者ID进行比较。
· 如果不匹配,则递减系统时间并重试。
· 如果匹配,这意味着我们已经找到了第二个受害者ID。 因此,这个时间很可能与生成AES密钥的种子时间非常接近。这样,就可以将测试范围设置为100秒。
(我们知道AES密钥的生成时间与受害者ID生成时间非常接近,极有可能生成前者几秒钟后,就马上生成了后者)
现在,我们逐步递减时间指针,同时,对于每次迭代,我们实际上都会为AES密钥生成一个密码,并生成实际的测试AES密钥,接着使用该密钥对加密文件执行AES解密,然后将输出与已知的文件原始版本进行比对。
如果两者匹配,那么就意味着很可能找到了密钥,这样就可以用它来解密硬盘上的其他文件了。
如果两者不匹配,那可能意味着该种子碰巧生成了重复的数字序列。所以,可以回过头来,重复前面的步骤,逐步递减以秒为单位的系统时间值。
需要提示的是,我们从解密工具运行的时间开始,每次递减1秒,直到找到受害者文件的加密时刻为止,所以这两个时间差越大,工具花费的时间就越长。
但是,值得注意的是,生成一个由12个字符组成的随机字符串并与受害者ID进行字符串比较的操作其实非常快,为什么这么说呢?打个比方,就算是迭代500,000次,也用不了多长时间,因为每秒即使完不成1000次比较的话,完成100次总不成问题吧。所以说,即使文件是在一个月前被加密的,所需的破解时间也是完全可以接受的。
一旦匹配,计算密集的AES生成和解密操作只需执行100次就够了,甚至更少。这就是解密密钥搜索时间非常接近一个常数的原因。
小结
在本文中,我们不仅对恶意样本中的加密代码的工作机制进行了深入剖析,更重要的是,我们展示了加密方案中哪些安全弱点是可资利用的。我们详细分析了如何根据弱点设计解密程序的思路,下面,我们就要动手编写解密程序了,这些将在本系列的最后一部分中加以介绍。