mcpField
H
hunt-business-logic

hunt-business-logic

github.com/uphiago安全1.3k41 次安装8 周前更新
代码仓库

关于 hunt-business-logic

hunt-business-logic 是面向漏洞赏金测试者的安全测试技能,用于检查交易、验证和访问控制流程中的缺陷。内容围绕业务影响,整理攻击面线索、测试步骤、绕过模式和影响验证。

主要功能

  1. 01交易与验证流程检查
  2. 02速率限制与请求头篡改测试
  3. 03支付与 Webhook 校验检查
  4. 04内部页面发现
  5. 05影响验证清单

适用场景

  1. 01测试结账价格是否可被篡改
  2. 02检查 API 是否执行验证门槛
  3. 03评估回调与 Webhook 的防护
  4. 04查找暴露的内部页面

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/uphiago/recon-skills --skill hunt-business-logic

安装后在 Claude Code 中输入/hunt-business-logic确认已加载。

详细介绍

高价值目标

在金融交易、身份验证和访问控制与现实后果交汇的平台中,业务逻辑漏洞的收益最高。最有价值的目标包括:

  • 电商与支付平台(Valve/Steam、Shopify)——操纵支付流程、免费获取商品、篡改价格
  • 市场平台与零工经济应用(Airbnb、Uber)——绕过身份验证,进而实施欺诈或引发不安全互动
  • 采用分级访问权限的 SaaS(Mozilla Monitor)——绕过验证,在无权限的情况下解锁监控功能
  • 高流量消费类应用(Snapchat、Yelp)——绕过速率限制,从而大规模发送垃圾信息、枚举数据或实施滥用

高收益资产类型:结账流程、订阅端点、回调/验证系统、Webhook 处理程序、暴露在互联网上的员工/内部门户,以及任何信任客户端提供的数据来做出授权决策的端点。


攻击面信号

需要关注的 URL 模式:

  • /checkout、/order、/subscribe、/payment、/verify、/confirm、/callback
  • /internal、/employee、/summit、/staff、/admin——意外公开的内部页面
  • /api/v*/payment、/api/v*/notify、/webhook——支付服务提供商的回调
  • 接受 X-Forwarded-For、X-Real-IP、CF-Connecting-IP 标头的端点

响应/标头信号:

  • Set-Cookie 中包含未经验证、与购物车或订单数据关联的会话状态
  • 响应中出现支付服务提供商名称:Smart2Pay、Stripe、PayPal、Braintree
  • 经由第三方支付页面的重定向链(可在传输过程中获取数据)
  • 订阅/验证端点返回 200 OK,且没有 CAPTCHA 或令牌

JS 模式:

  • 前端捆绑文件中硬编码的内部 URL(/employee/、/staff/、/internal/)
  • 提交到服务器前在客户端计算价格
  • 仅在前端检查的验证逻辑(if (verified) { ... })
  • fetch('/api/subscribe', { method: 'POST', body: ... }),且没有防 CSRF 令牌或速率限制令牌

技术栈信号:

  • 带有草稿/未发布渠道页面的 Shopify 店面
  • 使用基于 IP 的速率限制、但未绑定会话/账户的应用
  • 未验证 HMAC 签名的支付 Webhook
  • 启用功能前未验证所有权的短信/电话回调流程

逐步狩猎方法

  1. 梳理所有身份验证边界。 对目标进行爬取。找出提供已验证身份用户内容的页面/端点(员工门户、高级功能、订单页面),并逐一测试未通过身份验证时的情况。查找 JS 包中索引到的内部页面,或 robots.txt/sitemap.xml 中链接的页面。

  2. 找出所有验证流程。 列出:电子邮件验证、电话/SMS 验证、付款验证、CAPTCHA、年龄门槛。对每种流程进行测试:如果完全跳过验证步骤会发生什么?如果在其他账户上重放有效令牌会发生什么?

  3. 测试每个表单上的速率限制控制。 对每个 POST 端点(订阅、登录、OTP、搜索)快速发送 50+ 个请求。尝试不同方式:移除 Cookie、轮换 X-Forwarded-For/X-Real-IP 标头、更改 User-Agent。检查服务器是否使用标头中的 IP,而非连接 IP。

  4. 拦截并篡改付款流程。 使用 Burp Suite 拦截浏览器、应用程序和付款提供商之间的每个请求。找出价格、货币、订单 ID 或状态字段的设置位置。尝试将金额改为 $0.01,或将货币改为低价值货币。查找接受付款确认的 POST 回调/webhook 端点,并测试它们是否验证 HMAC/签名。

  5. 测试电话/回拨号码验证。 每当平台接受回拨号码时,测试:能否将号码设置为自己不拥有的号码?平台会不会呼叫/短信该号码,并仅凭提交号码就授予信任?试着将其设为受害者的号码。

  6. 检查未受保护的员工/内部界面。 在 Shodan、GitHub、JS 包和 Wayback Machine 中搜索内部子域名/路径引用。测试未经身份验证能否访问。检查这些界面是否允许下单、访问数据或提升权限。

  7. 评估业务影响。 对每项发现,判断是否会造成经济损失、未授权访问或数据泄露。记录完整攻击链。


