fastjson反序列化漏洞研究(上)


前言

最近護網期間,又聽說fastjson傳出“0day”,但網上並沒有預警,在github上fastjson庫中也有人提問關於fastjson反序列化漏洞的詳情。也有人說是可能出現了新的繞過方式。不管怎樣這都激起了我研究該漏洞的欲望,以前也研究過java的反序列化漏洞,但是沒有具體研究過fastjson這個,借此機會好好分析下這個洞。

正文

fastjson主要功能就是實現對象和json字符串相互進行轉換,這樣方便傳輸。先簡單了解下fastjson的用法,如下圖所示,一般通過JSONObject.toJSONString()將對象序列化為json字符串(注意,這個和以往所說的java序列化是有些不一樣的,平時所說的java序列化是序列化為字節流,也就是一段亂碼,通常在http中傳輸還會base64編碼下,編碼前十六進制是以aced0005開頭,base64編碼后是以rO0AB開頭,黑盒測試中可以通過這個來挖掘java的反序列化漏洞,這是題外話了。)

 

 

一般開發者就用第一種方法輸出json字符串,這里測試代碼中估計將第二種方法寫出來,是想告訴大家fastjson可以識別json中的一些特殊的屬性,比如說如果json字符串中某個key是“@type”,它就認為該key對應的value用於指定該json字符串對應對象的類型。

之后可以再通過JSONObject.parseObject()、JSON.parse()、JSON.parseObject()等方法將json字符串反序列化為對象,大同小異,fastjson的反序列化漏洞就是存在於JSONObject.parseObject(),所以以它為例進行講解。以如下圖:

既然必須指定對象類型,但是實際開發中大多數時候是並不知道對象類型的,這樣怎么辦呢?通常開發者會將對象類型設置為Object.class,畢竟java中所有類都是Object的子類。那這樣又會出現一個問題,既然所有類都是Object的子類,fastjson如何知道反序列化對象的類型是什么呢?

這就是我們第一張圖中的代碼為什么會打印兩種json字符串出來,fastjson可以通過識別“@type”對應的value來指定對象類型。這也是為什么第二張圖中的代碼運行后,通過JSONObject.parseObject(json, Object.class)反序列化時,帶有“@type”的json字符串能成功反序列化為User對象,而不帶“@type”的json字符串則不能成功反序列化。

而fastjson的反序列化漏洞就出現在這里,當json字符串可控時(實際常見中就是我們經常抓包會在請求中看到一些json字符串,而我們是可以隨意修改這些字符串的,這就是可控),我們可以反序列化出任意對象,且fastjson返序列化時會調用User.class中屬性的getter和setter方法,如下圖我們可以看到,反序列化后的對象屬性是有值的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM