XSS扫描器成长记
字数 2936 2025-08-18 11:39:22
XSS扫描器开发与优化指南
1. XSS扫描器设计理念
现代XSS扫描器的核心目标是实现自动化检测跨站脚本漏洞,同时兼顾准确性和效率。通过分析主流扫描器(XSStrike、Xray、AWVS)的优点,我们可以总结出以下设计原则:
- 语义分析:基于HTML/JS语法解析而非简单正则匹配
- 上下文感知:准确识别回显位置(HTML标签内、属性内、JS代码中等)
- 渐进式探测:先发送无害探测字符,再根据响应调整payload
- 智能参数处理:内置常见XSS参数名,提高检测覆盖率
2. 关键技术实现
2.1 DOM XSS检测
DOM XSS检测主要通过识别敏感源(source)和汇(sink):
# 敏感源(数据来源)
sources = r'''
document\.(URL|documentURI|URLUnencoded|baseURI|cookie|referrer)|
location\.(href|search|hash|pathname)|
window\.name|
history\.(pushState|replaceState)|
(local|session)Storage
'''
# 敏感汇(危险函数)
sinks = r'''
eval|evaluate|execCommand|assign|navigate|getResponseHeader|
open|showModalDialog|Function|set(Timeout|Interval|Immediate)|
execScript|crypto.generateCRMFRequest|
ScriptElement\.(src|text|textContent|innerText)|
.*?\.onEventName|
document\.(write|writeln)|
.*?\.innerHTML|
Range\.createContextualFragment|
(document|window)\.location
'''
2.2 内置参数列表
从乌云镜像XSS分类中提取的常见参数名:
blindParams = [
'redirect', 'redir', 'url', 'link', 'goto', 'debug', '_debug',
'test', 'get', 'index', 'src', 'source', 'file', 'frame',
'config', 'new', 'old', 'var', 'rurl', 'return_to', '_return',
'returl', 'last', 'text', 'load', 'email', 'mail', 'user',
'username', 'password', 'pass', 'passwd', 'first_name', 'last_name',
'back', 'href', 'ref', 'data', 'input', 'out', 'net', 'host',
'address', 'code', 'auth', 'userid', 'auth_token', 'token',
'error', 'keyword', 'key', 'q', 'query', 'aid', 'bid', 'cid',
'did', 'eid', 'fid', 'gid', 'hid', 'iid', 'jid', 'kid', 'lid',
'mid', 'nid', 'oid', 'pid', 'qid', 'rid', 'sid', 'tid', 'uid',
'vid', 'wid', 'xid', 'yid', 'zid', 'cal', 'country', 'x', 'y',
'topic', 'title', 'head', 'higher', 'lower', 'width', 'height',
'add', 'result', 'log', 'demo', 'example', 'message'
]
2.3 HTML解析与反射分析
关键步骤:
- 发送随机flag探测参数回显
- 使用HTML解析器确定回显位置:
- HTML标签内
- HTML属性内
- JavaScript代码中
- HTML注释中
- 根据上下文环境选择适当的探测payload
推荐使用Python内置的html.parser模块进行HTML解析,而非自行编写复杂的解析函数。
3. 不同上下文环境的探测策略
3.1 JavaScript代码中的回显
测试用例:
<script>
$var = 'var a = "'.$_GET['q'].'";';
echo $var;
</script>
探测流程:
- 发送无害字符串:
pdrjzsqc - 发送带引号的字符串:
"-pdrjzsqc-" - 发送闭合标签尝试:
</sCrIpT><ojyrqvrzar> - 最终payload:
prompt(1)
注释中的回显:
<script>
var a = 11; // inline <?php echo $_GET["a"];?>
</script>
探测payload:
\n;chxdsdkm;// → 最终payload:\n;prompt(1);//
3.2 HTML标签内的回显
测试用例:
<textarea><?php echo $_GET["w"];?></textarea>
探测流程:
- 发送随机字符串:
spzzmsntfzikatuchsvu - 发送闭合标签尝试:
</tExTaReA><lixoorqfwj> - 确认尖括号未过滤后,发送多种标签尝试:
</TeXtArEa>sCrIpTjhymehqbkrScRiPt</TeXtArEa>iMgSrCoNeRrOrjhymehqbkr></TeXtArEa>SvGoNlOaDjhymehqbkr></TeXtArEa>IfRaMeSrCjAvAsCrIpTjhymehqbkr></TeXtArEa>aHrEfJaVaScRiPtjhymehqbkrClIcKa</TeXtArEa>iNpUtAuToFoCuSoNfOcUsjhymehqbkr>
- 最终payload:
</TeXtArEa>
3.3 Style属性内的回显
测试用例:
<input style="color:<?php echo $_GET["e"];?>">
探测payload:
- 随机字符串:
kmbrocvz - CSS表达式尝试:
expression(a(kmbrocvz))
3.4 HTML属性内的回显
测试用例:
<input value="<?php echo $_GET["r"];?>">
探测流程:
- 随机字符串:
spzzmsntfzikatuchsvu - 测试引号过滤:
"ljxxrwom="'ljxxrwom='ljxxrwom=
- 确认引号未过滤后,发送多种尝试:
"><vkvjfzrtgi>">ScRiPtvkvjfzrtgiScRiPt">ImGsRcOnErRoRvkvjfzrtgi>">SvGoNlOaDvkvjfzrtgi>">iFrAmEsRcJaVaScRiPtvkvjfzrtgi>">aHrEfJaVaScRiPtvkvjfzrtgicLiCkA">InPuTaUtOfOcUsOnFoCuSvkvjfzrtgi>" OnMoUsEoVeR=xviinqws
- 最终payload:
">"OnMoUsEoVeR=prompt(1)//
3.5 事件处理器属性
测试用例:
">
探测策略:
- 识别常见事件处理器属性(on*):
parName == "ONAFTERPRINT" || parName == "ONBEFOREPRINT" || parName == "ONBEFOREONLOAD" || parName == "ONBLUR" || parName == "ONERROR" || parName == "ONFOCUS" || // ... 其他事件处理器 - 最终payload:
prompt(1)
3.6 HTML注释中的回显
测试用例:
<!-- this is comment <?php echo $t;?> -->
探测流程:
- 随机字符串:
spzzmsntfzikatuchsvu - 尝试注释闭合:
--><husyfmzvuq>--!><oamtgwmoiz>
- 确认闭合后,发送多种标签尝试:
<bvwpmjtngz>sCrIpTbvwpmjtngzsCrIpTImGsRcOnErRoRbvwpmjtngz>sVgOnLoAdbvwpmjtngz>iFrAmEsRcJaVaScRiPtbvwpmjtngz>aHrEfJaVaScRiPtbvwpmjtngzcLiCkAInPuTaUtOfOcUsOnFoCuSbvwpmjtngz>
- 最终payload:
--><script>prompt(1)</script>
4. 扫描器架构设计
4.1 整体流程
- URL输入 → 爬虫爬取 → 参数入库 → 消息队列 → XSS扫描器 → 结果入库
- 使用组件:
- 爬虫:crawlergo(可自定义)
- 数据库:MongoDB
- 任务分发:Celery + RabbitMQ
- 通知:服务器酱微信推送
4.2 扫描核心流程
- 发送随机flag探测参数回显
- 确定回显位置(使用HTML/JS语法解析)
- 根据上下文发送针对性探测payload
- 使用语法解析验证payload是否生效
- HTML:检查是否新增了标签/属性
- JS:检查Identifier或Literal类型中是否包含flag
4.3 语法解析实现
HTML解析:
from html.parser import HTMLParser
# 发送<payload>后检查是否新增了对应标签
JS解析:
- 检查flag是否出现在Identifier或Literal类型中
- 如果是Identifier类型:直接判断存在XSS,payload为
alert(1)// - 如果是Literal类型:通过单双引号闭合进行检测
5. 优化与调试经验
-
误报处理:
- 初期微信推送频繁,通过优化检测逻辑和加入去重处理解决
- 对事件处理器属性采用白名单方式,减少误报
-
性能平衡:
- 扫描速度与准确性需要权衡
- 渐进式探测:先快速确认漏洞存在可能,再深入验证
-
测试验证:
- 使用本地靶机测试(如https://brutelogic.com.br/knoxss.html)
- 逐步扩展到真实环境扫描
6. 高级技巧
-
随机化技术:
- 使用随机字符串代替实际payload进行初步探测
- 随机大小写处理标签/属性名称(如
sCrIpT)
-
上下文敏感payload生成:
- 根据反射位置动态生成最可能成功的payload
- 考虑过滤规则(如
<script>被过滤时尝试其他标签)
-
框架特定检测:
- 针对AngularJS等流行框架的特殊XSS payload
- 处理meta标签的content属性等特殊情况
7. 实际成果
通过优化后的扫描器能够发现多种XSS漏洞,包括:
- 常规HTML注入
- JavaScript代码注入
- 属性注入
- 注释注入
- 框架特定漏洞
成功案例包括微软分站等知名网站的XSS漏洞发现。
8. 未来发展方向
- 增强对现代前端框架的检测能力
- 结合静态分析与动态探测
- 提高DOM XSS检测的准确性
- 优化爬虫与扫描器的集成
- 加入机器学习技术识别潜在注入点
通过持续优化和借鉴各扫描器的优点,可以构建出高效准确的XSS自动化检测系统。