欢迎来到安联智库seczk.com--做最好网安新媒体!!
快捷搜索:  热点  资讯  事件  漏洞  技术  攻防  

记一次与QNAPCrypt勒索软件背后黑手的攻防战

 

介绍

针对Linux操作系统的勒索软件在过去并不常见,不过现今网络犯罪分子们似乎有开始往这方向发展的趋势,且试图通过各种方法在这一领域中牟取利润。

近日,Intezer检测到了一起针对基于Linux文件存储系统(NAS服务器)的勒索软件行动,其目标是感染并加密文件以勒索赎金。Intezer将此勒索软件命名为QNAPCrypt(作者标记恶意软件的名称),QNAP是一家知名的NAS服务器品牌供应商。NAS服务器通常存储大量重要数据和文件,这也使得它们成为了攻击者眼中的一块肥肉。

目前,QNAPCrypt在所有主要的安全解决方案中的检测率都非常低。

本文的前两部分将简单解释下QNAPCrypt的工作机制,以及我们是如何通过恶意软件基础设施中的两个设计缺陷来暂时中止这场恶意行动的(不过也迫使攻击者部署了新的恶意软件样本)。最后,我们将对恶意软件进行详细的技术分析。

以下是Intezer对QNAPCrypt样本的遗传分析,仅供参考:

· ARM变种

· x86 变种

记一次与QNAPCrypt勒索软件背后黑手的攻防战

QNAPCrypt的工作机制

QNAPCrypt勒索软件的工作原理与其他勒索软件类似,不过也有几个明显区别:

1. 赎金票据仅作为文本文件包含在内,受害者屏幕上不会显示任何消息——这是理所应当的,因为受攻击的是服务器而不是终端。

2. 攻击者会为每个目标分配一个唯一的比特币钱包——这可以帮助攻击者避免被追踪。

3. 受害者受到攻击后,恶意软件会在文件加密之前从命令和控制服务器(C&C)请求钱包地址和公共RSA密钥。

我们是如何利用这场行动的?

记一次与QNAPCrypt勒索软件背后黑手的攻防战

为了进一步研究恶意软件及其行为,我们编写了一个脚本来伪造了一场大规模的感染。在对数百名“受害者”进行攻击后,我们发现了勒索软件架构中的两个主要的设计缺陷:

1. 比特币钱包列表是事先创建的,而且是静态的。也就是说,它不会为每个新受害者实时创建新钱包,而是从固定的预定列表中提取钱包地址。

2. 一旦分配完所有钱包,勒索软件将无法继续在受害者的机器中进行恶意操作。

在伪造了15批共计超过1,091次感染后,我们发现攻击者用完了钱包的份额,照理说接下来的感染过程也会随之结束,但之后几天,却出现了一个新变种,攻击者在其中更新了植入程序,绕过了基础设施中的设计缺陷,从而能继续他们的恶意行动。

新样本与前QNAPCrypt样本和Linux.Rex(一种Linux木马)之间都有大量代码重合,且这次使用了嵌入式静态钱包和RSA公钥。

技术分析

新样本中,首先新增的是一个静态链接的Golang二进制文件,它是用ARM架构的Go链接器构建的。在我们的整个研究过程中还确认有基于其他构架的变体,如x86 / x64。

Go二进制文件在被剥离时往往很难分析,因为剥离的静态链接二进制文件通常比动态链接二进制文件更难分析。

记一次与QNAPCrypt勒索软件背后黑手的攻防战

上图所示的这个二进制文件是一个Go可执行文件,可通过它的节头表中的节名查看。

如果能知道上图中红框突出显示的区域的位置(尤其是.gopclntab部分),就能够重建它们的符号名称和偏移量。方法如下图所示:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

想要进一步了解如何在Go二进制文件中填充函数名,我们强烈建议查看Tim Strazzere在GitHub中的演示和脚本

