一、概述

URLDNS 是ysoserial中利用链的一个名字,通常用于检测是否存在Java反序列化漏洞。该利用链具有如下特点:

不限制jdk版本,使用Java内置类,对第三方依赖没有要求

目标无回显,可以通过DNS请求来验证是否存在反序列化漏洞

URLDNS利用链,只能发起DNS请求,并不能进行其他利用

二、流程图

三、原理

java.util.HashMap 重写了 readObject, 在反序列化时会调用 hash 函数计算 key 的 hashCode.而 java.net.URL 的 hashCode 在计算时会调用 getHostAddress 来解析域名, 从而发出 DNS 请求.

四、过程概述

1、HashMap.readObject

在调用readObject方法时添加断点

调试到断点位置,步入此步,进入HashMap.readObject

private void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException {
// Read in the threshold (ignored), loadfactor, and any hidden stuff
s.defaultReadObject();
reinitialize();
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new InvalidObjectException("Illegal load factor: " +
loadFactor);
s.readInt(); // Read and ignore number of buckets
int mappings = s.readInt(); // Read number of mappings (size)
if (mappings < 0)
throw new InvalidObjectException("Illegal mappings count: " +
mappings);
else if (mappings > 0) { // (if zero, use defaults)
// Size the table using given load factor only if within
// range of 0.25...4.0
float lf = Math.min(Math.max(0.25f, loadFactor), 4.0f);
float fc = (float)mappings / lf + 1.0f;
int cap = ((fc < DEFAULT_INITIAL_CAPACITY) ?
DEFAULT_INITIAL_CAPACITY :
(fc >= MAXIMUM_CAPACITY) ?
MAXIMUM_CAPACITY :
tableSizeFor((int)fc));
float ft = (float)cap * lf;
threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ?
(int)ft : Integer.MAX_VALUE);
@SuppressWarnings({"rawtypes","unchecked"})
Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
table = tab; // Read the keys and values, and put the mappings in the HashMap
for (int i = 0; i < mappings; i++) {
@SuppressWarnings("unchecked")
K key = (K) s.readObject();
@SuppressWarnings("unchecked")
V value = (V) s.readObject();
putVal(hash(key), key, value, false, false);
}
}
}

关注putVal方法,putVal是往HashMap中放入键值对的方法,这里调用了hash方法来处理key,跟进hash方法(步入putVal后,单击hash):

2、HashMap.hash

    static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

这里又调用了key.hashcode方法,而key此时是我们传入的 java.net.URL 对象,那么跟进到这个类的hashCode()方法看下

3、URL.hashCode

public synchronized int hashCode() {
if (hashCode != -1)
return hashCode; hashCode = handler.hashCode(this);
return hashCode;
}

当hashCode字段等于-1时会进行handler.hashCode(this)计算,跟进handler发现,定义是

transient URLStreamHandler handler; // transient 关键字,修饰Java序列化对象时,不需要序列化的属性

跟进java.net.URLStreamHandler#hashCode()

4、java.net.URLStreamHandler#hashCode()

protected int hashCode(URL u) {
int h = 0; // Generate the protocol part.
String protocol = u.getProtocol();
if (protocol != null)
h += protocol.hashCode(); // Generate the host part.
InetAddress addr = getHostAddress(u);
if (addr != null) {
h += addr.hashCode();
} else {
String host = u.getHost();
if (host != null)
h += host.toLowerCase().hashCode();
} // Generate the file part.
String file = u.getFile();
if (file != null)
h += file.hashCode(); // Generate the port part.
if (u.getPort() == -1)
h += getDefaultPort();
else
h += u.getPort(); // Generate the ref part.
String ref = u.getRef();
if (ref != null)
h += ref.hashCode(); return h;
}

u 是我们传入的url,在调用getHostAddress方法时,会进行dns查询。

五、URL_DNS_POC构造

1、生成序列化文件

package com.mzy.URLDNS;

import java.io.*;

public class Serializable {
public static void serializable(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("mzy.ser"));
oos.writeObject(obj);
oos.close();
} public static void main(String[] args) throws IOException {
Student student = new Student("mzy",21);
serializable(student);
}
}
----------------------------------------------------- 运行此程序会在当前目录生成一个mm.ser的序列化文件

2、反序列化

package com.mzy.URLDNS;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream; public class unSerializable {
public static Object unserializable(String Filename) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj= ois.readObject();
return obj;
} public static void main(String[] args) throws IOException, ClassNotFoundException {
Student stu = (Student) unserializable("mm.ser");
System.out.println(stu);
} }

3、实验结果

六、总结

JDK1.8下的调用路线:

HashMap->readObject()

HashMap->hash()

URL->hashCode()

URLStreamHandler->hashCode()

URLStreamHandler->getHostAddress()

InetAddress->getByName()

