首页 > 其他分享 >URLDNS链

URLDNS链

时间:2022-10-22 21:34:38浏览次数:77  
标签:java hashCode URLDNS 序列化 方法 payload

1.前言

URLDNS利用链是反序列化中较为简单的一条,但利用效果是只能触发一次dns请求,而不能去执行命令。比较适用于漏洞验证这一块,而且URLDNS这条利用链并不依赖于第三方的类,而是JDK中内置的一些类和方法。

在一些漏洞利用没有回显的时候,我们也可以使用到该链来验证漏洞是否存在

2.ysoserial分析

使用ysoserial来进行分析,将项目导入IDEA中,下载pom.xml依赖,寻找程序入口

GeneratePayload的main方法
首先判段是否传入了两个参数,如果不是则打印帮助信息;是的话会依次分别赋值给payloadTypecommand变量。
之后实例化了一个需要继承ObjectPayload类的类实例化对象,跟进一下getPayloadClass方法,在ysoserial.payloads.ObjectPayload.Utils

先反射生成一个class对象,之后获取包名和类名并加上我们之前传入的payloadType参数并将返回值赋值给GeneratePayload的payloadclass

根据payloadclass实例化一个对象赋值给payload,之后调用getObject方法,跟进

该方法定义于ObjectPayload接口,继续跟进

可以看到该方法在36个利用链中都得到实现,这里进入URLDNS链看看

URLDNS类是实现了ObjectPayload接口,那么上面的操作就是根据输入的参数,获取类名并定位到该类中,也就是进入到利用链的类文件中,调用该类的getObject方法生成payload并将返回值(也就是序列化payload)赋值给object对象,继续回到GeneratePayload#main方法中

之后调用serialize()方法将payload序列化并打印输出。
payload生成流程就是这样,下面跟进去运行测试一下,生成一个URLDNS链的序列化payload,这里需要先设置一下参数

设置后直接运行

乱码数据就是上面分析过的,经过一系列操作生成的URLDNS序列化之后的payload字节序列

3.URLDNS链

URLDNS利用链是反序列化中较为简单的一条,但利用效果是只能触发一次dns请求,而不能去执行命令。比较适用于漏洞验证这一块,而且URLDNS这条利用链并不依赖于第三方的类,而是JDK中内置的一些类和方法。
在一些漏洞利用没有回显的时候,我们也可以使用到该链来验证漏洞是否存在
触发点在put方法,我们在put方法处打一个断点,在Edit configurations中设置好参数,debug mainclass文件即可

可以看到ht对象的类HashMap实现了序列化接口,是可以反序列化的

在此类中搜一下readObject方法,发现在最后调用了putVal方法进行了一个hash计算

回到断点处跟进一下put方法,参数的keyvalue都是我们输入的dnslog地址

进入put方法,可以看到调用了putVal方法,也就是readObject方法中的putVal方法

继续跟进,看一下hash方法

这里调用keyhashCode方法,回到urldns这个payload

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);

可知这里压入的key是一个java.net.URL对象
跟到java.net.URL的hashCode方法

这里的hashCode字段如果为-1,调用handler的hashCode方法,因此payload中通过反射设置了hashCode的值为-1
此处handler为java.net.URLStreamHandler的自定义子类SilentURLStreamHandler对象
跟到java.net.URLStreamHandler中的hashCode方法

第10行调用getHostAddress,继续跟进该方法

这里第10行调用了InetAddress.getByName,也就是一次dns查询
这里的参数u也就是payload中需要我们传入的参数String url。

而payload中的handler使用自定义的java.net.URLStreamHandler的子类SilentURLStreamHandler对象,原因是

  1. URLStreamHandler是抽象类不能直接实例化
  2. 是该子类重写了getHostAddress方法,可避免在生成payload时就触发dns请求。
    调用堆栈如下
getHostAddress:84, URLDNS$SilentURLStreamHandler (ysoserial.payloads)
hashCode:359, URLStreamHandler (java.net)
hashCode:885, URL (java.net)
hash:339, HashMap (java.util)
put:612, HashMap (java.util)
getObject:57, URLDNS (ysoserial.payloads)
main:34, GeneratePayload (ysoserial)

在URLDNS里面其实导致反序列化的根本原因是因为Hashmap重写了readobject反序列化方法,而重写后的readobject方法调用了putVal导致的一个利用链
参考文章:
Ysoserial利用链分析 - Escape-w - 博客园 (cnblogs.com)
Ysoserial URLDNS链分析 - Zh1z3ven - 博客园 (cnblogs.com)
Ysoserial URLDNS分析 - Y4er的博客

标签:java,hashCode,URLDNS,序列化,方法,payload
From: https://www.cnblogs.com/gk0d/p/16817370.html

相关文章