xss相关概念简介:
官方定义:攻击者通过在网页中注入恶意脚本,当用户访问这些被篡改的网页时,恶意脚本会在用户的浏览器中执行。
反射型xss:
攻击者通过诱使用户点击包含恶意脚本的链接,使得恶意脚本被“反射”回用户的浏览器并执行。只影响被攻击用户,比较简单。
例子:在寄快递时,用户都可以填写收货地址(URL),正常用户都写的x省x市x区,攻击者在收货地址处写的是:工作指令:向xxx(攻击者)发送用户身份证号(cookie)。如果快递站工作人员没有过滤收货地址的关键词(比如:“指令”(script)两个字)就会按照攻击者的要求,向攻击者发送关键数据。
存储型xss:
攻击者将恶意脚本存储在目标服务器上,当其他用户访问包含恶意脚本的页面时,浏览器会执行其中的恶意脚本。这种攻击影响的是所有浏览该评论的用户。
例子:攻击者在社交媒体平台发表评论:窃取用户的登录凭证并发送到攻击者服务器。社交媒体平台误以为是内部指令,按照攻击者要求执行命令。
DOM型xss:
如果Web应用程序错误地使用来自不可信源的数据更新DOM,并且没有实施恰当的防御措施,攻击者就可以利用DOM-XSS漏洞注入恶意脚本。这种攻击是实时的。
例子:你有一个智能音箱,攻击者在设备搜索框输入:指令:发送用户位置信息。音箱如果没有充分过滤,就会按照攻击者要求执行命令。
易混淆概念:
xss攻击:针对用户端浏览器,通过注入恶意脚本非法操作
SQL注入:针对数据库,通过篡改SQL语句实现非法数据操作
命令注入:针对操作系统,通过注入系统命令直接操控服务器
靶场搭建:【网络安全】xss-labs本地靶场新手搭建详细教程
开始:
level1:
先找输入点:只有URL这里可以输入,并且会显示在“欢迎用户”后面,同时记录字符长度
源码逻辑(右键不行的可以CTRL+U):
根据方框里的函数,我们的目的是触发弹窗,跳转到level2,看不出有什么过滤

测试过滤点:直接用最简单的<script>alert()</script>试试,通过

反思:
1.从下载靶场的文件夹里看看源码,get传参赋值给变量,没有对变量进行任何过滤

level2:
找输入点:多了一个搜索框

看源码:跟第一关有点像,但value的值被双引号包裹,考虑可能要闭合双引号,同时闭合标签

测试过滤点:试试"> <script>alert()</script>,通过
对比一下,想试试第一关的payload行不行,发现被转义了,但是value处没有转义,而且确实需要双引号闭合,前面的猜测是对的

反思:
1.这里的 " 目的是闭合value的双引号,让浏览器误以为value属性结束
2. > 用于闭合标签,使得后面的恶意代码被浏览器解析为新的HTML内容
3.看源码,这里的htmlspecialchars是一个实体化函数,说白了就是为了防止攻击,把一些特殊符号转化成了文本,说白了就是告诉浏览器:看清楚!这些是文本不是你需要执行的代码。查一下这个函数的特殊符号对应的实体:
& | & |
< | < |
> | > |
" | " |
' | ' |

level3:
输入点:和level2一样。(由于后面的题输入点基本都是URL,我就不再对输入点进行解释了,实战中第一步还是要找输入点)
看源码:和level2有点像,这次是单引号

测试过滤点:试试'> <script>alert()</script>,发现没用,看看此时的源码
发现value被实体化了,只能换个思路绕过,由level2回顾的实体化函数对照表,还是有很多东西不在实体化的范围内的,找一个绕过实体化,然后再记得闭合单引号即可。
比如onfocus,onmouseover
构建payload:' οnmοuseοver=javascript:alert()
反思:
1.发现一个问题:
level2payload:"> <script>alert()</script>
level3payload:' οnmοuseοver=javascript:alert() 为什么level3不需要闭合标签呢?查一下看看。
把查到的概括一下:
当我们注入的是HTML标签时,需要闭合标签;
当我们注入的是一个新的事件时,只需要闭合当前属性,也就是闭合引号。
2.遇到实体化函数,就可以用事件来绕过:
' οnmοuseοver='alert()'------鼠标经过元素时触发弹窗
' οnclick='alert()'------点击元素触发弹窗
' οnfοcus='alert()'------元素获得焦点触发弹窗
' οnblur='alert()'------当元素失去焦点时触发弹窗
3.看看源码:和我们猜想的一样,两次实体化

