当前位置: 首页 > news >正文

SRC众测实战:从业务逻辑漏洞到IDOR敏感信息泄露的完整挖掘链

1. 项目概述:一次典型的SRC众测实战复盘

最近在参与某次众测活动时,遇到了一个挺有意思的案例。目标是一个典型的Web应用,表面上看注册流程做得挺“严谨”,有图形验证码、手机号绑定、甚至还有邀请码机制。但越是看起来固若金汤的地方,往往越藏着意想不到的缝隙。这次的任务,就是从一个看似正常的注册入口开始,最终不仅绕过了限制成功注册了本不该存在的用户,还顺藤摸瓜发现了一处可能导致敏感信息泄露的接口。整个过程没有用到什么高精尖的0day,更多的是对业务逻辑的细致观察、对请求响应的反复揣摩,以及那么一点“如果我是开发者,我可能会犯什么错”的换位思考。如果你也对SRC漏洞挖掘、业务逻辑漏洞实战感兴趣,或者想了解如何从普通功能点切入深挖,那这次经历或许能给你一些启发。

2. 核心思路拆解:从“限制”本身寻找突破口

2.1 目标分析与攻击面梳理

接到目标后,我并没有急于上手测试。第一步永远是信息收集和攻击面梳理。这是一个提供在线服务的平台,注册是核心入口之一。前期的侦察发现,其注册页面包含以下几个关键控制点:

  1. 图形验证码:用于防止机器批量注册。
  2. 手机短信验证码:绑定实名信息,确保用户唯一性。
  3. 邀请码字段(非必填):暗示可能存在特殊的内部注册渠道。
  4. 用户角色/类型选择:注册时需选择“普通用户”或“企业用户”。

我的初步判断是,这套组合拳的目的很明确:精准控制用户来源和类型,防止无关人员或恶意用户注册。那么,我的测试思路也就围绕“如何成为系统未预期的用户”展开。重点不在于爆破验证码(那是体力活),而在于理解其业务规则权限模型。例如,那个“邀请码”字段,就是第一个值得玩味的地方。它是真的只是个摆设,还是通往某个特权世界的钥匙?

2.2 绕过限制的通用性思考框架

在Web安全测试中,“绕过限制”通常不是指正面攻克加密算法,而是寻找逻辑上的不一致或缺失。对于注册场景,我们可以建立一个简单的思考框架:

  • 客户端限制 vs 服务端校验:页面上有下拉框只能选A和B,是否意味着服务端也只接受A和B?如果我直接发包传一个C呢?
  • 多步骤流程的完整性校验:注册分三步,第一步验证手机号,第二步填写资料,第三步完成。系统是否在每一步都重新验证了前序步骤的令牌(token)或状态?我能否跳过第二步直接访问第三步的接口?
  • 参数可控性与边界处理:那些传入后端的参数,哪些是用户完全可控的?比如用户ID、角色字段。当传入一个负数、一个超长字符串、一个系统不存在的枚举值时,后端是报错、忽略,还是产生非预期行为?
  • 平行权限测试:如果注册普通用户走的是流程A,注册企业用户走的是流程B。那么,用流程A的请求,尝试带上流程B的参数,会发生什么?系统是否能清晰地分辨请求的“意图”?

带着这些疑问,我开始了具体的测试。

3. 实操过程:步步为营的漏洞挖掘

3.1 第一步:常规流程探查与请求分析

首先,我使用一个合法的手机号,完全按照正常流程注册了一个“普通用户”。这个过程必须做,而且要仔细做。我使用Burp Suite作为代理,捕获了整个注册流程的HTTP请求序列。

关键发现如下:

  1. 请求1:获取图形验证码GET /api/captcha/image?t=<timestamp>。这里注意验证码是否与session或token绑定,后续提交时是否校验。
  2. 请求2:发送短信验证码POST /api/sms/send, 参数为phone=13800138000&captcha=abcd。这里观察响应,除了成功/失败,是否返回了其他信息,如用户是否存在、邀请码状态等。
  3. 请求3:提交注册POST /api/user/register。这是核心请求,捕获到的参数类似:
    { "phone": "13800138000", "smsCode": "123456", "password": "Passw0rd!", "userType": "normal", "inviteCode": "", "nickname": "testuser" }
    响应成功,返回了用户ID、token等信息。

