在Collections
组件中提供了一个非常重要的类: org.apache.commons.collections.functors.InvokerTransformer
,这个类实现了:java.io.Serializable
接口。2015年有研究者发现利用InvokerTransformer
类的transform
方法可以实现Java反序列化RCE
,并提供了利用方法:CommonsCollections1.java。InvokerTransformer
类实现了org.apache.commons.collections.Transformer
接口,Transformer
提供了一个对象转换方法:transform
,主要用于将输入对象转换为输出对象。InvokerTransformer
类的主要作用就是利用Java反射机制来创建类实例。InvokerTransformer
类的transform
方法:
public Object transform(Object input) {
if (input == null) {
return null;
}
try {
// 获取输入类的类对象
Class cls = input.getClass();
// 通过输入的方法名和方法参数,获取指定的反射方法对象
Method method = cls.getMethod(iMethodName, iParamTypes);
// 反射调用指定的方法并返回方法调用结果
return method.invoke(input, iArgs);
} catch (Exception ex) {
// 省去异常处理部分代码
}
}
使用InvokerTransformer
实现调用本地命令执行方法:
public static void main(String[] args) {
// 定义需要执行的本地系统命令
String cmd = "open -a Calculator.app";
// 构建transformer对象
InvokerTransformer transformer = new InvokerTransformer(
"exec", new Class[]{String.class}, new Object[]{cmd}
);
// 传入Runtime实例,执行对象转换操作
transformer.transform(Runtime.getRuntime());
}
上述实例演示了通过InvokerTransformer
的反射机制来调用java.lang.Runtime
来实现命令执行,但在真实的漏洞利用场景我们是没法在调用transformer.transform
的时候直接传入Runtime.getRuntime()
对象的。