前言
BeanUtils – Commons (apache.org)
大多数Java开发人员习惯于为属性获取器和设置器创建符合JavaBeans命名模式的Java类。通过调用相应的getXxx和setXxx方法,直接访问这些方法是很自然的。但是,在某些情况下,需要动态访问Java对象属性(不需要调用属性getter和setter方法的编译知识)。
环境搭建
- jdk:jdk8u65
- CB:commons-beanutils 1.8.3
- pom.xml 添加
1 | <!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils --> |
CommonsBeanutils和JavaBean
CommonsBeanutils 是应用于 javabean 的工具,它提供了对普通Java类对象(也称为JavaBean)的一些操作方法
javaBean,是指符合如下标准的Java类:
- 类是公共的
- 有一个无参的公共的构造器
- 有私有属性,且须有对应的get、set方法去设置属性
- 对于boolean类型的成员变量,允许使用”is”代替上面的”get”和”set”
org.apache.commons.beanutils.PropertyUtils#getProperty可以直接调用任意JavaBean的getter方法
PropertyUtils (Apache Commons BeanUtils 1.9.4 API)
寻找利用点
java.util.PriorityQueue的利用需要寻找执行 java.util.Comparator 接口的 compare() 方法
在commons-beanutils包中就存 在一个:org.apache.commons.beanutils.BeanComparator
。
BeanComparator (Apache Commons BeanUtils 1.9.4 API)
按指定的 Bean 属性比较两个 Bean。
这是他的compare()方法。
1 | public int compare(Object o1, Object o2) { |
方法传入两个对象,如果 this.property
为空,则直接比较这两个对象;如果 this.property
不为空,则用 PropertyUtils.getProperty
分别取这两个对象的 this.property
属性,比较属性的值。
利用 TemplatesImpl 动态加载恶意类的利用链为
1 | /* |
getOutputProperties()
方法即其 _outputProperties 属性的 getter 方法是加载恶意字节码的起点,我们可以利用前面提到的,commons-beanutils里的PropertyUtils.getProperty()
去调用getter,第一个参数传恶意的TemplatesImpl对象,第二个参数传”property”,而 property 的值为 outputProperties 时,将会自动调用getter,也就是 TemplatesImpl#getOutputProperties() 方法,触发代码执行。
CB1利用链构造
利用链
1 | PriorityQueue.readObject() |
EXP
1 | import java.io.ByteArrayInputStream; |
无依赖的Shiro反序列化利用链
Shiro-550利用的难点
之前利用Shiro-550是用的CC6需要用到commons-collections,那如果目标环境没有这个包,那就是没法利用的,这个时候就需要利用CB链了,因为Shiro是依赖于commons-beanutils的。当然这个时候需要注意一个东西叫做serialVersionUID
计算serialVersionUID
是将类名,属性名,属性修饰符,继承的接口,属性类型,名称,方法,静态代码块等等…这些都考虑进去了,都写到一个DataOutputStream
中,然后再做hash运算
。为了防止如果两个不同版本的库使用了同一个类,而这两个类可能有一些方法和属性有了变化,此时在序列化通 信的时候就可能因为不兼容导致出现隐患。
shiro550中自带CommonsBeanutils 1.8.3
为了调用BeanComparator.compare()来寻找实现Comparator接口
找到了CaseInsensitiveComparator
。并且实现 java.io.Serializable 接口 Java、shiro或commons-beanutils自带,且兼容性强
A Comparator that orders String objects as by compareToIgnoreCase.
一个比较器,按compareToIgnoreCase排序字符串对象。
This comparator is serializable.
这个比较器是可序列化的。
1 | public static final Comparator<String> CASE_INSENSITIVE_ORDER |
通过 String.CASE_INSENSITIVE_ORDER
即可拿到上下文中的 CaseInsensitiveComparator
对 象,用它来实例化 BeanComparator
,并且添加字符串到优先队列
1 |
|