Caja是Google的一個(gè)能對(duì)html和javascript做XSS過濾的工具,2018年3月筆者發(fā)現(xiàn)并向谷歌提交了一個(gè)Caja的XSS漏洞。到5月份的時(shí)候,這個(gè)XSS問題已經(jīng)被修復(fù),不過我發(fā)現(xiàn)谷歌某站點(diǎn)用的是沒有打補(bǔ)丁的Caja,所以馬上看了下能不能XSS,然而并沒有成功。
Caja在解析html和JavaScript文件時(shí)會(huì)過濾掉敏感的js內(nèi)容,比如iframe標(biāo)簽、object標(biāo)簽以及像document.cookie這種的敏感的js屬性。正常情況是在客戶端操作和過濾這些html標(biāo)簽,但如果涉及到遠(yuǎn)程js標(biāo)簽(比如<script src=”xxx”>這種),那這些遠(yuǎn)程資源會(huì)在服務(wù)端進(jìn)行獲取、解析和過濾。
我在自己的服務(wù)器上上傳了一個(gè)js文件https://[attacker].com/script.js
,用來檢查谷歌某網(wǎng)站在服務(wù)端解析js時(shí)有沒有XSS漏洞,可惜服務(wù)器響應(yīng)是訪問不到這個(gè)遠(yuǎn)程js。
測(cè)了半天,結(jié)論是Caja只能獲取到https://www.google.com
和https://www.gstatic.com
這些來自谷歌官方的遠(yuǎn)程資源,而像https://www.facebook.com
這種第三方的是訪問不了的。
谷歌的這個(gè)邏輯不太合乎常理,這么做風(fēng)險(xiǎn)會(huì)比較大,因?yàn)楣雀璧臉I(yè)務(wù)線很廣泛,一般來說一個(gè)URL不太好判斷是不是谷歌官方的,會(huì)比較容易誤判。不過也許在某種情況下,能輕而易舉地讓谷歌認(rèn)為是一個(gè)來自官方的資源……
一般當(dāng)我發(fā)現(xiàn)谷歌的后端內(nèi)容服務(wù)器的話,我都會(huì)先測(cè)一下SSRF問題,不幸的是我測(cè)試了百來次都沒有成功找到漏洞。不管怎么說我確定了Caja是在谷歌的內(nèi)網(wǎng)中做的抓取,否則不會(huì)只加載內(nèi)部資源,而不能獲取第三方資源,這應(yīng)該是個(gè)bug,但是不是安全漏洞還得進(jìn)行進(jìn)一步的確認(rèn)。
因?yàn)楣雀柙品?wù)的存在,在谷歌自家服務(wù)器上托管和運(yùn)行代碼就是一件順理成章的事情了,我創(chuàng)建了一個(gè)云App服務(wù)實(shí)例,上傳了之前放在第三方的js文件,然后在谷歌某站點(diǎn)上引用這個(gè)遠(yuǎn)程js,神奇地發(fā)現(xiàn)谷歌Caja獲取并且解析了這個(gè)js!之后我查看了云App上的記錄的遠(yuǎn)程IP,居然是10.x.x.201這樣的一個(gè)內(nèi)網(wǎng)地址,看起來勝利就在眼前了。
我用這個(gè)內(nèi)網(wǎng)IP替換了本來谷歌某站點(diǎn)訪問外部js資源的URL,等著服務(wù)器響應(yīng),花了30秒還沒加載出來,又想到谷歌的SSRF可不是那么好挖的,在我要放棄的最后一刻,居然加載出來了,而且不是普通的錯(cuò)誤響應(yīng)碼,響應(yīng)內(nèi)容大概有1M那么大……難怪加載這么久,打開確認(rèn)了下全都是內(nèi)網(wǎng)的數(shù)據(jù),我驚呆了!
我并沒有掃描谷歌的內(nèi)網(wǎng),只是發(fā)了以下幾個(gè)請(qǐng)求證明漏洞存在,并立即向谷歌漏洞賞金計(jì)劃報(bào)告了該漏洞,我是在周六提交的,谷歌響應(yīng)迅速,在48小時(shí)內(nèi)就修復(fù)了,期間我還嘗試了能不能引起RCE漏洞,然而并沒有成功。下圖是Borg的架構(gòu)圖:
第一個(gè)請(qǐng)求是發(fā)給http://10.x.201/
這個(gè)地址的,服務(wù)器返回的是Borg的管理頁(yè)面(文章開頭的圖),Borg是谷歌內(nèi)部的大規(guī)模集群管理系統(tǒng),經(jīng)過搜索查證后,我確認(rèn)直接訪問到了內(nèi)部Borg系統(tǒng)。雖然谷歌在2014年開源了Borg的下一代產(chǎn)品Kubernetes,開源的Kubernetes日益流行,但是在內(nèi)部生產(chǎn)環(huán)境仍然是依賴Borg的,當(dāng)然這并不是因?yàn)锽org的界面設(shè)計(jì)(開個(gè)玩笑)。
第二個(gè)請(qǐng)求是發(fā)給 http://10.x.x.1/
這個(gè)地址的,響應(yīng)是另外一個(gè)Borg的管理頁(yè)面,第三個(gè)請(qǐng)求是發(fā)到http://10.x.x.1/getstatus
,響應(yīng)的Borg管理頁(yè)面比前兩個(gè)有更多的細(xì)節(jié),有詳細(xì)的權(quán)限和參數(shù)信息。這兩個(gè)Borglet都是一個(gè)實(shí)體的后端服務(wù)器。
硬件方面,這兩臺(tái)服務(wù)器都用了Haswell的CPU,主頻2.3G赫茲,72核,相當(dāng)于一組兩臺(tái)或者三臺(tái)的Xeon E5 v3的CPU,兩臺(tái)服務(wù)器的CPU利用率都在77%,有250G的內(nèi)存,已經(jīng)使用了70%,硬盤的容量是2T,基本沒有使用,大概只用掉了15G的空間,沒有固態(tài)硬盤,所以數(shù)據(jù)應(yīng)該不是存在這兩臺(tái)服務(wù)器上的。
機(jī)器上的任務(wù)非常多,是整合優(yōu)化過的,有一些任務(wù)用消耗的是內(nèi)存,有的消耗CPU或者網(wǎng)絡(luò)資源,還有一些任務(wù)是高優(yōu)先級(jí)的,有一些視頻編碼、郵箱和廣告的服務(wù)比較頻繁,這些看起來都是正常的,視頻處理起來本來就比較耗資源,Gmail是谷歌的主要服務(wù),廣告也是谷歌的核心業(yè)務(wù)。
我沒有找到谷歌站點(diǎn)或者Caja的任務(wù),要不就是走了代理,要不就是Borg的10.x.x.201和我在谷歌云App上收集到的IP是不同的內(nèi)網(wǎng)。
參考谷歌的架構(gòu),我基本上找到了和谷歌Stack的幾乎所有的組件相關(guān)的任務(wù),特別是 MapReduce, BitTable, Flume, GFS…等等這些。
技術(shù)方面,大部分用的語(yǔ)言都是java,沒有發(fā)現(xiàn)部署過Python、C++、NodeJs或者Go語(yǔ)言,當(dāng)然結(jié)論也不能下的太早了,說不定是我沒有發(fā)現(xiàn)呢。
Borg和Kubernetes一樣,都是依賴Docker和VM這樣的容器,但視頻處理好像使用的是谷歌的開源工具Gvisor,大概是為了在容器的性能和VM安全之間做的一個(gè)平衡吧。
不同參數(shù)會(huì)展示如何到達(dá)端口的應(yīng)用信息的,在Borg系統(tǒng)里,好像所有的應(yīng)用都是用的同一個(gè)IP地址,用不同的服務(wù)端口區(qū)分。
應(yīng)用中的對(duì)象是最有意思的,因?yàn)檫@些基本就是源代碼了,我發(fā)現(xiàn)了一些谷歌沒有公開的有趣小算法:
MSCR(M(Customer.AdGroupCriterion+Customer.AdGroupCriterion-marshal+FilterDurianAdGroupCriterion+FilterNeedReviewAdGroupCriterion+GroupAdGroupCriterionByAdGroupKey+JoinAdGroupData/MakeUnionTable:3)+M(JoinAdGroupData/MakeUnionTable:2)+M(Customer.AdGroup+Customer.AdGroup-marshal+FilterDurianAdGroup+ParDo(AdGroupDataStripFieldsFn)+JoinAdGroupData/MakeUnionTable)+R(JoinAdGroupData/GroupUnionTables+JoinAdGroupData/ConstructJoinResults+JoinAdGroupData/ExtractTuples+ExtractCreativeAndKeywordReviewables))
還有Gmail的系統(tǒng)管理用戶是gmail@prod.google.com
gmail@prod.google.com
還有一個(gè)用戶“l(fā)egal-discovery@prod.google.com”在數(shù)據(jù)庫(kù)記錄mdb:all-person-users 中有“auth.impersonation.impersonateNormalUser”的權(quán)限(澄清一下,只是在一個(gè)大數(shù)組中看到的信息,按照字面意思理解,不一定準(zhǔn)確)。
也有一些歷史信息證明有很多的項(xiàng)目在實(shí)現(xiàn)之前就被中斷了。
/getFile?FileName=/sys/borglet/borglet.INFO
大量的URL是去訪問其他的服務(wù)器或者終端,我覺得比較有戲的一個(gè)http://wiki/
地址也訪問不到,詳細(xì)的路徑是
/getFileFileName=/sys/borglet/borglet.INFO
我是在2018年5月12日(周六)提交的漏洞,系統(tǒng)自動(dòng)判定為P3,大概是個(gè)中危的等級(jí),周天我又給谷歌安全團(tuán)隊(duì)發(fā)了一封郵件,希望有人能跟進(jìn)下,周一上午風(fēng)險(xiǎn)等級(jí)被修改成了P0,也就是嚴(yán)重級(jí)別,再后來改為P1高危,周一晚上漏洞修復(fù),有風(fēng)險(xiǎn)的后端就下線了。
要確定SSRF的影響范圍不太容易,要看在內(nèi)網(wǎng)里能訪問到多少信息,谷歌一般是在內(nèi)部使用大量的web站點(diǎn)來維持基礎(chǔ)架構(gòu),也就是說,一旦發(fā)生SSRF,就意味著可以訪問到大量的內(nèi)部web應(yīng)用,不過好在很多系統(tǒng)都做了鑒權(quán)和身份認(rèn)證,降低了SSRF的危害。
我提的這個(gè)漏洞里,正好Borglet系統(tǒng)的管理頁(yè)面沒有做身份認(rèn)證,所以泄漏了大量的基礎(chǔ)信息,或許在繼任產(chǎn)品Kubernetes中是做了授權(quán)的,所以沒有泄漏。
谷歌VRP獎(jiǎng)勵(lì)我$13337,相當(dāng)于任意文件訪問的等級(jí),對(duì)方解釋說雖然大部分資源都需要權(quán)限校驗(yàn),但很多開發(fā)人員在調(diào)試程序時(shí)都有很大的權(quán)限,可能造成的問題不僅僅是信息泄漏,因此按照最高的風(fēng)險(xiǎn)等級(jí)來獎(jiǎng)勵(lì)。也感謝谷歌的獎(jiǎng)金、負(fù)責(zé)任的態(tài)度和迅速的響應(yīng),當(dāng)然也希望谷歌不會(huì)因?yàn)槲疫@篇文章追責(zé)(開個(gè)玩笑,文中所有敏感信息都處理掉了)。
這就是我發(fā)現(xiàn)谷歌SSRF的全過程,希望大家能有所收獲,歡迎大家踴躍交流。