核心原理

readObject()方法是XStreadm反序列化的核心之一; 和CC链非常相似, 利用 Java 的反序列化机制和一些恶意类

构造

首先找到一个可以利用的恶意类的readObject()方法或是其他类似方法例如finalize()

当XStream 对一个 XML 数据进行反序列化时,如果它解析到一个 <object-name> 标签,它会尝试实例化这个类,并调用其 readObject() 方法来填充数据

然后就是通过恶意链简介调用java.lang.Runtime.exec(), 那么就可以实现远程代码执行

示例

典型的 XStream 攻击链(Groovy 示例)

一个经典的 XStream 攻击链利用了 Groovy 库,它曾经在 XStream 的黑名单之外

恶意 XML 构造:攻击者构造一个 XML,其中包含一个 Groovy.lang.Closure 对象。这个对象可以在其 call() 方法中执行任意代码

利用java.util.concurrent.ConcurrentHashMap:攻击者会将 Groovy.lang.Closure 封装到 ConcurrentHashMap 中,并利用其序列化特性

XStream 反序列化:当 XStream 解析 XML 时,它会创建 ConcurrentHashMap 实例,并填充其数据

Groovy 代码执行:在反序列化过程中,ConcurrentHashMap 会调用其内部的某些方法,这些方法会触发 Groovy.lang.Closure 的 call() 方法,从而执行攻击者预设的 Groovy 代码,例如:

“whoami”.execute() 远程代码执行:最终,Groovy 代码会被执行,实现了 RCE

这个攻击链的本质是利用了 Groovy.lang.Closure 这个 Bad Gadget,结合 ConcurrentHashMap 的反序列化特性,在不被 XStream 黑名单拦截的情况下,触发了命令执行