攻击载荷与检测模式

通过轮换标头绕过速率限制:

# Rotate X-Forwarded-For to bypass IP rate limiting
for i in $(seq 1 100); do
  curl --max-time 30 --connect-timeout 10 -s -X POST https://target.com/api/subscribe \
    -H "X-Forwarded-For: 10.0.0.$i" \
    -H "X-Real-IP: 10.0.0.$i" \
    -H "Content-Type: application/json" \
    -d '{"email":"victim+'"$i"'@example.com"}' \
    -o /dev/null -w "%{http_code}\n"
done

篡改付款——修改传输中的价格:

POST /payment/initiate HTTP/1.1
Host: target.com

amount=0.01&currency=USD&order_id=12345&product_id=99
# Look for unvalidated webhook endpoints
curl --max-time 30 --connect-timeout 10 -X POST https://target.com/payment/callback \
  -H "Content-Type: application/json" \
  -d '{"status":"success","amount":"0.01","order_id":"12345","transaction_id":"fake-txn"}'

发现未经身份验证的内部页面:

# Check robots.txt and sitemap for internal paths
curl --max-time 30 --connect-timeout 10 -s https://target.com/robots.txt | grep -iE "(disallow|allow)" 
curl --max-time 30 --connect-timeout 10 -s https://target.com/sitemap.xml | grep -iE "(employee|internal|staff|summit|admin)"

# Grep JS bundles for internal paths
curl --max-time 30 --connect-timeout 10 -s https://target.com/assets/app.js | grep -oE '"/[a-zA-Z0-9/_-]{3,50}"' | sort -u

绕过电子邮件验证:

# Skip the verification step: hit the post-verification API endpoint directly
# with an unverified session. If it succeeds, the gate is UI-only.
curl --max-time 30 --connect-timeout 10 -s -X POST https://monitor.target.com/api/monitoring/enable \
  -H "Cookie: session=<your_unverified_session>" \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]"}'

# Replay verification token on different account
curl --max-time 30 --connect-timeout 10 -X POST https://target.com/verify \
  -d 'token=VALID_TOKEN_FROM_ACCOUNT_A&[email protected]'

用于查找客户端逻辑问题的 grep 模式:

# Find price calculations in JS
grep -iE "(price|amount|total|cost)\s*[=*+]" app.js

# Find internal URLs in JS bundles
grep -oE '"/(employee|internal|staff|admin|summit)[^"]*"' *.js

# Find unvalidated IP header usage in server code
grep -iE "x-forwarded-for|x-real-ip|cf-connecting-ip" src/ -r

常见根本原因

  1. 服务器信任客户端提供的财务决策数据。 开发者将价格计算交给前端,或通过表单/URL 传递金额字段,却不在服务器上根据规范数据源(产品数据库)重新验证。

  2. 验证只在 UI 中强制执行,而未在 API 中强制执行。 前端将功能隐藏在验证门槛之后,但后端 API 端点无需验证状态即可正常运行——任何已通过身份验证的请求都能成功。

  3. 基于 IP 的速率限制读取可伪造的标头。 开发者使用 request.headers['X-Forwarded-For'] 而非实际连接 IP 来实现速率限制,因此可以通过篡改标头轻易绕过。

  4. 付款 webhook 缺少签名验证。 开发者实现了“成功” webhook,却未验证付款提供商提供的 HMAC 签名,因此任何人都可以 POST 伪造的成功通知。

  5. 内部/员工页面没有访问控制。 内部工具部署在生产域名上,却没有身份验证中间件;原因可能是开发者误以为只要 URL 不公开就安全,也可能是忘了给新路由添加身份验证。

  6. 电话/回拨验证仅供参考,并未强制执行。 系统接受电话号码,并向提交号码的人授予信任,却不确认提交者是否拥有或控制该号码。

  7. 草稿/特定渠道的店面继承了完整的订单功能。 Shopify 等平台允许为特定渠道(员工活动)创建未公开的店面;只要知道 URL,仍可完整地下单。


