Java反序列化漏洞簡介html
Java序列化就是把對象轉換成字節流,便於保存在內存、文件、數據庫中,Java中的 ObjectOutputStream 類的writeObject()方法能夠實現序列化。java
Java反序列化即逆過程,由字節流還原成對象。ObjectInputStream類的readObject()方法用於反序列化。git
所以要利用Java反序列化漏洞,須要在進行反序列化的地方傳入攻擊者的序列化代碼。若是Java應用對用戶輸入,即不可信數據作了反序列化處理,那麼攻擊者能夠經過構造惡意輸入,讓反序列化產生非預期的對象,非預期的對象在產生過程當中就有可能帶來任意代碼執行。github
下面結合一些demo介紹一款用於 檢測和簡單利用 java 反序列化漏洞的burpsuite 擴展: Java Deserialization Scanner。web
插件安裝數據庫
該插件能夠在 burp Suite 的 BApp Store 中安裝 , 安裝好後須要配置 ysoserial(一款java反序列化漏洞payload生成器) 的路徑。瀏覽器
你能夠本身從github上下載源碼,編譯。或者使用我剛編譯的: https://pan.baidu.com/s/1eSxPPQi 密碼: nxv4. 放到 burpsuite.jar 同一目錄,而後填上文件名便可(如上圖所示)。tomcat
插件測試服務器
插件做者很貼心,不只寫了個這麼棒的插件,還附帶了不少示例。我以 sampleCommonsCollections3 爲例介紹該插件的使用。首先在 tomcat 中把 這個 war 包部署好。而後就能夠在 webappssampleCommonsCollections3 下查看對應源碼和他使用的庫,該插件檢測反序列化漏洞就是基於一些已知庫中的gadget(依賴於 ysoserial),進行檢測。進入 webappssampleCommonsCollections3 會看到app
訪問 http://localhost:8008/sampleCommonsCollections3/ 就能夠看到 示例的首頁了(端口根據本身的狀況修改,我這是 8008)。
這些示例根據實際代碼中對 傳輸序列化對象的各類方式進行了模擬(直接傳輸,hex編碼傳輸,base64編碼傳輸,gzip壓縮傳輸,以及他們的一些組合)。插件也根據這些傳輸方案給出了對應的解決辦法。
對未編碼的序列化對象測試
先來看看 最簡單 的 testRawBody.jsp
<html>
<head>
<title>Java Deserialization Testing JSP Page</title>
</head>
<body bgcolor=white>
<h1>Java Deserialization Testing JSP Page</h1>
<p>This is the output of a JSP page that deserialize an object sent as POST body.</p> <%@ page import = "java.io.ObjectInputStream" %> <%@ page import = "java.io.InputStream" %> <%@ page import = "java.io.ByteArrayInputStream" %> <% ObjectInputStream objectInputStream = new ObjectInputStream(request.getInputStream()); String deserializedString = (String)objectInputStream.readObject(); out.println("<p>Deserialized string:</p>"); out.println("<p>" + deserializedString + "</p>"); %> </body> </html>
直接對POST過來的數據進行了 反序列化, 下面看看它的庫, 進入 WEB-INFlib 目錄,
存在 commons-collections-3.1.jar 這個庫是有利用反序列化漏洞所須要的漏洞類的。下面用插件來試試。瀏覽器進入 sampleCommonsCollections3/ ,burpsuite抓包,點擊第一個 Serialized Java Object in body (不編碼直接發送序列化對象到服務端)。
而後右鍵把請求包發送到 插件中
設置好測試的位置
最下面的一排,表示選中的數據是以什麼格式編碼的, 倒數第2排的那個下拉框,選擇判斷漏洞是否存在使用的方式,有 DNS(依賴於burpsuite的Collaborator功能來獲取響應), Sleep (若是有漏洞讓服務器sleep 幾秒鐘), 還有 cpu模式。這裏選擇 Sleep模式,而後 點擊 Attack (由於這裏的序列化對象沒有被編碼),等一陣就有結果了。
能夠看到,檢測出 Apache Commons Collections 3 漏洞。而後右鍵,
在 Exploitation tab 在確認下,下面那個輸入框下 輸入 ysoserial 的參數, 這裏檢測出了 Apache Commons Collections 3 ,因此使用 CommonsCollections3 COMMAD 。以下圖所示:
上面會在服務器下執行 calc , 彈出一個計算器。
下面再以 gzip 爲例對 編碼過的序列化對象 測試
看看代碼 webappssampleCommonsCollections3testGzipBody.jsp:
<html> <head> <title>Java Deserialization Testing JSP Page</title> </head> <body bgcolor=white> <h1>Java Deserialization Testing JSP Page</h1> <p>This is the output of a JSP page that deserialize a compressed GZIP object sent as POST body.</p> <%@ page import = "java.io.ObjectInputStream" %> <%@ page import = "java.io.InputStream" %> <%@ page import = "java.io.ByteArrayInputStream" %> <%@ page import = "java.io.ByteArrayOutputStream" %> <%@ page import = "java.io.ByteArrayInputStream" %> <%@ page import = "java.util.zip.GZIPInputStream" %> <%@ page import = "java.util.Map" %> <% GZIPInputStream gzis = new GZIPInputStream(request.getInputStream()); byte[] buffer = new byte[1024]; java.io.ByteArrayOutputStream byteout = new java.io.ByteArrayOutputStream(); int len; while ((len = gzis.read(buffer)) > 0) { byteout.write(buffer, 0, len); } byte[] uncompressed = byteout.toByteArray(); ByteArrayInputStream bais = new ByteArrayInputStream(uncompressed); ObjectInputStream objectInputStream = new ObjectInputStream(bais); String deserializedString = (String)objectInputStream.readObject(); out.println("<p>Deserialized string:</p>"); out.println("<p>" + deserializedString + "</p>"); %> </body> </html>
對數據gzip解壓,而後 反序列化。
在首頁中點擊 Serialized Java Object in body, compressed in GZIP, burp 抓包
下面的一個問題是咱們怎麼這個這東西就是 序列化對象的數據呢? java 序列化對象的 開頭 2個字節爲 0xaced , 因此咱們看到數據開頭爲 0xaced ,就能夠大體推測這是序列化的對象。下面在介紹一個 Decompressor 插件,它用於自動的把 gzip 壓縮的數據解壓。該插件也可在 BApp Store中安裝。安裝後,在抓到的數據包中的數據是以 gzip壓縮時,會增長一個 tab 來顯示解壓後的數據。
因此這是以 gzip壓縮的 序列化對象 ,而後將它發送到 Java-Deserialization-Scanner 插件, 點擊 Attack Gzip 便可(其餘設置和以前那個例子同樣)。
總結
該插件使得咱們發現和測試 Java 反序列化漏洞 更加容易,並且他還提供了幾種針對序列化數據被編碼的場景進行利用的方式,同時因爲該插件是開源的,因此很方便測試人員在測試時根據狀況進行擴展。
參考
http://blog.nsfocus.net/java-deserialization-vulnerability-comments/
https://github.com/federicodotta/Java-Deserialization-Scanner