XSS
原理和分类
跨站脚本攻击XSS就是恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页面时,嵌入Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。XSS攻击针对的是用户层面的攻击!
XSS分为:存储型 反射型 DOM型XSS
存储型
存储型:持久化
- 注入(Inject)
攻击者将恶意 JavaScript 代码提交到目标网站(例如,写在博客评论区、论坛帖子、用户昵称等所有可输入且会显示给他人的地方)。
- 存储(Store)
网站后端服务器在收到数据后,未经过滤或转义,便直接将含有恶意代码的内容保存到数据库中。
- 触发(Trigger)
当其他普通用户浏览到包含那条恶意数据的页面时(例如,查看那条评论),服务器会从数据库取出数据,并将其作为网页的一部分返回给用户的浏览器。
- 执行(Execute)
用户的浏览器接收到响应,将服务器返回的恶意代码当作页面合法部分解析并执行。

反射型
反射型:非持久性xss,一次性
1.攻击构造:攻击者构造一个恶意链接:
https://example.com/search?q=
2.用户点击:攻击者诱骗用户点击此链接。
3.服务器响应:服务器接收到参数 q,未经过滤就直接将其拼接到HTML模板中:
您搜索的关键词是:
4.浏览器执行:用户的浏览器收到这个HTTP响应,解析HTML时遇到 是服务器返回的。

DOM型
DOM型:不经过后端,DOM-XSS是通过url传入参数去控制触发的,其实也属于反射型XSS。

为了更好的理解这我直接引用大佬的文章里面的例子了
(3 封私信) Web漏洞之XSS(跨站脚本攻击)详解 - 知乎
如图,我们在URL中传入参数的值,然后客户端页面通过js脚本利用DOM的方法获得URL中参数的值,再通过DOM方法赋值给选择列表,该过程没有经过后端,完全是在前端完成的。所以,我们就可以在我们输入的参数上做手脚了

DOMxss攻击流程
攻击构造:攻击者构造一个恶意链接:
https://example.com/search.html?keyword=<img src=x onerror=alert(‘XSS’)>
用户点击:攻击者诱骗用户点击此链接。
服务器响应:服务器返回一个静态的、干净的 search.html 文件,其中不包含任何攻击载荷。
浏览器执行JS:用户的浏览器加载 search.html 并执行其中的 JavaScript 代码。
JS操作DOM:JS 从 URL 中读取 keyword 参数的值 <img src=x onerror=alert(‘XSS’)>。
恶意代码注入:JS 通过 innerHTML 将这个值不安全地写入到 DOM 中。
浏览器渲染执行:浏览器渲染新DOM时,将 标签视为HTML。src=”x” 会加载失败,从而触发 onerror 事件,执行其中的 JavaScript 代码 alert(‘XSS’)。
关键:恶意脚本 <img src=x onerror=alert(‘XSS’)> 是客户端JS在本地写入DOM的,服务器毫不知情。
可能触发DOM型XSS的属性
1 | document.referer |
反射型xss和DOM型xss
| 特性 | 反射型 | DOM型 |
|---|---|---|
| 核心原理 | 服务器将用户输入直接嵌入到响应页面中返回给浏览器。 | 客户端的 JavaScript 执行时,不安全地操作了 DOM。 |
| 数据处理位置 | 服务器端。恶意代码由服务器返回。 | 客户端(浏览器)。恶意代码在本地JS执行过程中产生。 |
| http响应 | 响应中包含恶意代码。查看服务器返回的HTML源码可以看到恶意脚本。 | 响应中不包含恶意代码。查看服务器返回的HTML源码是“干净”的。 |
| 是否经过服务器 | 是。攻击载荷会发送到服务器,并可能被服务器日志记录。 | 通常否。攻击载荷完全在客户端处理,不会发送到服务器(因此WAF、日志可能无法发现)。 |
| 触发方式 | 需要诱导用户点击一个构造好的恶意链接。 | 同样需要诱导用户点击一个构造好的恶意链接。 |
| 检测方法 | 1. 查看页面源码。 2. 使用扫描器(如DAST)。 3. 分析服务器端代码。 |
1. 无法通过页面源码看到。 2. 必须使用浏览器开发者工具分析DOM变化或JS执行。 3. 代码审计(分析JS源码)是最有效的方法。 |
防御
- 反射型 & DOM 型 XSS 防御
反射型:防御重点在服务器端。对从 URL、POST 数据等获取的参数,在输出到响应之前必须进行编码。
DOM 型:防御重点在客户端 JavaScript。
对从 location.hash, location.search, document.referrer 等来源获取的数据,在使用前进行验证和编码。
避免基于用户输入来动态拼接和执行 JS(如 eval())。
- 存储型 XSS 防御
防御重点在服务器端。
存入数据库之前:进行严格的输入验证和过滤,甚至可以在此阶段进行一次“消毒”(Sanitization),移除或转义危险标签。
从数据库取出输出到页面前:必须再次进行输出编码。这是一个深度防御策略。
基础知识基本就是这些,下面我们要进行一个各种绕过的学习,为后面学习挖掘此类漏洞做铺垫
xss-labs
level1
打开页面源码