绕过技术

防御措施绕过方法
基于 IP 的速率限制每次请求轮换 X-Forwarded-For、X-Real-IP、True-Client-IP、CF-Connecting-IP 标头
订阅表单上的 CAPTCHA优先尝试基于标头的绕过;如果 CAPTCHA 只出现在网页表单上,直接调用底层 API 端点
邮箱验证关卡直接访问验证后的 API 端点;重放有效令牌;检查 verified=true 是否是由客户端设置的 Cookie/参数
服务端验证付款金额将货币改为价值较低的货币;尝试 $0.00 或负数金额;篡改订单 ID 以引用其他商品
Webhook HMAC 验证尝试不带签名标头或使用空签名标头(验证是否实际生效——只有在未强制验证时,篡改后的载荷才会“通过”);重放捕获到的未修改 Webhook,以测试是否缺少幂等性/防重放机制
内部页面上的身份验证尝试未登录访问;尝试使用低权限账户;尝试路径遍历变体(/employee/../employee/)
电话验证(发送 OTP)不经过 OTP 验证就提交他人的号码;检查系统是在提交号码时还是在确认 OTP 后授予信任

Gate 0 验证

撰写任何报告前,请回答以下三个问题:

  1. 攻击者现在能做什么? 请具体说明:“未登录用户可以零成本下单购买实物”或“攻击者可以绕过邮箱验证,在未拥有某个邮箱地址的情况下监控该邮箱”或“攻击者可以向任意地址发送无限量的订阅邮件。”影响描述含糊 = 驳回。

  2. 受害者会遭受什么损失? 明确具体且可归因的损失:经济损失(免费获得商品、欺诈性付款)、隐私损失(伪造电话号码、未经授权的监控)、服务滥用(通过绕过速率限制发起垃圾邮件活动),或安全性降低(未经验证的身份被信任,可执行敏感操作)。如果损失纯属理论推测,请重新评估严重性。

  3. 能否在 10 分钟内从头复现? 创建一个新账户(或不使用账户)。按照你记录的步骤操作,并实现相应影响。如果你无法依据所写步骤,在 10 分钟内从头到尾稳定地复现问题,则说明方法尚不完整——提交前请完善。


实际影响示例

场景 1 — 通过暴露的内部店铺免费获取实物商品(类似 Shopify) 某员工峰会页面被部署到公开的 Shopify 店铺,作为向员工免费发放书籍的专用渠道。通过分析 JS bundle 或分享链接即可发现该 URL。匿名用户访问该 URL 后,无需身份验证即可浏览商品并完成结账,实物商品由公司承担运费并寄出。影响:每笔订单都会造成直接经济损失;若未能及时发现,还可能被批量下单。

场景 2 — 通过篡改传输中的数据操纵支付(类似 Valve/Steam) 支付流程通过由客户端控制的参数传递订单金额和货币,然后重定向到第三方支付服务提供商(Smart2Pay)。攻击者可以使用 Burp Suite 拦截重定向并修改金额字段,以 $0.01 完成真实支付;由于应用的 webhook 未进行 HMAC 验证,因此会接受服务提供商的确认,并向账户发放完整的商品/服务。影响:造成严重的经济损失;攻击者几乎无需付费即可获得全部价值的商品/服务,而且可以无限次重复利用。

场景 3 — 绕过电子邮件验证,未经授权地进行监控(类似 Mozilla) 某泄露监控服务要求先验证电子邮件地址,才能为其启用监控提醒。验证检查仅在 UI 流程中执行,但底层 API 使用有效会话即可接受针对任意地址的监控设置请求,完全跳过验证步骤。攻击者可以监控自己并不拥有的电子邮件地址,并接收受害者账户的泄露通知数据(可能包括凭据是否已泄露)。影响:侵犯隐私;攻击者可以在目标不知情或未同意的情况下,获知目标的电子邮件是否出现在数据泄露事件中。


