0x00 漏洞介绍
Struts2 S2-052远程代码执行漏洞和以往的Struts2漏洞是不同的,S2-052利用的是Java反序列化漏洞,而不是臭名昭著的ognl。
本次漏洞触发点是REST插件在解析请求中的xml文件时,调用了XStreamHandler,传入的数据会被默认进行反序列化,如果当传入的xml是个经过XStream序列化的恶意对象时,便造成反序列化漏洞。
0x01 漏洞分析
本次漏洞的成因由两部分组成,一个是 Struts2 REST插件本身没有对进入的数据进行安全检查,导致攻击者可以传入恶意的xml对象可以传入到XStream里。另一个是XStream在反序列化传入的xml造成的远程代码执行。
关键代码在org.apache.struts2.rest.ContentTypeInterceptor里。
public String intercept(ActionInvocation invocation) throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
ContentTypeHandler handler = selector.getHandlerForRequest(request);
Object target = invocation.getAction();
if (target instanceof ModelDriven) {
target = ((ModelDriven)target).getModel();
}
if (request.getContentLength() > 0) {
InputStream is = request.getInputStream();
InputStreamReader reader = new InputStreamReader(is);
handler.toObject(reader, target);
}
return invocation.invoke();
}
问题出在以下两点
ContentTypeHandler handler = selector.getHandlerForRequest(request);
和
handler.toObject(reader, target);
Struts2的漏洞点本身没什么难度,这个漏洞出在漏洞利用方面。
0x02 利用分析
本次漏洞,最开始的poc生成是利用marshalsec工具生成ImageIO的远程代码序列化对象,这个poc适用的环境是java1.8以上,这是个非常苛刻的条件。
然而有没有在其他版本java的利用代码呢,答案是有的。因为漏洞的本质是反序列化漏洞,而反序列化工具ysoserial提供了大量的反序列化代码。通过查看marshalsec工具生成XStream的代码,发现利用下面代码再结合ysoserial工具的代码,即可生成更多的利用代码。
public class XStream extends MarshallerBase<String> implements CommonsConfiguration, Rome, CommonsBeanutils, ServiceLoader, ImageIO,BindingEnumeration, LazySearchEnumeration, SpringAbstractBeanFactoryPointcutAdvisor, SpringPartiallyComparableAdvisorHolder, Resin, XBean {
@Override
public String marshal ( Object o ) throws Exception {
com.thoughtworks.xstream.XStream xs = new com.thoughtworks.xstream.XStream();
return xs.toXML(o);
}
@Override
public Object unmarshal ( String data ) throws Exception {
com.thoughtworks.xstream.XStream xs = new com.thoughtworks.xstream.XStream();
return xs.fromXML(data);
}
@Override
public Object makeComparatorTrigger ( Object tgt, Comparator<?> cmp ) throws Exception {
return JDKUtil.makePriorityQueue(tgt, cmp);
}
public static void main ( String[] args ) {
new XStream().run(args);
}
}
利用commons.collections和XStream可以生成在java1.7环境下稳定利用的poc。
利用中,执行的代码为:
touch /tmp/manning_s2_052
生成利用的代码暂不公开。
之前我在微博说利用可能达到11种,这个说法现在来看不准确,理论上marshalsec和ysoserial和SerialKillerBypassGadgetCollection的反序列化利用代码可以在本次的漏洞使用,因此本次漏洞的利用的变化是非常大的。
0x03 漏洞防御
由于漏洞利用变化极大,建议暂时关闭有REST插件的Struts2站点。
0x04 参考内容
https://0bin.net/paste/xI3qQXBnBFi+ZIC6#y151P6VdT9DXPOBqgQviWRECRnW6+gSuK+frvsnAfZy