《奇虎360陳思雨:通過(guò)漏洞組合利用實(shí)現(xiàn)企業(yè)內(nèi)網(wǎng)入侵》要點(diǎn):
本文介紹了奇虎360陳思雨:通過(guò)漏洞組合利用實(shí)現(xiàn)企業(yè)內(nèi)網(wǎng)入侵,希望對(duì)您有用。如果有疑問(wèn),可以聯(lián)系我們。
陳思雨(RickGray)
奇虎360 高級(jí)安全研究員
奇虎 360,Web 攻防團(tuán)隊(duì) 0keeTeam 成員之一.專注于 Web 方面漏洞的研究,喜好研究新的漏洞類型和攻擊方法.
作者來(lái)自360信息安全部的 0KeeTeam.作者專注于 Web 漏洞挖掘和分析以及安全工具的開(kāi)發(fā).本文列舉兩個(gè)漏洞組合場(chǎng)景,講述如何從黑客的角度去看待運(yùn)維中那些容易出現(xiàn)的漏洞點(diǎn).
你們是否有過(guò)這樣的疑問(wèn),有業(yè)務(wù)暴露在外網(wǎng)的時(shí)候被攻擊了,安全部門的同事要求搬到內(nèi)網(wǎng),運(yùn)維們就要通過(guò)一些簡(jiǎn)單的做法直接把業(yè)務(wù)功能搬到內(nèi)網(wǎng).
接下來(lái)會(huì)用兩個(gè)實(shí)際漏洞組合的例子,說(shuō)明這些問(wèn)題出現(xiàn)的點(diǎn)到底在哪里.
SSRF 如何攻擊內(nèi)網(wǎng)的 Redis 服務(wù)的?
也許大家不是很清楚 SSRF 是什么,這是服務(wù)端的請(qǐng)求偽造,我用一個(gè)簡(jiǎn)單的流程講一下 SSRF 漏洞的原理和具體的表現(xiàn)形式.
外網(wǎng)的服務(wù)器 O1 提供圖片代理接口,用戶提供圖片的鏈接給了 O1.O1 根據(jù)地址請(qǐng)求資源,將具體的內(nèi)容返回給用戶.
正常的邏輯是一個(gè)用戶,然后請(qǐng)求一個(gè)圖片地址,到C1的服務(wù)器里取內(nèi)容.O1直接請(qǐng)求 C1 上的資源返回給用戶,這是正常的功能邏輯.
非正常的邏輯,一個(gè)黑客或者攻擊者在看到這個(gè)連接地址后會(huì)怎么做呢?
搞安全人員會(huì)這樣做,將圖片連接替換成不是圖片的資源連接,或者內(nèi)網(wǎng)的地址.這時(shí)候如果 O1 沒(méi)有做一些資源請(qǐng)求方面的限制,它就會(huì)去請(qǐng)求它所在內(nèi)網(wǎng)的服務(wù)器上的資源,并返回給攻擊者或者黑客.
剛才寫(xiě)到的漏洞流程中,黑客為什么可以將內(nèi)網(wǎng)的資源請(qǐng)求并返回給攻擊者?
第一、 O1圖片沒(méi)有對(duì)傳過(guò)來(lái)的連接進(jìn)行類型判斷.
第二、 沒(méi)有判斷連接指向的資源是否是圖片
第三、 沒(méi)有判斷請(qǐng)求資源是否是在可允許的范圍之內(nèi),可能是內(nèi)網(wǎng)的地址,也可能是敏感的服務(wù)器地址.
如果攻擊者將參數(shù)替換成內(nèi)網(wǎng)地址,O1會(huì)毫無(wú)保留請(qǐng)求地址,將資源內(nèi)容返回給攻擊者.這是簡(jiǎn)單的 SSRF 的漏洞原理和表現(xiàn)形式.
首先,我們可以利用 SSRF 進(jìn)行內(nèi)網(wǎng)的端口掃描和 Web 指紋探測(cè).如果請(qǐng)求內(nèi)網(wǎng)地址的端口是存在的,在服務(wù)器返回給攻擊者信息的時(shí)候,可能有500或者錯(cuò)誤狀態(tài)碼,通過(guò)這些標(biāo)志可以判斷掃描的端口是否開(kāi)放或者關(guān)閉的狀態(tài).
其次,針對(duì)內(nèi)網(wǎng)應(yīng)用服務(wù)的攻擊,通過(guò) Struts2 可以進(jìn)行請(qǐng)求發(fā)送.在某一些應(yīng)用漏洞中,可以直接地通過(guò) GET 請(qǐng)求出發(fā).SSRF 服務(wù)器的內(nèi)網(wǎng)有 Struts 服務(wù),我們可以通過(guò) SSRF 直接嘗試攻擊內(nèi)網(wǎng)的 Struts2 的服務(wù).如果真的存在漏洞,攻擊者間接的使用 SSRF 進(jìn)行做這些應(yīng)用.
最后轉(zhuǎn)換協(xié)議.在 SSRF 向服務(wù)端請(qǐng)求的底層實(shí)現(xiàn)上,一般都是利用CURL ?實(shí)現(xiàn),用戶所能控制的是 url 的值.如果我們講常規(guī)的 http 協(xié)議轉(zhuǎn)化成 file 協(xié)議,就會(huì)去請(qǐng)求本地的資源或者內(nèi)網(wǎng)的文件,并且返回給攻擊者.
gopher 協(xié)議,我們可以利用 gopher 協(xié)議對(duì)任意的端口進(jìn)行應(yīng)用層的數(shù)據(jù)發(fā)送.我列舉了簡(jiǎn)單的例子,下面標(biāo)注的是利用 gopher 協(xié)議實(shí)現(xiàn)請(qǐng)求的圖.
以 gopher 協(xié)議開(kāi)頭,后面跟著是一個(gè)請(qǐng)求服務(wù)的地址,后面是一個(gè)端口.目錄以下滑線作為關(guān)鍵字的開(kāi)頭,后面跟的就是具體應(yīng)用層需要發(fā)送的數(shù)據(jù).可以在 SSRF 利用中,通過(guò) gopher 協(xié)議向任意的端口進(jìn)行應(yīng)用層數(shù)據(jù)的發(fā)送,這是比較關(guān)鍵的.
Redis是比較流行的存儲(chǔ)服務(wù).大家知道的Redis漏洞中,未授權(quán)訪問(wèn)大家非常了解.
未授權(quán)訪問(wèn)這種漏洞,在我看來(lái)式因?yàn)檫\(yùn)維人員或開(kāi)發(fā)人員錯(cuò)誤的配置造成的.一些官方的應(yīng)用必須得給權(quán)限,但運(yùn)維人員和開(kāi)發(fā)人員在配置使用的過(guò)程中,沒(méi)有按照官方的安全建議執(zhí)行.
我們可以通過(guò)攻擊者未授權(quán)訪問(wèn)進(jìn)行哪一些攻擊?篡改 Redis 服務(wù)中的數(shù)據(jù),清空數(shù)據(jù)進(jìn)行破壞.
可以通過(guò)數(shù)據(jù)庫(kù)備份的功能進(jìn)行文件寫(xiě)的操作.怎樣的條件下可以達(dá)到寫(xiě)文件的攻擊?運(yùn)行 Redis 服務(wù)的用戶需要有一定的權(quán)限,可以往你所備份的數(shù)據(jù)庫(kù)路徑下寫(xiě)一個(gè)文件.
在 Redis 配置的時(shí)候,起用數(shù)據(jù)庫(kù)備份的指令.在這兒已經(jīng)列了一個(gè) Save 和 Config.通過(guò)寫(xiě)文件操作,往服務(wù)器上寫(xiě)一個(gè)計(jì)劃任務(wù),這是后面所要執(zhí)行計(jì)劃任務(wù)的規(guī)則.
設(shè)置你所保存的文件名,剛剛說(shuō)到了你所起的 Redis 服務(wù),在這個(gè)路徑下必須得有相應(yīng)的文件操作權(quán)限,才可以成功地往里進(jìn)行寫(xiě)入.下面是成功寫(xiě)入的截圖.
簡(jiǎn)單說(shuō)了 Redis 未授權(quán)訪問(wèn)利用的方式.據(jù)不完全統(tǒng)計(jì),最近也經(jīng)過(guò)一次掃描,發(fā)現(xiàn)在公網(wǎng)仍然存在著大約有1.5萬(wàn)臺(tái)的服務(wù)器存在問(wèn)題.
暴露在公網(wǎng)上的Redis有那么多,一些企業(yè)測(cè)試環(huán)境或者企業(yè)內(nèi)部使用的Redis服務(wù)也是非常多.
我們?nèi)绾喂暨@些處在內(nèi)網(wǎng)的 Redis 服務(wù)?
可以利用 SSRF 往內(nèi)網(wǎng)發(fā)送任意的應(yīng)用層數(shù)據(jù),我們將 SSRF 漏洞和 Redis 未授權(quán)漏洞串聯(lián)起來(lái),我們就可以通過(guò) SSRF 向內(nèi)網(wǎng)的 Redis 服務(wù)進(jìn)行攻擊嘗試.
有兩個(gè)條件需要滿足,第一存在 SSRF 漏洞的服務(wù)器必須得支持 gopher 協(xié)議,才可以成功地往內(nèi)網(wǎng)的服務(wù)器端口進(jìn)行數(shù)據(jù)發(fā)送.第二內(nèi)網(wǎng)中確實(shí)有存在 Redis 的未授權(quán)服務(wù).
我們將剛才 Redis 寫(xiě)計(jì)劃任務(wù)的一系列指令,通過(guò) gopher 協(xié)議進(jìn)行封裝.然后通過(guò) SSRF 漏洞的接口,攻擊者將這個(gè)參數(shù)替換成 gopher 的協(xié)議,O1解析 gopher 協(xié)議,向它處在的內(nèi)網(wǎng)環(huán)境中的 Redis 服務(wù)進(jìn)行攻擊.
如果 L2 上的 Redis 服務(wù)確實(shí)存在未授權(quán)訪問(wèn),且具有相應(yīng)的權(quán)限,這時(shí)候攻擊者就會(huì)成功地達(dá)到攻擊的目標(biāo).
SSRF 堪稱內(nèi)網(wǎng)攻擊的神器,在安全圈里.這是 SSRF 隔山打牛攻擊內(nèi)網(wǎng)的服務(wù).
利用序列化的方式攻擊分布式集群.數(shù)據(jù)序列化可以在不同的兩個(gè)應(yīng)用程序間進(jìn)行對(duì)象的傳遞或者方法的調(diào)用.
在這兒有一個(gè)應(yīng)用A,應(yīng)用A中有一個(gè)對(duì)象A1,通過(guò)序列化方式以后,將序列化的數(shù)據(jù)傳遞給程序B,程序B通過(guò)反序列化的操作得到B1.
在一定的本質(zhì)下,A1和B1的兩個(gè)對(duì)象是等價(jià)的,包括了它們兩個(gè)對(duì)象的屬性值和一些相應(yīng)的方法.不同之處,只是它們處在不同的應(yīng)用環(huán)境或者不同的底層的地址上.
在歷史上出現(xiàn)了很多反序列化造成的問(wèn)題.PHP 有一些問(wèn)題被攻擊者利用,在底層代碼實(shí)現(xiàn)的時(shí)候由于不安全的反序列化操作,造成了遠(yuǎn)程命令執(zhí)行問(wèn)題.
在 Django 框架下有 Session 控制的問(wèn)題.Java 反序列化漏洞,當(dāng)時(shí)涉及到的組件很多,上到 Java 外部框架下到 Java 的擴(kuò)展庫(kù)都存在著遠(yuǎn)程命令執(zhí)行的問(wèn)題.
在漏洞組合的例子中.這是 Java 反序列化執(zhí)行命令的實(shí)例,上面是簡(jiǎn)單的代碼.通過(guò)簡(jiǎn)單的操作,對(duì)用戶輸入的值進(jìn)行反序列化的操作.下面通過(guò)傳遞一串特殊構(gòu)造后的代碼,在下面成功地觸發(fā)命令執(zhí)行漏洞.這個(gè)例子講的是攻擊和分布式框架.
Celery 是 Python 中非常流行的分布式任務(wù)框架.Celery 消息隊(duì)列間,通過(guò)隊(duì)列的形式實(shí)現(xiàn)分布式任務(wù)的下滑.既然有消息的傳遞和分發(fā),就會(huì)涉及到消息的封裝.
一般分布式架構(gòu)中都必須得有這兩個(gè)東西,Celery 的框架中它所支持的消息中間件有 ?RabbitMQ、Redis、MongoDB,它所支持的消息封裝方式,pickle、json、msgpack,yaml.
通過(guò)序列化操作將具體的任務(wù)信息進(jìn)行封裝,然后發(fā)送給中間件,中間件根據(jù)消息的具體路由信息,傳遞給具體的集群解析消息,并執(zhí)行.
剛才所寫(xiě)到的 Celery 任務(wù)下發(fā)到流程中和剛剛提到的框架組成中,我不知道大家是否發(fā)現(xiàn)有比較明顯的安全隱患.如果 Redis 和 pickle 存在安全隱患,如何結(jié)合這兩點(diǎn)攻擊后面所在的集群呢?
Redis 作為 Celery 中間件的時(shí)候,它的消息存儲(chǔ)形式怎樣?去除掉一些必要的字段后,我們可以看到在 Redis 中消息 JSON 的形式存儲(chǔ).比較關(guān)鍵的地方,它的 BODY 字段存儲(chǔ)信息是 Celery 在任務(wù)下發(fā)那端,通過(guò)序列化的方式所形成的封裝數(shù)據(jù).
在默認(rèn)配置下,Celery 又是使用 pickle 進(jìn)行消息封裝.Worke 端在得到消息后,會(huì)根據(jù)相應(yīng)的配置反序列化,這一串?dāng)?shù)據(jù).
簡(jiǎn)單的在 Worker 端可以用這個(gè)代碼表示,通過(guò) pickle 反序列化消息中的 boby 字段.
如果我們有可能去控制消息中間件,并且往其中寫(xiě)入我們想要的數(shù)據(jù),這時(shí)候worke端反序列化的時(shí)候,就有可能反序列化我們注入的消息.
我們這里已經(jīng)可以控制中間件,攻擊者構(gòu)造一個(gè)包含有惡意數(shù)據(jù)的消息,把它輸入到消息中間件中,消息中間件根據(jù)攻擊者所制造的路由信息會(huì)發(fā)送給 worke 端,worke 端根據(jù)配置反序列化這一串?dāng)?shù)據(jù).如果整個(gè)流程都成功地話,worke 會(huì)有反序列化的漏洞.
在上一個(gè)例子中,我也提到了 Redis 服務(wù)有大量的數(shù)量在互聯(lián)網(wǎng)上暴露,并且存在未授權(quán)訪問(wèn)的問(wèn)題.在 Celery 支持的中間件應(yīng)用中,有 Redis 和 Mongo,它也是未授權(quán)訪問(wèn)的重災(zāi)區(qū).
根據(jù)掃描統(tǒng)計(jì),還有1.4萬(wàn)個(gè) MongoDB 未授權(quán)暴露在官網(wǎng)上.有 Redis 未授權(quán)和 MongoDB 未授權(quán)存在著,數(shù)量也是非常大的.可以認(rèn)為在未授權(quán)的 Redis 和 Mongo 中,確實(shí)存在著一些作為 Celery 中間件的應(yīng)用.
如何從2.9萬(wàn)個(gè)未授權(quán)的服務(wù)中,鑒別這些服務(wù)是否作為Celery中間件而存在.如何檢測(cè) Celery 中間件在 Redis 和 MongoDB 中.我對(duì) Redis 和 Mongo 進(jìn)行分析,Celery 默認(rèn)隊(duì)列名是 Celery,你在寫(xiě)程序或者功能實(shí)現(xiàn)的時(shí)候可能有其它的隊(duì)列,有隊(duì)列A或者隊(duì)列B,在這個(gè)地方可以存在 kombu binding.
本地起了 Redis 服務(wù),作為 Celery 的中間件.Celery 通過(guò)類型查看,存儲(chǔ)的是具體的任務(wù)隊(duì)列,保存在列表中.binding.Celery 字典的形式存在,保存的是路由的信息在里面.MongoDB 中 Celery 表現(xiàn)的形式,有剛剛提到的名稱.我們?nèi)绾谓Y(jié)合這些安全問(wèn)題攻擊分析師框架呢?
需要具備幾個(gè)條件,在使用 Celery 框架實(shí)現(xiàn)的應(yīng)用中,它確實(shí)配置了 pickle 的消息封裝方式進(jìn)行處理.但經(jīng)過(guò)了解,在 4.0.0 版本情況下 Celery 使用了 pickle 進(jìn)行消息封裝.
我們有可能控制消息中間件進(jìn)行消息注入的操作,剛才寫(xiě)到了我們可以在1.5萬(wàn)個(gè) Redis 和1.4萬(wàn)個(gè) MongoDB 中,找出作為 Celery 中間件的應(yīng)用進(jìn)行攻擊的嘗試.
如果這一系列的流程都順利,Worker 會(huì)解析攻擊者注入的消息和數(shù)據(jù),成功的觸發(fā)一個(gè)反序列化的操作.成功的 Worker 會(huì)執(zhí)行攻擊者預(yù)先設(shè)定的指令和命令,不成功的肯定不受影響.
我們?cè)卺槍?duì)這些命令檢測(cè)的時(shí)候,如何判斷漏洞是否有觸發(fā)呢.我們需要在外網(wǎng)的回聯(lián)服務(wù)器,我們?cè)谶M(jìn)行遠(yuǎn)程命令執(zhí)行檢測(cè)的時(shí)候,我們會(huì)將執(zhí)行的命令設(shè)置為往我們服務(wù)器上發(fā)連接的具體形式.
我當(dāng)時(shí)在進(jìn)行全網(wǎng)驗(yàn)證的時(shí)候,設(shè)置了往我的服務(wù)器上進(jìn)行簡(jiǎn)單的回聯(lián).在所執(zhí)行的命令中進(jìn)行標(biāo)志位的處理,回聯(lián)回來(lái)當(dāng)時(shí)所在的用戶是什么,我攻擊的中間件IP和類型是什么.
我攻擊的類型是 Redis,或者是 MongoDB.前面是 Worker 端執(zhí)行的時(shí)候代表的用戶,這是中間件的 IP 地址,這是中間件的具體應(yīng)用類型.
這是這邊的 IP 地址是 Worker 端回聯(lián)的時(shí)候所在的 IP 地址,通過(guò)這兩條消息的對(duì)比,我們可以看到在往 90.156 進(jìn)行注入的時(shí)候,后端有兩個(gè)不同的 Worker 觸發(fā)了漏洞,并進(jìn)行了回聯(lián),xx.xx.78.211 和 xx.xx.84.216.
通過(guò)簡(jiǎn)單的例子說(shuō)明確實(shí)能夠結(jié)合反序列化漏洞和消息注入攻擊 Celery 分布式框架.存在消息注入的問(wèn)題,不僅限于 Celery 的分布式框架,在其它的語(yǔ)言應(yīng)用中也存在著這樣的問(wèn)題,只是沒(méi)有被挖掘出來(lái).
為什么存在漏洞攻擊的問(wèn)題,最大的原因就是在存在 SSRF 漏洞的服務(wù)器上,沒(méi)有限制接口資源的訪問(wèn),這會(huì)導(dǎo)致攻擊者可以控制你所請(qǐng)求的連接,然后可能會(huì)往你的內(nèi)網(wǎng)服務(wù)器進(jìn)行攻擊的嘗試.
在 SSRF 的漏洞中,它支持 gopher 協(xié)議進(jìn)行更加廣的攻擊面.在企業(yè)內(nèi)網(wǎng)中存在著很多弱口令服務(wù),應(yīng)用的弱口令或者說(shuō)空口令.如果 Redis 的未授權(quán),可能還有其它的一些未授權(quán)情況.
有一次做安全測(cè)試的時(shí)候,有一家公司叫我們從外網(wǎng)進(jìn)行攻擊嘗試,我找到了 SSRF 漏洞.我對(duì)它的內(nèi)網(wǎng)進(jìn)行簡(jiǎn)單地探測(cè),發(fā)現(xiàn)內(nèi)網(wǎng)中存在著大量的 java 應(yīng)用.
當(dāng)時(shí)處在 java 反序列化爆發(fā)的期間,我自己已經(jīng)把攻擊的問(wèn)題實(shí)現(xiàn).我結(jié)合 SSRF 的漏洞攻擊企業(yè)的內(nèi)網(wǎng),直接拿到了一臺(tái)服務(wù)器權(quán)限.
這臺(tái)服務(wù)器又保存了管理服務(wù)器的登錄公鑰和私鑰,相當(dāng)于集群部署的 muster 在服務(wù)器上,直接拿到了服務(wù)器下面的所有管理的服務(wù)器權(quán)限我都可以訪問(wèn).
涉及到生產(chǎn)環(huán)境的服務(wù)器.說(shuō)明在內(nèi)網(wǎng)中這些脆弱的點(diǎn),我們需要特別去關(guān)注.
反序列化的漏洞問(wèn)題這跟運(yùn)維關(guān)系不是特別大.開(kāi)發(fā)人員進(jìn)行功能開(kāi)發(fā)的時(shí)候,常使用一些存在潛在問(wèn)題的代碼方法.
但運(yùn)維在配置的時(shí)候存在一定的安全問(wèn)題,也有 Redis 未授權(quán)口令問(wèn)題.結(jié)合這些問(wèn)題可以進(jìn)行組合攻擊,可以形成非常大的影響.
有一些關(guān)鍵字我進(jìn)行了標(biāo)記,那就是管理運(yùn)維必須要注意的點(diǎn).如未授權(quán)、服務(wù)器權(quán)限、配置不當(dāng)、間接攻擊、默認(rèn)配置,未驗(yàn)證資源來(lái)源.
通過(guò)兩個(gè)實(shí)例講解,希望運(yùn)維朋友們能夠更加重視安全,重視運(yùn)維過(guò)程中那些細(xì)小的點(diǎn),不留下任何的安全隱患.
轉(zhuǎn)載請(qǐng)注明本頁(yè)網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/4314.html