已披露报告引用(补充 +5 — 2016-2023)

以下 5 个真实且经过验证的漏洞赏金/协调披露案例扩展了此技能。这 5 个案例都具有可衡量的财务影响(已证实的实际损失或可量化的平台级风险敞口)。

  1. Stripe — 费用折扣竞态重复兑换(H1 #1849626)

    • 子类:优惠券/折扣竞态重复兑换 + 财务原语
    • 攻击载荷:Stripe 支持团队发放了一次性 $20,000 费用抵扣额度。研究人员捕获了“accept-discount” POST 请求,并通过 Burp Turbo Intruder 并行重放 30 次,每次接受都会再次为账户记入抵扣额度
    • 根本原因:折扣接受端点缺少幂等性;(account_id, discount_id) 没有唯一约束
    • 年份:2023 — $5,000,修复前累计产生了 $600,000 的免手续费交易(按 3% 抽成计算,Stripe 实际损失约为 $18,000)
  2. marketplace.example.com — 礼品卡竞态重复兑换(H1 #759247)

    • 子类:礼品卡/商店额度竞态重复兑换
    • 攻击载荷:使用一张有效礼品卡,通过 Turbo Intruder 从 10 个套接字并行向 /redeem 发送 POST 请求。余额会增加面值的 N 倍
    • 根本原因:gift_card 表没有行级锁;余额扣减和入账分别在不同事务中执行
    • 年份:2019 — $1,500
  3. Upserve / OLO — 负数量价格操纵(H1 #364843)

    • 子类:购物车负数量价格篡改
    • 攻击载荷:POST /api/order {"items":[{"id":1,"qty":1,"price":50},{"id":2,"qty":-3,"price":50}]} — 订单总额计算为 -$100,在扣款时被限制为约 $0,但食物仍会照常配送
    • 根本原因:服务器将 qty * price 相乘时未检查 qty >= 1
    • 年份:2018 — 该子类的典型引用案例(仅获确认的计划)
  4. Krisp — 篡改 PUT 请求以降低每席位费用(H1 #1446090)

    • 子类:单位价格批量赋值/数量折扣操纵
    • 攻击载荷:PUT /v2/seats 请求正文包含一个服务器信任的 price 字段。将 price=1 替代 $60。订阅更新后,计费引擎会按每席位 $1 向 100 个席位收费
    • 根本原因:服务器从请求正文读取价格,而不是通过 plan_id 查询;这是典型的批量赋值
    • 年份:2021 — 使用 Stripe 计费的 SaaS 价格风险敞口
  5. Stripe — 通过流程中途切换使用已归档价格(H1 #1328278)

    • 子类:购物车状态 TOCTOU/取消后仍交付(结账时的价格版本竞态)
    • 攻击载荷:商家将旧价格归档(例如 $5,而新价格为 $50)。买家通过新付款链接开始结账,然后在流程中途将 price_id 切回已归档价格。Stripe 收取 $5;订阅则按新档位开通
    • 根本原因:付款链接会验证“是否启用”,价格对象会验证“是否存在”——但缺少“price.active AND price ∈ link.allowed_prices”这一联合检查
    • 年份:2021 — Stripe 中危(每个订阅都会造成持续损失)

验证

运行此自测以确认业务逻辑测试准备就绪:

  1. API 直接调用测试 — 确认 curl 可以绕过前端验证:

    curl --max-time 30 --connect-timeout 10 -s -X POST "https://httpbin.org/post" -H "Content-Type: application/json" -d '{"quantity":-1,"price":0}' | python3 -m json.tool 2>/dev/null | grep -q "quantity" && echo "PASS" || echo "(httpbin may be down)"
    
  2. 并发请求测试 — 验证并行 curl 能力:

    curl --help 2>/dev/null | grep -q "parallel" && echo "PASS: curl parallel support" || echo "NOTE: older curl version"
    
  3. 整数边界情况 — 确认对边界情况的认知:

    echo "-1 0 2147483648 999999999" | grep -q "2147483648" && echo "PASS: overflow edge case present" || echo "FAIL"
    

这 3 项测试均用于验证业务逻辑探测准备情况。


易踩的坑

  • 认为业务逻辑漏洞影响较低——价格篡改、优惠券滥用和退款欺诈都是赏金最高的漏洞之一。不要把它们当成“只是逻辑问题”而轻视。
  • 只测试正常路径——漏洞往往藏在边缘情况中。测试负数数量、零价格、兑换时的竞争条件、过期优惠券和并发请求。
  • 只测试单个步骤——业务逻辑漏洞通常需要多个步骤的组合(添加到购物车 + 应用优惠券 + 更改数量 + 结账)。测试完整流程。
  • 忽略错误处理——边缘情况下的 500 错误往往会暴露未处理的状态,进而导致数据不一致(部分订单、重复扣款、免费商品)。
  • 不对比前端与 API——前端可能施加了 API 并未施加的限制。通过直接调用 API 测试所有约束。
  • 货币与舍入问题——小数货币处理(例如,0.001 USD)可能产生舍入误差,并在批量操作中累积。

相关技能与攻击链

  • hunt-race-condition——逻辑流程中的每个唯一性/配额检查都可能存在竞争条件。攻击链原语:业务逻辑(优惠券/额度/促销)+ 竞争条件 → 通过 Turbo Intruder 在单个 TCP 数据包中兑换优惠券 N 次。
  • hunt-idor——信任客户端提供的标识符(order_id、tenant_id、beneficiary_id)的逻辑流程与 IDOR 直接重合。攻击链原语:跳过业务逻辑步骤 + beneficiary_id 上的 IDOR → 从受害者账户转出资金。
  • hunt-api-misconfig——跳过步骤和绕过验证通常与批量赋值字段相邻。攻击链原语:跳过业务逻辑中的邮箱验证 + API 批量赋值(verified:true, role:admin)→ 无需控制邮箱即可实现 ATO。
  • hunt-ato——密码重置、邮箱变更和账户恢复流程中的逻辑漏洞是 ATO 的核心攻击路径。攻击链原语:业务逻辑(更改邮箱时无需重新验证)+ hunt-ato 路径 2 → 悄无声息地替换受害者邮箱 → 将密码重置邮件发送到攻击者邮箱。
  • security-arsenal——加载业务逻辑探测清单(负数量、十进制溢出、货币互换、通过直接 URL 导航跳过步骤、状态机逆向)和始终被拒绝清单,以避免提交自找的问题。
  • triage-validation——应用 7 问门槛(尤其是 Q4“外部攻击者能否在无需不切实际前提的情况下利用此漏洞?”):逻辑漏洞需要明确的金额/PII/状态影响,而不能只是“流程看起来很奇怪”。

价格篡改——客户端信任模式

SaaS 中最常见的业务逻辑模式:服务器信任客户端请求正文中的 price 字段。客户端发送 "price":0,服务器便以 R$0 创建结账会话,而不是从数据库中查询产品价格。

检测
# 1. Create a purchase with normal flow, capture the request
# 2. Replay with modified price
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://api.target.com/checkout" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"items":[{"id":"premium_product","quantity":1,"price":0}]}'

# 3. Test negative prices  
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://api.target.com/api/payments/create" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"items":[{"id":"plan","quantity":1,"price":-100}]}'

# 4. Test arbitrary quantities
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://api.target.com/api/checkout" \
  -d '{"items":[{"id":"key","quantity":999,"price":0}]}'
指标
  • 结账/支付端点返回第三方支付 URL(Stripe、Asaas、MercadoPago)
  • 支付 URL 带有 cs_test_ 前缀(Stripe 测试模式——实际上不会处理付款)
  • 无论价格值是多少,服务器都会响应购买 ID + 结账 URL
  • 产品价格可在 JS 包中看到,但服务器端从未进行交叉核对
验证
  • 已确认:以 R$0 创建结账 URL,支付页面加载并显示 R$0.00
  • 已确认严重:以 R$0 完成购买,并获得许可证/密钥
  • 误报:服务器以“price mismatch”拒绝,或使用服务器端价格查询
相关
  • hunt-write-gap——当服务器 PATCH/POST 端点缺少验证,导致价格篡改成功时
  • hunt-supabase——PostgREST 通过 anon key 接受价格字段的任意值

评论

支持 Markdown