我如何發現Facebook伺服器中的遠端程式碼執行漏洞:OpenID中的XML外部實體擴充套件漏洞

smilesisi發表於2014-02-12

大家好!首先我做一下自我介紹。我叫Reginaldo Silva,是一名巴西籍的計算機工程師。最近我的工作與資訊保安有關,尤其是在Web應用程式安全性的方面。如果可以的話,我很樂意給大家演示如何入侵網站和應用程式。我的主頁上有一些相關資訊,歡迎大家瀏覽。

今天,我想講一下我發現一個影響Facebook的遠端漏洞程式碼的過程。正如一般的故事開頭那樣,這一過程也是在很長時間以前就開始了(實際上僅僅是一年多,但我一然感覺很漫長)。如果你覺得這個話題很有趣,或者想讓我幫你在你的(或你公司的)程式碼中做一些有關審查和滲透測試的安全問題,請發郵件給我。我的郵箱是reginaldo@ubercomp.com

2012年的9月22日對我來說是個特別的日子,因為那天我發現了一個XML外部實體擴充套件(XXE)漏洞,它能影響Drupal管理OpenID的那部分功能。XML外部實體的功能很強大,它能讀檔案系統中的所有檔案,能連線任意網路。如果你想尋求刺激,你可以用billion laughs進行DoS攻擊。

最開始我並沒有在意其他人也存在這樣的漏洞,當我發現時,我立即將其提交到CVE上。這是我的第一個貢獻,所以從那以後我將這條資訊寫在了簡歷上(這條漏洞的編號是CVE-2012-4554)。五天後,我突然想到OpenID的應用很廣,因此,其它地方也可能存在這樣的漏洞。我檢查了一下StackOverflow的登入方式,發現的確存在漏洞,而且可危及整個網站。

然後,我準備查詢谷歌伺服器中的OpenID 程式碼。雖然我無法開啟檔案,無法進行網路連線,但谷歌的應用引擎和部落格平臺都很容易受到DoS攻擊。這個漏洞讓我賺到了第一桶金,大約有500美元。

在向谷歌報告了這個漏洞後,我又測試了幾個例項,最後發現,這個漏洞正在危及許多系統。這裡就不列舉具體內容了,但是用Java, C#, PHP, Ruby, Python, Perl等語言編寫的執行庫或多或少都存在問題。不公佈的原因是因為這些系統實在太脆弱了。一個瞭解安全機制的人可以讀取OpenID 和XML外部實體,然後就能一段惡意程式碼進行攻擊。哎呀,我有些跑題了。

之後我聯絡了一些編寫OpenID庫的開發者,有些作者只把安全列表託管在了OpenID基金會上面,我又給他們發了一篇題為“一個可以掌控一切的漏洞:運用XML外部實體實現 OpenID中的脆弱性”的郵件來說明這一問題。我想大部分庫作者都是列表中的成員,所以補丁將會發給他們每個人。我自以為做得很好了,事實上,我才走了一小步而已。

跟我經常交流的讀者依然有這樣的問題:Facebook的遠端程式碼執行漏洞到底是什麼?它竟然使我們做到這種程度。過去,Facebook使用OpenID進行登入。然而,當我在2012年第一次發現OpenID漏洞的時候,我就找不到任何能進入任意OpenID網址的終結點。以前可以在

e 動些手腳,現在consumer_helper.php節點已經關閉了。一年後我以為Facebook的安全性有所提高,但我又測試了一下忘記密碼得到了這樣的結果:

那時候我開始懷疑Facebook還是存在一年前我發現的那個漏洞的危害。然後我做了許多測試證明了這個猜想。簡言之,如果你忘記密碼了,你可以向Facebook說明你有一個@gmail.com的郵箱,然後登入自己郵箱後,把自己的資訊提交給Facebook。這實際上是用郵箱登進Facebook的,這種登入方式就是基於OpenID的。到目前為止,一切都進展的不錯,只是我自己遇到了些問題。我知道,由於工作的失誤,OpenID的依賴方需要向已被控制的OpenID提供商(OP)傳送一個Yadis發現請求,比如說http://www.ubercomp.com/。然後我的惡意提供商就會回覆一個惡意的XML,它被依賴方解析,從而遭受XXE攻擊。

因為我沒有干預原始的OpenID請求(Facebook 與 Google之間的直接請求),實際上我沒有機會進入在我控制下的作為OpenID標示符的網址,也沒有讓Facebook傳送Yadis發現請求到這個網站。所以,我想這種錯誤應該不會發生了,除非我能獲取谷歌到Facebook的那段惡意XML,而這種可能性極低。幸運的是,我錯了。在仔細閱讀了OpenID 2.0規範後,第11.2節驗證發現的資訊寫到:

