1. 信息收集阶段:最先动手的地方,往往决定后面能不能成事
我在接一个SRC项目时,第一步向来不是拿扫描器对着域名一顿乱扫。外面很多渗透测试教程会把信息收集讲成一套工具链,但到了逻辑漏洞这块,工具能帮你的非常有限。真正决定你能不能从普通用户一路摸到后台拿权的,往往是你对业务的理解和走一步看一步的思路。
1.1 资产收集不只是域名爆破
最基础的信息收集当然是资产测绘:根域名、子域名、独立IP、旁站、C段,这些都要做。但做的时候要带脑子,而不是机械地跑一遍字典就完事。举个很常见的场景:一家做企业SaaS的公司,它的核心资产往往不是官网,而是那几个登录进去才能真正干活的子系统——管理后台、开放API、数据导出、客服工单,甚至是一个不起眼的内部运维平台。这些系统才是渗透测试中真正值得投入时间的"富矿"。
我一般会把收集结果整理成一张表,按价值排优先级:
| 资产类型 | 例子 | 价值判断 |
|---|---|---|
| 官网/营销站 | www.example.com | 低,通常无登录,攻击面小 |
| 主业务系统 | app.example.com | 高,有完整业务逻辑和用户体系 |
| 管理后台 | admin.example.com | 极高,目标明确,拿到就是"后台拿权" |
| 开放API | api.example.com | 高,接口通常比Web页面更容易出逻辑问题 |
| 测试/预发环境 | test.example.com | 视情况,常有配置遗漏和调试接口 |
这张表里的每一行,都是后面测试的入口。我个人的习惯是优先打管理后台和开放API,因为它们要么权限非常集中,要么因为不是主推产品而疏于维护。很多SRC的高危漏洞,最后都出在这两类资产上。
1.2 从业务功能里找"价值集中点"
资产收集完,下一步是看功能。毫不夸张地说,我对一个业务系统的第一眼,取决于它有没有注册入口、有没有支付流程、有没有角色权限、有没有文件上传。这四个功能点全部命中,基本上可以确定这是SRC上容易出货的系统。
注册入口意味着你能拿到一个合法身份,所有后续的越权测试都建立在这个身份上;支付流程意味着有钱和数量参数可以篡改;角色权限意味着存在垂直越权的可能性;文件上传则通常和拿到服务器权限挂钩。这四个功能点,刚好对应了逻辑漏洞的大部分常见场景。
1.3 把信息收集的终点变成一张业务逻辑图
我习惯在信息收集收尾时,画一张简单的"业务逻辑图"——不需要多精美,几行文字就行:用户→注册→登录→浏览→下单→支付→查看订单→申请售后,管理员→登录→用户管理→订单管理→配置管理。画完这张图,你其实已经隐隐约约看到了哪些环节容易出现"以为做了校验,实际却没做全"的问题。
这一步做完,才进入真正的测试环节。信息收集恰恰是很多人忽略的地方——他们急着拿工具跑,结果跑出来的都是别人已经修过的漏洞。逻辑漏洞的测试从来不是靠工具的,它靠的是对业务的理解。
2. 逻辑漏洞的"博弈感":为什么它比SQL注入更能体现测试水平
2.1 自动化工具的盲区,正好是逻辑漏洞的藏身之处
你拿常规漏扫工具扫一个站,能扫出来SQL注入、XSS、文件包含这些常规问题,但这些往往也是厂商自测时最容易发现的问题。逻辑漏洞不一样,工具扫不出来,因为它不属于某个固定的漏洞类型,而是"程序员的预期和现实之间的差距"。
举一个最典型的例子:一个电商系统的下单接口,前端页面做了库存校验,当库存不足时下单按钮会置灰。但攻击者直接抓包,绕过前端,把购买数量改成1,绕过了库存限制。问题在于,库存校验做在前端还是后端?很多系统会把这类业务校验放在前端,后端只接参数然后生成订单。这种情况下,即使库存只剩50件,你也能下100件的单。
这就是逻辑漏洞的博弈感:攻击者站在"开发者视角"看问题,找到开发者和测试者之间信息的缝隙。开发者认为"前端已经校验过了,后端不用再校验一遍",但攻击者知道,所有前端校验都是可以绕过的前提。
2.2 高频出现的逻辑漏洞类型
按我这两年跑SRC的经验,逻辑漏洞大致能分这么几类:
- 越权类:水平越权(改一个ID就能看到别人的数据)和垂直越权(普通用户调用管理员接口)。这是逻辑漏洞里出现频率最高的,也是通往后台拿权最直接的路径。
- 验证码类:验证码不失效、短信验证码不校验服务端session、对同一个手机号不限制发送次数导致短信轰炸。
- 支付类:修改金额、修改数量、价格篡改、优惠券重用、支付状态轮询绕过。
- 条件竞争类:同时并发请求导致积分、余额、库存被重复计账。
- 状态机绕过类:跳过某个必填步骤,比如跳过支付直接进入发货流程。
每一类背后都有一个共同的根源:服务端没有对关键业务环节做完整的状态校验或者权限校验。逻辑漏洞之所以"不好修",是因为修复往往要动业务核心代码,甚至要重构接口设计,而不像SQL注入那样加个参数化查询就行。
2.3 判断标准:能不能证明、能不能复现、有没有实际影响
很多新手在SRC上提交漏洞被驳回,最大原因不是漏洞不存在,而是无法证明影响。判断逻辑漏洞能不能报,我个人的标准就三条:
第一,能不能用两个普通账号稳定复现。第二,越权或篡改有没有实际的数据影响,比如订单、余额、个人信息。第三,影响面有多大,是影响单个用户还是全平台。
我见过不少人在测试一个系统时,发现某个接口没有鉴权就直接报了"未授权访问",结果平台回复"该接口本身设计为公开接口"。这其实不是漏洞,是误报。在提交之前把业务语义搞清楚,比多报一个漏洞有用多了。换句话说,提交报告之前,先站在厂商的角度问自己一遍:这个行为是设计如此,还是确实是校验缺失?
3. 实战复盘:从注册到普通用户,再从一个接口翻到后台
为了把前面的方法论落到具体例子里,我讲一个去掉敏感信息的SRC项目记录。目标是某个企业的客户管理系统,资产清单里有一个主业务站点和一个运营后台。主站支持注册,后台没有对外注册入口。这个配置非常典型,也是后面一切故事的起点。
3.1 从合法身份入手
先在主站注册了A和B两个普通账号,这是越权测试的基本配置。测试订单、用户信息、权限这类接口,都得有至少两个身份才能做对照。这一步没啥技术含量,但非常重要——没有对照组的越权测试,基本等于盲人摸象。
登录之后,我习惯先看浏览器的开发者工具里加载了哪些JS文件,再配合Burp Suite抓包看请求。为什么看JS?现在很多前后端分离的项目,接口清单和参数结构全写在JS里,甚至有些注释里会残留测试用的接口地址。我在这类文件里翻到过不少"隐藏"的内部接口,这次也不例外。
3.2 水平越权:把别人的订单看作自己的
测试订单查看功能的时候,我抓到这样一个请求:
GET /api/order/detail?orderId=10086响应返回当前账号的订单详情。我直接在Burp里把orderId改成10087,响应里出现了另一个账号的订单数据。再看字段,里面包含收货人姓名、手机号、详细地址。这一下就是标准水平越权漏洞,而且批量遍历orderId可以拿到全量订单信息,属于信息泄露。
但我没有着急把它提交,我想要的权限比这个更高。水平越权虽然能过审,但定级通常在高危边缘,而且在不涉及金融数据的系统上,平台经常只给中危。它更大的价值在于证明"这个系统的鉴权设计有重大问题",可以作为后续垂直越权漏洞的前置铺垫。
3.3 翻JS文件,找到管理员用的内部接口
继续翻JS文件,我在一个叫admin.bundle.js的压缩文件里看到了几个管理端接口的调用,路径类似:
/api/admin/user/list /api/admin/user/role/update这里有个关键判断:这些接口写在主站域名的JS里,说明管理后台和用户端共用了一套后端API网关。那么问题来了,这些接口的鉴权是怎么实现的?我带着普通用户的token直接请求了/api/admin/user/list,返回401 Unauthorized。这说明有登录态校验,但401只验证了"你登录了没有",并没有验证"你是不是管理员"。
带着这个怀疑,我把注意力转移到了/api/admin/user/role/update这个接口上。从名字看,这是一个更新用户角色的接口。这类接口的常见写法是接收两个参数:目标用户ID和要设置的角色ID。如果它只校验登录态、不校验调用者角色,那就意味着任意登录用户都能把自己或别人改成管理员。
3.4 从角色字段修改到后台登录
我先从自己的用户信息接口里拿到当前账号的roleId,返回的是1。JS文件里有一段常量配置,注释里写着角色枚举:1为普通用户,2为管理员。我构造了这样一个请求:
POST /api/admin/user/role/update userId=自己的用户ID roleId=2正常来说,这个接口应该拒绝普通用户调用。但响应回来了200 OK。我退出账号重新登录,发现账号角色已经变成了管理员,菜单栏里多出了用户管理、订单管理、数据导出这些原本看不到的功能。点进用户管理,能看到所有注册用户的信息列表,包括管理员账号的登录名和手机号。到这里,普通用户变成了后台管理员,后台拿权完成。
到这里我没有继续往下探测。SRC测试的核心边界是"证明漏洞存在、讲清楚影响",而不是真的把整个后台翻一遍,更不是去下载全量数据。截图记录好漏洞点和影响之后,我直接退出,开始准备报告。
4. 拿到后台权限之后:证明影响与守住边界同等重要
4.1 拿权不是终点,证明才是
得到管理员权限之后,第一件事不是兴奋,而是冷静下来做证明。你需要给厂商一个能复现的路径,让他们相信这不是误报。截图或录屏是必须的,我通常按这个顺序保留证据:
- 当前账号修改角色前的个人信息截图,要能看到角色字段是普通用户。
- 调用的关键请求的Burp截图,包括URL、请求体、响应状态码。
- 修改后的响应和重新登录后的菜单截图,证明权限提升成功。
证据链要完整,每一张截图都要能对上复现步骤中的一句话。很多人在报告里只贴最后一张"我是管理员"的截图,平台工程师根本无法判断你是怎么变成管理员的,这种报告很容易被打回要求补充。
4.2 影响要落到业务语言上
影响部分要落到业务语言,而不是技术语言。比如写"任意登录用户可通过构造请求提升为管理员,进而查看全量用户手机号、地址信息和订单数据",这句话比"存在一个逻辑漏洞"有用得多。厂商评估漏洞等级时,看的是这个影响,而不是你用了什么炫酷的技巧打进去的。
这里我习惯做一个小对比:漏洞发现前,普通用户能做什么;漏洞利用后,管理员能做什么。把差异写清楚,平台才好定级。比如在这次案例里,普通用户只能看自己的订单,管理员能看到所有人的订单和用户资料,影响面从"一个人"变成了"整个平台",定级自然就上去了。
4.3 边界控制:哪些事绝对不能做
SRC平台的测试和真实的授权众测有很大区别,前者是"有限授权",后者才是"全面对抗"。拿到管理员权限后,以下这些事绝对不能做:
- 不要下载或导出全量用户数据,哪怕只是为了测试。证明风险存在即可,验证时用小范围数据就够了,比如只读取一条测试账号的数据。
- 不要对授权范围外的系统继续渗透。哪怕你发现隔壁系统也有漏洞,只要不在任务范围里,都不能碰。
- 不要尝试读取管理员密码或重置管理员账号,更不要修改任何生产数据。你测试用的普通账号是你自己注册的,可以随便改,但别人的数据一根手指头都不能动。
守住边界,你的报告才会被认可;一旦越界,轻则漏洞作废,重则面临封号甚至更严重的后果。这在我接触过的圈子里有不止一次惨痛教训。
5. 报告环节的"第二场博弈":让漏洞定级配得上它的影响
5.1 平台是怎么给逻辑漏洞定级的
各大厂商SRC平台和公益SRC平台的定级逻辑大同小异,一般分严重、高危、中危、低危四个等级。对逻辑漏洞来说,定级主要看影响面:能直接进后台拿权的垂直越权,通常是高危起步;涉及大量用户敏感信息泄露的水平越权,一般也是高危;只影响单个用户且数据价值不高的,往往是中低危。
这里有个微妙的地方:同一个漏洞在不同平台、不同业务场景下的定级可能不一样。一个涉及金融数据系统的水平越权,和一个只涉及公开信息系统的水平越权,定级会差很多。所以选对漏洞提交的平台也很重要,有些专项SRC对敏感系统有更高的奖励评级。
5.2 我固定使用的报告结构
写报告这件事,我踩过不少坑,后来沉淀出一个固定结构,每次照着填:
| 报告模块 | 内容要点 |
|---|---|
| 漏洞标题 | 明确到功能点,例如"用户订单接口未校验归属权限,任意用户可遍历订单号泄露他人信息" |
| 漏洞类型 | 逻辑漏洞-水平越权/垂直越权 |
| 影响等级 | 按自己的评估填写,附上理由 |
| 复现步骤 | 每一步配一张截图,按时间顺序写 |
| 影响分析 | 落到业务语言,说明影响对象和范围 |
| 修复建议 | 给出可执行的修复方向 |
标题尤其重要。很多平台的审核员一天要看几十份报告,标题写得含含糊糊的很容易被压到低优先级。标题里把"哪个接口、什么问题、什么影响"一次说清楚,审核员一眼就能判断该找谁去验证。
5.3 常见驳回原因和避免方式
根据个人经验,逻辑漏洞的报告被驳回,常见原因无非这几种:
- 影响证明不足。只有一个状态码200,没有展示实际影响到的数据。
- 复现步骤不清晰。漏掉了某个前置条件,审核员按步骤复现不出来。
- 业务语义没搞清。把"设计如此"当成漏洞来报,比如注册接口支持弱密码,平台可能认为这是产品设计而非漏洞。
- 自己都没完全搞清楚原理。报告里说不清楚为什么能越权,审核员也无法确认是不是误报。
还有一个容易踩的坑:当你在同一个系统里发现多个同类型逻辑漏洞时,不要一个一个提交。平台通常会把同根因的漏洞合并处理,提交太多反而显得像是在凑数量。选影响最大的那个提交,然后在报告末尾注明"同类接口可能还有多处,建议统一排查",这样反而能体现专业度。
6. 攻击复盘的反面:如果这套系统由我来修
6.1 从这次测试链路反推修复清单
每次测试结束,我都会站在开发和安全团队的角度重新过一遍漏洞链路,这算是逼自己从"攻击者思维"切回"防御者思维"。对应这次案例,修复点其实非常明确:
- /api/order/detail接口必须校验订单归属,服务端要从token里取当前用户ID,再判断该订单是否属于当前用户,而不是只信任前端传的orderId。
- /api/admin/user/role/update接口必须校验调用者的角色,只有管理员才能调用,而且要区分"登录态校验"和"权限校验",这是两个层面的事。
- 管理端接口和普通用户接口不能共用同一套无差别的登录态校验逻辑,至少要在网关层做角色路由隔离。
- 前端的admin.bundle.js不应该暴露内部接口的调用路径,建议把管理端静态资源和用户端静态资源分开部署。
6.2 通用防护思路
把这次测试再抽象一层,能看到几个通用的防护原则:
- 统一鉴权组件。所有涉及数据查询和权限修改的接口,必须走同一个鉴权组件,而不是每个接口自己写一段token解析逻辑。组件内部要同时校验"身份"和"角色"。
- 服务端校验一切业务参数。前端传上来的金额、数量、角色ID、步骤编号,全部要当作不可信数据对待,该用服务端数据替代的就用服务端数据替代。
- 关键业务步骤加状态机。比如订单从"待支付"到"已支付"再到"待发货",每一步只能从前置状态流转过来,不能跳跃。
- 敏感操作加审计日志。谁在什么时间改了什么权限、查了什么数据,全部记录。这既是安全要求,也是出了事后追溯的救命稻草。
6.3 给刚入门的人几句实在话
如果你刚开始接触渗透测试和SRC漏洞挖掘,我的建议是先从公益SRC平台的真实项目练手,不要一上来就想着打大型厂商。公益项目目标多、范围清晰、对新人友好,哪怕挖到的是中低危漏洞也能积累提交记录和报告经验。
测试的时候,多整理自己的逻辑漏洞测试清单,把每一种场景的请求特征记下来。比如越权测试,核心动作就是"替换身份标识"——把请求里的订单号、用户ID、角色ID换掉,观察响应是否变化。这个动作看起来简单,但能坚持在每个功能点上都做一遍的人并不多。
最后,电子取证式地保留好每一份证据。记录漏洞的技术细节是次要的,锻炼自己的思路才是主要的。跑SRC这行,很多人一开始靠的是运气,但能持续出货的,靠的是对业务的理解和对边界的敬畏。这句话是我在复盘里最常提醒自己的,也送给看到这里的你。