在本系列的第一部分中,加密101:恶意软件分析师的底漆,我们介绍了恶意软件中使用的一些基本加密概念。如果您尚未阅读过,我们建议回复审核,因为为了能够完全遵循第二部分,我们的案例研究是必要的。在这项研究中,我们将通过行审查勒索软件Shione线的加密。

本案例研究的主要重点是完全理解加密过程的示例勒索制造器可以使用。我们正在使用Shione作为课程的实际部分,而不是因为它特别独特或使用任何新颖的技术,但只是相反的:它相对直截了当,并写入C#,这将使关键组件更容易。

加密方法

在前一篇文章中,我们谈到了勒索软件可以使用的几种不同的加密方法。它们包括:

  • 加密密钥在受害者计算机上本地生成,并发送到C2服务器。
  • 密钥是生成预发布并嵌入在赎金软件中的键。

对于这种特殊的样本,我们将显示第二种情况。加密密钥是脱机生成的,然后嵌入到恶意软件中,然后发送出攻击。

当我说加密密钥离线生成并嵌入时,我是指非对称密钥。我们将看到在这个勒索软件中同时使用RSA和AES加密算法。

AES是一种对称算法,这意味着用于加密的密钥也将用于解密。您可以将其视为加密和解密的密码。AES的密钥实际上是动态生成的,并存储在文件本身中。这个勒索软件的实际文件加密使用这种AES加密。

RSA是这个过程的非对称部分——预生成和嵌入部分。它用于隐藏对每个文件进行加密的AES密钥(密码)。这个恶意软件中只有RSA对的公钥,因为它只做加密部分。在勒索软件中,使用这种对称/非对称加密的组合实际上是很常见的。

主要加密功能

我们分析的样本是:

408A97AC8FB82398187FFE6D4C5937D7

跳过过去初始化和恶意软件的部分后枚举驱动器中的文件,(因为这是非常标准的,并且不需要任何额外的解释),我们将到下面的主要加密函数被称为CRTP(String路径)。

这个函数是从主目录枚举循环调用的,因此,它将为它找到的每个文件分别调用。它是程序中唯一调用任何加密api或随机数生成器的函数。这告诉我们,很可能会使用一个唯一的密钥来加密每个文件。

我想添加一个音符。如前所述,主加密密钥是脱机生成的,并由作者嵌入到恶意软件中。相比之下,如果这是在本地生成主键的ransomware类型,那么我们肯定会看到在CRPT功能之外的目录搜索循环之前调用Crypto函数。同样,这不是这种情况,这就是为什么我们跳过了这个恶意软件的初始化代码。

让我们走过CRTP功能的细节:

加密过程通过调用来开始:String text = program.createsalt(32);

这是一个用户定义的函数,只需调用标准加密API以生成32个随机数的数组。此功能实际上非常重要,因为此处随机字节数组稍后使用(密码)AES键进行加密。它将为受害者计算机上的每个文件提供唯一加密,因为每个文件生成新密钥。因此,即使用户的系统上有两个文件相同,它们也会有不同的密文。

细节CreateSalt函数

//函数program.createsalt(){rngcryptoserviceprovider rngcryptoserviceprovider = new rngcryptoserviceprovider();字节[]数组=新字节[size];rngcryptoserviceprovider.getBytes(阵列);返回convert.tobase64string(阵列);

这实际上是在整个恶意软件中生成的最重要的数字,因为它是来自赎金软件的购买密钥将允许您访问以便解密每个文件。

随机数发生器

在继续之前,我想简要地提到一些关于RNG(随机数生成器)的细节。

RNGCryptoServiceProvider是安全标准兼容随机数生成器的默认实现。它是一个更强大的加密随机数。这是一个薄弱的替代品system.random。它是一个更简单的计算,并且可以更容易地通过黑客或在我们的情况下复制一个恶意软件分析师。此外,还有一些使用System.Random的恶意软件作者,并且在这些情况下,有可能解密。RNG是作为分析师的东西,你应该注意,这就是为什么我认为它应该在这里提到。

我们得出结论,这个样本正在使用强大的rng,所以我们可以继续。

我们现在将跳过下一部分代码的详细信息,这只是过滤勒索软件想要加密的文件类型。很容易理解并在实际加密过程本身中没有发挥作用。