如果宣告的標示符沒有事先告訴依賴方(“openid標識”可以是“http://specs.openid.net/auth/2.0/identifier_select”,或是不同的標示符,或是OP傳送的標識判斷),依賴方必須提出來,以確保該OP有權對聲稱的身份標識做出判斷。

我看了一下,openid標識果真是http://specs.openid.net/auth/2.0/identifier_select。實際上許多系統使用的都是這個。在幾分鐘後,我向 https://www.facebook.com/openid/receiver.php 發了一個請求,它可以讓Facebook向一個被我控制的網站傳送一個Yadis請求。之後會返回包含惡意XML的響應。 當我向Facebook伺服器請求開啟/dev/random,伺服器不會返回響應,而且幾分鐘後請求會失效。即使如此,我還是不能開啟任意檔案。我嘗試了許多XXE,包括各種組合和引數實體,但還是一無所獲。然後我突然意識到在此過程中是存在一些問題的,改正之後……

沒錯,響應中包含了Facebook的/etc/passwd。現在,我們可以隨意訪問了。我覺得我發現了通向王國的道路。通過Facebook 伺服器檢視節點能夠讀取任意檔案和進行網路連線,檢視節點不需要代理,這可是 Facebook不惜高成本建立的。隨後我又有了新想法,覺得應該將其形成一個完整遠端執行程式。

網路中漏洞獎勵計劃是非常好的方式,它也有自己的規則:不管何時發現了漏洞,請不要猶豫。將其按程式提交,安全小組會全面考慮,並向支付相應的報酬。起初,我並不信任 Facebook的安全小組,並且認為他們不會把我提交的漏洞看做是遠端程式碼執行漏洞。我不想造成誤解,所以我決定立即提交,然後我申請了一個許可權進行RCE升級。升級完畢後,它可以正常執行。我想這應該沒什麼問題了。因為大部分漏洞都需要花很長時間來處理,我有足夠的時間升級RCE,同時我覺得我是一個優秀的白帽黑客。在寫完漏洞報告後,我決定出去走走,順便吃個午餐,回來之後繼續工作。

然而,我又錯了,因為這是一個嚴重的漏洞,吃過午飯後,我加快了速度。我把報告發出去不到2個小時,讓我既難忘又難過,但因為我知道如何升級遠端程式碼執行漏洞,我將如何修復告訴了安全小組。當他們測試攻擊是否有效時,我很相信他們給出的結論。我為我的作為而高興。在接到一些反饋和4封郵件後,安全小組確認我的攻擊是安全的,我發現的RCE的確能影響他們的伺服器。

所以這就是攻擊的入口,即我迄今發現的第一個高衝擊漏洞。它大概也是懸賞最高的漏洞之一。另外,我還可以吹牛說我攻入了Facebook……不錯,是吧?順便說一句,安全小組的成員也寫了一篇關於這事的文章。

歡迎加入黑客新聞進行討論。

事件時間點

所有時間以格林威治標準時間。不重要的資訊我就不提了。

  •  2013-11-19 15:51: 寫報告
  •  2013-11-19 17:37: 安全小組成員Godot感謝我的發現
  •  2013-11-19 17:46: 我得到了可以讀任意檔案的答覆
  •  2013-11-19 19:31: 安全小組成員 Emrakul通知我短暫的修復將持續30分鐘。
  •  2013-11-19 20:27: 我確信漏洞已被修復。
  •  2013-11-21 20:03: 獲得酬金。安全小組說這是他們目前支付的最高金額。
  •  2013-11-22 2:13: 我發了封郵件,詢問安全小組把漏洞看做是RCE還是僅僅是檔案洩露。
  •  2013-11-23 1:17: 安全小組回覆說,他們認為攻擊不能升級到RCE。
  •  2013-11-23 19:54: 我解釋說明如何進行升級
  •  2013-11-24 21:23: Facebook 回覆說我的攻擊起作用了,他們會進行處理的。
  •  2013-12-03 4:45:  Facebook 通知我說修復會持續一段時間,他們準備討論一個新的報酬計劃。
  •  2013-12-03 19:14: 我雙手交叉,向他們表示感謝。
  •  2013-12-13 13:04: 我看到了一篇引自Ryan McGeehan的一篇文章,Ryan負責管理Facebook的事件響應部門,他說“如果有一個價值百萬美元的漏洞,那麼我們願意支付”。然後又詢問了一下他們是否有新訊息。
  • 2013-12-30 4:45: Facebook通知我說漏洞已經成為了RCE,所以費用會更高。我不會透漏具體數額,你可以猜一猜,然後說出來。當然我也不會得到一百萬那麼多,我引用McGeehan的話僅僅是為了娛樂一下,不要當真。

相關文章