游客发表
去年冬天,检具我在一个漏洞赏金项目里花了整整三天,测工才在一个电商网站的检具搜索框里挖出一个存储型 XSS。手动测试的测工痛苦在于,你永远不知道 payload 到底是检具被过滤了、被编码了,测工还是检具压根没进入 DOM。从那时起,测工我开始系统性地折腾各种 XSS 检测工具——不是检具为了写测评,纯粹是测工想让自己少熬几个通宵。
市面上的检具工具大致分两类:一类是代理型扫描器,比如 Burp Suite 的测工 Active Scan 和 OWASP ZAP 的扫描模块;另一类是专用型检测脚本,像 XSStrike、检具XSser 这种。测工代理型的检具好处是能结合整个请求上下文,缺点也很明显——Burp 的扫描队列一跑起来,CPU 风扇就跟直升机似的。XSStrike 倒是轻量,但它那个基于模糊测试的 payload 生成逻辑,有时候会给你吐出几百个变体,真正能弹窗的没几个。
我印象最深的一次翻车,是用某款开源工具扫一个 Vue 写的后台。工具报告了 17 个“疑似 XSS”,我挨个手动验证,结果全是误报。原因是那个页面用了 v-html 渲染用户输入,但后端做了严格的实体编码。工具只看到 <script> 被原样输出,却没注意到它出现在 v-html 的绑定值里——浏览器根本不会执行。这件事让我明白:检测工具的输出必须结合前端框架特性来解读,否则就是自嗨。
后来我养成了一个习惯:任何工具报出的 XSS,先看三个东西——注入点所在的 HTML 上下文、输出编码方式、以及有没有 CSP 头。举个例子,如果响应头里有 Content-Security-Policy: script-src 'self',那即使 payload 成功注入,内联脚本也跑不起来。很多工具不检查 CSP,直接报“高危”,这属于耍流氓。
说说我目前常用的组合。日常手动测试,XSStrike 的 --fuzzer 模式配合自定义字典,效率比纯手工高不少。它的 --crawl 功能可以顺着链接爬,但别开太深,否则容易把目标站爬挂。Burp 那边,我装了一个叫 “XSS Validator” 的插件,配合 PhantomJS 做无头浏览器验证——只有真正弹窗的才标记为漏洞。这个思路很关键:用浏览器引擎做二次确认,能干掉 90% 以上的误报。
还有个小众工具叫 “XSS Radar”,它不直接扫漏洞,而是分析页面里所有可能接收用户输入的位置——URL 参数、hash、referer、甚至 postMessage 的监听器。然后它会生成一份“攻击面地图”。这玩意儿在挖 DOM 型 XSS 时特别有用,因为传统扫描器根本看不到 document.location.hash 这种动态 sink。
当然,工具再强也替代不了人脑。我见过最离谱的漏报,是一个工具把 onerror 事件里的 payload 当成了合法属性,直接跳过。而实际上,只要图片加载失败,onerror 就会触发。所以我现在会定期用 alert(document.domain) 这种最朴素的 payload 手动测一遍关键参数——工具会骗你,但浏览器不会。
最后说个反直觉的观察:很多 XSS 检测工具在扫描时,会发送大量带有 <script> 的请求,结果被 WAF 封了 IP。这时候与其换代理,不如换 payload 编码方式。比如把 <script> 拆成 <scr\0ipt> 或者用 <svg/onload>。工具本身不负责绕过 WAF,那是你的活。
折腾了这一年多,我的结论很简单:没有银弹。XSStrike 适合快速探测,Burp 适合深度结合业务逻辑,XSS Radar 适合 DOM 型场景。但最终能确认漏洞的,永远是你自己打开浏览器控制台,敲下那个 payload,然后看到弹窗的那一刻。
友情链接