批踢踢實業坊 邏輯漏洞 - HITCON ZeroDay

Vulnerability Detail Report

Vulnerability Overview

  • ZDID: ZD-2023-00143
  •  發信 Vendor: 批踢踢實業坊
  • Title: 批踢踢實業坊 邏輯漏洞
  • Introduction: 存在邏輯漏洞及洩漏 stack 資訊

處理狀態

目前狀態

公開
Last Update : 2023/06/04
  • 新提交
  • 已審核
  • 已通報
  • 未回報修補狀況
  • 未複測
  • 公開

處理歷程

  • 2023/03/21 15:47:00 : 新提交 (由 愛麗絲 更新此狀態)
  • 2023/03/22 10:41:38 : 審核中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2023/03/26 20:24:01 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2023/04/24 12:55:54 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2023/04/24 12:55:54 : 修補中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2023/04/24 12:55:54 : 修補中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2023/05/16 17:52:24 : 修補中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2023/05/16 17:52:40 : 修補中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2023/06/04 03:00:02 : 公開 (由 HITCON ZeroDay 平台自動更新)

詳細資料

  • ZDID:ZD-2023-00143
  • 通報者:fxfxxxfxx (愛麗絲)
  • 風險:低
  • 類型:邏輯漏洞 (Logic Flaws)

參考資料

攻擊者可經由該漏洞繞過網站邏輯行為進行惡意攻擊。

漏洞說明: OWASP - Testing for business logic
https://www.owasp.org/index.php/Testing_for_business_logic

漏洞說明: CWE-840: Business Logic Errors
https://cwe.mitre.org/data/definitions/840.html
(本欄位資訊由系統根據漏洞類別自動產生,做為漏洞參考資料。)

相關網址

https://term.ptt.cc/
及使用 https://github.com/ptt/pttbbs 的站台

敘述

板主等具有舉辦樂透功能的帳號可以讓P幣(該網站的虛擬幣)不正常增加
以及可以 leak 出部份 stack 上的資訊

原始碼位於 https://github.com/ptt/pttbbs

在 mbbsd/gamble.c 中
可以發現,如果使用者停在購買樂透的頁面
此時若板主結束當下的樂透並重新開一個新的樂透的話
使用者此時便能以過去的價格購買到下一個樂透

因此若板主先開一個單價 10 元的樂透
另一個使用者停在購買頁面後
板主重新開一個單價 10000 元的樂透
便能將 P幣 翻 (1000 * 0.95) 倍

還有另一個增長更為快速的方法
樂透的紀錄共有兩個檔案
分別是紀錄各選項數目的 FN_TICKET_OUTCOME
以及紀錄使用者選什麼選項的 FN_TICKET_USER

假設目前使用者A、B分別能購買 X, Y份樂透
以下是流程:

  1. 板主開啟有兩個選項的樂透
  2. 使用者A 停留在購買頁面
  3. 板主結束樂透並開啟新的有三個選項的樂透
  4. 使用者B 購買 Y-1 份樂透(選項3)
  5. 使用者A 購買 X 份樂透(選項2)
  6. 使用者B 購買 1 份樂透(選項3)
  7. 板主開獎(選項3)

關鍵在第 5 步時,使用者A 會因為只寫入前兩個選項的結果而造成
在 FN_TICKET_OUTCOME 中選項3遺失

mbbsd/gamble.c:157:

    ftruncate(fileno(fp), 0);
    rewind(fp);
    for (i = 0; i < count; i++)
        fprintf(fp, "%lld ", ticket[i]);
    fflush(fp);

變數 count 是使用者A 當時的選項數(2)
所以第 4 步使用者B 的選項3 便會在 FN_TICKET_OUTCOME 中遺失

在板主開獎時,賠率會是 X/1 = 1:X
但在發放獎金時使用的 FN_TICKET_USER 仍然有使用者B的紀錄
因此使用者B可以拿到 ((Y-1)X + 1X) * 0.95 = 0.95XY

以上兩種方法並不衝突,所以複合後可以達到 950XY

下圖是我用原始碼在本地實驗的結果,並沒有在網站上使用

圖片
(可以看到上方選項3 只有1份,但下方發獎金時發了23+1份)

另外,若板主先開啟四個選項的樂透再開二個選項的樂透的話
便能讓使用者在後者下出不存在的第四個選項
在開獎印出選項名稱時,此時 betname[mybet] 是未初始化的 char[30]
因此可以 leak 出 stack 上的資訊
此後若能控制 control flow
便有機會藉此資訊達成 RCE

mbbsd/gamble:466:

        } else {
        if (fp)
            fprintf(fp, "     %-*s 買了 %3d 張 %s\n" ,
                IDLEN, userid, i, betname[mybet]);
        continue;
            }

擷圖

留言討論

聯絡組織

 發送私人訊息
您也可以透過私人訊息的方式與組織聯繫,討論有關於這個漏洞的相關資訊。
;