Pikachu靶场实战:深入理解与挖掘越权漏洞 1. 项目概述为什么Pikachu是理解越权漏洞的绝佳起点如果你刚开始接触Web安全或者对“越权漏洞”这个概念感觉既熟悉又模糊那么从Pikachu靶场入手绝对是一个明智的选择。我见过太多安全新人一上来就扎进复杂的真实环境或综合性靶场结果被各种干扰项弄得晕头转向基础没打牢反而留下了知识漏洞。Pikachu靶场的设计初衷就是化繁为简它把像越权漏洞这样的核心安全风险单独剥离出来给你一个纯净、可控的环境去“折腾”。所谓越权漏洞用大白话讲就是“你干了你不该干的事儿”。系统本应严格区分每个用户的权限边界——普通用户只能看自己的信息管理员才能管理所有人——但如果在设计或编码时留下了逻辑缺陷就可能让一个普通用户绕过限制执行高权限操作或者访问其他用户的私密数据。这听起来简单但在实际复杂的业务逻辑里它往往隐藏得很深。Pikachu靶场的好处在于它直接把这个漏洞“摆”在你面前让你能像做解剖实验一样清晰地看到漏洞的成因、利用手法以及修复的关键点。这次实战我们不只满足于“点一下按钮就成功”的复现。我会带你从零开始搭建Pikachu靶场然后深入其越权漏洞模块拆解水平越权和垂直越权这两种核心类型。更重要的是我们会站在攻击者和防御者两个角度去思考攻击者是如何一步步发现并利用这个漏洞的他的每一步操作背后有什么意图而作为开发者或安全工程师又应该在代码的哪个环节设置检查点才能从根本上堵住这个漏洞这个过程远比单纯记住一个漏洞利用的Payload有价值得多。2. 环境准备与Pikachu靶场搭建详解工欲善其事必先利其器。在开始“攻防”之前我们得先把“战场”布置好。Pikachu靶场本质上是一个用PHP写的Web应用所以我们需要一个标准的PHP运行环境。2.1 基础运行环境搭建最省心、兼容性最好的方案是使用集成环境包比如PHPStudy或XAMPP。这里以PHPStudy V8.1版本为例因为它对Windows用户非常友好且自带多种PHP版本切换方便我们应对不同情况。首先去PHPStudy官网下载安装包并完成安装。安装路径建议不要有中文和空格比如D:\phpstudy_pro。安装完成后启动PHPStudy你会看到它的主界面。我们需要做两件事启动Apache或Nginx和MySQL服务。通常点击对应的“启动”按钮即可状态变绿说明服务运行正常。接下来是关键一步选择PHP版本。Pikachu靶场对PHP版本有一定要求推荐使用PHP 5.4至PHP 7.0之间的版本。太老的版本可能缺少某些函数太新的版本如PHP 8.x则可能因为语法不兼容而报错。在PHPStudy的“软件管理”或“环境”选项卡里可以很方便地安装和切换PHP版本。我个人的经验是PHP 5.6.9 或 PHP 7.0.9 这两个版本与Pikachu的兼容性最好几乎不会出问题。注意如果你在启动Apache时遇到端口冲突比如80端口被占用可以在PHPStudy的“其他选项菜单” - “PHPStudy设置” - “端口常规设置”中修改Apache的端口例如改为8080。后续访问靶场就需要用http://localhost:8080。2.2 Pikachu源码部署与数据库初始化环境准备好后我们来部署靶场源码。从Pikachu的官方GitHub仓库下载最新的ZIP压缩包。解压后你会得到一个名为pikachu-master的文件夹。将这个文件夹整个复制到PHPStudy的网站根目录下。网站根目录的路径通常在PHPStudy安装目录下的WWW文件夹里例如D:\phpstudy_pro\WWW。为了便于访问我习惯将文件夹重命名为简单的pikachu。这样靶场的访问地址就是http://localhost/pikachu如果你改了端口就是http://localhost:8080/pikachu。现在打开浏览器访问这个地址。如果环境配置正确你应该能看到Pikachu的安装引导界面。页面会提示你数据库连接失败这是正常的因为我们还没有配置数据库。点击页面上的“安装/初始化”按钮。Pikachu的安装脚本会自动完成两件重要的事创建数据库和表它会在你的MySQL中创建一个名为pikachu的数据库并导入所有必需的数据表。生成配置文件它会在靶场目录下生成一个inc/config.inc.php文件里面写入了数据库的连接信息主机、用户名、密码、数据库名。这里有一个至关重要的实操细节MySQL的默认密码。PHPStudy安装的MySQL其root用户的初始密码通常是root。如果安装脚本报错提示数据库连接失败十有八九是密码不对。你需要手动检查并修改配置文件。找到pikachu/inc/config.inc.php文件用记事本打开你会看到类似下面的内容define(DBUSER,root); define(DBPWD,root); // 检查这一行密码可能为空‘’或者是‘root’ define(DBNAME,pikachu); define(DBHOST,localhost); define(DBPORT,3306);确保DBPWD的值与你本地MySQL的root密码一致。如果不确定可以打开PHPStudy在“MySQL管理器”中查看或修改密码。修改保存配置文件后刷新浏览器安装页面再次点击“安装/初始化”。看到“安装成功”的提示后整个Pikachu靶场就搭建完毕了。你可以点击“进入主页”开始我们的漏洞探索之旅。3. 越权漏洞核心原理与分类深度拆解在动手之前我们必须把理论地基打牢。越权漏洞Broken Access Control在OWASP Top 10中长期位列前列其危害性在于它直接破坏了系统的权限模型。我们可以从两个维度来理解它水平越权和垂直越权。Pikachu靶场对这两种类型都有非常典型的案例。3.1 水平越权同级用户间的权限僭越水平越权也叫作“访问控制缺失Insecure Direct Object References, IDOR”。想象一下在一个论坛里每个用户都有一个唯一的用户ID。你的个人资料页的URL可能是http://example.com/user.php?id123而我的可能是id124。水平越权漏洞就发生在系统只在前端页面上隐藏了指向其他用户资料的链接却没有在后台接口真正校验“当前登录的用户是否有权查看id124的资料”。攻击本质攻击者通过修改请求参数如URL中的ID、表单中的隐藏字段、API请求体中的JSON数据来访问属于其他同级用户的数据或功能。关键在于系统在进行数据操作时没有将请求者的身份Session或Token与要操作的数据对象通过ID标识进行绑定校验。Pikachu靶场中的体现在“越权漏洞(over permission)”模块下有一个“水平越权”案例。场景通常是一个查看个人信息的页面URL中带有一个id参数。漏洞就在于后端代码直接信任了这个id执行了类似SELECT * FROM users WHERE id $_GET[‘id’]的查询而没有先判断$_SESSION[‘user_id’]是否等于$_GET[‘id’]。3.2 垂直越权低权限用户获取高权限功能垂直越权比水平越权更危险。它指的是一个低权限角色如普通用户能够执行本应只有高权限角色如管理员才能执行的操作。例如普通用户本应只能在前台浏览文章但却能通过某种方式访问到后台管理员的文章审核页面甚至直接调用后台的管理接口。攻击本质系统对功能或页面的访问控制存在缺陷。可能的原因包括基于前端隐藏的“伪防护”仅通过前端UI隐藏了管理员功能链接或按钮但对应的后端API接口URL依然可以被猜测或抓包获取。缺失功能级权限校验在进入关键功能控制器Controller或处理函数时没有校验当前用户的角色或权限码。配置错误Web服务器如Nginx/Apache或应用框架的路由配置错误导致本应受保护的目录或文件被直接访问。Pikachu靶场中的体现在“垂直越权”案例中通常会模拟两个用户lucy普通用户和admin管理员。以lucy身份登录后虽然页面上看不到“添加用户”的管理员功能但攻击者可以通过浏览器开发者工具F12查看网络请求或者根据经验猜测管理员添加用户的URL如/admin/add_user.php然后直接尝试访问或构造请求如果成功就构成了垂直越权。3.3 一个常被忽略的混合类型上下文相关越权在实际审计中还有一种更隐蔽的类型它混合了水平和垂直的特点我称之为“上下文相关越权”。例如在一个电商系统中用户A可以查看自己订单的物流详情水平权限但物流详情接口里可能包含了“修改物流状态”的按钮或链接这是一个垂直权限功能。如果系统没有在渲染这个按钮时结合“当前用户角色”和“当前订单状态”进行双重校验那么用户A就可能看到并触发这个本应只属于客服或管理员的按钮。理解这些原理后我们再去看Pikachu靶场的代码就能一眼看出问题所在。它的价值就在于把这些有缺陷的代码模式赤裸裸地展示给你看。4. 水平越权漏洞实战攻击与代码审计现在让我们进入Pikachu靶场亲手触发一个水平越权漏洞。打开靶场主页找到左侧的“越权漏洞(over permission)” - “水平越权”。4.1 攻击流程复现与每一步的意图分析正常登录与观察首先我们用系统提供的测试账号lucy/123456进行登录。登录成功后页面可能会显示“欢迎 lucy”以及一些个人信息。关键动作留意浏览器地址栏。你很有可能会看到一个包含用户ID参数的URL例如http://localhost/pikachu/vul/overpermission/op1/op1_mem.php?uid1。这个uid1就是当前用户lucy在数据库中的唯一标识。这一步的目的是定位用于标识用户的关键参数。参数篡改与试探我们将URL中的uid参数值从1改为2然后回车访问。意图分析我们假设用户id2是另一个用户比如lili。这个操作是在试探后端逻辑“你是直接根据我提供的uid去数据库查数据还是会先检查一下这个uid是不是我本人当前登录的lucy的uid”结果预测如果页面显示的内容变成了“欢迎 lili”以及lili的隐私信息如电话、邮箱那么水平越权漏洞就实锤了。这说明后端代码毫无校验。深入利用与信息收集漏洞确认后攻击不会停止。攻击者可能会写一个简单的脚本自动遍历uid从1到1000批量抓取所有用户的敏感信息。更进一步如果这个页面不仅有查看功能还有通过GET/POST参数执行的“修改个人信息”功能那么攻击者就可以通过篡改uid和其他参数如email,phone来篡改任意用户的数据危害从信息泄露升级为数据篡改。4.2 后端漏洞代码深度解析攻击成功了我们来看看靶场“故意”留下的漏洞代码。找到对应的PHP文件根据URL路径通常是pikachu/vul/overpermission/op1/op1_mem.php。你会看到类似下面这样问题代码的核心片段// 假设这里已经开始了Session $_SESSION[‘username’] ‘lucy’; $uid $_GET[‘uid’]; // 直接接收用户输入的参数 $sql “SELECT * FROM users WHERE id ‘{$uid}‘ LIMIT 1”; $result mysqli_query($link, $sql); $row mysqli_fetch_assoc($result); echo “用户名” . $row[‘username’]; echo “邮箱” . $row[‘email’]; // … 输出其他敏感信息漏洞根因代码直接使用了未经校验的$_GET[‘uid’]来构建SQL查询。它完全没有将请求中的$uid与当前登录用户的身份存储在$_SESSION[‘user_id’]里进行比对。正确的逻辑应该像这样session_start(); $current_uid $_SESSION[‘user_id’]; // 从Session中获取当前登录用户的真实ID $request_uid intval($_GET[‘uid’]); // 获取请求的ID并转为整数防注入 if ($current_uid ! $request_uid) { die(‘权限不足无法查看他人信息。’); // 核心校验 } // 只有ID一致才执行查询 $sql “SELECT * FROM users WHERE id {$current_uid} LIMIT 1”; // … 后续操作实操心得在审计代码时看到一个外部传入的ID参数被直接用于数据查询你的安全警报就应该立刻响起。必须追踪这个参数是否与当前用户的身份凭证进行了绑定校验。这种校验必须放在服务端任何前端JavaScript的校验都是不可信的。5. 垂直越权漏洞实战攻击与路径探测垂直越权的攻击思路与水平越权不同它更侧重于发现隐藏的功能接口。5.1 攻击流程从普通用户到管理员低权限会话建立使用普通用户账号如lucy/123456登录系统。仔细浏览所有可见的菜单和页面用浏览器开发者工具的“网络(Network)”面板记录下所有的请求。功能接口猜测与探测基于目录结构很多老式PHP应用的管理后台就在/admin/、/manage/、/backend/目录下。直接尝试访问http://localhost/pikachu/admin/。基于常见功能名添加用户的功能可能叫add_user.php,user_create.php,saveUser.action。修改权限的功能可能叫grant.php,edit_role.php。基于参数动作观察普通用户功能点的URL模式。如果普通用户修改自己信息的URL是edit_info.php?actionupdate那么管理员批量操作的可能就是edit_info.php?actionadmin_update。直接访问与权限绕过在保持lucy登录状态即Session有效的情况下在浏览器新标签页直接输入你猜测的管理员功能URL。结果分析如果直接跳转到了登录页或提示权限不足说明后端有基本的权限校验。如果成功进入了管理员页面或者更糟糕直接显示了管理员功能界面并可以操作那么垂直越权漏洞就存在了。这意味着系统只检查了“用户是否登录”但没有检查“登录的用户是什么角色”。5.2 后端漏洞代码逻辑缺失分析垂直越权的后端代码问题通常出在入口控制器或路由分发器。例如一个admin_add_user.php的文件开头可能只有session_start(); if (!isset($_SESSION[‘username’])) { header(‘Location: login.php’); exit; } // 缺少了关键的角色检查 // if ($_SESSION[‘role’] ! ‘admin’) { die(‘Forbidden’); } // 下面是执行添加用户的管理员逻辑这段代码只验证了“是否登录”没有验证“是否是管理员”。正确的做法是在所有需要特权操作的入口处进行基于角色Role或权限Permission的强制检查。注意事项在现代的MVC框架如ThinkPHP, Laravel, Spring Security中垂直权限检查通常通过“中间件(Middleware)”、“拦截器(Interceptor)”或“注解(Annotation)”来实现。审计时要检查这些控制层的代码是否覆盖了所有需要保护的管理路由是否存在配置遗漏。Pikachu靶场用简单的PHP文件模拟了这种配置遗漏的场景。6. 漏洞防御从开发到运维的立体化方案理解了如何攻击我们才能更好地防御。修复越权漏洞不是一个单点动作而是一套需要在软件开发生命周期SDLC中贯彻的体系。6.1 开发编码阶段的核心防御策略实施“最小权限原则”与强制访问控制所有功能点默认拒绝在设计之初所有API接口、控制器方法的默认权限应该是“拒绝”然后显式地为特定角色授予权限。使用统一的权限检查中间件不要在每个函数里都写一遍权限判断代码。抽象出一个权限检查函数或中间件在路由层或控制器入口处统一调用。例如在Laravel中可以使用Gate或Policy。服务端绑定会话与对象所有权这是防御水平越权的黄金法则。永远不要信任客户端传来的对象ID。在执行任何数据操作增删改查前必须增加一步校验// 伪代码示例 function getUserOrder($orderIdFromClient) { $userId getCurrentUserIdFromSession(); // 从可信源Session获取当前用户ID $order Order::where(‘id’, $orderIdFromClient)-first(); if (!$order || $order-user_id ! $userId) { // 校验数据所有权 throw new AccessDeniedException(); } return $order; }对于复杂的查询尽量在SQL的WHERE条件中直接加入用户ID约束而不是先查出数据再判断。SELECT * FROM orders WHERE id {input_id} AND user_id {session_user_id}基于角色的访问控制RBAC与基于属性的访问控制ABACRBAC适合权限模型相对固定的系统。为用户分配角色如管理员、编辑、访客为角色分配权限。在代码中检查if (user.hasRole(‘admin’))或if (user.can(‘delete_user’))。ABAC更灵活适合复杂场景。权限决策基于用户属性角色、部门、资源属性文档状态、所属项目、环境属性时间、IP等多个属性。例如“允许文档的创建者在工作时间内从公司内网编辑状态为‘草稿’的文档”。这需要更复杂的安全策略引擎。6.2 测试与运维阶段的加固措施自动化安全测试DAST动态应用安全测试使用ZAP、Burp Suite等工具进行主动扫描配置扫描策略重点检测越权漏洞。可以手动设置两个不同权限的账号让工具自动对比两者的访问能力差异。IAST交互式应用安全测试在测试环境中部署IAST探针在QA进行功能测试时实时分析代码执行流和数据流能更精准地发现潜在的权限校验缺失点。代码审计与同行评审将“权限校验”作为代码审查清单中的必查项。重点关注所有包含用户ID、资源ID等参数的API接口、服务层方法。使用静态代码分析工具SAST并为其编写或启用专门检测“未经验证的重定向”、“不安全的直接对象引用”等问题的规则。运维监控与日志审计在应用程序日志中详细记录所有敏感操作登录、数据访问、权限变更的操作者、时间、IP、操作对象如资源ID、操作结果。建立异常访问告警机制。例如同一个用户账号在短时间内尝试访问大量不同ID的资源或者一个低权限账号尝试访问已知的管理员接口路径这些行为日志都应该触发告警以便安全团队及时介入调查。防御越权漏洞是一场持久战它要求开发、测试、运维和安全团队协同工作。从编码时的一行校验代码到上线后的每一行监控日志共同构成了系统权限安全的护城河。7. 实战进阶使用Burp Suite系统化挖掘越权漏洞手工测试适合理解原理但面对成百上千个功能点我们需要更高效、更系统化的工具和方法。Burp Suite是Web安全测试的“瑞士军刀”用它来辅助越权测试事半功倍。7.1 配置测试环境与会话管理浏览器代理设置将浏览器如Chrome的代理设置为127.0.0.1:8080指向Burp Suite。捕获登录流量在Burp中确保“Intercept is on”。用低权限账号lucy登录Pikachu靶场。Burp会捕获到登录的POST请求。将这个请求发送到“Repeater”模块方便后续重放。同时将这个请求发送到“Scanner”模块进行被动扫描。会话管理Burp的会话管理功能Project options-Sessions非常重要。我们需要为两个不同的用户lucy和admin创建独立的会话处理规则让Burp能自动为每个用户的请求维护各自的Cookie或Token避免手动切换的麻烦。7.2 使用“Compare Site Maps”功能进行差异对比这是发现垂直越权最有效的自动化方法之一。以低权限用户身份爬取站点地图在Burp的Target-Site map中右键点击你的靶场域名选择“Spider this host”。或者更推荐手动浏览网站所有lucy能访问的页面让Burp自动记录流量。浏览完成后站点地图里就是lucy视角下的整个应用结构。右键站点地图选择“Save selected items”将其保存为一个XML文件命名为sitemap_lucy.xml。以高权限用户身份爬取站点地图清除浏览器和Burp的缓存、Cookie。在Burp中切换到“Proxy” - “Options”找到“Match and Replace”规则可以临时添加规则清空Cookie头确保是一个全新的会话。用管理员账号admin/123456登录并完整浏览网站特别是那些只有管理员才能看到的后台管理页面。同样将管理员视角的站点地图保存为sitemap_admin.xml。对比分析在Burp的Target选项卡下有一个“Compare site maps”功能。加载刚才保存的两个XML文件。Burp会高亮显示两者之间的差异。那些只出现在sitemap_admin.xml中而不在sitemap_lucy.xml中的URL就是潜在的管理员专属接口。这些URL就是垂直越权测试的核心目标清单。7.3 使用Burp Intruder进行水平越权批量测试对于发现的一个疑似存在水平越权的接口如/api/getUserInfo?id我们可以用Intruder进行自动化参数爆破。定位请求在Proxy历史记录或Repeater中找到包含目标参数如id的请求。发送到Intruder右键请求选择“Send to Intruder”。设置攻击类型与载荷位置在“Positions”标签页清除所有自动标记然后手动将id参数的值标记为载荷位置。攻击类型Attack type选择“Sniper”即可。配置载荷切换到“Payloads”标签页。在“Payload type”中选择“Numbers”。设置数字范围例如从1到100步长为1。这代表我们将尝试遍历id从1到100的用户信息。开始攻击与结果分析点击“Start attack”。Intruder会使用当前活跃的会话即lucy的会话批量发送请求。攻击完成后我们需要重点关注“Length”或“Status”列。如果所有请求返回的HTTP状态码都是200且长度各不相同这强烈暗示着水平越权漏洞的存在——因为lucy的会话成功获取到了其他ID用户的数据。我们可以进一步查看响应内容确认是否真的包含了不同用户的敏感信息。通过Burp Suite这套组合拳我们可以将越权漏洞的挖掘从手动、随机的试探转变为系统化、自动化的检测流程极大提升了测试的覆盖率和效率。8. 总结与反思从靶场到真实世界的思维转变在Pikachu靶场里漏洞被精心设计并放在显眼的位置我们能够按图索骥轻松复现。但真实世界的应用远比这复杂。权限校验可能分散在多个层级——前端路由守卫、后端控制器注解、服务层方法、甚至数据库存储过程。业务逻辑也错综复杂一个“删除”操作可能不仅需要检查用户是否有删除权限还要检查数据的状态、所属部门等属性。因此走出靶场后我们需要建立更立体的安全思维。在代码审计时要像攻击者一样思考寻找每一个外部输入参数与权限校验逻辑之间的断点。在设计系统时要秉持“默认拒绝”和“最小权限”的原则。在测试时不要只满足于正向用例更要设计大量异常和越权用例。我个人在多年的渗透测试中有一个深刻体会越权漏洞的根源常常不是技术难题而是意识缺失和逻辑疏忽。开发者在专注于实现复杂的业务功能时很容易忘记在某个不起眼的查询接口里加上一句if (currentUser ! targetUser)。而这恰恰是安全工程师的价值所在——用攻击者的视角去审视整个系统补上这些缺失的逻辑链条在功能实现与安全边界之间建立起坚固的防线。Pikachu靶场的实战正是训练这种视角和思维的绝佳第一步。