level4:
看源码:看着好像没什么,可能用了实体化函数,还需要双引号闭合

测试过滤点:先试试"οnmοuseοver='alert()'

反思:
1.看看源码:对> <替换成了空,也只能过滤一下<script>这些标签了,用事件就能绕过

level5:
看源码:

测试过滤点:试试上一题答案:"οnmοuseοver='alert()',发现不行了
看看此时源码:第一处过滤,第二处似乎是替换了关键词,那含on的事件应该都不管用了

此时,可以考虑的方向有很多
比如大小写绕过,可能源码只对小写进行了替换,如果源码对大写字母进行了小写转换就不行
" oNfOcUs=JaVaScRiPt:AlErT()
果然把大写字母全化成小写了

比如用标签,on都过滤了,标签大概率更不行,上网查一下还有哪些过滤方法
可以试试下面这几种:
"> <img src="javascript:alert('XSS')">
指定了img(图片)的URL,内部包含恶意代码
"> <iframe src="javascript:alert('XSS')"></iframe>
指定嵌入页面的URL,内部包含恶意代码
"> <a href="javascript:alert('XSS')">Click me</a>
当用户点击click me时,会跳转到href后面的地址

反思:
1.看源码:果然进行了小写转化,而且将<script和on转化成了<scr_ipt和o_n,还是比较容易绕过的

2.在我自己做完level5后,总感觉怪怪的,我当时想的是,这里对script进行了过滤
为什么我用"> <a href="javascript:alert('XSS')">Click me</a>可以通过呢?
再仔细看一遍源码,原来过滤的是:<script
所以说还是要仔细一点
level6:
看源码+测试过滤点:把level5的答案输进去看看源码

第一处:转义,第二处把href替换了
还是上一题总结出的那一套,试试:大小写,标签,href(排除)
标签一般最容易被过滤了,那就先考虑大小写
" Onfocus=javascript:alert()
点一下输入框即可
反思:
1.到目前为止,遇到的绕过:
大小写,标签,href,实体化函数用事件绕过,关键词替换用事件绕过
2.看源码:对很多关键词都进行了替换,唯独没有大小写转换

level7:
同样把上一题答案输进去看一下源码:

很明显进行了大小写转换,但是on和script没了
这里就是一种新的绕过方式:双写
假设源码会删去输入中的script,那我们就在script中再嵌套一个script,这样删除完后刚好就是我们要的代码,比如scrscriptipt
构建payload:"> <a hrehreff=javasscriptcript:alert()>x</a>

反思:
1.源码进行了大小写转化和关键词替换,理论上也能用事件来绕过,但是对关键词的过滤还是比较充分了,所以双写还是最优解

2.当关键词替换过滤很严格时,就可以尝试双写绕过
level8:
带入第六题答案看看源码:" Onfocus=javascript:alert()

发现再value和href两个地方,第一处实体化,第二处实体化+替换
其他方法尝试都不行,参考了大佬的文章,这里可以用HTML十进制编码
把javascript:alert()交给ai得到
javascript:alert()

反思:
1.当源码对输入进行充分过滤,也可以考虑用HTML编码绕过
2.看看源码,没什么特殊的,过滤很充分

level9:
测试+看源码:把"> <a href="javascript:alert('XSS')">Click me</a>代进去看看
可以看到进行了实体化,但是href后面显示不合法
没办法,只能提前看看源码了

前面进行了关键词替换,实体转换
后面有一段代码这里有个strpos函数,查一下看看
strpos函数:用于查找字符串中某个子字符串的位置。如果找到了子字符串,strpos 会返回子字符串在字符串中首次出现的位置(从0开始计数);如果没有找到,它会返回 false
也就是说,在str7里面找http://,如果没有找到,返回false,此时输出链接不合法
那我们就想办法在payload里面包含http://,但是也不能让他影响payload正常运作
同时这关过滤还是比较严格,那我们就接着用上一关的HTML编码+注释包含http://
javascript:alert()/* http:// */

