Level 1裸奔的输出​因果逻辑​数据落在 h2[这里]/h2​ 之间。由于后端没做任何过滤浏览器会直接把输入当 HTML 指令。​Payload​?namescriptalert(1)/script​​通关动作​直接回车页面解析脚本并弹窗。Level 2属性的逃逸​因果逻辑​数据在 input value[这里]​。直接写脚本会被当成属性值。​绕过思路​利用 ​ 逃离属性利用 ​ 逃离标签。​Payload​?keywordscriptalert(1)/script​​通关动作​闭合原标签后新标签 script​ 开始生效。Level 3不严谨的转义单引号注入​因果逻辑​数据在 input value[这里]​。后端用了 htmlspecialchars()​但该函数默认不转义单引号 ​且无法拦截标签内的事件属性。​绕过思路​既然不能用尖括号写新标签就利用 onmouseover​ 事件。​Payload​?keyword onmouseoveralert(1)​​通关动作​鼠标移动到输入框上。Level 4正则过滤的死角双引号注入​因果逻辑​数据在 input value[这里]​。后端正则删除了 ​ 和 ​但漏掉了双引号 ​。​绕过思路​用双引号闭合属性注入不需要尖括号的事件。​Payload​?keyword onmouseoveralert(1)​​通关动作​鼠标移动到输入框上。Level 5黑名单防御伪协议注入​因果逻辑​后端会把 on​ 替换成 o_n​把 script​ 替换成 scr_ipt​。​绕过思路​所有“事件”和“脚本标签”都废了。改用 a​ 标签的 href​ 属性利用 javascript:​ 伪协议绕过检测。​Payload​?keyword a hrefjavascript:alert(1)click/a​​通关动作​必须手动点击生成的那个 click 链接。Level 6大小写的疏忽​因果逻辑​黑名单很全过滤了 href​, on​, script​但后端的替换函数 str_replace​ 是区分大小写的。​绕过思路​HTML 对属性名不区分大小写改变大小写即可躲过过滤。​Payload​?keyword a HREFjavascript:alert(1)click/a​*(或者?keyword OnMouseOveralert(1)​)​通关动作​点击链接或滑过输入框。Level 7不递归的替换​因果逻辑​后端会将敏感词删掉但只执行一次非递归。​绕过思路​构造“套娃”字符串 scscriptript​。​Payload​?keyword scscriptriptalert(1)/scscriptript​​通关动作​后端删掉中间的 script​ 后两边剩下的字母自动合体成新的 script​。Level 8利用浏览器的实体解析​因果逻辑​输出在 href​ 内部关键字全被拉黑。​绕过思路​利用 href​ 属性在执行前会进行 HTML 实体解码 的特性。​Payload​?keyword#106;#97;#118;#97;#115;#99;#114;#105;#112;#116;:alert(1)​​通关动作​点击页面下方的“友情链接”。Level 9特定的逻辑校验​因果逻辑​后端强制要求输入包含 http://​。​绕过思路​在 Payload 中利用 JS 注释 //​ 塞进网址骗过后端校验。​Payload​?keyword#106;#97;#118;#97;#115;#99;#114;#105;#112;#116;:alert(1)//http://​​通关动作​点击页面下方的“友情链接”。Level 10隐藏字段的曝光​因果逻辑​数据掉进了 typehidden​ 的隐藏表单。由于元素不可见任何鼠标事件onclick/onmouseover都无法触发。​绕过思路​注入 typetext​强行修改标签属性让它显示出来。​Payload​?t_sort typetext onmouseoveralert(1)​​注意​参数名必须是 t_sort​。​通关动作​移动鼠标到新出现的输入框上。Level 11Referer 溯源注入​因果逻辑​后端代码里有一句 $_SERVER[HTTP_REFERER]​。它会读取你“从哪个页面跳过来”的链接并把它输出在隐藏表单中。​绕过思路​直接在 URL 里传参没用必须用 Burp Suite 拦截请求修改 Referer​ 字段。​Payload​在 Burp 中修改Referer: typetext onmouseoveralert(1)​​通关动作​提交修改后的数据包鼠标滑过页面上新出现的输入框。Level 12User-Agent 浏览器指纹注入​因果逻辑​后端读取 $_SERVER[HTTP_USER_AGENT]​ 并输出。开发者以为浏览器指纹是系统生成的不会有毒。​绕过思路​同 L11拦截数据包修改 User-Agent​ 字段。​Payload​User-Agent: typetext onmouseoveralert(1)​​通关动作​提交后鼠标滑过新出现的输入框。Level 13Cookie 注入​因果逻辑​后端读取 $_COOKIE[user]​ 字段并输出。​绕过思路​拦截包找到 Cookie​ 字段中的 user...​ 部分进行修改。​Payload​Cookie: user typetext onmouseoveralert(1)​​通关动作​提交后鼠标滑过新出现的输入框。Level 14Exif 盲区此关通常因外链失效无法复现​因果逻辑​本来是利用图片文件里的 Exif​ 信息拍摄设备、经纬度等进行 XSS。​面试谈资​这关在实战中很有意义——​文件上传 XSS​。如果一个网站允许上传图片你可以在图片的元数据里塞进脚本服务器在读取图片信息展示时就会中招。Level 15AngularJS 模板注入​因果逻辑​后端使用了 AngularJS 框架并使用了 ng-include​ 指令。​绕过思路​ng-include​ 会包含并执行另一个页面的内容。我们可以让它包含第一关L1因为 L1 没有任何过滤。​Payload​?srclevel1.php?nameimg src1 onerroralert(1)​​通关动作​自动弹窗。这是典型的​前端框架 XSS​面试时提到 ng-include​ 会显得你懂前端架构。Level 16被过滤的空格​因果逻辑​后端把 script​、on​ 以及空格都给过滤或替换了。​绕过思路​在 HTML 和 JS 中除了空格回车符 (%0a) 也可以起到分隔符的作用。​Payload​?keywordimg%0asrc1%0aonerroralert(1)​​通关动作​自动弹窗。利用回车符绕过了对空格的正则检测。首先得用一个支持flash插件的浏览器Level 17嵌入式插件的属性注入 (Embed)​因果逻辑​页面使用了 embed​ 标签来插入多媒体插件。数据通过 arg01​ 和 arg02​ 传入并直接拼接到 src​ 属性后面。​绕过思路​由于数据是拼接到 src​ 属性内的我们无法闭合 src​后端过滤了引号和尖括号但我们可以注入其他的 ​事件处理器​。​Payload​?arg01aarg02 onmouseoveralert(1)​​通关动作​鼠标划过那个黑色的插件区域。​原理​虽然没有引号但 HTML 允许不带引号的属性。浏览器解析为 embed src...a onmouseoveralert(1)​。Level 18同样的 Embed不同的触发​因果逻辑​与 L17 完全一致只是场景稍有变化。​绕过思路​依然利用属性间不需要引号的特性。​Payload​?arg01aarg02 onmouseoveralert(1)​​通关动作​划过插件区域。​面试价值​这关证明了在一些老旧组件或特定标签中即使开发者转义了引号和尖括号​只要空格没过滤​攻击者依然可以增加新的属性。Level 19Flash XSS 的绝响 (已基本失效)因果逻辑这是经典的 Flash XSS。利用 Flash 文件.swf内部的 getURL​ 或 ExternalInterface.call​ 函数执行 JS。Level 20Flash 编码绕过​因果逻辑​在 L19 的基础上增加了对非法字符的过滤。​绕过思路​通过对 Payload 进行十六进制编码或利用 Flash 内部的解析特性绕过。​结论​这关更多是针对特定版本 Flash 插件的漏洞了解其“参数可控导致脚本执行”的本质即可。