struct2漏洞
2010年,漏洞一个编号为S2-003的漏洞漏洞在安全圈炸开了锅。它不需要复杂的漏洞工具,一条精心构造的漏洞URL就能让服务器把内部文件吐出来。那是漏洞Struts2框架最风光的年代,Java Web开发几乎被它垄断,漏洞谁也没想到这个明星框架会开启长达十年的漏洞“漏洞批发”模式。
我印象最深的漏洞是2017年那次S2-045。那天我正在帮朋友排查一个电商网站的漏洞异常,对方说后台登录页总是漏洞报错。我随手在Content-Type头里塞了一段OGNL表达式,漏洞服务器直接回显了系统命令的漏洞执行结果。整个过程不到十秒,漏洞连验证码都没触发。漏洞那种感觉就像你发现自家门锁其实是漏洞个摆设——不是技术多高超,是钥匙孔本身就设计歪了。
Struts2的漏洞核心总绕不开OGNL表达式。框架为了“灵活”,允许用户参数直接参与表达式解析。这设计初衷是好的,但开发人员低估了攻击者的想象力。从S2-001到S2-062,攻击面从URL参数扩展到HTTP头、Cookie甚至上传文件名。最讽刺的是,很多补丁只是给过滤规则打了补丁,换个编码方式或者加个空格就能绕过。
有个细节特别能说明问题。S2-016漏洞公开时,Apache官方给出的修复建议是“升级到最新版本”。但大量国内企业还在用着2011年的老版本,因为他们的业务系统是外包团队写的,没人敢动核心代码。我见过一家银行的运维人员,把防火墙规则改成了“禁止所有包含OGNL的请求”——结果正常业务里有个搜索功能也用了类似语法,直接瘫痪了半天。
这类漏洞最坑人的地方在于,它不挑环境。不管你的服务器是Windows还是Linux,不管数据库是Oracle还是MySQL,只要用了Struts2,攻击方式就完全一样。2018年某招聘网站泄露了数亿简历,事后调查发现攻击入口就是S2-057。那个漏洞利用起来简单到什么程度?一个curl命令就能拿到服务器权限,连菜鸟黑客都能上手。
现在Struts2的市场份额早被Spring Boot挤下去了,但老系统还在跑。我去年做安全审计时,发现某省级政务平台仍在使用Struts2 2.3.20版本——这个版本至少存在二十个已知RCE漏洞。对方技术负责人苦笑着说:“系统迁移成本够买三辆宝马了。”这大概是很多企业的真实写照:不是不知道危险,是换引擎的代价比修漏洞高太多。
回头看Struts2这十年,它教会了行业一个血淋淋的教训:框架的“便捷”和“安全”往往是跷跷板两端。开发人员图省事用表达式解析,黑客就专攻表达式注入;厂商急着出补丁,攻击者就研究补丁的绕过姿势。这场猫鼠游戏至今没结束,只是战场转移到了Log4j、Fastjson这些新宠身上。技术债终归要还的,只是利息可能比想象中贵得多。
(责任编辑:焦点)