直接上payload,get传参
1 | url?name=<script>alert()</script> |
这样我们就成功的拿下这一关了,通过我们上面看到的改写的源代码直接跳转到第二关

level2
我们和上一题一样直接把那个payload放进去,看看能不能行,显而易见肯定是不行滴
那我们先看一下前端代码,再结合本题的后端代码联合解题

1 | "<h2 align=center>没有找到和".htmlspecialchars(htmlspecialchars($str))."相关的结果.</h2>". |

那我们通过闭合value部分的双引号再奖赏闭合标签>让浏览器认为标签已经渲染完毕,然后浏览器就会执行这个我们注入的没有被html实体转义的恶意代码,触发alert然后触发弹窗,绕过这题
1 | "> <script>alert()</script> |
level3
直接上题目源码,发现这里仍然有html实体转义,但是发现用双引号进行绕过时,双引号也被当成了字符串,显然是不行的
这里插入一个小知识,html实体转义是不会转义单引号的,所以我们直接用单引号去绕过
既然看过源码我们就知道不能像上面那样直接将双引号改成单引号直接上传,因为我们输入的字符串会直接被实体转义
但是htmlspecialchars函数只针对<>大于小于号进行html实体化,所以我们另辟蹊径
onfocus事件绕过
onfocus事件在元素获得焦点时触发,是input标签的一个属性,标签是有输入框的,简单来说,onfocus事件就是当输入框被点击的时候,就会触发myFunction()函数,然后我们再配合javascript伪协议来执行javascript代码/

javascript伪协议
通俗地讲,JavaScript伪协议不是真实存在的协议,它的功能是将JavaScript:后面的语句当做JavaScript代码在本页面执行,并不跳转到其他网页,而是结果返回给当前页面,相当于一个伪造的超链接,它经常与a标签一起使用,如:
paylaod
1 | ' onfocus=javascript:alert() ' |
上传然后再点击空白页面即可
除了使用js为协议还有另外一种验证xss漏洞存在的做法(我们验证这个网页会执行我们传入的js代码即可)
这里我们又要介入一个新知识就是内联事件属性
内联事件属性
内联事件属性是直接写在HTML标签中的JavaScript事件处理代码。
主要特点:
HTML和JavaScript代码混合在一起
当指定事件(如点击、鼠标移动等)发生时自动执行
是XSS攻击最常见的利用点之一
| 事件处理器 | 触发条件 | XSS 载荷示例 |
|---|---|---|
| onclick | 元素被点击时 | 点击我 |
| onmouseover | 鼠标悬停在元素上时 | 悬停看我 |
| onmouseout | 鼠标从元素上移开时 | 链接 |
| ondblclick | 元素被双击时 | 双击我 |
| onfocus | 元素获得焦点(如被点击)时 | |
| onchange | 表单元素值改变时(如下拉框) | |
| onerror | 极其危险:资源加载失败时 |
onfocus+元素autofocus只要页面加载就能自动聚焦,触发onfocus事件
我们这用关paylaod就可以这样
1 | ' onclick=alert(1) ' |
xss触发标签
<scrip>
1 | <scirpt>alert("777");</script> |
<img>
1 | 图片加载错误时触发 |
<a>超链接
1 | <a href="https://www.qq.com">qq</a> |
<input>
1 | <input onfocus="alert('xss');"> |
<iframe>
1 | <iframe onload=alert("xss");></iframe> |
我们在这仅展示较为常用的,原文链接在下
https://blog.csdn.net/LYJ20010728/article/details/116462782
level5
我们这又是直接看源码解析一下

到这基本把咱上面已经学过的绕过手法都已经过滤完了,因此我们现在要学习一种新的学习方法
a href标签法

