前言
本章我们来分析 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
-
添加参数 , 生成可利用的 ACC5 Payload .
-
加载 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 中我们会遇到一些不一样的东西 :)