在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()对象的。
