struts2漏洞检查工具
作者:热点 来源:热点 浏览: 【大 中 小】 发布时间:2026-10-17 06:39:34 评论数:
Struts2 的漏洞漏洞检查,最怕的检查就是把扫描器当摆设。我见过太多人拿着工具跑一遍,工具看到“可能存在 S2-045”就慌了神,漏洞结果连版本号都没核对。检查实际上,工具Struts2 的漏洞漏洞利用有很强的版本和配置依赖,盲目扫等于给自己加戏。检查
先说一个真实案例。工具去年帮朋友看一个老系统,漏洞他用某商业扫描器扫出 S2-016 漏洞,检查报告里写着“可直接执行命令”。工具我让他把请求包发过来,漏洞一看 URL 里带着 action: 前缀,检查但服务器返回的工具是 404。为什么?因为那个应用根本没开 struts.enable.DynamicMethodInvocation,而且用的是 Struts 2.3.15,这个版本对 S2-016 已经打了补丁。扫描器只认特征,不认环境。后来我手动构造 redirect: 和 action: 的 payload,确认无法利用。工具没错,错在拿工具当判决书。
自己写检查工具或者用现成的,核心就三件事:版本探测、漏洞特征匹配、回显验证。版本探测别只依赖 /struts/webconsole.html 这种老掉牙的路径,很多系统早就删了。更稳的方法是发一个畸形的 OGNL 表达式,看报错信息里有没有 Struts 的版本号。比如请求 ?redirect=%24%7B%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%7D,如果返回 500 且错误页带 Struts Problem Report,再结合 struts.version 字段就能定位。
漏洞特征匹配要分优先级。S2-045 和 S2-046 是 Content-Type 头注入,检查时直接发 Content-Type: %{ #context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('X-Test','1')}.multipart/form-data,看响应头有没有 X-Test: 1。有,就是活的;没有,别浪费时间。S2-052 是 REST 插件的问题,得先确认 struts-plugin.xml 里有没有 struts-rest。没有这个插件,扫一万遍也扫不出。
回显验证是最容易被忽略的一步。很多工具只检测“命令是否执行”,却不检查“结果是否返回”。我习惯用 id 命令,但把输出写到响应头里。比如 S2-045 的 payload 里加 %{ #context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('X-Result',#a=@java.lang.Runtime@getRuntime().exec('id').getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[500],#c.read(#d),#e=new java.lang.String(#d),#e)}。然后看 X-Result 头里有没有 uid=。没有回显,就算命令执行了,你也拿不到东西,这种漏洞在实际攻击链里价值大打折扣。
工具选择上,别迷信大而全。Struts2-Scan 这个 Python 脚本就挺好,但它默认的 payload 列表太长,容易触发 WAF。我一般改它的 payload.txt,只留 S2-045、S2-046、S2-016、S2-052 这几个高风险的,并且把 Content-Type 里的空格换成 %20,绕过一些简单的规则。还有,扫描前先抓一个正常请求,把 Cookie 和 User-Agent 复制进去,否则有些系统直接 302 到登录页,你扫个寂寞。
最后说个坑。Struts2 的漏洞检查工具在遇到 struts.action.extension 配置为 do,action,, 的时候,路径构造会出问题。比如你请求 /index.action 能通,但工具硬拼 /index.do 就 404。这时候得手动改工具里的路径拼接逻辑,或者干脆用 Burp 的 Intruder 配合自定义 payload 跑。工具是死的,人是活的。别让一个 False Positive 浪费你一整个下午。