这现在将我们带来了下一个代码块,它使用相同的RNG内部函数创建另一个随机数组:

字节[] array = program.generaterandomsalt();

我不包括细节WeneraterAndomsalt()函数,因为它与前面的代码没有太大的不同。这个数组将用作主文件加密的salt,稍后将在代码流中解释。

接下来,勒索软件获取数组开头生成的第一个数字(文本变量),并调用一个函数对其进行加密存储:

string s = program.encryption(文本)

如上所述,该组数字实际上将被用作前进的AES关键。要清除,文本变量用作纯文本形式的键,但是被加密并加入到文件的末尾以进行存储。上面的流程图说明了这一点。

加密功能

这是加密在攻击期间的工作原理。勒索软件:

  • 生成RSA公共和私钥(本地或预先生成的离线)。
  • 生成随机数作为输入(密码),用于生成AES密钥。
  • 使用新创建的AES密钥加密文件。
  • 使用RSA公钥加密AES密钥。
  • 在加密文件中追加加密的AES密钥。

以下是威胁演员在赎金后解密文件的解密。他们:

  • 找到加密文件。
  • 搜索文件以获取加密的AES密码。
  • 读入内存,以获取AES密钥的加密密码种子。
  • 使用RSA私钥解密AES密码。
  • 使用此明文密码作为AES Defrypt的输入。

细节加密(文本)功能如下所示。

[突出显示的线是勒索软件在其中拉嵌入式公钥的位置。]

ransomware通过拍摄嵌入在可执行文件本身的公钥来启动,并使用它使用RSA 2048加密传递的随机数(文本AKA,AES密码密码)。

请注意:此功能与实际文件加密无关。它只是勒索软件用来将其AES密钥隐藏给用户。在实践中,可以完全跳过此功能,对实际文件加密的功能没有影响。

剥夺这一点的重要事项是公钥嵌入恶意软件中。这意味着RSA密钥未动态生成,这意味着在恶意软件服务器端生成RSA公共和私钥对,因此只有作者可以访问解密密钥。

执行加密

此时,勒索软件拥有它需要对当前文件执行唯一加密所需的一切。在该特定情况下使用的加密是CBC模式中的AES(密码块链接)。这意味着它将循环通过要加密的原始文件的数据循环,并且文件的数据将在块中加密或块。循环的每次迭代都是从原始文件加密的顺序数据块。

For (i = 0;我和音箱;音箱;音箱;音箱;肝移植;num;i += array3.Length) {int len = fileStream. length;读(array2 0 array2.Length);array3 = program.aes_(array2,bytes,array,len);fileStream.Seek((长)我,SeekOrigin.Begin);文件流。写(array3 0 array3.Length);}

让我们深入进入这个功能:array3 = program.aes_(array2,bytes,array,len);因为这将是实际执行文件加密的函数。

将参数过于AES_函数,Array2.是原始文件数据,字节是在开头生成的“密码”随机数Program.Createsalt(32);数组第二个随机数组是否生成为salt,用于创建加密过程Program.generaterandomsalt();当然,Len.是要加密文件的数据的长度。

您可以在此处看到,实际加密文件的方法是AES。该算法使用盐进一步随机化“PassionBytes.“(AES密钥)通过了。这是AES的标准。AES CBC模式需要初始化的初始化向量,您可以在代码中看到它。功能的功能generateIV ()是另一个随机数生成器。然后对原始文件数据逐块执行AES加密。每个被加密的区块实际上使用了一个不同的IV。这将被附加到该区块加密字节的末尾。这很重要,因为解密算法需要知道当前块使用了什么IV。

现在在Crypt函数的最终阶段,文件已完全加密后,勒索软件通过将盐值写入文件而启动。然后它写出了RSA加密AES密码,最后是实际加密的文件数据(密文)。同样,此密文还包括每个块的盐值。

当解密软件运行时,它将循环每个文件并读取salt值。然后,它将使用嵌入到解密器中的RSA私钥解密AES密钥。最后,它将读取加密的文件数据和IVs。它现在有了逆转加密所需要的一切。

结论

在本案例研究中,我们详细介绍了标准文件加密器的功能。收听的第三部分加密101系列,我们将覆盖加密中的弱点,分析了实现弱加密的勒索软件的示例,并讨论如何创建文件解密器。