内容纲要

前言

本章我们来分析 Apache CommonsCollections5 Payload 的构造与利用

Java 反序列化漏洞(4) – Apache Commons Collections POP Gadget Chains 剖析 一文中 , 我有总结调用 transform() 方法的两种方式.

  • TransformedMap 攻击链
  • LazyMap攻击链

在分析LazyMap攻击链时 ,我提到了 TiedMapEntry 类 , 并且存在如下可供利用的方法调用链。

BadAttributeValueException.readObject() --->
TiedMapEntry.toString() --->
TiedMapEntry.getValue() --->
LazyMap.get()

可见 , 我们还可以通过 BadAttributeValueException 和 TiedMapEntry 两个类来调用 LazyMap.get() 方法 .

在 YSoSerial 中存在该利用链对应的 Payload , 即 : Apache CommonsCollections5 Payload.


CommonsCollections5

CommonsCollections5 Payload 复现

先拿 Payload 打一遍 , 浮现一下该漏洞.

复现环境 : JDK1.7_67 + Tomcat7 + CommonsCollections-3.1

  1. 添加参数 , 生成可利用的 ACC5 Payload .

  2. 加载 CommonsCollections-3.1 组件并启动 Tomcat7 , 将本地生成的 Payload 通过 Curl 工具发出.

    curl "http://localhost:8080/webdemotest_war_exploded/demotest" --data-binary @/tmp/payload.ser

    Payload 被成功执行 , 漏洞复现成功.


CommonsCollections5 Payload 构造

有了分析 ACC1 - ACC4 的基础 , 分析 ACC5 Payload 就不难了

构造 ChainedTransformer - ConstantTransformer - InvokerTransformer 反射调用链

这一段大家都比较熟悉 :

  • 通过 ConstantTransformer 类来获取 Runtime 类( Runtime.class 不能被序列化传输 , 所以反序列化时必须要通过 ConstantTransformer 类来获取 Runtime 实例对象 )
  • 通过 InvokerTransformer 类来指定反射调用的方法与参数
  • 通过 ChainedTransformer 类将多个反射调用组合起来 , 实现对 java.lang.Runtime.getRuntime().exec() 的调用.

最终返回的 Transformer[] 数组如下


构造 LazyMap 实例对象与 TiedMapEntry 实例对象

TiedMapEntry 构造方法中仅做了一些赋值操作.

注意此处 this.map 参数指向 LazyMap 实例对象.


构造 BadAttributeValueExpException 实例对象

查看 BadAttributeValueExpException 构造方法定义 , 如下:

当传入构造方法的参数 val 值不为 null 时 , 程序会调用 val.toString() 方法 , 将参数 val 转换成 String,class 类型

而在 BadAttributeValueExpException.readObject() 反序列化时 , 程序会判断变量 val 的类型 , 只有当 val 不为 String 类型且值不为 null 时 , 才会进入反序列化利用链 .

因此 , 在构造 Payload 时 , 需要先将 null 传入 BadAttributeValueExpException 构造方法中 , 避免 val 参数被转换成 String 类型 .

然后再通过 Java 反射机制获取生成 BadAttributeValueExpException 对象的 val 属性 , 并将其指向 TiedMapEntry 对象 . 由于 val 属性通过 Private 修饰符修饰 , 因此需要通过 setAccessible(true) 方法来设置访问权限 .


向 ChainedTransformer 对象填入触发序列化漏洞的反射调用链

这里直接通过 Reflections.setFieldValue() 方法替换 ChainedTransformer 对象的 iTransformers 属性值即可.

这样整个 Apache CommonsCollections5 Payload 就已经构造完毕 .


CommonsCollections5 Payload 利用

贴一下函数调用调用栈

没有什么难点 , 归根到底还是文章开头那一组函数调用 :

BadAttributeValueException.readObject() --->
TiedMapEntry.toString() --->
TiedMapEntry.getValue() --->
LazyMap.get()

如果不明白的师傅可以参考 Java 反序列化漏洞(4) – Apache Commons Collections POP Gadget Chains 剖析 一文


总结

Apache CommonsCollections5 Payload 的构造还是比较简单的 , 没有什么难点 .

下一章我们将会分析 CommonsCollections6 Payload , 在该 Payload 中我们会遇到一些不一样的东西 :)