CommonsCollections1链分析
前言
之前的urldns链是反序列化利用链中比较简单的,在实战中还是需要能直接执行命令的链,本篇主要分析CC1这个链。
0x01 POC1执行
0x02 POC1分析
Transformer
在代码的最开始先是new了一个Transformer类型的数组,Transformer本身是一个接口,而new的这个数组是Transformer的实现类对对象:
再分别来看数组里面的值:
ConstantTransformer
第一个值:new ConstantTransformer(Runtime.class)
这个方法跟进去之后,看到这个类是实现了Transformer, Serializable接口,里面的ConstantTransformer方法是重写了有参构造,传入的参数就是Runtime.class,然后赋值给属性Object的变量,最终返回回来生成的实例化对象。
下面是断点调试的返回,返回了runtime的类
InvokerTransformer
第二个值:new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] {"getRuntime", new Class[0] })
可以看到InvokerTransformer同样实现了Transformer, Serializable接口,并且重写的这个有参构造里面,有三个参数:
第一个是方法名,第二个是参数类型,第三个是参数的值。
- String iMethodName:要调用的方法名
- Class[] iParamTypes:传入方法的参数类型
- Object[] args:要传入的参数
后面一共初始化了三次,每次的参数值为:
第一次:
getMethod,null,getRuntime
第二次:
invoke,null,null
第三次:
exec,null,Calculator.app
ChainedTransformer
Transformer transformerChain = new ChainedTransformer(transformers);
ChainedTransformer这个类将之前的transformers数组通过循环的方式调用每个元素的trandsform方法,将得到的结果再传入下一次的trandform方法中。
第一次执行,将runtime传入到了参数里面
第二次传入Runtime.getRuntime()
第三次将返回的实例化对象传入exec参数里面:
这样通过ConstantTransformer得到Runtime.class,然后再InvokerTransformer反射得到getRuntime方法,然后通过反射执行invoke才能去调用getRuntime方法,这样得到一个Runtime对象,然后再去调用Runtime对象的exec方法去达到命令执行。
这样链子有了,怎么才能用呢?
TransformedMap
查看源码:
可以看到TransformwdMap的decorate方法根据传入的参数重新实例化一个TransformedMap对象,再看下面的put方法,不管是key
还是value
都会间接调用transform
方法,而这里的this.valueTransformer
也就是transformerChain
,也就是说只要构造一个TransformedMap并且去修改value值,就能触发
最终执行弹出计算器。
POC2分析
在上面是我们手动添加了put操作,但是在反序列化中我们需要找到一个类,直接或者间接的调用这种类似put的操作。
这个类就是AnnotationInvocationHandler,他重写了readObject方法:
然后在yso项目中,作者使用的不是TransformedMap而是LazyMap,LazyMap中可以通过get方法调用transform:
然后AnnotationInvocationHandler中的invoke方法可以调用LazyMap#get:
这里注意调试该链需要用jdk小于8u71的版本,因为之后的版本AnnotationInvocationHandler#readObject方法被官方修改了。
下面为完整POC:
这里最后采用了java动态代理机制,创建了动态代理map对象proxymap
动态代理对象与真实对象会实现相同的接口,也就意味着会有相同的方法。
最后传入Map类的动态代理对象proxyMap作为参数重新赋值给handler对象,当调用到被代理对象的任何方法时,都会先调用InvocationHandler
接口中的invoke
方法,而AnnotationInvocationHandler
正好实现了该接口,从而达到命令执行。
总结
最终利用链为:
参考
https://www.anquanke.com/post/id/248653
https://www.cnblogs.com/nice0e3/p/13779857.html
https://www.cnblogs.com/CoLo/p/15225390.html
__EOF__

本文链接:https://www.cnblogs.com/N0r4h/p/15975781.html
关于博主:一个废物到自闭的人
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!