概述
跨站脚本(cross site script)为了避免与样式css混淆,所以简称为XSS。
XSS是一种经常出现在web应用中的计算机安全漏洞,也是web中最主流的攻击方式。那么什么是XSS呢?
XSS是指恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而添加一些代码,嵌入到web页面中去。使别的用户访问都会执行相应的嵌入代码。从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。
XSS的危害
1、盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号
2、控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力
3、盗窃企业重要的具有商业价值的资料
4、非法转账
5、强制发送电子邮件
6、网站挂马
7、控制受害者机器向其它网站发起攻击
XSS的起因
主要原因:过于信任客户端提交的数据!
解决办法:不信任任何客户端提交的数据,只要是客户端提交的数据就应该先进行相应的过滤处理然后方可进行下一步的操作。
进一步分析细节:
客户端提交的数据本来就是应用所需要的,但是恶意攻击者利用网站对客户端提交数据的信任,在数据中插入一些符号以及javascript代码,那么这些数据将会成为应用代码中的一部分了。那么攻击者就可以肆无忌惮地展开攻击啦。
因此我们绝不可以信任任何客户端提交的数据!!!
XSS的分类
XSS主要分为三类:反射型、存储型和DOM型,下面逐一介绍。
反射型
反射型XSS也被称为非持久性XSS,是现在最容易出现的一种XSS漏洞。当用户访问一个带有XSS代码的URL请求时,服务端接收数据后处理,然后把XSS代码的数据发送到浏览器,浏览器解析这段带有XSS代码的数据后,最终造成XSS漏洞。这个过程就像一次反射,故被称为反射型XSS。
来看一个具体案例。新建一个xss.php文件并加入以下代码:
\XSS反射演示
<?php
$xss = @$_GET['xss'];
if($xss!==null){
echo $xss;
}
1
2
3
4
5
6
7
8
9
10
这段代码中首先包含一个表单,用于向页面自己发送 GET 请求,带一个名为xss的参数。 然后 PHP 会读取该参数,如果不为空,则直接打印出来,这里不存在任何过滤。也就是说,如果xss中存在 HTML 结构性的内容,打印之后会直接解释为 HTML 元素。
部署好这个文件,访问http://localhost/xss.php,直接输入一个js代码,比如,
之后点击test:
我们输入的HTML代码被执行了。用Firebug查看,我们输出的内容直接插入到了页面中,解释为之间输入JavaScript代码,实现一些“特殊效果”。在真实的攻击中,攻击者不仅仅弹出一个框,通常使用方式来加载外部脚本,而在x.txt中就存放着攻击者的恶意JavaScript代码,这段代码可能是用来盗取用户的cookies,也可能是监控键盘记录等恶意行为。
注意:Javascript加载外部的代码文件可以是任意扩展名(无扩展名也可以),如:,即使文件为图片扩展名x.jpg,但只要其文件中包含,JavaScript代码就会被执行。
上面的弹框攻击可能会使读者误解反射型XSS的威力,下面来看一个案例:
存储型
来看看以下两个图片,了解XSS输入输出点、构造闭合的方式、存储型XSS的利用。
DOM型
XSS的利用
XSS不仅仅是弹出一个框那么简单,在某些情况下,XSS不弱于SQL注入。下面列举几个常见的危害:
(1)盗取用户Cookie;
(2)修改网页内容;
(3)网站挂马;
(4)利用网站重定向;
(5)XSS蠕虫。
XSS会话劫持
关于Cookie的简介:
下面来看看如何利用XSS进行会话劫持:
注意:有些开发者使用Cookie时,不会当作身份验证来使用,比如,才能出一些临时信息。这时,即使黑客拿到了Cookie也是没有用的,并不是说只要有Cookie,就一定可以进行“会话劫持”。
XSS蠕虫病毒
待补充。
XSS的修复
XSS跨站漏洞最终形成的原因是对输入和输出没有严格的过滤,在页面执行JavaScript等客户端脚本,这就意味着只要将敏感字符过滤,即可修补XSS跨站漏洞。
字符串过滤
在HTML中,<、>、"、‘、&都有比较特殊的意义,因为HTML标签、属性是由这几个符号组成的。如果直接输出这几个特殊字符,极有可能破坏整个HTML文档的结构。所以,一般情况下,XSS将这些特殊字符转义。
HttpOnly
严格地说,HttpOnly对防御XSS漏洞不起作用,而主要目的是为了解决XSS漏洞后续的Cookie劫持攻击。那么,What is HttpOnly?
HttpOnly是微软公司的Internet Exploer 6 SPI引入的一项新特性。这个特性为Cookie提供了一个新属性,用以阻止客户端脚本访问Cookie。至今已成为一个标准,几乎所有的浏览器都会支持HttpOnly。
在介绍XSS会话劫持时,详细介绍了Cookie的存储形式,并且演示了如何使用JavaScript获取Cookies。一个服务器可能会向服务器端发送多条Cookies,但是带有HttpOnly的Cookie,JavaScript将不能获取。HttpOnlyTest.php代码如下:
DVWA
反射型
【Low】
界面如图所示:
查看后台源码:
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
echo '
Hello ' . $_GET[ 'name' ] . '';
}
?>
1
2
3
4
5
6
7
8
观察到程序并没有对用户输入的name进行任何的过滤操作。那么我们直接输入即可观察到弹窗,从而验证XSS漏洞的存在。
再来尝试更过分的,直接获取Cookie值,输入 ,结果如下:
顺利读到Cookie值,F12打开开发者选项,可以看到,HttpOnly属性没有设置为true:
咱们将其改为true,再尝试一下用刚才的弹框获取Cookie值:
此时,已经无法获取到Cookie值了。
咱们来将刚才获得的Cookie值利用起来,进行免密码登录的尝试。
首先,打开另一个浏览器(谷歌),访问DVWA的登录页面
然后,打开F12,将Cookie值替换掉,安全等级改为low,然后访问127.0.0.1:8088/DVWA,即可成功进入系统:
以上可见XSS漏洞的危害!在获取他人登录状态下的Cookie后可以实现免密码登录他人账号!
【Medium】
将系统的安全等级调为Medium,然后输入刚才的payload: ,发现已经无法正常发生弹窗了:
查看后台源码:
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = str_replace( '
一样可以弹框,当然绕过的还有很多方式。处理这样的paylaod的时候最好再在前面加一个strtolower()函数,将传递的name值得字符统统改为小写。这样就可以不管大小写都能逃不出去(只针对这一个payload)。
【High】
先来查看源码:
<?php
header ("X-XSS-Protection: 0");
// 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
echo "
Hello ${name}";
}
?>
1
2
3
4
5
6
7
8
9
10
观察到使用了正则表达式来过滤。这里利用了preg_replace()函数,将包含<script的字符,不管大小写,不管后面跟着1个或多个与之相同的字符都转换为空。那么我们就不能使用大小写绕过和重写的方法来绕过了。
虽然无法使用 ,可以看到,我们的js代码立即就执行了:
咱们打开数据库查询:
在“其他选项菜单”中,选择Mysql工具->MySQL命令行,进入操作数据库的Shell窗口,并查看刚才插入的数据:
查看页面前端源代码,可以看到,Message位置显示的是我们的js代码,因为这里显示的数据是调用数据库里的数据:
除了在Message字段插入JS代码,咱们来试试在Name字段插入。但是发现,Name字段的长度被限制为10个字符了(超过了就输入不进去):
不过没关系,我们可以使用在前端直接更改maxlength的值,或者通过BurpSuite抓包后改包并绕过。
看看BP的:
成功绕过前端参数限制:
【Medium】
代码分析:
addslashes(string) :函数返回在预定义字符之前添加反斜杠的字符串,预定义字符 ' 、" 、\ 、NULL
strip_tags(string) :函数剥去string字符串中的 HTML、XML 以及 PHP 的标签
htmlspecialchars(string): 把预定义的字符 "<" (小于)、 ">" (大于)、& 、‘’、“” 转换为 HTML 实体,防止浏览器将其作为HTML元素
1
2
3
当我们再次在Name和Message依次输入Dog 和 ,strip_tags函数把,如下图所示:
【补充】我们在DVWA输入以下数据,Name=,也可以使用URL编码后的:
URL编码只是简单的在特殊字符的各个字节(16进制)前加上”%”即可。URL编码的原则就是使用安全的字符(没有特殊用途或者特殊意义的可打印字符)去表示那些不安全的字符。
关于为什么要进行URL编码:https://www.cnblogs.com/jerrysion/p/5522673.html
2.大小写混淆绕过
Burpsuite抓包改name参数为:
3.使用非 script 标签的 xss payload
eg:img标签——Burpsuite抓包改name参数为:
其他标签和利用还有很多很多….
以上抓包修改数据Forward后,均成功弹窗:
【High】
分析:
这里使用正则表达式过滤了
1
也能实现弹框:
写入页面的效果是这样的:
【原理】由于 form表单提交的数据想经过JS 过滤 所以注释部分的JS代码不会被传到服务器端(也就符合了白名单的要求)。
【Impossible】
服务端源代码:
<?php
Don't need to do anything, protction handled on the client side
?>
1
2
3
我们可以看到,impossible级别的代码没有任何东西,注释写的是保护的代码在客户端的里面。我们可以看到,客户端的JS逻辑代码发生了改变:
发现这里对我们输入的参数并没有进行URL解码,所以我们输入的任何参数都是经过URL编码,然后直接赋值给option标签。所以,就不存在XSS漏洞了。
我们来尝试实验一下,访问链接
http://127.0.0.1/vulnerabilities/xss_d/?default=
1
发现页面并没有弹出任何东西,而且语言框内的值是我们输入的参数的经过URL编码后的数据:
查看下页面代码:
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_39190897/article/details/86005088