内容纲要

前言

上一章我们分析了 CommonsCollections3 Payload , 该 Payload 没有用什么新知识 , 而是将 ACC1 Payload 和 ACC2 Payload 组合并成了一个新的 Payload . 本章我们分析的 CommonsCollections4 Payload 同样由 ACC2 Payload 和 ACC3 Payload 组合而来 .

不同于 ACC3 中通过 "JDK原生动态代理 + LazyMap.get()" 来实现 ChainedTransformer.transform() 方法的调用 , ACC4 中采用 TransformingComparator.compare() 方法来调用 ChainedTransformer.transform() 方法 , 其结构类似 ACC2 Payload .

废话不多说 , 我们快速过一遍该 Payload 的构造与利用.


CommonsCollections4

CommonsCollections4 Payload 复现

由于 Payload 的构造使用了优先级队列( PriorityQueue ) , 因此服务端部署的 Apache CommonsCollections 版本为 4-4.0

复现环境 : JDK1.7_67 + Tomcat7 + CommonsCollections4-4.0

  1. 指定 YSoSerial 运行参数为 "CommonsCollections4 "mate-calc"" , 并生成 Payload

  2. 在 Tomcat 服务器上 加载 CommonsCollections4-4.0 组件 , 并启动 Tomcat 服务

    可以在 MVNRepository 上直接下载 CommonsCollections4-4.0.jar 组件.

  3. 将保存在本地的恶意序列化数据发送到 Tomcat 服务器上

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

    成功弹出计算器 , Payload 被成功执行.


CommonsCollections4 Payload 构造

下面让我们来看一看 ACC4 Payload 的构造


通过 JAVAssist 技术生成携带恶意静态代码块的字节码对象

生成的恶意字节码被存储在返回对象的 _bytecodes 数组中 , 这个技巧在 ACC2 和 ACC3 中都用过了 , 因此我们不再深入分析 , 生成的恶意类如下所示 :

不明白这一步的师傅可以参考 Java 反序列化漏洞(8) – 解密 YSoSerial : CommonsCollections2 POP Chains


构造 ConstantTransformer 对象 与 InstantiateTransformer 对象

这一步与 ACC3 相同 , 最终都用于构造 ChainedTransformer 反射链 . 只不过 ACC4 中先用 String.class"foo" 进行占位与初始化 , 然后再通过反射来覆盖字段 , 注入触发反序列化漏洞的类与对象.

这里对比一下就很容易理解.

  • ACC3 Payload

    在构造 ChainedTransformer 反射链时直接注入触发反序列化漏洞的类与对象

  • ACC4 Payload

    在构造 ChainedTransformer 反射链时先通过 String.class"foo" 占位初始化 , 然后再通过反射注入触发反序列化漏洞的类与对象.


构造 ChainedTransformer 对象

根据上面的分析 , 我们在构造 ChainedTransformer 时只会填入占位的类与对象 . 这部分没有什么疑点.


指定自定义比较器并构造优先级队列( PriorityQueue )

在 ACC2 中 , YSoSerial 通过指定优先级队列的自定义比较器来调用 ChainedTransformer.transform() 方法 , 这里思路相同.

通过调试不难看出 , 这里的自定义比较器( TransformingComparator )的 this.transformer 属性被指向 ChainedTransformer 对象 , 当优先级队列通过自定义比较器比较( compare )时 , 会调用 ChainedTransformer.transform() 方法 , 进入反射调用链 .


填充 ChainedTransformer 对象 , 注入触发反序列化漏洞的类与对象

这一步前面就讲过了 , 通过 JAVA 反射机制替换前面占位的 String.class"foo" , 填入真正触发反序列化漏洞的类与对象.

最后返回优先级队列对象 , 服务端在反序列化时会解析该对象 , 调用自定义比较器进行比较来还原优先级队列 , 进而进入构造好的反射调用链 , 实现代码执行.

至此 , CommonsCollections4 Payload 的构造就分析完了 , 实际上 ACC4 Payload 就是 ACC2 Payload 与 ACC3 Payload 组合而成的 .


CommonsCollections4 Payload 利用

服务端利用这方面没什么重点 , 贴个函数调用栈您就明白了.

如果您不明白上图的含义 , 可以参考下面的链接.


总结

Apache CommonsCollections4 Payload 的内容很少 , 因为该 Payload 实际是将 ACC2 Payload 和 ACC3 Payload 组合后形成了一个新 Payload , 没有使用其他新的知识点 , 所以分析起来很简单 .