初步分析:流程看似完整。但我的注意力立刻被userType: "normal"inviteCode: ""吸引了。这是两个明确的可控输入点。

3.2 第二步:关键参数篡改与模糊测试

接下来,就是针对核心注册请求进行篡改测试。我使用Burp的Repeater模块,对刚才捕获的请求进行重放和修改。

测试1:用户类型(userType)篡改"userType": "normal"依次修改为:

  • "enterprise"(页面上存在的另一个选项)
  • "admin""superuser""manager"(猜测可能存在的管理角色)
  • "null"""(空值)
  • "normal'--"(尝试SQL注入)

结果:当修改为"userType": "enterprise"时,请求竟然成功了!系统返回了注册成功的响应,并且用户信息里显示"role": "enterprise"。这意味着,前端虽然对普通用户隐藏了企业用户的选项,但后端接口并未对用户传入的userType值进行严格校验,只要是一个它“认识”的类型(比如在数据库枚举值里存在),它就照单全收。

注意:这里成功的前提是,其他参数(尤其是短信验证码)必须有效。这说明后端对业务连续性校验(手机号-验证码绑定)是有的,但对业务逻辑校验(谁有资格注册为企业用户)是缺失的。

测试2:邀请码(inviteCode)探测虽然注册普通用户时邀请码为空,但系统设计了此字段,必然有用。我尝试:

  • 常见弱口令000000,111111,123456,invite
  • 构造规律值:根据已注册的用户ID(比如10001),尝试"inviteCode": "10001""REF10001"
  • 暴力枚举(谨慎):如果邀请码是数字,写一个简单的脚本,在较低速率下尝试一个较小范围(如1000-2000)。务必注意众测规则,避免对系统造成压力

结果:在尝试到"inviteCode": "888888"时,注册请求的响应出现了变化!虽然依旧是注册成功,但返回的用户权限对象中,多出了一个"vipLevel": 1的字段。而普通注册的用户没有这个字段。这说明,邀请码是一个“特权码”,可以开通额外的服务或身份。后端逻辑可能是:有有效邀请码 -> 赋予VIP身份;无邀请码 -> 普通身份。但这里同样没有校验“谁”有资格使用这个邀请码。

3.3 第三步:组合漏洞利用与敏感信息泄露发现

至此,我已经可以绕过限制注册一个具有“企业”角色或“VIP”身份的用户了。但这还不够,我需要验证这些“非正常”身份是否带来了新的安全风险。

我以新注册的“企业用户”身份登录系统。登录后,开始遍历前端功能点和抓取API请求。在查看“企业资料”或“我的项目”相关页面时,Burp捕获到了一个关键的API请求:GET /api/enterprise/projects?page=1&size=10

这个请求返回了一个项目列表。仔细查看其中一个项目的详细数据,发现了一个问题:

{ "projectId": "PROJ2024001", "projectName": "内部测试项目A", "creatorId": "10086", "creatorName": "张经理", "**memberList**": [ {"userId": "10010", "userName": "李四", "phone": "138****1111", "email": "li@example.com"}, {"userId": "10011", "userName": "王五", "phone": "139****2222", "email": "wang@example.com"} ], "attachmentList": [ {"fileId": "FILE001", "fileName": "设计方案.pdf", "**downloadUrl**": "/api/file/download/FILE001?token=eyJhbGciOiJ..."} ] }

漏洞点出现了

  1. 敏感信息过度暴露memberList中直接返回了其他成员的手机号(虽然打了码,但有时可能不打码)和邮箱。这是典型的敏感信息泄露。作为企业用户,我可能有权看到项目成员,但不应直接获取他们的个人联系信息。
  2. 文件下载权限控制缺失(更严重的发现)downloadUrl中的链接指向一个文件下载接口,并附带了一个token。我尝试直接访问这个URL(/api/file/download/FILE001?token=eyJhbGciOiJ...),竟然成功下载了“设计方案.pdf”文件。然后,我尝试修改fileId参数,比如改成FILE002,再次访问,同样成功下载了另一个不属于我项目的文件!

