反序列化对象列表发生异常_通过反序列化漏洞,黑客能做什么呢?
在之前的文章中講解了一個反序列化的例子,我們已經知道,通過反序列化漏洞,黑客可以調用到Runtime.exec()來進行命令執行。換一句話說,黑客已經能夠在服務器上執行任意的命令,這就相當于間接掌控了你的服務器,能夠干任何他想干的事情了。
即使你對服務器進行了一定的安全防護,控制了黑客掌控服務器所產生的影響,黑客還是能夠利用反序列化漏洞,來發起拒絕服務攻擊。比如,曾經有人就提出過這樣的方式,通過 HashSet 的相互引用,構造出一個 100 層的 HashSet,其中包含 200 個 HashSet 的實例和 100 個 String,結構如下圖所示。
對于多層嵌套的對象,Java 在反序列化過程中,需要調用的方法呈指數增加。因此,盡管這個序列化的數組大概只有 6KB,但是面對這種 100 層的數據,Java 所需要執行的方法數是近乎無窮的(n 的 100 次方)。也就是說,黑客可以通過構建一個體積很小的數據,增加應用在反序列化過程中需要調用的方法數,以此來耗盡 CPU 資源,達到影響服務器可用性的目的。
如何進行反序列化漏洞防護 ?
現在,你應該對序列化和反序列化的操作產生了一些警惕。那你可能要問了,既然反序列化漏洞危害這么大,我們能不能直接剔除它們呢?顯然是不可能的,尤其是 JSON,作為目前最熱門的跨平臺數據交換格式之一,其易用性是顯而易見的,你不可能因為這些還沒發生的危害就剔除它們。因此,我們要采取一些有效的手段,在把反序列化操作的優勢發揮出來的同時,去避免反序列化漏洞的出現。我們來看 3 種具體的防護方法:認證、限制類和 RASP 檢測。
1. 認證和簽名
首先,最簡單的,我們可以通過認證,來避免應用接受黑客的異常輸入。要知道,很多序列化和反序列化的服務并不是提供給用戶的,而是提供給服務自身的。比如,存儲一個對象到硬盤、發送一個對象到另外一個服務中去。對于這些點對點的服務,我們可以通過加入簽名的方式來進行防護。比如,對存儲的數據進行簽名,以此對調用來源進行身份校驗。只要黑客獲取不到密鑰信息,它就無法向進行反序列化的服務接口發送數據,也就無從發起反序列化攻擊了。
2. 限制序列化和反序列化的類
事實上,認證只是隱藏了反序列化漏洞,并沒有真正修復它。那么,我們該如何從根本上去修復或者避免反序列化漏洞呢?
在反序列化漏洞中,黑客需要構建調用鏈,而調用鏈是基于類的默認方法來構造的。然而,大部分類的默認方法邏輯很少,無法串聯成完整調用鏈。因此,在調用鏈中通常會涉及非常規的類,比如,剛才那個 demo 中的 InvokerTransformer。我相信 99.99% 的人都不會去序列化這個類。因此,我們可以通過構建黑名單的方式,來檢測反序列化過程中調用鏈的異常。
在 Fastjson 的配置文件中,就維護了一個黑名單的列表,其中包括了很多可能執行代碼的方法類。這些類都是平常會使用,但不會序列化的一些工具類,因此我們可以將它們納入到黑名單中,不允許應用反序列化這些類(在最新的版本中,已經更改為 hashcode 的形式)。
我們在日常使用 Fastjson 或者其他 JSON 轉化工具的過程中,需要注意避免序列化和反序列化接口類。這就相當于白名單的過濾:只允許某些類可以被反序列化。我認為,只要你在反序列化的過程中,避免了所有的接口類(包括類成員中的接口、泛型等),黑客其實就沒有辦法控制應用反序列化過程中所使用的類,也就沒有辦法構造出調用鏈,自然也就無法利用反序列化漏洞了。
3.RASP 檢測
通常來說,我們可以依靠第三方插件中自帶的黑名單來提高安全性。但是,如果我們使用的是 Java 自帶的序列化和反序列化功能(比如ObjectInputStream.resolveClass),那我們該怎么防護反序列化漏洞呢?如果我們想要替這些方法實現黑名單的檢測,就會涉及原生代碼的修改,這顯然是一件比較困難的事。
為此,業內推出了 RASP(Runtime Application Self-Protection,實時程序自我保護)。RASP 通過 hook 等方式,在這些關鍵函數的調用中,增加一道規則的檢測。這個規則會判斷應用是否執行了非應用本身的邏輯,能夠在不修改代碼的情況下對反序列化漏洞攻擊實現攔截。關于 RASP,之后的課程中我們會專門進行講解,這里暫時不深入了。簡單來說,通過 RASP,我們就能夠檢測到應用中的非正常代碼執行操作。
我個人認為,RASP是最好的檢測反序列化攻擊的方式。 我為什么會這么說呢?這是因為,如果使用認證和限制類這樣的方式來檢測,就需要一個一個去覆蓋可能出現的漏洞點,非常耗費時間和精力。而 RASP 則不同,它通過 hook 的方式,直接將整個應用都監控了起來。因此,能夠做到覆蓋面更廣、代碼改動更少。
但是,因為 RASP 會 hook 應用,相當于是介入到了應用的正常流程中。而 RASP 的檢測規則都不高效,因此,它會給應用帶來一定的性能損耗,不適合在高并發的場景中使用。但是,在應用不受嚴格性能約束的情況下,我還是更推薦使用 RASP。這樣,開發就不用一個一個去對漏洞點進行手動修補了。
寫在最后
反序列化漏洞的產生原理,即黑客通過構造惡意的序列化數據,從而控制應用在反序列化過程中需要調用的類方法,最終實現任意方法調用。如果在這些方法中有命令執行的方法,黑客就可以在服務器上執行任意的命令。
對于反序列化漏洞的防御,我們主要考慮兩個方面:認證和檢測。對于面向內部的接口和服務,我們可以采取認證的方式,杜絕它們被黑客利用的可能。另外,我們也需要對反序列化數據中的調用鏈進行黑白名單檢測。成熟的第三方序列化插件都已經包含了這個功能,暫時可以不需要考慮。最后,如果沒有過多的性能考量,我們可以通過 RASP 的方式,來進行一個更全面的檢測和防護。
總結
以上是生活随笔為你收集整理的反序列化对象列表发生异常_通过反序列化漏洞,黑客能做什么呢?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MATLAB绘图函数plot详解
- 下一篇: maven setting.xml 中文