在检索Go函数名之后,分析二进制代码就变得简单很多,如下图所示可以突出显示应用程序的相关函数。不要忘记二进制文件的大小是4MB。

记一次与QNAPCrypt勒索软件背后黑手的攻防战

在对目录白名单和类似功能的参数进行了几次加密算法初始化和解析之后,恶意软件将向CNC发送一个GET请求,表明一个新的受害者已经被攻击,系统锁定正在发生:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

发送此GET请求后,恶意软件将尝试使用SOCKS代理协议版本5的客户端检索受害者密钥配置。

记一次与QNAPCrypt勒索软件背后黑手的攻防战

此代理将请求连接到洋葱的域名(.onion)。下图表示连接的相关数据包:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

通过代理成功连接到洋葱域后,将完成对勒索软件REST API的另一个GET请求,此步的目的是检索将用于加密文件系统的RSA公钥,一个惟一的比特币钱包和受害者的赎金通知。所有这些构件似乎都是基于特定的活动ID进行检索的。

记一次与QNAPCrypt勒索软件背后黑手的攻防战

服务器的响应如下:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

获取受害者配置之后,恶意软件将删除自身,然后解析检索到的RSA公钥。

记一次与QNAPCrypt勒索软件背后黑手的攻防战

这个RSA公钥将用于加密一组随机字节序列,序列用于加密文件系统。加密密钥采用的是base64编码,并将写入名为README_FOR_DECRYPT.txt的赎金说明文件的末尾。我们还注意到,勒索软件为每一个受攻击的系统分配了不同的比特币钱包:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

创建该文件后,恶意软件将继续执行锁定机制,使用派生加密密钥AES CFB遍行文件系统加密文件,会避免加密刚刚创建的赎金通知:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

恶意软件针对有以下扩展名的文件:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

加密后恶意软件会重命名文件,使其后缀为“.encrypt”:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

如要进行系统解密,需要在支付了所需的赎金后,把RSA公钥加密的base64编码随机序列通过洋葱网站发送给勒索软件运营商:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

系统锁定完成后,勒索软件将再次通过CNC向受害者发送通知:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

二进制文件之外

在分析QNAPCrypt时,我们希望达成的目标之一是评估受害者的规模,于是在Reddit上找到了一个帖子,联系了一些受影响的受害者:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

在与一些受害者交谈时,我们能够将最初的攻击媒介识别为SSH暴力攻击,并且攻击主要针对NAS服务器供应商:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

接着我们研究了攻击者的基础设施。在ARM的样本中,发现有一个通过其REST API的请求,目的是像前面讨论的那样检索新的受害者配置密钥。下图是勒索软件的操作概览:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

到SOCKS5代理的连接是在不强制执行任何身份验证的情况下完成的,任何人都能连,因此我们决定与勒索软件的基础设施进行交互,以检索配置密钥,并可能暂时中止勒索软件的操作:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

由于攻击者从钱包的静态池中为每个受害者提供了一个比特币钱包,我们可以通过复制感染包来检索所有钱包,直到他们无法控制其他的钱包,这样当感染发生时,被勒索的用户将不会被检索到配置工件。

我们编写了以下脚本来实现上述方法:

import socket
import hexdump
import json
import sys
 
HOST = '192.99.206.61'  
PORT = 65000        
 
for i in range(15):
    BTC_WALLETS = list()
    while True:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((HOST, PORT))
        
        s.send(b'\x05\x01\x00')
        data = s.recv(1024)
        hexdump.hexdump(data)
        
        s.send(b'\x05\x01\x00\x03\x16' + b'sg3dwqfpnr4sl5hh.onion\x00' + b'\x50')
        data = s.recv(1024)
        hexdump.hexdump(data)
        
        s.send(b'GET /api/GetAvailKeysByCampId/%.2d HTTP/1.1\x0d\x0a' % i +
                b'Host: sg3dwqfpnr4sl5hh.onion\x0d\x0a' +
                b'User-Agent: http/2\x0d\x0a' +
                b'Accept-Encoding: gzip\x0a\x0d\x0a')
        data = s.recv(1024)
        print '[+] Campaign id %.2d' % i
        hexdump.hexdump(data)
 
        try:
            data = json.loads(data[data.find('{'):])
            print data['BtcPublicKey']
            s.close()
            
            if data['BtcPublicKey'] not in BTC_WALLETS:
                BTC_WALLETS.append(data['BtcPublicKey'])
            else:
                sys.exit()
 
        except ValueError as e:
            print "[+] CAMPAIN HAS NO WALLETS LEFT"
            with open("wallets_%0d.txt" % i, 'w+') as fd:
                for wallet in BTC_WALLETS:
                    fd.write(wallet+'\n')
            break