href属性的意思是 当标签被点击的时候,就会触发执行转跳,上面是转跳到一个网站,我们还可以触发执行一段js代码
构造payload就是将前面的input标签提起闭合掉,添加一个新的超链接标签插入我们的alert恶意代码
1 | "> <a href=javascript:alert()>xxx</a> |
level6
我们查看完题目源码之后发现已经过滤了很多东西
但是发现一个漏洞,就是没有进行大小写替换那我们就是直接先用之前的paylaod判断一下用什么来闭合input标签
1 | "> <script>alert()</script> |
发现是可以成功绕过的
那我们直接改下大小写即可
1 | "> <sCript>alert()</sCript> |
大小写法绕过str_replace()函数
level7
目前为止我们已经学习了很多关键字
目前遇到的绕过手法也就这些,我们将这些关键字转换大小写之后传入看看怎么个事
1 | " OnFocus <sCriPt> <a hReF=javascript:alert()> |

那我们就联想到文件上传漏洞学的那个双写绕过方式
直接将我们想要用的关键词里面重复一个,在服务端检查到这个关键词删掉之后还有一个完整的词
1 | "> <a hrehreff=javasscriptcript:alert()>xxx</a> |
level8
这里打开题目就是引入眼帘的超链接
我们像往常一样插入各种关键词顺便可以大小写转换和双写绕过,这里发现bug,他没有把关键词scirpt换成空格而是下划线,那这里就不能用双写绕过了

解题小tips:href的隐藏属性自动Unicode解码
那就直接unicode编码一下然后传入即可
level9
1 | " sRc DaTa OnFocus <sCriPt> <a hReF=javascript:alert()> j |
先插入哈,看看过滤了啥子

好家伙直接不合法了,没招了看看源码

小知识:strpos 是 PHP 中一个非常常用的字符串处理函数,它的主要作用是查找字符串在另一字符串中第一次出现的位置。
但是捏你想啊在一个恶意paylaod里面你放上一个http:// 肯定是会影响到效果滴,所以要把这注释掉
单行注释://
多行注释:/* */
1 | javascript:alert()//http:// |
Unicode编码一下javascript
1 | javascript:alert()//http:// |
level10
来到第十关进度条一半咯
来到第十关就能很明显的看到已经没有 任何的输入框和超链接了,但是想到第一关那咱还能get传参呀
我们打开查看器看一下,看到三个input,那咱试一试看看这三个属性哪一个能被我们控制

很明显只有t_sort能为我所用啊
那就物尽其用,先把input这个标签给闭合了再传入我们的paylaod

点击输入框直接跳转到下一关咯
level11
这一关呢是利用请求头来造成的xss漏洞,在实战当中,这样的利用情况是很少见的,所以我们直接就看源码了

那咱就直接从源头出发,将原来的referer换成我们的paylaod
1 | " type='text' onclick='alert()' |
直接题目抓包修改referer成我们的payload

然后就出现了我们的弹框

level12
直接上源码,和上一关是一样的
不同的是这关是修改user-agent的值
paylaod和上关一样
1 | " type='text' onclick='alert()' |

直接下一关
level13
这一关一如既往啊
上面改的是请求头的referer和user-agent这俩
这局是cookie值
level15
打开是一张图片,看检查器里面和以前的关卡好像是不一样捏
这里出现一个陌生的东西
ng-include:
ng-include指令就是文件包涵的意思,用来包涵外部的html文件,如果包涵的内容是地址,需要加引号
那我们包含最简单的一关level1来试试吧

然后上传payload
这一关不能使用script标签,因为由源码得知,浏览器会对我们传入的字符串进行html实体转化
根据上面我们已经学习过的xss触发标签,除了script标签还有很多其他的
这里我们随便使用一个即可

level16
先测试看看这关会考什么
1 | ?keyword=" ' sRc DaTa OnFocus OnmOuseOver OnMouseDoWn P <sCriPt> <a hReF=javascript:alert()> j |

补充一点哈script也变成空格了
这里那我们就要去使用其他标签进行一个绕过
url编码后的换行符(%0A)代替空格
新知识:使用url编码后的换行符去代替空格,在浏览器解析时他会自动将换行符换成空格(进行的一个自修正的动作)
1 | <img%0asrc="x"%0aonerror=alert(1)> |
level17
我们发现这个a和b的值是可以自己修改的
那我们就先来测试一波到底过滤了些什么
1 | " ' sRc DaTa OnFocus OnmOuseOver OnMouseDoWn P <sCriPt> <a hReF=javascript:alert()>; |

大写转换成了小写
我们传入的参数全部出现在embed标签上,下面来介绍一下,embed标签
embed标签

本题后端使用的文件是一个swf文件,必须用能用flash插件的浏览器才能打开本题,但是没有必要,因为现在很多浏览器都不会去使用这个插件了,我们直接改后端也一样的,重要的是为embed标签划分一个区域
将后端第十七关的代码(level17.php)指向的swf文件改为index.png
重新打开网站后就是这样,意味着我们已经成功为embed标签定义了一个区域