URLDNS链分析的更多相关文章

  1. Java安全之URLDNS链

    Java安全之URLDNS链 0x00 前言 在学习Java的反序列化漏洞的时候,就不得不学习他的一个利用链.很多刚刚入门的对于利用链这个词可能比较陌生.那么这里先来了解一下Java反序列化和反序列化 ...

  2. yso中URLDNS的pop链分析(重新分析整理)

    #发现之前对这个链关注的点有点问题,重新分析了一下 由于最近面试的过程中被问到了yso中URLDNS这个pop链的工作原理,当时面试因为是谈到shiro的怎么检测和怎么攻击时谈到了这个.其实在实战中用 ...

  3. ysoserial分析【二】7u21和URLDNS

    目录 7u21 gadget链分析 hashCode绕过 参考 URLDNS 7u21 7u21中利用了TemplatesImpl来执行命令,结合动态代理.AnnotationInvocationHa ...

  4. [原创]基于SpringAOP开发的方法调用链分析框架

    新人熟悉项目必备工具!基于SpringAOP开发的一款方法调用链分析插件,简单到只需要一个注解,异步非阻塞,完美嵌入Spring Cloud.Dubbo项目!再也不用担心搞不懂项目! 很多新人进入一家 ...

  5. 行为链分析zipkin

    行为链分析zipkin - 跑zipkin python例子 https://github.com/openzipkin/pyramid_zipkin-example # get the latest ...

  6. Linux内核通知链分析【转】

    转自:http://www.cnblogs.com/jason-lu/articles/2807758.html Linux内核通知链分析 1. 引言 Linux是单内核架构(monolithic k ...

  7. ThinkPHP v5.1.x POP 链分析

    环境:MacOS 10.13 MAMAP Prophp 7.0.33 + xdebugVisual Studio Code前言我所理解的 POP Chain:利用魔术方法并巧妙构造特殊属性调用一系列函 ...

  8. Java安全之FastJson JdbcRowSetImpl 链分析

    Java安全之FastJson JdbcRowSetImpl 链分析 0x00 前言 续上文的Fastjson TemplatesImpl链分析,接着来学习JdbcRowSetImpl 利用链,Jdb ...

  9. YsoSerial 工具常用Payload分析之URLDNS

    本文假设你对Java基本数据结构.Java反序列化.高级特性(反射.动态代理)等有一定的了解. 背景 YsoSerial是一款反序列化利用的便捷工具,可以很方便的生成基于多种环境的反序列化EXP.ja ...

  10. URLDNS分析

    学习了很久的Java基础,也看了很多的Java反序列化分析,现在也来分析学习哈最基础的URLDNS反序列化吧. Java反序列化基础 为了方便数据的存储,于是乎有了现在的Java序列化于反序列化.序列 ...

随机推荐

  1. 强化学习从基础到进阶-常见问题和面试必知必答[4]::深度Q网络-DQN、double DQN、经验回放、rainbow、分布式DQN

    强化学习从基础到进阶-常见问题和面试必知必答[4]::深度Q网络-DQN.double DQN.经验回放.rainbow.分布式DQN 1.核心词汇 深度Q网络(deep Q-network,DQN) ...

  2. LyScript 实现Hook改写MessageBox

    LyScript 可实现自定义汇编指令的替换功能,用户可以自行编写一段汇编指令,将程序中特定的通用函数进行功能改写与转向操作,此功能原理是简单的Hook操作. 插件地址:https://github. ...

  3. 由刷题学习 heapq

    今日一题是 面试题 17.14. 最小K个数 https://leetcode-cn.com/problems/smallest-k-lcci/ 还好 提示 0 <= len(arr) < ...

  4. 17.5 稀疏调拨的内存映射文件--《Windows核心编程》

    原文链接:https://www.likecs.com/show-306421749.html,原文中代码是C++MFC程序,更详细.本文是C语言测试代码. (1)稀疏文件(Sparse File)定 ...

  5. Python学习之Pytorch

    一.如何查看本机是否安装了Pytorch 在Python环境中查看是否安装了PyTorch可以通过几个简单的步骤来完成.这里有一些方法: 使用Python命令行: 打开你的命令行工具(比如Termin ...

  6. 欧拉公式 Euler's Formula

    欧拉公式是数学中最重要的公式之一, 它涉及到了复数, 无理数, 三角函数, 简单优美 \(e^{i\theta} = cos(\theta) + isin(\theta)\) 欧拉公式代表的含义并不是 ...

  7. 将CH340G的USB2TTL扩展出RTS, DTR口

    关于 要测试串口中的RTS和DTR, 最常见的USB2TTL基于CH340G, 并没有引出RTS, 然而这个IC是支持这些信号的, 只是PCB上将这些pin留空了. 这块板子的PCB 电路 详细信息可 ...

  8. 【Unity3D】空间和变换

    1 空间 1.1 左右手坐标系及其法则 1.1.1 左右手坐标系 左手坐标系与右手坐标系 ​ Unity 局部空间.世界空间.裁剪空间.屏幕空间都采用左手坐标系,只有观察空间采用右手坐标系. ​ 左右 ...

  9. pico命令

    pico命令 pico是一个简单易用.以显示导向为主的文字编辑程序,具有pine电子邮件编写器的风格.在现代Linux系统上,nano即pico的GNU版本是默认安装的,在使用上和pico一模一样. ...

  10. springboot项目读取自定义的properties文件

    现在我们要在某个地方读取config.properties里的这几个属性值 这里使用三个注解即可读取自定义的配置文件内容(注意这里需要写他的setter和getter方法) @Component #注 ...