1. 程式人生 > >奇虎360陳思雨:通過漏洞組合利用實現企業內網入侵

奇虎360陳思雨:通過漏洞組合利用實現企業內網入侵

作者簡介:

陳思雨(RickGray)
奇虎360 高階安全研究員

奇虎 360,Web 攻防團隊 0keeTeam 成員之一。專注於 Web 方面漏洞的研究,喜好研究新的漏洞型別和攻擊方法。

1、前言

作者來自360資訊保安部的 0KeeTeam。作者專注於 Web 漏洞挖掘和分析以及安全工具的開發。本文列舉兩個漏洞組合場景,講述如何從黑客的角度去看待運維中那些容易出現的漏洞點。

2、場景一:SSRF隔山打牛攻擊Readis服務

你們是否有過這樣的疑問,有業務暴露在外網的時候被攻擊了,安全部門的同事要求搬到內網,運維們就要通過一些簡單的做法直接把業務功能搬到內網。

  • 問題一:這種做法真的就安全嗎?
  • 問題二:一個繫結在本地的 Redis 服務,為什麼莫名其妙地被黑客黑掉了?
  • 問題三:如何通過連結攻破企業的內網?

接下來會用兩個實際漏洞組合的例子,說明這些問題出現的點到底在哪裡。

2.1 SSRF漏洞原理

SSRF 如何攻擊內網的 Redis 服務的?

也許大家不是很清楚 SSRF 是什麼,這是服務端的請求偽造,我用一個簡單的流程講一下 SSRF 漏洞的原理和具體的表現形式。

外網的伺服器 O1 提供圖片代理介面,使用者提供圖片的連結給了 O1。O1 根據地址請求資源,將具體的內容返回給使用者。

正常的邏輯是一個使用者,然後請求一個圖片地址,到C1的伺服器裡取內容。O1直接請求 C1 上的資源返回給使用者,這是正常的功能邏輯。

非正常的邏輯,一個黑客或者攻擊者在看到這個連線地址後會怎麼做呢?

搞安全人員會這樣做,將圖片連線替換成不是圖片的資源連線,或者內網的地址。這時候如果 O1 沒有做一些資源請求方面的限制,它就會去請求它所在內網的伺服器上的資源,並返回給攻擊者或者黑客。

剛才寫到的漏洞流程中,黑客為什麼可以將內網的資源請求並返回給攻擊者?

第一、 O1圖片沒有對傳過來的連線進行型別判斷。
第二、 沒有判斷連線指向的資源是否是圖片
第三、 沒有判斷請求資源是否是在可允許的範圍之內,可能是內網的地址,也可能是敏感的伺服器地址。

如果攻擊者將引數替換成內網地址,O1會毫無保留請求地址,將資源內容返回給攻擊者。這是簡單的 SSRF 的漏洞原理和表現形式。

2.2 SSRF漏洞利用方式

首先,我們可以利用 SSRF 進行內網的埠掃描和 Web 指紋探測。如果請求內網地址的埠是存在的,在伺服器返回給攻擊者資訊的時候,可能有500或者錯誤狀態碼,通過這些標誌可以判斷掃描的埠是否開放或者關閉的狀態。

其次,針對內網應用服務的攻擊,通過 Struts2 可以進行請求傳送。在某一些應用漏洞中,可以直接地通過 GET 請求出發。SSRF 伺服器的內網有 Struts 服務,我們可以通過 SSRF 直接嘗試攻擊內網的 Struts2 的服務。如果真的存在漏洞,攻擊者間接的使用 SSRF 進行做這些應用。

最後轉換協議。在 SSRF 向服務端請求的底層實現上,一般都是利用CURL  實現,使用者所能控制的是 url 的值。如果我們講常規的 http 協議轉化成 file 協議,就會去請求本地的資源或者內網的檔案,並且返回給攻擊者。

gopher 協議,我們可以利用 gopher 協議對任意的埠進行應用層的資料傳送。我列舉了簡單的例子,下面標註的是利用 gopher 協議實現請求的圖。

以 gopher 協議開頭,後面跟著是一個請求服務的地址,後面是一個埠。目錄以下滑線作為關鍵字的開頭,後面跟的就是具體應用層需要傳送的資料。可以在 SSRF 利用中,通過 gopher 協議向任意的埠進行應用層資料的傳送,這是比較關鍵的。

2.3 Redis未授權訪問漏洞

Redis是比較流行的儲存服務。大家知道的Redis漏洞中,未授權訪問大家非常瞭解。

未授權訪問這種漏洞,在我看來式因為運維人員或開發人員錯誤的配置造成的。一些官方的應用必須得給許可權,但運維人員和開發人員在配置使用的過程中,沒有按照官方的安全建議執行。

2.4 Redis未授權訪問漏洞利用方式

我們可以通過攻擊者未授權訪問進行哪一些攻擊?篡改 Redis 服務中的資料,清空資料進行破壞。

可以通過資料庫備份的功能進行檔案寫的操作。怎樣的條件下可以達到寫檔案的攻擊?執行 Redis 服務的使用者需要有一定的許可權,可以往你所備份的資料庫路徑下寫一個檔案。

在 Redis 配置的時候,起用資料庫備份的指令。在這兒已經列了一個 Save 和 Config。通過寫檔案操作,往伺服器上寫一個計劃任務,這是後面所要執行計劃任務的規則。