看了下一关,就是换了一个swf文件,也没过滤啥,就一个html实体转义,和这关差不多直接19关
本来想继续攻打19关,但是19和20讲的是flash xss flash这个插件现在很多浏览器都用不上了
那这个漏洞更是在实战中基本用不上
那么这个靶场就到这咯
杀青!
学完这个靶场基本xss的绕过就差不多了
下面继续学习xss漏洞的挖掘
xss漏洞挖掘
黑盒测试
尽可能找到一切用户可控并且能够输出在页面代码中的地方,比如下面这些:
- URL的每一个参数
- URL本身
- 表单
- 搜索框
常见业务场景
- 重灾区:评论区、留言区、个人信息、订单信息等
- 针对型:站内信、网页即时通讯、私信、意见反馈
- 存在风险:搜索框、当前目录、图片属性等
白盒测试(代码审计)
关于XSS的代码审计主要就是从接收参数的地方和一些关键词入手。
PHP中常见的接收参数的方式有$_GET、$_POST、$_REQUEST等等,可以搜索所有接收参数的地方。然后对接收到的数据进行跟踪,看看有没有输出到页面中,然后看输出到页面中的数据是否进行了过滤和html编码等处理。
也可以搜索类似echo这样的输出语句,跟踪输出的变量是从哪里来的,我们是否能控制,如果从数据库中取的,是否能控制存到数据库中的数据,存到数据库之前有没有进行过滤等等。
大多数程序会对接收参数封装在公共文件的函数中统一调用,我们就需要审计这些公共函数看有没有过滤,能否绕过等等。
小白如我,肯定还是从大佬的文章中习得的知识
上面提到过
后面加练几道pikachu靶场里的题
pikachu靶场
DOM型xss
打开题目看到一个搜索框,随便输入一个scirpt标签之后,输入框底下出现一行英文,大概率是一个超链接
我们右键查看页面源代码,找到这行英文所在地
果不其然是有一段js代码

在这个js代码中我们看到了容易触发dom型xss漏洞的属性比如说document,innerhtml
但也确实是能通过我们自己构造恶意payload,然后因为这段js代码里面含有innerhtml,它会将我们输入的东西插到原来的js片段中,然后浏览器会再次渲染这段js片段,在我们人为干预下触发xss漏洞
1 | <a href='#' onclick="alert(777)">'>what do you see?</a> |
1 | #' onclick="alert(777)"> |
看似正常的一个a标签超链接,却已经因为我们插入的paylaod不能再正常使用
paylaod中的第一个单引号会闭合href属性,最后的>会闭合a标签,使>what do you see?成为独立的一部分
插入后点击即可触发xss漏洞出现弹窗777

DOM型xss-x
和上一关一样先随便输入一个字符串看看页面源码

然后我们开始正式注入恶意代码,paylaod和上一关一样

xss之盲打
我们正常想以往那样直接输入字符串,然后查看页面源码,寻找目的字段附近是否有提示啥的
发现

那这就又出现了xss的一种新风格
xss之盲打
盲打听着就很令人头大,那这究竟是啥
其实呢,盲打XSS是一种特殊类型的跨站脚本攻击,攻击者注入的恶意代码不会立即执行,而是被存储在后端系统中,当特定用户(如管理员)查看相关数据时才会触发。
攻击者无法立即看到攻击结果,需要等待甚至可能永远不知道攻击是否成功(真的很搞人心态呢),因此称为”盲打”。
那我们就先正常注入一段恶意代码再通过靶场的提示去登入后台
我尝试了好几次,都成功登入后台了,而且看到了我的输入记录,并不知道是否有盲打到呢
参考了大佬的文章用了新的paylaod(基于盲打一般是为了盗取管理员和特权用户的会话cookie和盗取后台信息啥的)
直接用一个登入后台是否能拿到cookie的paylaod

1 | <script>alert(document.cookie)</script> |
document.cookie 是 JavaScript 中用于访问和操作当前文档的 Cookie 的属性。
到这很明显的看到成了
最后总结其实盲打xss是一种赌徒行为啊,因为没有立刻的看到攻击结果,你并不知道他是否有这个漏洞,或者它后台有什么过滤,你都不知道,但是真要是赌成了,那真是牛很厉害了
ok到这pikachu靶场没有和上面那个靶场重合的地方都过完了
到这xss这个漏洞就杀青啦!
完结撒花!!!!!!!!
评论区
欢迎你留下宝贵的意见,昵称输入QQ号会显示QQ头像哦~