【漏洞分析】360天眼实验室:Struts2 S2-052(CVE-2017-9805)远程代码执行漏洞分析

http://p6.qhimg.com/t015f49e9747b570b29.png

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.collectionsXStream可以生成在java1.7环境下稳定利用的poc。

https://p5.ssl.qhimg.com/t0141a5f4129858acfc.png

利用中,执行的代码为:

touch /tmp/manning_s2_052

https://p4.ssl.qhimg.com/t0139a7e1319391f96e.png

生成利用的代码暂不公开。

之前我在微博说利用可能达到11种,这个说法现在来看不准确,理论上marshalsec和ysoserial和SerialKillerBypassGadgetCollection的反序列化利用代码可以在本次的漏洞使用,因此本次漏洞的利用的变化是非常大的。


0x03 漏洞防御

由于漏洞利用变化极大,建议暂时关闭有REST插件的Struts2站点


0x04 参考内容

https://0bin.net/paste/xI3qQXBnBFi+ZIC6#y151P6VdT9DXPOBqgQviWRECRnW6+gSuK+frvsnAfZy 

http://bobao.360.cn/learning/detail/4372.html 

(完)