XStream是一个著名的反序列化的库,用途广泛,原文中作者以Jenkins为例。实际上XStream可以用在JIRA, Confluence, Bamboo,甚至是Spring和Struts中。
作者发现,在groovy.util.Expando重载hashCode方法的时候出了问题:public int hashCode() {
Object method = getProperties().get("hashCode");
if (method != null && method instanceof Closure) {
// invoke overridden hashCode closure method
Closure closure = (Closure) method;
closure.setDelegate(this);
Integer ret = (Integer) closure.call();
return ret.intValue();
} else {
return super.hashCode();
}
}
当Expando中存在闭包对象时,Expando会使用该方法计算并返回hashCode,然而这个闭包对象是可控的,从而可以执行我们的代码。
于是作者给出了EXP,使用XStream解析下面的片段时,会弹出计算器:
给出的执行链:
MapConverter#populateMap() 调用了 HashMap#put()
HashMap#put() 调用了 Expando#hashCode()
Expando#hashCode() 调用了 MethodClosure#call()
MethodClosure#call() 调用了 MethodClosure#doCall()
MethodClosure#doCall() 调用了 InvokerHelper#invokeMethod()
InvokerHelper#invokeMethod() 调用了 ProcessBuilder#start()
EXP的意义是我们在MethodClosure#call()中执行动作,传递进去污染数据,执行任意代码。
详细见:
https://www.contrastsecurity.com/security-influencers/serialization-must-die-act-2-xstream?platform=hootsuite