剖析与检测Babuk勒索软件的加密技术
作者:Sylvain Pelissier和Antonio De La Piedra(Kudelski安全研究团队)
Babuk(又称Babyk)勒索软件在两年前被发现。这是一个有趣的案例,因为在感染华盛顿特区大都会警察局后,操作者中的一名成员于2021年7月在一个论坛上发布了该勒索软件的源代码。然而,这些源代码也帮助其他组织创建了该勒索软件的克隆版本,如Rook或PrideLocker。Babuk后来被复制到一个GitHub存储库中。从研究的角度来看,研究源代码是很有趣的,在本文中,我们探讨了用于构建该勒索软件的加密算法选择。
尽管Babuk勒索软件是两年前发布的,但最近仍被用于一些VMware ESXi系统上,在利用我们最近描述的OpenSLP漏洞后加密虚拟机。Babuk还通过电子邮件钓鱼、未受保护的RDP部署和未修补的漏洞传播,特别是利用了Microsoft Exchange中的三个漏洞,分别被标识为CVE-2021-34473、CVE-2021-34523和CVE-2021-31207。
操作概述
Babuk勒索软件有三个不同的版本:一个用于ESXi,一个用于NAS设备,一个用于Windows。Windows和ESXi版本用纯C++语言编写,不导入许多外部库。这使得它非常便携,可用于许多不同的操作系统。NAS版本用Go语言编写,除了x86设备外,还允许用于ARM设备的二进制文件。
加密算法包括两个步骤:
第一步使用非对称加密。这意味着程序在加密程序中嵌入攻击者的公钥,但不包含相应的私钥,私钥留在攻击者的机器上。使用非对称密钥算法可以防止受害者恢复攻击者的私钥,因为私钥从未出现在受害者的设备上。首先,它使用Diffie-Hellman密钥协商算法在攻击者公钥和文件临时密钥之间派生一个32字节的共享秘密。
第二步使用对称加密。共享秘密被哈希处理以获得一个32字节的密钥,用于流密码进行高速文件加密。文件加密后,每个文件的公钥被写入文件末尾。
我们注意到,对于ESXi版本,每次操作后,密钥或算法状态等敏感信息都会用memset函数清除。这防止了典型的内存取证操作,如我们过去针对GPG所展示的操作。
非对称加密
在加密算法的第一步中,生成一个临时密钥。对于ESXi版本,这是通过为每个加密文件调用一个具有误导性名称的函数csprng来完成的:
|
|
该函数包括读取/dev/urandom设备。这可以看作是椭圆曲线Diffie-Hellman(ECDH)算法中使用的文件私钥。该值存储在变量u_priv中。它后来用于生成存储在变量u_publ中的文件的公钥。攻击者公钥也存储在代码中的全局变量m_publ中。
ECDH通常用作两方之间的密钥协商机制。也就是说,它允许在两方之间生成共享密钥。然后,这个共享密钥可以用于加密(通常使用对称算法)两方之间的消息。最初在DH中,当一方a(通常是Alice)和另一方b(通常是Bob)想要通过不安全通道通信时,执行以下操作:他们同意使用一个阶为的整数乘法群(例如RFC3526),其中是素数,生成元或基点为。每个用户都有一个密钥对,即Alice的秘密密钥和公钥计算为,Bob的秘密密钥和公钥部分为。在通道上,每方交换和,并分别使用和和他们的秘密密钥计算共享密钥和。类似地,DH可以在椭圆曲线上执行(即在EC上的点的乘法群上),使用生成元,使用点乘法而不是模幂运算和,共享密钥为。在Babuk的这个特定案例中,ECDH算法在Curve25519上实现。
勒索软件重用了Adam Langley的代码用于Windows和ESXi版本的曲线实现,并使用Go加密包的实现用于NAS版本。这个选择很聪明,因为这条曲线是最快的曲线之一,并且设计为不易出现实现错误。
在curve25519上执行ECDH操作使用curve25519-donna实现,通过以下调用:
首先,我们需要生成一个32字节的私钥。 给定曲线的生成元和我们的私钥,我们可以生成我们的公钥为:
|
|
其中mypublic是32字节秘密密钥mysecret的最终公钥。
当生成共享密钥时,例如对于Bob的参数,我们调用curve25519_donna函数为:
|
|
例如,theirpublic是Bob的参数,mysecret是秘密密钥,如果我们例如是Alice。
为什么Babuk使用非对称加密
在勒索软件的ESXi版本中实现为:
|
|
对curve25519_donna函数的第一次调用通过将先前生成的文件私钥与曲线的基点(或生成元)进行标量乘法来计算文件的公钥,该基点被定义为Curve25519上的标准生成元。第二次调用通过将文件私钥与攻击者的公钥进行标量乘法来生成共享秘密。生成的共享秘密通常使用哈希函数(如SHA-256)进行处理。
在这种背景下很难看出为什么使用ECDH。我们可以将恶意软件操作者视为一方Alice,它与加密每个文件的代码部分生成共享密钥。在加密操作结束时,执行文件加密的一方的共享密钥被擦除,仅由恶意软件操作者保留。
文件公钥被写入文件末尾,以便在受害者支付赎金时能够解密它。确实,解密程序包含攻击者的私钥。要解密加密文件,它读取文件的公钥并再次派生共享秘密,从而允许文件解密。
我们强调,支付赎金的受害者将收到一个解密程序,因此将能够提取攻击者的私钥。这意味着如果攻击者为另一个受害者重用相同的密钥,加密程序中的公钥将与解密程序中已经观察到的私钥匹配。例如,Babuk Windows版本包含一个文件s.txt,由一对私钥和公钥组成。我们可以用简单的Python命令验证,确实,私钥生成了相应的公钥。
|
|
为了允许进一步的恶意软件研究,我们发布了一个Yara规则,仅基于使用的常量来识别Curve25519算法。这并不明显,因为Curve25519在其实现中不使用许多常量,我们的检测基于基点9后跟31个零和常量a24 = 121665。这与之前为PrideLocker制作的基于x86指令的Yara规则不同。
对称加密
对于对称加密,Babuk最初使用Chacha8流密码,但在泄露的源代码中,ESXi版本使用Sosemanuk,Windows版本使用HC-128,NAS版本使用Chacha20。这三者都是流密码,被eSTREAM项目选为高效和安全的流密码。这是一个有趣的选择,因为Sosemanuk和HC-128密码并不非常广泛。它们是纯软件实现,并且速度快。Sosemanuk在我的旧笔记本电脑上单核加密速度为388MiB/s。因此,它对于加密数据很快。它不依赖像Intel AES-NI这样的特殊指令。使用带有此类指令的AES在CTR模式下,OpenSSL基准测试速度为5427MiB/s,而Salsa20在同一基准测试中的速度为138MiB/s。选择Sosemanuk或HC-128算法可能是因为它们不为人所知,缺乏Yara规则进行检测,而AES、Chacha和其他密码已有现有规则。我们还实现了用于Sosemanuk流密码检测的Yara规则,并改进了Chacha20的检测规则。以下是在Babuk样本上结合现有规则使用此类规则的示例:
|
|
请注意,恶意软件中使用的所有算法都被正确检测到。我们希望这有助于研究人员更快地识别勒索软件中使用的加密算法。
结论
在这篇文章中,我们揭示了Babuk勒索软件中使用的加密技术,并解释了我们对算法选择的假设。我们还发布了一些用于检测的Yara规则。我们希望这有助于理解加密机制的内部工作原理,并协助未来对恶意软件的进一步分析。