設定你所儲存的檔名,剛剛說到了你所起的 Redis 服務,在這個路徑下必須得有相應的檔案操作許可權,才可以成功地往裡進行寫入。下面是成功寫入的截圖。

簡單說了 Redis 未授權訪問利用的方式。據不完全統計,最近也經過一次掃描,發現在公網仍然存在著大約有1.5萬臺的伺服器存在問題。

暴露在公網上的Redis有那麼多,一些企業測試環境或者企業內部使用的Redis服務也是非常多。

2.5 組合利用兩種漏洞攻擊內網服務

我們如何攻擊這些處在內網的 Redis 服務?

可以利用 SSRF 往內網傳送任意的應用層資料,我們將 SSRF 漏洞和 Redis 未授權漏洞串聯起來,我們就可以通過 SSRF 向內網的 Redis 服務進行攻擊嘗試。

有兩個條件需要滿足,第一存在 SSRF 漏洞的伺服器必須得支援 gopher 協議,才可以成功地往內網的伺服器埠進行資料傳送。第二內網中確實有存在 Redis 的未授權服務。

我們將剛才 Redis 寫計劃任務的一系列指令,通過 gopher 協議進行封裝。然後通過 SSRF 漏洞的介面,攻擊者將這個引數替換成 gopher 的協議,O1解析 gopher 協議,向它處在的內網環境中的 Redis 服務進行攻擊。

如果 L2 上的 Redis 服務確實存在未授權訪問,且具有相應的許可權,這時候攻擊者就會成功地達到攻擊的目標。

SSRF 堪稱內網攻擊的神器,在安全圈裡。這是 SSRF 隔山打牛攻擊內網的服務。

3、場景二:危險序列化結合脆弱中介軟體攻擊分散式節點

3.1 危險的資料序列化

利用序列化的方式攻擊分散式叢集。資料序列化可以在不同的兩個應用程式間進行物件的傳遞或者方法的呼叫。

在這兒有一個應用A,應用A中有一個物件A1,通過序列化方式以後,將序列化的資料傳遞給程式B,程式B通過反序列化的操作得到B1。

在一定的本質下,A1和B1的兩個物件是等價的,包括了它們兩個物件的屬性值和一些相應的方法。不同之處,只是它們處在不同的應用環境或者不同的底層的地址上。

在歷史上出現了很多反序列化造成的問題。PHP 有一些問題被攻擊者利用,在底層程式碼實現的時候由於不安全的反序列化操作,造成了遠端命令執行問題。

在 Django 框架下有 Session 控制的問題。Java 反序列化漏洞,當時涉及到的元件很多,上到 Java 外部框架下到 Java 的擴充套件庫都存在著遠端命令執行的問題。

在漏洞組合的例子中。這是 Java 反序列化執行命令的例項,上面是簡單的程式碼。通過簡單的操作,對使用者輸入的值進行反序列化的操作。下面通過傳遞一串特殊構造後的程式碼,在下面成功地觸發命令執行漏洞。這個例子講的是攻擊和分散式框架。

3.2 窺探Celery中的訊息佇列

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 會有反序列化的漏洞。

3.3 脆弱的中介軟體

在上一個例子中,我也提到了 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。

3.4 Dancing on Internet

本地起了 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 的分散式框架,在其它的語言應用中也存在著這樣的問題,只是沒有被挖掘出來。

4、總結

為什麼存在漏洞攻擊的問題,最大的原因就是在存在 SSRF 漏洞的伺服器上,沒有限制介面資源的訪問,這會導致攻擊者可以控制你所請求的連線,然後可能會往你的內網伺服器進行攻擊的嘗試。

在 SSRF 的漏洞中,它支援 gopher 協議進行更加廣的攻擊面。在企業內網中存在著很多弱口令服務,應用的弱口令或者說空口令。如果 Redis 的未授權,可能還有其它的一些未授權情況。

有一次做安全測試的時候,有一家公司叫我們從外網進行攻擊嘗試,我找到了 SSRF 漏洞。我對它的內網進行簡單地探測,發現內網中存在著大量的 java 應用。

當時處在 java 反序列化爆發的期間,我自己已經把攻擊的問題實現。我結合 SSRF 的漏洞攻擊企業的內網,直接拿到了一臺伺服器許可權。

這臺伺服器又儲存了管理伺服器的登入公鑰和私鑰,相當於叢集部署的 muster 在伺服器上,直接拿到了伺服器下面的所有管理的伺服器許可權我都可以訪問。

涉及到生產環境的伺服器。說明在內網中這些脆弱的點,我們需要特別去關注。

反序列化的漏洞問題這跟運維關係不是特別大。開發人員進行功能開發的時候,常使用一些存在潛在問題的程式碼方法。

但運維在配置的時候存在一定的安全問題,也有 Redis 未授權口令問題。結合這些問題可以進行組合攻擊,可以形成非常大的影響。

有一些關鍵字我進行了標記,那就是管理運維必須要注意的點。如未授權、伺服器許可權、配置不當、間接攻擊、預設配置,未驗證資源來源。

通過兩個例項講解,希望運維朋友們能夠更加重視安全,重視運維過程中那些細小的點,不留下任何的安全隱患。