一共收集了准备通过15次行动分发的1091个独特的钱包。

记一次与QNAPCrypt勒索软件背后黑手的攻防战

通过耗尽攻击者储存的比特币钱包,我们能够暂时阻止恶意软件的进一步传播,因为如果无法解析RSA公钥,客户端就会退出:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

下图显示了在耗尽整个静态比特币钱包池后洋葱域将检索到的数据包:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

HTTP请求返回200,但内容长度为0,因此无法检索配置,勒索软件客户机也会停止执行。这意味着,我们通过不断耗尽其静态比特币钱包池,阻止了勒索软件的进一步感染。

归因与攻击者反应

在连续几天对QNAPCrypt客户机进行DoS操作之后,我们遇到了另一个QNAPCrypt样本,这次是针对x86系统的。

记一次与QNAPCrypt勒索软件背后黑手的攻防战

基于遗传恶意软件分析,我们观察到该样本中重用了x86 Linux.Rex的大部分代码。Linux.Rex因在2016年部署针对Drupal服务器的攻击而闻名,目的是进行勒索软件和DDoS操作。

下面是Linux.Rex和更新后的QNAPCrypt变体之间的一些相似之处:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

尽管这两种恶意软件功能上有所区别,但值得注意的是,它们都是以类似的方式编写的。

此外,我们可以观察到新样本与QNAPCrypt的ARM实例的相似之处,但也有一些区别——RSA公钥、比特币钱包和赎金票据在二进制文件中是硬编码的:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

我们还可以看到,硬编码的洋葱域和ARM变种的完全一样,支付赎金的网站设计也是一样的,不过比特币的赎金要求似乎比之前的版本要低一些:

记一次与QNAPCrypt勒索软件背后黑手的攻防战

我们认为,这些新样本很可能是攻击者的应对举措,他们被迫更新了代码,并将比特币钱包集中了起来,使追踪收入变得更加方便。

结论

我们在前文中介绍了QNAPCrypt勒索软件的运行机制,以及我们发现设计缺陷、防止恶意软件进一步感染的过程,最终让攻击者更新了绕过这些缺陷的新样本。

此外,Golang恶意软件数量上似乎正在呈现上升趋势,因为它非常利于创建跨平台的恶意软件。

我们还讨论了Linux勒索软件与Windows勒索软件在目标选择上可能略有不同,例如在本例中是NAS服务器,而不是Linux端点。

当前,QNAPCrypt的检出率很低,与其他类型的Linux威胁相比,它可能会造成重大的金钱损失和经济损失。

此外,我们还创建了一个自定义的YARA签名,用于检测未来的QNAPCrypt变体。

IOCs

sg3dwqfpnr4sl5hh[.]onion

192.99.206[.]61

3d7ebe73319a3435293838296fbb86c2e920fd0ccc9169285cc2c4d7fa3f120d

076a6fa4e051c061e19b9e3e37da9c63a9bc7c1a99111ac13b32eb2f70b7fa5c

本文翻译自:https://www.intezer.com/blog-seizing-15-active-ransomware-campaigns-targeting-linux-file-storage-servers/转载地址: https://www.4hou.com/web/19233.html

9999.jpg


暂无

您可能还会对下面的文章感兴趣: