91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何進行Fastjson 1.2.24反序列化漏洞深度分析

發布時間:2021-12-14 10:09:42 來源:億速云 閱讀:158 作者:柒染 欄目:安全技術

如何進行Fastjson 1.2.24反序列化漏洞深度分析,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

前言

FastJson是alibaba的一款開源JSON解析庫,可用于將Java對象轉換為其JSON表示形式,也可以用于將JSON字符串轉換為等效的Java對象。近幾年來fastjson漏洞層出不窮,下面將會談談近幾年來fastjson
RCE漏洞的源頭:17年fastjson爆出的1.2.24反序列化漏洞。以這個漏洞為基礎,詳細分析fastjson漏洞的一些細節問題。

關于Fastjson 1.2.24反序列化漏洞,自從17年以來已經有很多人分析過了,一些基礎內容本文就不再陳述了。此次漏洞簡單來說,就是Fastjson通過parseObject/parse將傳入的字符串反序列化為Java對象時由于沒有進行合理檢查而導致的

小編將著重分析一下這個漏洞沒有被詳細介紹過的細節問題,如下:

1、parseObject(String text) 、parse (String text)、 parseObject(String text, Class\ clazz)三個方法從代碼層面上來看,究竟有何不同?

2、使用TemplatesImpl攻擊調用鏈路構造poc時,為什么一定需要構造_tfactory以及_name字段?

3、_outputProperties與其getter方法getOutputProperties()方法名字并不完全一致是如何解決的?

除此之外,在介紹TemplatesImpl攻擊調用鏈路時,以模擬尋找漏洞利用鏈的思路,從最終的執行點開始向上尋找入口,模擬還原出挖掘這個TemplatesImpl利用鏈的完整過程。

漏洞分析

關于parse (String text) 、parseObject(String text)、 parseObject(String text, Class\ clazz)三個方法,我們進行一個測試

如何進行Fastjson 1.2.24反序列化漏洞深度分析

FastJsonTest類中變量以及其setter/getter關系如下表

| | public String t1 | private int t2 | private Boolean t3 | private Properties t4 | private Properties t5 |
| ------ | ---------------- | -------------- | ------------------ | --------------------- | --------------------- |
| setter | 有 | 有 | 無 | 無 | 有 |
| getter | 有 | 有 | 有 | 有 | 有 |

接下來,我們分別使用下圖三種方式分別將JSON字符串反序列化成Java對象

如何進行Fastjson 1.2.24反序列化漏洞深度分析

1、Object obj = JSON.parse(jsonstr);

2、Object obj = JSON.parseObject(jsonstr, FastJsonTest.class);

3、Object obj = JSON.parseObject(jsonstr);

首先我們運行一下Object obj = JSON.parse(jsonstr);這種方式

如何進行Fastjson 1.2.24反序列化漏洞深度分析

結果:

setT1() 、setT2() 、getT4() 、setT5() 被調用

JSON.parse(jsonstr)最終返回FastJsonTest類的對象

接著我們運行下Object obj = JSON.parseObject(jsonstr, FastJsonTest.class);

如何進行Fastjson 1.2.24反序列化漏洞深度分析結果:

與JSON.parse(jsonstr);這種方式一樣setT1() 、setT2() 、getT4() 、setT5() 被調用

JSON.parse(jsonstr)最終返回FastJsonTest類的對象

最后我們運行下Object obj = JSON.parseObject(jsonstr);

如何進行Fastjson 1.2.24反序列化漏洞深度分析

結果:

這次結果與上兩次大不相同,FastJsonTest類中的所有getter與setter都被調用了,并且JSON.parseObject(jsonstr);返回一個JSONObject對象

通過上文運行結果,不難發現有三個問題

1. 使用JSON.parse(jsonstr);與JSON.parseObject(jsonstr, FastJsonTest.class);兩種方式執行后的返回結果完全相同,且FastJsonTest類中getter與setter方法調用情況也完全一致,parse(jsonstr)與parseObject(jsonstr, FastJsonTest.class)有何關聯呢?

2. 使用JSON.parse(jsonstr);與JSON.parseObject(jsonstr, FastJsonTest.class);兩種方式時,被調用的getter與setter方法分別為setT1()、setT2()、setT5()、getT4()。FastJsonTest類中一共有五個getter方法,分別為getT1()、getT2()、getT3()、getT4()、getT5(),為什么僅僅getT4被調用了呢?

3. JSON.parseObject(jsonstr);為什么返回值為JSONObject類對象,且將FastJsonTest類中的所有getter與setter都被調用了

問題一解答

