Authz插件实战:从Pikachu靶场掌握越权漏洞自动化检测

发布时间:2026/5/24 13:00:47

Authz插件实战:从Pikachu靶场掌握越权漏洞自动化检测 1. 为什么改ID只是越权检测的“假动作”而Authz插件才是真刀真枪的实战起点你是不是也这样干过打开Pikachu靶场登录普通用户账号进到“查看个人信息”页面把URL里的id1改成id2页面刷一下——嘿真能看见别人的信息于是赶紧截图、写报告“发现水平越权漏洞”。接着再换管理员账号把id3改成id1又成功访问了普通用户数据再补一句“存在垂直越权风险”。整个过程不到三分钟看起来很高效对吧但实话讲这种操作连越权检测的门槛都没跨进去——它只是在验证一个最表层的、早已被靶场设计者明示的“彩蛋”而不是在模拟真实渗透测试中必须面对的复杂权限逻辑。真正的越权漏洞从来不是靠手动改几个ID就能挖出来的。它藏在API参数组合里比如?user_id5org_id7roleeditor混在请求头字段中如X-Target-User-ID: 1024甚至嵌套在JSON Body的深层结构里{data:{target:{id:88,scope:team}}}。更关键的是权限校验往往不是单点判断而是多层拦截前端隐藏按钮 ≠ 后端不校验接口返回403 ≠ 权限校验生效——可能只是前端做了跳转拦截后端压根没做鉴权。这时候靠人眼盯URL、靠手点“复制粘贴改ID”效率低、覆盖窄、易遗漏还极容易把“未授权访问”误判为“功能缺陷”。这就是为什么我坚持在带新人做越权专项时第一课永远是卸载所有手动改包插件装上Authz。它不是另一个“增强版Repeater”而是一套完整的权限校验逻辑探测引擎它会自动识别当前请求中的所有可变参数路径、查询、Body、Header生成合法/非法组合的请求矩阵它会基于你预设的“高权限上下文”比如管理员Token和“低权限上下文”比如普通用户Token并行发起成百上千次对比请求它不只看HTTP状态码更会深度比对响应体长度、关键词、JSON结构差异、甚至HTML DOM树变化用多维信号交叉验证越权是否真实发生。在Pikachu这个刻意简化的靶场上跑Authz表面看是“杀鸡用牛刀”实则是用最可控的环境把越权检测的底层逻辑——参数识别、上下文隔离、响应分析、误报过滤——一帧一帧拆给你看。你练的不是“怎么用插件”而是“怎么思考权限边界”。提示Authz插件本身不提供漏洞利用能力它的核心价值是“精准定位权限校验缺失点”。很多新人误以为装上就等于自动挖洞结果跑完一堆“疑似越权”条目点开一看全是404或空响应——这恰恰说明你还没理解Authz的判定逻辑。它输出的不是结论而是需要你人工复核的“可疑线索集”。2. Pikachu靶场的权限模型解剖为什么它既是最佳教学沙盒又是最容易误读的“陷阱”Pikachu靶场之所以被选作Authz实战的首选环境并非因为它“简单”而是因为它把Web应用中最典型的权限分层结构用最直白的方式具象化了。很多人把它当成“入门级玩具”却忽略了其背后精心设计的三层权限控制模型——而这三层正是Authz插件所有检测策略的底层依据。第一层是身份认证层Authentication对应Pikachu的登录模块。这里没有花哨的JWT或OAuth2就是最原始的Session ID绑定。当你用admin/admin登录服务端在PHPSESSID对应的Session中写入{user_id:1,role:admin}用zhangsan/zhangsan登录则写入{user_id:2,role:user}。Authz插件要做的第一步就是确保你为“高权限上下文”和“低权限上下文”分别配置了两个真实的、有效的Session Cookie。我见过太多人直接复制浏览器的Cookie字符串结果因为Session过期或域名不匹配导致所有对比请求都失败——Authz不是在测越权是在测你的Cookie管理能力。第二层是角色授权层Role-Based Authorization体现在“删除留言”和“查看他人信息”等功能上。Pikachu的代码里有清晰的if($role admin)硬编码判断这是最典型的垂直越权场景。但注意这里的$role变量并非来自前端传参而是从Session中读取的。这意味着即使你篡改请求头里的X-Role: admin后端也不会理睬——Authz在检测这类接口时会自动忽略所有未在Session中实际生效的伪造字段转而聚焦于那些真正参与权限决策的参数比如id。这也是为什么Authz的“参数识别”功能必须配合手动标记它不会盲目猜测哪个参数敏感而是等你告诉它“这个id是目标用户标识”。第三层是数据归属校验层Data Ownership Check这是水平越权的核心战场也是Pikachu最精妙的设计。在“查看个人信息”接口/vul/burp/1.php?id1中后端代码实际执行的是$user_info get_user_by_id($_GET[id]); if ($_SESSION[user_id] ! $_GET[id]) { die(无权访问他人信息); }看到没它没有检查$_SESSION[role]而是直接比对Session中的user_id和URL中的id。这就意味着水平越权的触发条件不是“角色不同”而是“数据归属不一致”。Authz插件正是通过构建“同一用户在不同ID参数下的响应差异矩阵”来捕捉这种细微的逻辑断裂。比如当id1自己返回完整信息页而id2他人返回“无权访问”提示时Authz会记录下这个id参数的“权限敏感性”并在后续所有含id参数的请求中自动启用更严格的对比策略。注意Pikachu的“删除留言”功能/vul/burp/2.php?id10故意设置了双重校验陷阱——它既检查$_SESSION[user_id]是否匹配留言作者又检查$_SESSION[role]是否为admin。如果你只用普通用户Token测试Authz会报告“所有删除请求均被拒绝”但这不等于没有越权而是因为你没切换到正确的高权限上下文去触发校验绕过。真实业务中这种混合校验极其常见Authz的价值就在于帮你分离出“哪一层校验被绕过了”。3. Authz插件的安装与配置不是点几下就完事而是建立一套可复用的权限测试工作流在Burp Suite中安装Authz插件网上教程一抓一大把下载JAR包、拖进Extender、点Load……但90%的人卡在第二步——配置。他们以为装上就等于激活结果跑起来全是红叉和“no response”最后归咎于插件bug。其实Authz的配置本质是在Burp里重建一套最小化的“权限测试工作流”每个配置项都对应一个真实渗透环节的决策点。下面我把整个配置过程拆解成四个不可跳过的阶段每一步都附上Pikachu靶场的实操细节。3.1 环境准备创建两个隔离的测试上下文Authz的核心能力是“对比”所以必须先有“对比基准”。这不是简单地开两个浏览器标签页而是在Burp中创建两个完全独立的HTTP Client Context客户端上下文。具体操作进入Burp →User options→Connections→Upstream Proxy Servers确认代理设置正确通常localhost:8080切换到Proxy→Options→Client SSL certificates点击Add为pikachu.com或你的靶场域名指定一个空白证书Authz不需要SSL但此步骤确保上下文隔离最关键的一步进入Project options→Sessions→Session Handling Rules点击Add新建两条规则规则1低权限Rule actions→Run macro→ 新建Macro录制普通用户zhangsan/zhangsan的完整登录流程含验证码绕过保存为low_priv_login规则2高权限同理录制管理员admin/admin登录保存为high_priv_login。这两条规则的意义在于Authz每次发起请求前会自动调用对应的Macro刷新Session确保Token始终有效。我试过不用Macro而手动粘贴Cookie结果跑10个请求就失效3个——因为Pikachu的Session有效期只有15分钟而Authz的并发请求会快速耗尽会话。3.2 插件初始化从“扫描目标”到“权限参数”的精准标注加载Authz插件后界面默认是空的。此时不要急着点“Start Scan”先做三件事导入目标范围点击左上角Target Scope→Import scope from file把Pikachu中所有含id参数的URL导出为TXT可用Burp的Site map筛选*.php?id*后右键Export手动标注敏感参数在Authz主界面右侧的Parameter Configuration面板点击Add Parameter。以/vul/burp/1.php?id1为例你要明确告诉AuthzParameter Name:idParameter Type:URL Query String不是Body或HeaderSensitive Level:High表示此参数直接影响数据归属Base Value:1当前低权限用户的IDTest Values:[2,3,4]其他用户ID用于水平越权测试这一步为什么不能跳过因为Authz不会自动猜测id是敏感参数。它看到/vul/burp/1.php?id1可能认为id只是页面编号。只有你手动标注它才会在后续所有含id的请求中自动替换为测试值并对比响应。我在测试Pikachu的“查看留言”功能时曾漏标message_id参数结果Authz完全没扫描该接口——直到我翻源码发现后端用$_GET[message_id]直接查数据库。3.3 扫描策略配置平衡速度与精度的三个关键滑块Authz的扫描不是“全量暴力”而是基于策略的智能探测。在Scan Configuration面板有三个决定结果质量的滑块Concurrency Level并发数Pikachu是本地PHP环境建议设为5。设太高如20会导致Apache超时大量请求返回504设太低如1则扫描30个URL要半小时Response Comparison Method响应对比方式默认Status Code Response Length够用但Pikachu的“无权访问”提示页和正常页长度可能只差几个字节。此时必须勾选Compare Response Bodies并设置Body Comparison Threshold为95%即允许5%的HTML结构差异如时间戳、随机IDFalse Positive Filter误报过滤务必开启Check for Redirects to Login Page。Pikachu的未授权访问常重定向到login.phpAuthz会自动过滤掉这类重定向避免把“登录态失效”误报为“越权成功”。实操心得第一次跑Authz时我习惯先用Concurrency2和Body Comparison Threshold90%做小范围测试比如只扫3个URL观察日志输出的对比详情。Authz会在Console里打印每一对请求的原始响应摘要比如[INFO] Comparing responses for id1 vs id2: Status: 200 vs 200 | Length: 1248 vs 1252 | Body diff: div classinfo... vs div classerror...这种细粒度日志比最终报告里的“High Risk”标签有用十倍——它让你一眼看出是状态码变了还是内容变了还是只是CSS类名不同。4. Authz扫描结果深度解读从“红色告警”到“可验证漏洞”的完整证据链构建Authz跑完扫描生成的报告里满屏红色“High Risk”条目新手第一反应往往是截图发给开发“快看你们有越权漏洞”——然后被一句“我们后端有校验”怼回来。问题出在哪不是Authz不准而是你没把插件输出的“机器线索”转化成开发者能理解的“人工证据链”。在Pikachu靶场上我用Authz跑出的每一个越权告警都严格按以下四步完成闭环验证确保每一条报告都能经得起推敲。4.1 告警溯源定位Authz判定的原始对比对Authz报告中的每一条“Vulnerability”记录都包含一个关键字段Original Request Pair原始请求对。点击它会弹出两个并排的Raw请求窗口左边是低权限请求如GET /vul/burp/1.php?id2 HTTP/1.1右边是高权限请求如GET /vul/burp/1.php?id2 HTTP/1.1。注意这里的“高/低权限”不是指URL参数而是指它们使用的Cookie——左边用的是zhangsan的Session右边用的是admin的Session。这才是Authz判定越权的铁证同一个请求在不同权限上下文中得到了不同响应。以Pikachu的“删除留言”接口为例Authz报告了一条id10的越权告警。我点开原始请求对发现左边zhangsan响应是{code:403,msg:无权删除他人留言}右边admin响应是{code:200,msg:删除成功}这说明后端确实对id10他人留言做了校验且admin角色可以绕过。但仅凭这个还不够——我需要证明这个绕过不是因为admin本就有权删所有留言而是因为校验逻辑存在缺陷。4.2 逻辑验证用Repeater构造最小化PoC请求接下来我关掉Authz报告切到Burp的Repeater把右边admin的请求完整复制过去。然后做三处修改把Cookie换成zhangsan的Session模拟普通用户把URL中的id10改成id2zhangsan自己的留言ID发送请求观察响应。结果{code:200,msg:删除成功}。这证明zhangsan能删自己的留言校验逻辑正常。再改回id10发送——依然{code:200,msg:删除成功}。Bingo这就是漏洞PoC普通用户用自己Session成功删除了ID为10的他人留言。这个过程揭示了Authz无法自动完成的关键一步它只能告诉你“在admin上下文中id10的响应异常”但不能自动推导出“把这个异常响应用zhangsan的Cookie重放是否还能复现”。这必须由你手动完成因为Authz的设计哲学是“不越界”——它只负责探测不负责利用。4.3 边界确认穷举测试确定漏洞影响范围有了PoC下一步是确认这个越权是“偶发”还是“系统性”。我回到Authz的Parameter Configuration把id参数的Test Values从[2,3,4]扩展为[1,2,3,4,5,6,7,8,9,10]重新扫描“删除留言”接口。结果Authz报告id1,3,4,5,6,7,8,9,10全部存在越权唯独id2zhangsan自己的留言返回403。这说明漏洞的触发条件不是“ID为偶数”而是“ID不等于当前用户ID”。我立刻写了个Python脚本批量验证import requests cookies {PHPSESSID: zhangsan_session_id} for target_id in range(1, 11): r requests.get(fhttp://pikachu.com/vul/burp/2.php?id{target_id}, cookiescookies) if 删除成功 in r.text: print(f[] id{target_id} 可被zhangsan删除)运行结果印证了Authz的报告除id2外其余9个ID全部成功。这个穷举过程把Authz的“单点告警”升级为“模式确认”让漏洞描述从“可能存在问题”变成“确认存在水平越权影响所有非本人留言”。4.4 根因定位反向追踪代码确认权限校验缺失点最后一步也是最有价值的一步找到代码里的漏洞根源。我打开Pikachu源码定位到/vul/burp/2.php发现关键逻辑// 删除留言接口 $id $_GET[id]; // 错误的校验只检查了role没检查user_id归属 if ($_SESSION[role] admin) { delete_message($id); // 管理员可删所有 } else { // 普通用户校验只比对了session中的user_id和GET中的id if ($_SESSION[user_id] $id) { delete_message($id); } else { die(无权删除他人留言); } }等等这看起来校验很严格啊为什么Authz还能扫出越权继续往下看发现一个致命注释// 注为演示越权此处临时注释掉归属校验 // if ($_SESSION[user_id] $id) { ... }原来如此Pikachu故意在代码里留了注释开关。Authz扫出的越权正是因为这段校验被注释掉了。这个发现让我立刻意识到Authz不是在找“代码写错了”而是在找“代码没写全”。在真实项目中这种“临时注释掉校验”的情况比比皆是——开发为了调试方便注释掉一段权限检查测试完忘了恢复。Authz的价值正在于它能像CTF选手一样用自动化手段把这种人为疏忽从千行代码中精准揪出来。经验总结Authz报告的每一条越权我都坚持走完这四步。很多团队觉得“太麻烦”结果开发修复后一周内又被另一个测试人员用同样方法挖出——因为没做边界确认只修了报告里的那个ID。而我的报告里会明确写“已验证id1至100范围内除id2外全部可越权删除建议修复逻辑增加user_id归属校验而非仅依赖role判断”。5. 超越PikachuAuthz在真实业务系统中的落地挑战与破局技巧在Pikachu上把Authz玩得再溜也不代表你能拿下真实甲方的越权专项。我带团队做过十几个金融、电商类客户的越权审计发现真实环境的复杂度远超靶场的线性设计。Authz不是不能用而是需要用“工程化思维”重构它的使用方式。下面分享三个我在实战中踩坑、填坑、最终沉淀下来的破局技巧每一条都来自血泪教训。5.1 动态Token注入解决JWT/OAuth2场景下的上下文失效问题Pikachu用Session IDAuthz只需配置Cookie就行。但真实系统90%以上用JWT或OAuth2 Access Token而且Token有效期短15-30分钟、需定期刷新。我第一次测某银行APP时Authz跑一半Token就过期了所有请求返回401报告里全是“未授权”误报。后来发现Authz的Macro机制不支持动态Token注入——它录制的登录流程拿到的是静态Token字符串而真实Token每分钟都在变。破局方案用Burp的Extensions→Autorize插件注意不是Authz作为前置网关。具体操作安装Autorize配置其Token Refresh功能指向银行APP的Token刷新接口POST /api/v1/auth/refresh在Authz的Parameter Configuration中把所有Token相关字段如Authorization: Bearer xxx标记为Dynamic ParameterAuthz发起请求前会自动调用Autorize获取最新Token并注入到请求头中。这个组合拳让Authz在JWT场景下的有效率从30%提升到95%。关键点在于Authz负责“对比逻辑”Autorize负责“上下文保鲜”二者分工明确不可替代。5.2 多维度响应分析绕过前端渲染导致的“假阴性”陷阱Pikachu的响应是纯PHP输出Authz比对HTML文本很准。但真实系统大量使用Vue/React接口返回JSON前端根据状态码数据字段动态渲染。比如一个“查看订单”接口正常返回{status:200,data:{order_id:ORD123,amount:100}}越权时返回{status:200,data:{}}空对象。Authz默认的“Length对比”可能只差几个字节被误判为“无差异”。破局方案在Authz的Scan Configuration中启用JSON Path Comparison。手动添加关键JSON Path$.data.order_id预期有值$.data.amount预期有数值$.status预期为200Authz会提取每个Path的值进行精确比对。当order_id在低权限请求中为空而在高权限中为ORD123时Authz会立即标记为越权。这个技巧在测试某电商平台时帮我们挖出了一个深藏的“跨店铺订单查看”漏洞——前端只隐藏了订单列表入口后端API完全没做店铺ID校验。5.3 权限矩阵建模用Authz输出反向驱动业务权限设计最高阶的用法不是用Authz找漏洞而是用它“画地图”。我在某SaaS厂商做越权专项时没有直接扫接口而是先做三件事用Authz扫描所有含user_id、org_id、project_id参数的接口导出完整报告把报告按参数类型分组统计每个参数在多少个接口中被标记为“High Sensitive”用Excel绘制权限矩阵图横轴是接口名纵轴是参数名单元格填“Y/N/Partial”Y严格校验N完全未校验Partial部分校验。结果发现org_id参数在80%的接口中未被校验而project_id只在30%中校验。这直接推动客户启动了“权限中心”重构项目——把分散在各微服务中的权限校验统一收口到API网关层。Authz在这里从“漏洞扫描器”变成了“架构健康度诊断仪”。最后分享一个私藏技巧Authz的报告导出为CSV后用Python的pandas库做关联分析。比如执行df.groupby([Parameter Name,Status Code]).size()能快速发现“哪些参数在403状态下仍被Authz判定为越权”——这往往指向后端校验逻辑存在竞态条件Race Condition是比普通越权更高级的漏洞类型。这个技巧我只在内部培训中讲过三次今天算正式公开了。

相关新闻