近期,安全研究者Alex Birsanl對PayPal登錄界面的身份驗證機制進行分析,發(fā)現(xiàn)了其中一個隱藏的高危漏洞,可以通過請求其驗證碼質(zhì)詢服務(wù)端(reCAPTCHA challenge),在質(zhì)詢響應(yīng)消息中獲取PayPal受害者的注冊郵箱和明文密碼,危害嚴重,漏洞最終獲得了PayPal官方$15,300的獎勵。
漏洞前言
當我們在做漏洞測試時,相對于那些顯而易見的功能應(yīng)用來說,我們還會去關(guān)注那些未知資產(chǎn)或模糊端點的服務(wù),有時候這種犄角旮旯服務(wù)產(chǎn)生的漏洞同樣至關(guān)重要,影響關(guān)鍵。
在面對測試目標時,如果你是第一個關(guān)注它并對它開展測試評估的人,那么細致全面的檢查無疑會發(fā)現(xiàn)一些安全問題,尤其是一些代碼已經(jīng)成型且處于持續(xù)運轉(zhuǎn)的應(yīng)用,若能在這種應(yīng)用功能中發(fā)現(xiàn)安全漏洞,將會是非常重要非常危急,且收獲頗豐的。本文中,作者就在PayPal用戶經(jīng)常用到的功能點 - 登錄框架中發(fā)現(xiàn)了一個高危漏洞,我們一起來看看。
最初研究
我在研究PayPal的驗證機制時,發(fā)現(xiàn)其auth驗證頁面的一個javascript腳本文件(recaptchav3.js)中,包含了一個CSRF token和一個會話ID(Session ID),如下:
這馬上引起了我的注意,因為在有效javascript文件中存在的任何類型的會話數(shù)據(jù),都有可能被攻擊者以各種方式檢索獲取到。如用跨站腳本包含(cross-site script inclusion,XSSI),攻擊者可以用一個嵌入了HTML<script>的Web頁面包含進惡意跨域腳本,然后通過該惡意跨域腳本繞過邊界竊取用戶存儲在網(wǎng)站中的敏感信息。
由此,我進行了一個簡單測試,測試發(fā)現(xiàn)我猜測的跨站腳本包含漏洞(XSSI)是確定存在的。盡管每個Request請求中都會有一個javascript混淆方法去隨機化變量名,但其中敏感的用戶token還是一樣會響應(yīng)出現(xiàn)在了之前我們預(yù)計的位置,如果額外加點料,完全能實現(xiàn)對其中敏感信息的檢索提取。
然而,一個安全問題的好壞在于你能用它來實現(xiàn)怎樣的安全威脅。因此,有了以上 _csrf 和 _sessionID的發(fā)現(xiàn),我立即著手對它們進行分析,想搞清楚它們的具體用途和可利用之處。
深入分析
經(jīng)過無數(shù)次對上述PayPal身份驗證請求中的CSRF token值(_csrf )的替換,之后,我認為用這個CSRF token不可能實現(xiàn)經(jīng)典的跨站請求偽造攻擊(CSRF),同樣,替換_sessionID值也不能實現(xiàn)對受害者的冒充。
接下來,我回到了之前的recaptchav3.js中繼續(xù)分析 _csrf 和 _sessionID的具體用途,之后,我順藤摸瓜來到了PayPal主要安全機制之一的安全質(zhì)詢發(fā)起功能點的防暴力枚舉處,雖然該功能用于大多數(shù)PayPal服務(wù)中,但我還是把關(guān)注點聚集到了PayPal的主登錄框架中。
因為:如果經(jīng)過數(shù)次的登錄失敗嘗試,之后,在繼續(xù)登錄之前,PayPal會向用戶發(fā)起一個驗證碼質(zhì)詢(reCAPTCHA challenge),以驗證當前嘗試登錄的主體是否是人還是暴力枚舉的Robot。然而,就是這樣一個功能實現(xiàn),卻讓我發(fā)現(xiàn)了其中隱藏的信息,讓我有點吃驚。
如果PayPal一旦檢測到可能的暴力登錄嘗試,那么,在下次登錄嘗試之前,PayPal登錄界面會彈出一個Google驗證碼(Google Captcha)輸入提示,如果最終該驗證碼由用戶輸入完成,那么就會向PayPal服務(wù)端/auth/validatecaptcha發(fā)起一下如下的HTTP POST請求:
可見,其請求體中包含了我們熟悉的_csrf 和 _sessionID, 除此之外,還有jse和captcha兩個數(shù)值比較大的參數(shù)。
發(fā)起上述驗證碼質(zhì)詢(reCAPTCHA challenge)請求后,其后續(xù)的響應(yīng)旨在將用戶重新引入身份驗證流程,為此,響應(yīng)消息中包含了一個自動提交表單,其中存有用戶最新登錄請求中輸入的所有數(shù)據(jù),包括相關(guān)的電子郵件和純文本密碼(Plain Text Password)!!經(jīng)解析后的HTML如下:
OMG,有了這些,攻擊者可以通過社工或釣魚方式,在正確時機范圍內(nèi)對受害者形成一些交互,就能獲取上述的_csrf 和 _sessionID等token信息,有了這些token信息,再向/auth/validatecaptcha發(fā)起驗證碼安全質(zhì)詢,如果受害者登錄成功,最終質(zhì)詢響應(yīng)回來的信息中就會包含受害者的注冊郵箱和明文密碼信息。在真實攻擊場景中,攻擊者只需制作一個惡意頁面(類似釣魚頁面),迷惑受害者點擊訪問,以模擬PayPal身份驗證的反復(fù)嘗試,去調(diào)用PayPal的驗證碼質(zhì)詢(Google Captcha),然后在其質(zhì)詢響應(yīng)消息中即可實現(xiàn)對受害者PayPal登錄密碼的獲取。
最后,我又回到對/auth/validatecaptcha的HTTP POST請求中,想看看jse和captcha兩個參數(shù)的實際作用,分析發(fā)現(xiàn):
jse根本沒起到驗證作用;
recaptcha是Google提供過來的驗證碼質(zhì)詢(reCAPTCHA challenge)token,它與特定的用戶會話無關(guān),無論人機驗證,只要與其匹配的任何有效輸入token,它都會接受。
漏洞利用
綜上所述,除去Google的驗證碼質(zhì)詢解決方案以外,為了對以上漏洞進行成功利用,我把所有東西組合起來,制作了一個PoC驗證。整個PoC驗證包含兩個步驟:
1、用跨站包含漏洞(XSSI)獲取受害者會話中的_csrf 和 _sessionID等token信息,之后,利用這些token信息在受害者瀏覽器端發(fā)起針對PayPal身份驗證服務(wù)端/auth/validatecaptcha的POST請求,形成暴力猜解登錄嘗試的模擬,以觸發(fā)PayPal的驗證碼安全質(zhì)詢機制;
2、一旦受害者成功登錄到PayPal之后,之前對/auth/validatecaptcha的請求響應(yīng)消息中,將會包含受害者的注冊郵箱和登錄PayPal的明文密碼。在我設(shè)計的PoC中,這些敏感信息會顯示在頁面中。整個PoC的最后步驟是去請求Google獲取一個最新的reCAPTCHA token。
利用此方法,我又發(fā)現(xiàn),在PayPal的一些未經(jīng)用戶授權(quán)的支付頁面中,同樣存在該漏洞,可以用上述方法獲取到用戶的明文***數(shù)據(jù)信息。
漏洞上報及處理進程
2019.11.18 我將PoC驗證資料連同其它敏感信息一并提交給了PayPal在HackerOne上的眾測項目;
2019.12 PayPal確認了漏洞的有效性;
2019.12.10 PayPal官方獎勵了我$15,300,同時漏洞被PayPal評定為CVSS 8.0 (高危) ;
2019.12.11 PayPal及時修復(fù)了漏洞
漏洞修復(fù)及建議
現(xiàn)在,PayPal的驗證碼質(zhì)詢功能點/auth/validatecaptch加入了CSRF token,已經(jīng)不能實現(xiàn)之前的跨站腳本包含攻擊。雖然漏洞是可以修復(fù)的,但如果遵循信息安全最古老的建議:永遠不要以純文本方式存儲密碼,那么這一切原本都是可以避免的。
*參考來源:medium,clouds編譯整理