經過調試可以發現,無論使用JSON.parse(jsonstr);或是JSON.parseObject(jsonstr,
FastJsonTest.class);方式解析json字符串,程序最終都會調用位于com/alibaba/fastjson/util/JavaBeanInfo.java中的JavaBeanInfo.build()
方法來獲取并保存目標Java類中的成員變量以及其對應的setter、getter

首先來看下JSON.parse(jsonstr)這種方式,當程序執行到JavaBeanInfo.build()
方法時情景如下圖

如何進行Fastjson 1.2.24反序列化漏洞深度分析

此時的調用鏈如下圖

如何進行Fastjson 1.2.24反序列化漏洞深度分析

此時傳入JavaBeanInfo.build() 方法的參數值如下圖

如何進行Fastjson 1.2.24反序列化漏洞深度分析

再來看下JSON.parseObject(jsonstr,
FastJsonTest.class)這種方式,當程序執行到JavaBeanInfo.build() 方法時情景如下圖

如何進行Fastjson 1.2.24反序列化漏洞深度分析

此時的調用鏈如下圖

如何進行Fastjson 1.2.24反序列化漏洞深度分析

此時傳入JavaBeanInfo.build() 方法的參數值如下圖

如何進行Fastjson 1.2.24反序列化漏洞深度分析

二者執行到JavaBeanInfo.build() 方法時調用鏈對比如下

如何進行Fastjson 1.2.24反序列化漏洞深度分析

可見二者后面的調用鏈是完全一樣的。二者不同點在于調用JavaBeanInfo.build()
方法時傳入clazz參數的來源不同:

JSON.parseObject(jsonstr, FastJsonTest.class)在調用JavaBeanInfo.build()
方法時傳入的clazz參數源于parseObject方法中第二個參數中指定的“FastJsonTest.class”。

JSON.parse(jsonstr);這種方式調用JavaBeanInfo.build()
方法時傳入的clazz參數獲取于json字符串中\@type字段的值。

如何進行Fastjson 1.2.24反序列化漏洞深度分析

關于JSON.parse(jsonstr);從json字符串中\@type字段獲取clazz參數,具體代碼如下

如何進行Fastjson 1.2.24反序列化漏洞深度分析

程序通過解析傳入的json字符串的\@type字段值來獲取之后傳入JavaBeanInfo.build()
方法的clazz參數

因此,只要Json字符串的\@type字段值與JSON.parseObject(jsonstr,
FastJsonTest.class);中第二個參數中類名一致,見下圖

如何進行Fastjson 1.2.24反序列化漏洞深度分析

JSON.parse(jsonstr)與JSON.parseObject(jsonstr,FastJsonTest.class)這兩種方式執行的過程與結果是完全一致的。二者唯一的區別就是獲取clazz參數的途徑不同

問題二解答

> 使用JSON.parse(jsonstr)與JSON.parseObject(jsonstr, FastJsonTest.class)兩種方式時,被調用的getter與setter方法分別為setT1()、setT2()、setT5()、getT4()。FastJsonTest類中一共有五個getter方法,分別為getT1()、getT2()、getT3()、getT4()、getT5(),為什么僅僅getT4被調用了呢?

這個問題要從JavaBeanInfo.build() 方法中獲取答案:

通過上文的分析可以發現,程序會使用JavaBeanInfo.build()
方法對傳入的json字符串進行解析。在JavaBeanInfo.build()
方法中,程序將會創建一個fieldList數組來存放后續將要處理的目標類的 setter
方法及某些特定條件的 getter
方法。通過上文的結果可見,目標類中所有的setter方法都可以被調用,但只有getT4()這一個getter被調用,那么到底什么樣的getter
方法可以滿足要求并被加入fieldList數組中呢?

在JavaBeanInfo.build() 方法可見如下代碼

如何進行Fastjson 1.2.24反序列化漏洞深度分析

程序從clazz(目標類對象)中通過getMethods獲取本類以及父類或者父接口中所有的公共方法,接著進行循環判斷這些方法是否可以加入fieldList中以便后續處理

條件一、方法名需要長于4

如何進行Fastjson 1.2.24反序列化漏洞深度分析

條件二、不是靜態方法

如何進行Fastjson 1.2.24反序列化漏洞深度分析

條件三、以get字符串開頭,且第四個字符需要是大寫字母

如何進行Fastjson 1.2.24反序列化漏洞深度分析

條件四、方法不能有參數傳入

如何進行Fastjson 1.2.24反序列化漏洞深度分析

條件五、繼承自Collection \|\| Map \|\| AtomicBoolean \|\| AtomicInteger \|\|
AtomicLong