漏洞原理分析:这里存在一个**不安全的直接对象引用(IDOR)**漏洞。文件下载接口/api/file/download/{fileId}虽然使用了token,但这个token很可能只是一个会话标识或通用令牌,并未在服务端严格校验当前登录用户是否有权限下载fileId对应的文件。系统错误地认为:“只要你有有效的登录token,并且知道文件的ID,你就可以下载它”。这导致了越权访问和敏感文件泄露。

4. 漏洞原理与深度解析

4.1 业务逻辑漏洞:信任边界混淆

本次发现的注册绕过,核心是业务逻辑漏洞。系统在设计时,混淆了“身份验证”、“权限校验”和“业务规则校验”的边界。

  • 身份验证:证明你是你(密码、短信验证码)。这部分目标系统做得不错。
  • 权限校验:决定你能做什么(RBAC模型)。这部分开始出现裂缝,例如文件下载接口的缺失。
  • 业务规则校验:在特定业务流程中,附加的条件(如:只有市场部员工才能提交报销;只有获得邀请码的用户才能注册为VIP)。这部分校验被严重依赖前端,后端几乎缺失。

开发者可能认为:“前端下拉框只有‘普通’和‘企业’,用户只能选这两个,所以后端拿到的一定是这两个值之一。” 这种将安全依赖于客户端不可控输入的想法,是逻辑漏洞的温床。攻击者根本不用浏览器,直接伪造HTTP请求,规则就被轻易绕过。

4.2 敏感信息泄露:权限最小化原则的失效

敏感信息泄露(如成员手机号、邮箱)和IDOR漏洞,共同违反了信息安全中的权限最小化原则访问控制原则。

  • 权限最小化:接口应只返回完成当前操作所必需的最少信息。列表页显示成员姓名即可,详情页再根据权限决定是否展示联系方式。一股脑全返回,是偷懒也是风险。
  • 访问控制:每个访问受保护资源的请求,都必须经过授权检查。在文件下载的例子中,服务端代码缺失了关键一步:
    // 错误示例:缺失权限校验 File file = fileService.getById(fileId); return download(file); // 正确示例:增加权限校验 File file = fileService.getById(fileId); Project project = projectService.getByFileId(fileId); // 检查当前登录用户是否属于该项目 if (!project.getMembers().contains(currentUser)) { throw new AccessDeniedException("无权访问此文件"); } return download(file);
    这个校验必须放在服务端,基于当前会话用户(currentUser)和要访问的资源(fileproject)进行关联性判断。

4.3 漏洞链的形成:从入口点到核心资产

单独看,每个漏洞可能危害等级不同:

  • 绕过注册限制:中危。可能造成垃圾账号、占用资源。
  • 敏感信息泄露:中危/高危。侵犯用户隐私,可能为社工攻击提供素材。
  • 文件越权下载(IDOR):高危。直接导致核心业务数据(设计文档、合同、报告)泄露。

但当它们形成链条时,危害急剧放大:

  1. 攻击者通过逻辑漏洞,绕过限制注册了一个高权限(企业/VIP)账号。
  2. 利用这个账号,访问到本不应访问的功能模块(企业项目列表)。
  3. 在该模块中,发现敏感信息泄露存在IDOR漏洞的接口
  4. 通过IDOR漏洞,直接窃取系统内的敏感文件

这个链条清晰地展示了:一个不显眼的入口点漏洞(注册逻辑缺陷),如何成为攻击者打入系统内部、获取高价值资产的跳板。

5. 修复建议与安全开发思考

