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