跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets,CSS)的缩写混淆,故将跨站脚本攻击缩写为 XSS 。恶意攻击者往 Web 页面里插入恶意 JavaScript 代码,当用户浏览器该页之时,嵌入 Web 页面里的代码会被执行,从而达到恶意攻击用户的目的。
imgPayload
Payload 的中文含义是有效载荷,在 XSS 中指代攻击代码或攻击语句。
常见的 Payload 有:
- 正常弹窗
alert(1)
- ``
- 弹出网站 Cookie
alert(document.cookie)
- ``
分类
总共有三种
- 反射型:Payload 经过后端,不经过数据库
- 存储型:Payload 经过后端,经过数据库
- DOM:Payload 不经过后端
原理:反射型
非持久化,需要欺骗用户点击链接才能触发 XSS 代码(数据库中没有这样的页面和内容)。Payload 一般存在于 URL 或者 HTTP 正文中,需要构造页面,或者构造 URL。
将这段代码保存为xss.php
。
<?php
header('X-XSS-Protection: 0');
?>
<p>反射型 XSS 演示</p>
<form action="" method="get">
<input type="text" name="xss"/>
<input type="submit" value="test"/>
</form>
<?php
$xss = @$_GET['xss'];
if($xss!==null){
echo $xss;
}
我们看到,这段代码中首先包含一个表单,用于向页面自己发送 GET 请求,带一个名为xss
的参数。 然后 PHP 会读取该参数,如果不为空,则直接打印出来,我们看到这里不存在任何过滤。也就是说,如果xss
中存在 HTML 结构性的内容,打印之后会直接解释为 HTML 元素。
我们部署好这个文件,访问http://localhost/xss.php
,如图:
我们直接输入一个 HTML 代码,比如alert(1)
,之后点击test
:
我们可以看到弹窗,也就是我们输入的 HTML 代码被执行了。
之后我们查看元素,这表明,我们输出的内容直接插入到了页面中,解释为``标签。
img我们可以自定义弹窗中的内容来利用 XSS,比如改成alert(document.cookie)
。
这个例子中 URL 为http://localhost/xss.php?xss=%3Cscript%3Ealert%281%29%3C%2Fscript%3E
,这个 URL 容易引起怀疑,可以使用短网址工具缩短后发送给受害者。
从上面的例子中,我们可以看出,反射型 XSS 的数据流向是:浏览器 -> 后端 -> 浏览器。
原理:存储型
持久化,代码储存在数据库中。如在个人信息或发表文章等地方,假如代码,如果没有过滤或过滤不严,那么这些代码将储存到数据库中,用户访问该页面的时候出发代码执行。这种 XSS 比较危险,容易造成蠕虫,盗窃 Cookie 等。
这里我们把xss.php
内容改为(同时数据库中需要配置相应的表):
<?php
header('X-XSS-Protection: 0');
?>
<p>存储型 XSS 演示</p>
<form action="" method="post">
<input type="text" name="xss"/>
<input type="submit" value="test"/>
</form>
<?php
$xss=@$_POST['xss'];
mysql_connect("localhost","root","root");
mysql_select_db("xss");
if($xss!==null){
$sql="insert into test(id,payload) values('1',$xss)";
$result=mysql_query($sql);
echo $result;
}
可以看到,用户输入的内容还是没有过滤,但是不直接显示在页面中,而是插入到了数据库。
我们新建res.php
,内容为:
mysql_connect("localhost","root","root");
mysql_select_db("xss");
$sql="select payload from test where id=1";
$result=mysql_query($sql);
while($row=mysql_fetch_array($result)){
echo $row['payload'];
}
该代码从数据库读取了之前插入的内容,并将其显示出来。
我们部署之后首先查看test
数据库,确认它是空的:
然后访问xss.php
,像之前一样输入 HTML 代码并点击test
,如下:
点击之后却发现没有任何动静,但事实上,我们的数据已经插入到了数据库中。
img那么,当我们访问res.php
查询这个值的时候,代码就会被执行。
所以说,存储型 XSS 的执行位置通常不同于输入位置。我们可以看出,存储行 XSS 的数据流向是:浏览器 -> 后端 -> 数据库 -> 后端 -> 浏览器。
网友评论