5.1 针对性修复方案

  1. 注册逻辑修复

    • 服务端强校验:在后端注册接口,对userTypeinviteCode等参数进行白名单校验。不仅校验值是否合法,更要校验当前请求上下文(如:注册IP、来源、是否经过特定前置流程)是否有权使用该值。
    • 业务状态机:将注册流程状态化。每一步完成后,在服务端Session或数据库中标记状态。下一步请求必须验证上一步状态已完成,防止跳步或乱序提交。
    • 邀请码机制:邀请码应具备唯一性、时效性、绑定关系(如绑定给某个发起人)。使用后立即失效,并在使用校验时,核对发起人与使用者的关系(如果需要)。
  2. 敏感信息与IDOR漏洞修复

    • 接口数据脱敏:列表类接口严格遵守最小化原则。个人联系方式、身份证号等敏感字段,除非必要,否则一律脱敏(如138****1111)或不返回。
    • 强制访问控制:在所有涉及资源ID(fileId,projectId,userId)的增删改查接口中,加入权限校验层。可以使用Spring Security、Shiro等框架的注解,或在业务逻辑代码中显式编写校验逻辑。核心原则:永远不要相信客户端传来的资源ID,服务端必须二次确认权限。
    • 使用不可预测的标识符:避免使用自增ID(1,2,3...)作为资源标识符暴露给前端。可以使用UUID、雪花算法ID等,增加攻击者猜测的难度。

5.2 对开发与测试的启示

  • 对开发者而言:必须树立“服务端是唯一可信方”的理念。所有来自客户端的输入都是不可信的,所有业务规则必须在服务端得到最终执行和校验。设计API时,要像审问者一样思考:“调用这个接口,我需要知道他的所有信息吗?我如何确保他只能做他被允许的事?”
  • 对测试者而言:挖掘这类漏洞,需要具备“业务视角”。不要只盯着SQL注入、XSS这些传统漏洞。多问几个“为什么”:为什么这个字段在这里?为什么这个流程要这样设计?如果我不按它的来,它会怎么样?工具(Burp)帮你看到流量,但思考帮你看到漏洞。重点关注:
    • 所有传入参数:特别是那些代表状态、身份、权限的枚举值。
    • 所有步骤流程:尝试跳过、回退、并发提交。
    • 所有返回数据:仔细查看每一个JSON字段,思考哪些信息是不应该给我的。

6. 常见问题与排查技巧实录

在挖掘和验证这类漏洞时,经常会遇到一些困惑和障碍。这里分享几个实战中的技巧:

问题1:修改参数后,请求返回“参数错误”或“验证失败”,如何判断是前端还是后端校验?

  • 技巧:使用Burp Repeater,完全重放浏览器捕获的原始请求(包括所有Header,尤其是Cookie、Token、Content-Type)。如果原始请求能成功,你只修改了Body里的一个参数就失败,那基本是后端校验。如果请求根本无法从Repeater发出(比如缺少某个前端生成的加密参数),那可能是前端校验或复杂签名。此时可以尝试用浏览器调试工具,跟踪这个参数是如何生成的。

问题2:发现了疑似越权的接口(如/api/admin/listAllUsers),但直接访问返回403,怎么办?

  • 技巧:403不代表没漏洞,只代表你当前的身份没权限。尝试:
    1. 降级访问:把/admin/路径改成/user/,或者把listAllUsers改成listMyUsers,看看是否能访问到本应属于自己的数据,这可能是水平越权。
    2. 参数污染:在原有正常请求的参数基础上,额外添加管理员接口的参数,看看是否会执行部分管理功能。
    3. 关注Referer和Origin:有些接口会校验请求来源。在Repeater中尝试添加或修改Referer: https://target.com/admin/这样的Header。

问题3:如何高效地测试IDOR漏洞?

  • 技巧:不要盲目爆破。先收集资源ID。
    • 从自身数据入手:登录后,查看“我的项目”、“我的订单”,记下属于你的资源ID(如 projectId: 1001, orderId: 2001)。
    • 进行加减遍历:尝试访问projectId=1000projectId=1002。如果系统使用自增ID,这很可能发现属于其他用户的资源。
    • 观察ID格式:如果是UUID(如550e8400-e29b-41d4-a716-446655440000),爆破难度极大,但可以检查系统在分享功能中生成的URL是否使用了可预测的短ID或弱hash。
    • 使用Burp的“Compare”功能:分别抓取查看自己资源A和(猜测的)他人资源B的响应包,用Compare功能高亮差异,能快速发现数据层面的不同。

