OWASP A2 XSS跨站脚本
一.什么叫xss
XSS叫做跨站脚本攻击,网站页面对于用户输入的内容过滤不严格,导致恶意代码被植入网站,也属于注入攻击,常见危害盗取用户cookie,session劫持攻击,钓鱼攻击等。
二.XSS分类
2.1存储型XSS(严重)
存储型XSS一般存在于论坛,评论区等,存在于用户写入数据的地方,并且网站的安全策略对于用户输入的内容缺少有效的过滤,导致攻击者植入具有攻击性质的代码,存放入服务器,盗取用户cookie,无需使用用户的密码即可登录用户账号,也叫作持久型XSS.
// 留言解析攻击
<td><script src='https://bundle.js'></script></td>
<textarea><script src='https://bundle.js'></script></textarea>
// 诱导到钓鱼网站
<img onclick="window.location.href='http://www.baidu.com'" width='300' src='img/webwxgetmsgimg.jpg'/>
// 劫持流量实现恶意跳转
<script>window.location.href="http://www.baidu.com";</script>
2.2反射性XSS
反射型XSS一般是存在于链接中,用户点击后会导致跳转,也叫作非持久型XSS。
2.3DOM型XSS
DOM,在一个网页中,会存在许多元素和标签,为了方便管理网站,提供了一个接口方式,也就是一种新的逻辑结构,能够方便快速的找到每个元素唯一的ID值,是一种树状结构。
DOM xss是基于dom文档对象模型,前端脚本通过dom动态修改页面,由于不与服务端进行交互,而且代码是可见的,从前端获取dom中的数据在本地执行。
三.存储型XSS
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = stripslashes( $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)) ? "" : ""));
// Sanitize name input
$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();
}
?>
3.1代码解析
POST传参,Post传输数据时,不需要在URL中显示出来,而Get方法要在URL中显示。
Post传输的数据量大,可以达到2M,而Get方法由于受到URL长度的限制,只能传递大约1024字节.
.Post顾名思义,就是为了将数据传送到服务器段,Get就是为了从服务器段取得数据.而Get之所以也能传送数据,只是用来设计告诉服务器,你到底需要什么样的数据.Post的信息作为http请求的内容,而Get是在Http头部传输的。
$massage参数对应的是输入的massage
mysql_real_escape_string(string,connection)
对于特殊字符进行转义
stripslashes(string)
函数删除字符串中的反斜杠。
trim(string,charlist)
函数移除字符串两侧的空白字符或其他预定义字符,预定义字符包括、\t、\n、\x0B、\r以及空格,可选参数charlist支持添加额外需要删除的字符。
3.2可以进行的操作
我们发现没有对于输入的内容进行过滤,因此我们可以进行burpsuit抓包,修改上传的参数信息,将我们的代码执行在里面,造成攻击。
3.3遇到过滤特殊函数的情况
常见的XSS语句
<script>alert('hello,gaga!');</script>
<script>alert(document.cookie)</script>
常见过滤XSS的函数和方法
htmlspecialchars方法对用户输入数据进行编码转换
htmlentities转换所有的html标记
htmlspecialchars只格式化& 、’、 “、 <、> 这几个特殊符号
$name = str_replace( '<script>', '', $name );
str_replace函数,将
报错就会弹出,src地址为0是一个错误地址
<img src=0 onerror=alert(/xss1/)>
大小写替换原本的<script>标签
<Script>alert(/xss2/)</sCript>
双重<script>标签:
<sc<script>ript>alert(/xss3/)</script>
四.反射性XSS
最简单的一个反射型的XSS注入
<script>alert(/xss/)</script>
绕过和防御都和上一步的情况差不多,常见的函数也是上面的几种过滤,包括正则表达式的循环遍历, $name = preg_replace( ‘/<(.)s(.)c(.)r(.)i(.)p(.)t/i’, ‘’, $_GET[ ‘name’ ] );
这种情况改变标签也无法进行绕过,大小写、双层
五.DOM型XSS
DOM树,整个文档是一个文档节点
每个 HTML 元素是元素节点
HTML 元素内的文本是文本节点
每个 HTML 属性是属性节点
注释是注释节点
针对DOM型结构是访问查找某一个特定的元素或者值,所以可能会对查找的内容进行一个过滤,例如:
array_key_exists检查数组里是否有指定的键名或索引,并且default值不为null。
stripos 返回default中字符串<script首次出现的位置(不区分大小写),如果未发现返回false。且进入header跳转。 此时
HTML节点内容
HTML属性
JavaScript代码 (字符串提前关闭)
富文本
1、HTML节点内容
这个其实就是我之前演示的,HTML节点中暗藏攻击脚本。
HTML节点内容**
2、HTML属性
这里img的src属性是由用户传递过来的值,当用户把图片地址写成错误的:1"%20οnerrοr="alert(%27哈哈被攻击%27)
六.主要危害
1、盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号
2、控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力
3、盗窃企业重要的具有商业价值的资料
4、非法转账
5、强制发送电子邮件
6、网站挂马
7、控制受害者机器向其它网站发起攻击
七.如何防御
1、HTML节点内容的防御
将用户输入的内容进行转义:
str = str.replace(/</g,’<’);
str = str.replace(/>/g,’>’);
2、HTML属性的防御
对空格,单引号,双引号进行转义
1)黑名单
我们可以把
2)白名单
这种方式只允许部分标签和属性。不在这个白名单中的,一律过滤掉它。但是这种方式编码有点麻烦,我们需要去解析html树状结构,然后进行过滤,把过滤后安全的html在输出。
这里提供一个包,帮助我们去解析html树状结构,它使用起来和jquery非常的类似。