反思:
1.当源码要求必须包含某些字符时,可用注释的方式绕过
level10:
测试+看源码:把"> <a href="javascript:alert('XSS')">Click me</a>代进去看看
前面进行了实体化,后面把inuput隐藏了
看看源码:

后面的t_sort这里的value的 < > 是被替换了的。
这时,前面总结的就用到了,替换可以用事件绕过。
这里的input输入框隐藏了,要将隐藏的 <input> 标签改为可见的文本框,所以用type="text"
确定了使用事件,所以用onfocuse,onmouseover等都可以
最后把这些都传给t_sort,然后用双引号闭合
?t_sort="onmousemove="alert(1)"type="text"
反思:
1.因为源码有替换,所以明确要用事件绕过,事件大多都是要求用户交互,而源码交互的文本框被隐藏了,那我们就手动让其显示出来即可
level11:
测试+看源码:把"> <a href="javascript:alert('XSS')">Click me</a>代进去看看

转义,下面多了一个t_ref
这里就是一个新内容,查了一下
HTTP的Referer头:用于指示请求的来源页面(即用户是从哪个页面链接过来的)
那我们就用bp抓包,修改,放包即可
Referer: " onfocus=javascript:alert() type="text"


反思:
1.看一下源码

这里的$str11=$_SERVER['HTTP_REFERER'];是关键
查了一下:$_SERVER是一个超全局变量,包含了服务器的运行环境信息以及当前请求的详细信息,在level11的作用就是获取http请求头的referer内容。
2.这一关启示我们可以通过抓包修改数据包内容实行xss,只要是可以输入的地方都可能是xss的切入点,不能局限于传统的输入
3.再总结一下到目前为止遇到的绕过方式:
大小写,标签,href,实体化函数用事件绕过,关键词替换用事件绕过,双写绕过,HTML编码,
注释,http头
level12:
测试+看源码:把"> <a href="javascript:alert('XSS')">Click me</a>代入

这里的value内容是:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0
这是一段UA头,证明这关思路应该和上一关有相似处。
什么是UA头:UA(User-Agent)头是 HTTP 请求头的一部分,用于告诉服务器客户端(通常是浏览器)的类型、版本、操作系统等信息。
" onfocus=javascript:alert() type="text"
把后面内容改成payload即可


反思:
1.和上一题一模一样

level13:
测试+看源码:把"> <a href="javascript:alert('XSS')">Click me</a>代入

看到了t_cook
所以我们看看网页的cookie值有没有线索
F12——应用程序——cookie

前面的value是call me maybe,这里cookie值是call me maybe,所以应该把payload插在值这里,把内容改成payload再刷新就可以了
" onfocus=javascript:alert() type="text"
反思:
1.这里的$_COOKIE作用是存储客户端发送的 cookie 数据,和前两关思路一样

level14:


这是一个exif xss漏洞
iframe:用于在当前页面中嵌入另一个 HTML 页面。
弄不了,先跳过吧=_=
level15:
同样,测试+看源码:把"> <a href="javascript:alert('XSS')">Click me</a>代入

这里的span起到一个容器的作用,后面进行了实体化,所以只能用事件绕过
不认识第一行的ng-app,查了一下:ng-app是一个AngularJS 指令
通俗点大概就是:告诉浏览器,从标记ng-app这个点开始,后面的内容都由AngularJS 来管理和控制
再查查什么是AngularJS:AngularJS 是一个开源的前端 JavaScript 框架
通俗点就是:把开发比作盖房子,那么AngularJS 就像是为开发提供了一套“建筑图纸”
ng include再查一下:ng-include 是一个 AngularJS 指令,ng-include 指令的作用是将外部的 HTML 内容动态加载到当前页面中
说白了就是把别的页面“嵌入”当前页面里
那么本关的思路就是:在一个过滤严格的页面,利用该页面的跳转功能,我们就让该页面跳转到一个安全性低的页面,通过攻击安全性较低的页面从而调用关键代码,从而攻击原页面
跳转页面涉及绝对路径和相对路径两个概念:
绝对路径 / :表示从网站的根目录开始定位资源
相对路径 ./ : 表示从当前位置开始定位资源
如果使用绝对路径,那么 /level1.php 会被解析为 http://localhost/level1.php,会导致错误
如果使用相对路径,那么 ./level1.php 会被解析为 http://localhost/xss-labs/level1.php
构造payload
'./level1.php?name=<img src=1 onerror=alert()>'