问题4:在众测中,如何避免测试行为被误判为攻击?

  • 核心原则:最小化、慢速化、可解释化。
    • 最小化:只修改必要的参数进行验证。例如,证明IDOR时,下载1-2个非所属文件即可,不要批量下载。
    • 慢速化:避免使用自动化工具进行高频请求。手动操作,间隔时间放长。
    • 可解释化:在提交报告时,清晰说明测试步骤、使用的测试账号(可标注为test_vul_1)、请求和响应截图。让安全运营人员能清晰复现,理解这是安全测试而非恶意攻击。

这次众测经历再次证明,坚固的系统往往不是被复杂的攻击技术攻破,而是败给了自身逻辑上的疏忽。安全是一个整体,任何一个环节的信任缺失或校验遗漏,都可能被串联起来,形成致命的突破口。对于防御方,需要在每一个业务决策点都加入安全思考;对于攻击方(白帽子),则需要用系统的、怀疑的眼光去审视每一个交互细节。挖洞的过程,其实就是与开发者进行一场跨越时空的思维博弈,乐趣与挑战,皆在于此。

http://www.gsyq.cn/news/1601364.html

相关文章:

  • RePKG深度技术解析:PKG资源提取与TEX图像转换的架构设计与性能优化
  • 实战解析:从EMA公式到MACD指标构建
  • DAC53608评估板实战指南:从硬件连接到软件配置与高级测试
  • C语言实战:手把手构建RSA加密算法核心模块
  • 如何用trackerslist彻底解决BT下载慢的问题:从龟速到极速的完整指南
  • Python操控AutoCAD终极指南:用代码解放你的设计工作
  • 东南大学学位论文LaTeX模板:从零配置到高效排版的实战指南
  • VQFN封装PCB与钢网设计实战:从热焊盘处理到焊接工艺优化
  • O3模型冷启动延迟超2.3秒?揭秘内存预加载+权重分片预热的实时推理加速协议
  • AnimeGANv2 ONNX模型部署实战:从图片到视频的实时动漫风格转换
  • 终极多平台DLC解锁指南:深入解析Koalageddon技术架构与实战应用
  • JAVA POI实战:精准拦截Excel数值科学计数法,守护长数字数据完整性
  • 第一章Netty,walkFileTree删除多级目录
  • Java进阶面试核心宝典:程序员突击必备!
  • 网络安全竞赛pwn全解及第一道ai的wp
  • LabVIEW性能调优实战:从瓶颈定位到速度飞跃
  • STM32实战:HC-SR04超声波测距模块的精准驱动与误差优化
  • N_m3u8DL-RE流媒体下载器:让在线视频轻松变成本地收藏
  • 从一维双原子链到声子谱:晶格振动的声学支与光学支全解析
  • 超越传统超频:SMUDebugTool如何解锁AMD Ryzen处理器隐藏性能
  • 仅限首批技术顾问获取:OpenAI未公开的模型行为差异手册(含system prompt敏感度、长文本截断策略、温度值响应曲线)
  • 从一段模板说起
  • SQLite 在独立开发中的实战与优化:用轻量架构应对高并发
  • 硬件原理图设计审查实战指南:从Checklist到高效协作
  • Linux内核页缓存覆写提权双链攻击深度剖析:CVE-2026-46331与CVE-2026-43503联动利用、检测与加固实战
  • 深入解析ChatGPT API的Token机制:从原理到精准计费实践
  • 《淘宝订单API为什么个人账号调不通?企业认证+场景核验避坑指南》(附python源码)
  • 【PyTorch】从ModuleNotFoundError到模型洞察:torchinfo安装、实战与避坑指南
  • 从手动到脚本:探索文件资源管理器(explorer)的优雅重启与状态恢复
  • 如何通过OneMore插件高效管理OneNote笔记:从基础编辑到智能组织实践指南