皮卡丘XSS
1, Get
很简单,直接bp抓包,然后get表单里面改就行。
但很奇怪的是前端直接输入它好像就给你过滤了。让我看看源代码,不过经我测试好像是有字数限制。
2Post
我试了一下前端直接输入,感觉有过滤。
CTRL shift加f搜索。
存储型之前写过,他是把这些东西存储在数据库中,只要你一打开就会这样。
DOM
前面的反射型是通过服务器返回的数据回显加载到了页面上,这个就纯依赖js文件。
无回显
你对DOM型XSS的原理理解是正确的。总结一下核心点:
- 漏洞完全在客户端DOM操作中产生,服务器不参与脚本执行;
- 利用方式是将恶意脚本通过DOM属性(如 href 、 onclick )或内联脚本注入到页面中,让浏览器执行;
- 这个场景里通过 javascript: 伪协议注入 alert(1) ,正是DOM型XSS“前端JS不安全处理用户输入,直接渲染为DOM属性”的典型表现。
DOMX
这题不就是二次插入吗点一下之后,把这个比语句注入到了第2个标签。
盲打的话肯定不是反射型,也肯定不是存储型,因为无回显,所以只有一个dom,不对,没有注入标签…
如果能登录后台的话,那应该就是存储型了,这个应该是坑管理员的。
所以让我随便写一个。。。
上面写下面不写,其实也可以下面写上面不写,或者两个都写我试试。
都可以
过滤。
这一看就是回显
他把那个关键词过滤了,让我再试试括号
既然如此就换一个方式。
我记得好像有一个可以闭合那个啥前面的标签,或者试试别的绕过。
AI启动
<!-- 图片标签事件 -->
<img src="x" onerror="alert('XSS')">
<!-- 链接标签事件 -->
<a href="javascript:alert('XSS')">点击触发</a>
<!-- 输入框事件 -->
<input type="text" onfocus="alert('XSS')" autofocus>
原理好像是直接注入了一个标签,然后居然还执行了∽不过第2个不行。
你看第1个也可以。
第3个也可以。
第2个不行的原因是把</a>给过滤掉了∽
接着是html sqecialchars∽
这是什么∽
哦,原来是过滤∽
原来是转义,让我看看网上有没有先加密之类的∽
有,但是不能反转义∽man!
哦,是回显∽
AI启动拼接大法。
要绕过HTML转义(如 htmlspecialchars ),核心前提是转义配置不完整(比如漏转特殊字符、编码不匹配)——若转义完全(如 htmlspecialchars($input, ENT_QUOTES, 'UTF-8') ),几乎无法绕过。以下是常见的“转义不完整”场景及绕过思路:
一、绕过“未转义单引号”的场景(最常见)
若 htmlspecialchars 未加 ENT_QUOTES 参数,仅转义双引号( " ),不转义单引号( ' ),可在单引号包裹的HTML属性中注入:
原理
假设页面代码(转义不完整):
php
// 仅转义双引号,单引号未转义
$input = htmlspecialchars($_GET['xss'], ENT_COMPAT, 'UTF-8');
echo "<input type='text' value='$input'>";
绕过Payload
构造 xss=' onfocus='alert(1)' autofocus ' ,最终渲染为:
html
<input type='text' value='' onfocus='alert(1)' autofocus ''>
此时 onfocus 事件被注入,页面加载后输入框自动获焦,触发 alert(1) 。
二、绕过“编码不匹配”的场景
若后端转义用 GBK 编码,前端页面声明 UTF-8 编码,可利用编码冲突让转义后的实体被重新解析为特殊字符:
原理
GBK编码中, %bf%27 会被解析为 縗' ,若后端用 htmlspecialchars 转义时未指定 UTF-8 ,可能导致转义失效。
绕过Payload
构造 xss=%bf%27 onclick=alert(1) %bf%27 ,在编码不匹配的页面中, %bf%27 会被解析为单引号,最终注入事件属性。
三、绕过“前端二次解码”的场景
若后端已转义(如将 < 转成 < ),但前端用 innerHTML 、 document.write 等方法二次渲染(自动解码HTML实体),可直接构造转义后的Payload:
原理
后端输出: <script>alert(1)</script>
前端代码(二次解码):
js
// 用innerHTML将转义后的实体重新解码为<script>标签
document.getElementById('box').innerHTML = "<?php echo $input; ?>";
绕过Payload
直接传原始 <script>alert(1)</script> ,后端转义后的实体被前端 innerHTML 解码,最终执行脚本。
四、利用“标签/事件的特殊解析”
若转义了 < 和 > ,但未过滤 javascript: 伪协议或部分危险事件,可在已有标签的属性中注入:
原理
假设页面有 <a href="{$input}">链接</a> , htmlspecialchars 仅转义 < / > ,不处理 javascript: 。
绕过Payload
构造 xss=javascript:alert(1) ,最终渲染为:
html
<a href="javascript:alert(1)">链接</a>
点击链接即可触发脚本。
关键提醒
- 若 htmlspecialchars 配置完整( ENT_QUOTES + UTF-8 编码),上述方法均无效,这也是防御XSS的“黄金标准”;
- 绕过本质是“利用转义的漏洞”,而非直接突破完整的转义逻辑。
果然可以这样∽
这玩意儿好像是跨站∽
好吧,没有那么高级
很明显的不是回显∽,让我试试js,好吧,这个纯变成超链接了。
那就试试别的。
远程加载好像也不行,我不会了,我查一下。
不是我一开始原来想到了就是js操了,他就是dom的,我被那个鬼超链接迷惑了,他就是普通的dom,只不过需要触发。
底下的那个也是这样。
最后一关了,我一开始没找到源码,加上不会我*了
这也没回显吧,我操,闭合加上js,不对,好像是回显,但js应该也可以。
因为是直接加载在gs环境中,所以不依赖回显就可以实现。
11'</script> <script> alert(1) </script>
你的理解完全正确!核心原因就是输入本身就处在JS执行环境中(直接拼接进 <script> 标签内的代码),所以不需要依赖“回显到HTML页面”这一步,就能直接触发脚本执行。
具体拆解:
1. “JS环境”的本质:之前的题目中,用户输入是被直接拼接到 <script> 标签内部的JS代码里(比如 $ms='用户输入' ),这里本身就是浏览器会主动解析执行的“JS代码上下文”——浏览器加载到 <script> 标签时,会逐行解析里面的代码,不需要先把输入“显示在页面上(回显)”再二次渲染。
2. 和“回显加载”的区别:
- 回显型XSS需要:输入→先作为文本回显到HTML页面(比如 <div>用户输入</div> )→浏览器渲染HTML时,把回显的内容解析成可执行的JS(比如回显的 <script>alert(1)</script> 被执行);
- 这道题的场景:输入→直接拼进 <script> 标签的JS代码里→浏览器解析 <script> 时,直接执行被注入的恶意代码(比如闭合后新增的 <script>alert(1)</script> ),全程跳过“回显到页面”的步骤。
简单说:因为输入一开始就“泡在JS代码里”,浏览器会直接执行这里的代码,自然不需要靠“回显到页面”来加载脚本。
首先纠正两个表述偏差:你说的“三个标签”其实是**“闭合原标签+注入新标签”的核心操作**(非固定数量),“gs”应该是“JS”的笔误——下面分两个问题拆解,核心都是“JS执行依赖‘上下文环境’,而非文件加载”:
一、“为什么只要两个关键标签就行”(不是固定三个,核心是“闭合+注入”)
你说的“三个标签”,本质是**“(闭合原标签)+ alert(1)(注入新标签)”这两个关键操作**,之所以能生效,是因为它们精准打破了原有的语法边界:
1. 第一个标签:——闭合“原生JS环境”
原页面有 <script> 标签包裹JS代码(比如 $ms='用户输入' ),输入 </script> 后,会直接“打断”这个原生 <script> 标签,让浏览器认为“原JS代码到此结束”。
例:原代码 <script>$ms='用户输入'</script> → 输入 </script> 后变成 <script>$ms=''</script> ,原标签被闭合。
2. 第二个标签:alert(1)——注入“新JS执行环境”
原 <script> 被闭合后,后续的 <script>alert(1)</script> 会被浏览器当作“新的、独立的JS代码块”,加载时直接执行里面的 alert(1) 。
这里不需要更多标签,因为“闭合原标签+注入新标签”已经完成了“从原JS代码中逃出来,再创建新的可执行JS环境”的全部逻辑——不是“三个标签必须”,而是这两个标签的组合刚好满足需求。
二、“那个JS为什么不行?JS语法不是依赖内部文件加载吗?”
你说的“JS不行”,本质是**“某类JS写法(比如伪协议 javascript:alert(1) )在‘原JS代码上下文’中无效”**,而JS执行根本不依赖“内部文件加载”——JS有两种执行方式,和文件加载无关:
1. JS执行的两种方式(都不依赖外部文件)
- 方式1:内嵌执行:写在 <script> 标签里的代码(比如 alert(1) ),浏览器加载到 <script> 时直接执行,不需要任何外部文件(这就是题目中的场景);
- 方式2:外部加载执行:通过 <script src="xxx.js"></script> 加载外部文件,文件里的JS代码会在加载完成后执行——但题目中没有用这种方式,全程是内嵌JS。
2. “某类JS不行”的原因:执行上下文错了
比如你之前提到的 javascript:alert(1) (伪协议),在“原JS代码上下文”中就不行,因为:
- 伪协议 javascript: 的生效条件是“必须放在HTML属性里”(比如 <a href="javascript:alert(1)"> ),依赖“HTML属性上下文”;
- 但在 <script> 标签内部的JS代码里(比如 $ms='javascript:alert(1)' ), javascript:alert(1) 只是普通字符串,浏览器会把它当成“文本”,不会执行——这不是“JS不行”,是“JS写法放错了环境”。
换成原生JS语句(比如 alert(1) ),在 <script> 里就会直接执行,因为它符合“JS代码上下文”的语法规则。
核心总结
- “标签少但能生效”:因为精准做到了“闭合原JS标签+注入新JS标签”,两步就够,不需要多;
- “JS行不行看环境”:JS执行不依赖外部文件,只看“放在哪个上下文”——伪协议要在HTML属性里,原生语句要在 <script> 里,放错了就无效。
需要用具体代码对比“伪协议在JS里无效”和“原生语句在JS里有效”的差异吗?
js必须在html中,而这个的话必须在js中。