如何進行Fastjson 1.2.24反序列化漏洞深度分析

條件六、此getter不能有setter方法(程序會先將目標類中所有的setter加入fieldList列表,因此可以通過讀取fieldList列表來判斷此類中的getter方法有沒有setter)

如何進行Fastjson 1.2.24反序列化漏洞深度分析

問題三解答

JSON.parseObject(jsonstr)為什么返回值為JSONObject類對象,且將FastJsonTest類中的所有getter與setter都被調用了

通過上文的分析可以發現,JSON.parse(jsonstr)與JSON.parseObject(jsonstr,
FastJsonTest.class)兩種方式從執行流程幾乎一樣,結果也完全相同;然而使用JSON.parseObject(jsonstr)這種方式,執行的結果與返回值卻與前兩者不同:JSON.parseObject(jsonstr)返回值為JSONObject類對象,且將FastJsonTest類中的所有getter與setter都被調用。

通過閱讀源碼可以發現JSON.parseObject(String text)實現如下

如何進行Fastjson 1.2.24反序列化漏洞深度分析

parseObject(String text)其實就是執行了parse(),隨后將返回的Java對象通過JSON.toJSON()轉為
JSONObject對象。

JSON.toJSON()方法會將目標類中所有getter方法記錄下來,見下圖

如何進行Fastjson 1.2.24反序列化漏洞深度分析

隨后通過反射依次調用目標類中所有的getter方法

如何進行Fastjson 1.2.24反序列化漏洞深度分析

完整的調用鏈如下

如何進行Fastjson 1.2.24反序列化漏洞深度分析

總結:

上文例子中,JSON.parse(jsonstr)與JSON.parseObject(jsonstr, FastJsonTest.class)可以認為是完全一樣的,而parseObject(String text)是在二者的基礎上又執行了一次JSON.toJSON()

parse(String text)、parseObject(String text)與parseObject(String text, Class\ clazz)目標類Setter\\Getter調用情況

| | parse(String text) | parseObject(String text) | parseObject(String text, Class\ clazz) |
| -------------- | ------------------ | ------------------------ | ------------------------------------------ |
| Setter調用情況 | 全部 | 全部 | 全部 |
| Getter調用情況 | 部分 | 部分 | 全部 |

此外,如果目標類中私有變量沒有setter方法,但是在反序列化時仍想給這個變量賦值,則需要使用Feature.SupportNonPublicField參數。(在下文中,為TemplatesImpl類中無setter方法的私有變量_tfactory以及_name賦值運用到的就是這個知識點)

TemplatesImpl攻擊調用鏈路

針對于上文的分析可以發現,無論使用哪種方式處理JSON字符串,都會有機會調用目標類中符合要求的Getter方法

如果一個類中的Getter方法滿足調用條件并且存在可利用點,那么這個攻擊鏈就產生了。

TemplatesImpl類恰好滿足這個要求:

com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl中存在一個名為_outputPropertiesget的私有變量,其getter方法中存在利用點,這個getter方法恰好滿足了調用條件,在JSON字符串被解析時可以調用其在調用FastJson.parseObject()序列化為Java對象時會被調用,下面我們詳細說明一下:

首先我們從漏洞點開始,一層層往入口分析:首先看一下TemplatesImpl類中的getTransletInstance方法

如何進行Fastjson 1.2.24反序列化漏洞深度分析

其中455行調用_class[_transletIndex]的newInstance( )方法來實例化對象的操作

我們看一下_class[_transletIndex]是如何獲取的,是否可以控制

\_class與_transletIndex值皆由451行處defineTransletClasses()方法中獲取

如何進行Fastjson 1.2.24反序列化漏洞深度分析

我們跟入defineTransletClasses()方法中一探究竟

如何進行Fastjson 1.2.24反序列化漏洞深度分析

在defineTransletClasses()方法中,首先在393行判斷_bytecodes值是否為空

如何進行Fastjson 1.2.24反序列化漏洞深度分析

值得注意的是,_bytecodes變量是TemplatesImpl類的成員變量

如何進行Fastjson 1.2.24反序列化漏洞深度分析

因此_bytecodes變量可以在構造json字符串時傳入,在構造poc時屬于可控變量

\_bytecodes變量非空值時,程序將會繼續執行至下圖紅框處

如何進行Fastjson 1.2.24反序列化漏洞深度分析

此時,需要滿足_tfactory變量不為null,否則導致程序異常退出。這就是為什么公開的poc中需要設置設置_tfactory為{
}的原因。因為_tfactory為私有變量,且無setter方法,這里需要指定Feature.SupportNonPublicField參數來為_tfactory賦值