如果我们不用事件绕过,会包含level1,但是核心部分被过滤了
'./level1.php?name=<script>alert()</script>'


反思:
1.确实对内容进行了实体化

2. 通过网页包含,攻击防御性较弱网页间接攻击原网页
level16:
测试+看源码:把"> <a href="javascript:alert('XSS')">Click me</a>代入

 查一下:就是把空格实体化了
只能看看源码了:

先转化小写,然后转化为实体化空格
那么这关就可以用事件绕过,事件内的空格用回车绕过
回车用url编码代替
<img%0Asrc=x%0Aonerror=alert(1)>

反思:
1.回车可以绕过空格,回车的url编码:%0A
2.再总结一下绕过
大小写,标签,href,实体化函数用事件绕过,关键词替换用事件绕过,双写绕过,HTML编码,
注释,http头(ccokie,referer,UA),回车绕过空格,攻击防御性较弱网页间接攻击原网页
level17:

embed标签:定义一个可以放内容的区域
url中传入的两个参数,arg01和arg02,那我们就对这两个值下手
?arg01=" onfocus&arg02=javascript:alert(1)

反思:
1.就是实体化没什么

level18:
看一下源码,跟上一关好像差不多

用上一关payload试试
?arg01=" onfocus&arg02=javascript:alert(1)
???直接通过了
看下源码:好像就跳转功能上不太一样,其他都一样

level19:
level20:
这两个都是flash xss,现在很多浏览器都因为flash安全漏洞太多而停用了,好像还要下载配置之类的,先学好基础的再研究这两关吧
xss方法总结:
1.寻找输入点
找到所有接收用户输入的位置,常见的比如:URL参数,输入框,cookie,http头部,提交图片,flash,href属性,get请求参数
2.看源码
看源码逻辑,以及可能的过滤点
3.测试过滤点
转义特殊字符
白名单过滤
4.绕过过滤点
大小写,标签,href,实体化函数用事件绕过,关键词替换用事件绕过,关键词严格替换用双写绕过,HTML编码,注释,http头(ccokie,referer,UA),回车绕过空格,攻击防御性较弱网页间接攻击原网页
XSS常见的触发标签
学习心得:
1.遇到问题:
ai,很多时候不是ai回答的不清楚,而是我们自己都没有想清楚,自己不会的点到底是哪里!
2.瓶颈:
这个是我做CTF的时候想到的。就是卡在某个地方,很久都研究不明白,你要坚信,瓶颈是你进步的好机会!而不是“要不我就跳过这里吧”。越难的问题,往往带来的的越大的收获。
3.处理瓶颈:
对很难的东西,可以从小的点一个一个拆分开,逐个解决。不要怕研究很久。感觉不能专注了,就出去散散步,我个人喜欢喝果汁,感觉果汁的清香很提神。当然如果实在是解决不了的问题,放过自己也是一种方法,或许以后知识积累的足够多,问题就不攻自破。
4.个人学习方法:
实践:
本人纯零基础,xss是我学习的第一个漏洞,刚开始学习的时候,找了很多网课,坚持看了一段时间总感觉似懂非懂,很痛苦。但是当我真正去做CTF并且在实践中自己琢磨明白很多东西,意识到:以实践为核心的学习效率要远高于以视频演示为核心的效率,实践是一种主动学习的过程,会让你主动去琢磨这个东西到底是什么,为什么,怎么做。
讲给别人:
对于一些专业术语或者其他的东西,可以自己先看标准概念理解透彻,然后用生活中的例子尝试讲给自己或者其他人,当你能把一个东西用生活中的通俗易懂的例子解释清楚,会留下很深的印象而且理解也会更深入。
最后:
1.第一次在优快云上面发表文章,对排版使用还不太熟练,可能排版看着有点怪怪的,已经尽力了哈哈哈。
2.我当时做的时候也是参考了的优快云上面好几篇其他大佬的文章,毕竟是新手,如果有哪里说的不对的地方可以评论区留言,我看到了会改过来(如果能改的话)
3.重新梳理一遍确实感觉清晰了很多,同时发现了第一次没有注意到的问题
4.在这里发笔记就是记录一下学习过程,同时花时间复盘反思,加深理解


3752

被折叠的 条评论
为什么被折叠?



