目录
1、XSS的原理
2、XSS的攻击类型
2.1 反射型XSS
2.2 存储型XSS
2.3 DOM-based 型
2.4 基于字符集的 XSS
2.5 基于 Flash 的跨站 XSS
2.6 未经验证的跳转 XSS
3、复现
3.1 反射性
3.2 DOM-based型
1、XSS的原理
XSS的原理是恶意攻击者往 Web 页面里插入恶意可执行网页脚本代码,当用户浏览该页之时,嵌入其中 Web 里面的脚本代码会被执行,从而可以达到攻击者盗取用户信息或其他侵犯用户安全隐私的目的。
2、XSS的攻击类型
2.1 反射型XSS
因为这种攻击方式的注入代码是从目标服务器通过错误信息、搜索结果等等方式“反射”回来的:发出请求时,XSS代码出现在URL中,作为输入提交到服务器端,服务器端解析后响应,XSS代码随响应内容一起传回给浏览器,最后浏览器解析执行XSS代码。这个过程像一次反射,故叫反射型XSS。
2.2 存储型XSS
他和反射型XSS最大的不同就是,攻击脚本将被永久地存放在目标服务器端(数据库,内存,文件系统等),下次请求目标页面时不用再提交XSS代码。
存储型 XSS 的三大特点:①持久性,植入在数据库中;②危害面广,甚至可以让用户机器变成 DDoS 攻击的肉鸡;③ 盗取用户敏感私密信息。
2.3 DOM-based 型
客户端的脚本程序可以动态地检查和修改页面内容,而不依赖于服务器端的数据。例如客户端如从 URL 中提取数据并在本地执行,如果用户在客户端输入的数据包含了恶意的 JavaScript 脚本,而这些脚本没有经过适当的过滤和消毒,那么应用程序就可能受到 DOM-based XSS 攻击。
2.4 基于字符集的 XSS
哪怕现在很多的浏览器以及各种开源的库都专门针对了 XSS 进行转义处理,尽量默认抵御绝大多数 XSS 攻击,但是还是有很多方式可以绕过转义规则,让人防不胜防。比如「基于字符集的 XSS 攻击」就是绕过这些转义处理的一种攻击方式,比如有些 Web 页面字符集不固定,用户输入非期望字符集的字符,有时会绕过转义过滤规则。
避免基于字符集的 XSS 攻击的两种方法:①记住指定 <meta charset="utf-8">;② XML 中不仅要指定字符集为 utf-8,而且标签要闭合。
2.5 基于 Flash 的跨站 XSS
基于 Flash 的跨站 XSS 也是属于反射型 XSS 的一种,AS 脚本可以接受用户输入并操作 cookie,攻击者可以配合其他 XSS(持久型或者非持久型)方法将恶意 swf 文件嵌入页面中。主要是因为 AS 有时候需要和 JS 传参交互,攻击者会通过恶意的 XSS 注入篡改参数,窃取并操作cookie。
避免基于 Flash 的跨站 XSS 的两种方法:①严格管理 cookie 的读写权限;②对 Flash 能接受用户输入的参数进行过滤 escape 转义处理。
2.6 未经验证的跳转 XSS
有一些场景是后端需要对一个传进来的待跳转的 URL 参数进行一个 302 跳转,可能其中会带有一些用户的敏感(cookie)信息。如果服务器端做302 跳转,跳转的地址来自用户的输入,攻击者可以输入一个恶意的跳转地址来执行脚本。
基于未经验证的跳转 XSS漏洞的两种方法:①对待跳转的 URL 参数做白名单或者某种规则过滤;②后端注意对敏感信息的保护, 比如 cookie 使用来源验证。
3、复现
3.1 反射性
我们这里用到的是DWVA靶场,选择的是反射性的xss:
1)等级low:
<?phpheader ("X-XSS-Protection: 0");// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {// Feedback for end userecho '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}?>
代码分析:直接采用get方式传入了name参数,并没有任何的过滤与检查,明显存在漏洞;
2)等级Medium
<?phpheader ("X-XSS-Protection: 0");// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {// Get input$name = str_replace( '<script>', '', $_GET[ 'name' ] );// Feedback for end userecho "<pre>Hello {$name}</pre>";
}?>
代码分析:这里我们可以明显的看出,是对 script 字符进行了过滤,于是我们需要想办法进行绕过过滤字符;
方法一:双写绕过
<scr<script>ipt>alert(1)</script>
方法二:大小写绕过
<ScRipt>alert(1)</ScRipt>
3)等级High
<?phpheader ("X-XSS-Protection: 0");// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {// Get input$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );// Feedback for end userecho "<pre>Hello {$name}</pre>";
}?>
代码分析:
针对特殊符号,均有过滤,使得双写绕过以及大小写混淆绕过失效。(正则表达式中的i表示不区分大小写)。script标签失效,但是可以通过img、body等标签的事件或者iframe等标签的src注入恶意的js代码。
采用img的标签转换后的xss payload:
<img src = 1 onerror = alert(1)>
3.2 DOM-based型
1)等级low
<?php# No protections, anything goes?>
代码分析:我们可以看到low等级源码中没有做出任何的限制;
2)等级Medium
<?php// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {$default = $_GET['default'];# Do not allow script tagsif (stripos ($default, "<script") !== false) {header ("location: ?default=English");exit;}
}
代码分析:
对<script>进行了过滤,并且将default的值设置为English。这里的script还设置了大小写绕过。
可以使用img标签来进行绕过。这里需要把option标签进行闭合才能发出。前面的low是利用设置default的值,把值进行url解码,然后在option标签中显示。而option标签中是不允许存在img图片标签的,所有需要闭合标签后才能触发。
</option></select><img src=1 οnerrοr=alert("1111")>