接下來,程序將會把_bytecodes變量中的值循環取出并通過loader.defineClass處理后賦值給_class[i]

如何進行Fastjson 1.2.24反序列化漏洞深度分析

我們首先來看下loader.defineClass方法是什么

如何進行Fastjson 1.2.24反序列化漏洞深度分析

可見,loader.defineClass方法其實就是對ClassLoader.
defineClass的重寫。defineClass方法可以從傳入的字節碼轉化為Class

回頭分析下上述流程

如何進行Fastjson 1.2.24反序列化漏洞深度分析

\_bytecodes變量非空值時,程序將會把_bytecodes數組中的值循環取出,使用loader.defineClass方法從字節碼轉化為Class對象,隨后后賦值給_class[i]。

如果此時的class為main
class,_transletIndex變量值則會是此時_bytecodes數組中的下標值

因此當我們構造出_bytecodes:[evilCode]這樣的json字符串(evilCode字符串為我們構造的惡意類的字節碼)后,程序會將evilCode化為Class對象后賦值給_class[0]

現在回到getTransletInstance()方法中

如何進行Fastjson 1.2.24反序列化漏洞深度分析

此時的_class[_transletIndex]即為我們構造傳入的evilCode類

程序通過調用evilCode類的newInstance()方法來實例化對象的操作,這將導致我們構造的evilCode類中的惡意代碼被執行

但在此之前,需要在poc構造json字符串時使得成員變量_name不為空,否則程序還未執行到將evilCode類實例化就提前return

如何進行Fastjson 1.2.24反序列化漏洞深度分析

注意:由于私有變量_name沒有setter方法,在反序列化時想給這個變量賦值則需要使用Feature.SupportNonPublicField參數。

在分析完存在漏洞的getTransletInstance方法,我們需要找到一條調用鏈,這條調用鏈需要在使用fastjson處理json字符串時成功串連到存在漏洞的getTransletInstance方法上。

我們繼續向上跟蹤代碼

如何進行Fastjson 1.2.24反序列化漏洞深度分析

com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java
newTransformer()方法中調用了getTransletInstance()

繼續向上跟蹤

如何進行Fastjson 1.2.24反序列化漏洞深度分析

com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java
getOutputProperties()方法中調用了newTransformer()

getOutputProperties()方法為_outputProperties成員變量的getter方法

如何進行Fastjson 1.2.24反序列化漏洞深度分析

細心的讀者可能會發現,成員變量_outputProperties與其getter方法getOutputProperties()方法名字并不完全一致,多了一個下劃線,fastjson是如何將其對應的呢?

實際上,fastjson在解析的時候調用了一個smartMatch() 方法

如何進行Fastjson 1.2.24反序列化漏洞深度分析

在尋找_outputProperties的getter方法時,程序將下劃線置空,從而產生了成員變量_outputProperties與getter方法getOutputProperties()對應的形式

FastJson與TemplatesImpl的有趣結合

首先說TemplatesImpl類。經過上文分析可發現:TemplatesImpl中存在一個反序列化利用鏈,在反序列化過程中,如果該類的getOutputProperties()方法被調用,即可成功觸發代碼執行漏洞。

再來分析下FastJson:經過上文對FastJson三種不同途徑處理JSON字符串時關于getter方法被調用的條件來看,TemplatesImpl類_outputProperties成員變量的getter方法滿足被調用條件。無論通過fastjson哪種方式解析json字符串,都會觸發getOutputProperties()方法。

二者放在一起一拍即合:FastJson在反序列化TemplatesImpl類時會恰好觸發TemplatesImpl類的getOutputProperties()方法;TemplatesImpl類的getOutputProperties()方法被觸發就會引起反序列化代碼執行漏洞。所以說這個漏洞利用很是巧妙。

看完上述內容,你們掌握如何進行Fastjson 1.2.24反序列化漏洞深度分析的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

晋中市| 鄂托克旗| 苍梧县| 铁岭县| 石门县| 安西县| 海淀区| 蓝田县| 临沧市| 峡江县| 海伦市| 元氏县| 饶平县| 玉环县| 理塘县| 东宁县| 白朗县| 滕州市| 肇州县| 钟山县| 深州市| 会理县| 翁牛特旗| 宝丰县| 聊城市| SHOW| 法库县| 鸡西市| 庆安县| 南城县| 千阳县| 普定县| 南安市| 苏尼特左旗| 肥西县| 社会| 鹤庆县| 阜阳市| 光泽县| 临夏县| 定南县|