OWASP API Top10 实战:CrAPI 靶机指南
本文最后更新于 2026年3月12日 下午
部署
1 | |
通过 docker 容器部署:
1 | |
对象级权限控制缺失(BOLA)漏洞
BOLA(Broken Object Level Authorization)是 OWASP API Top 10 中排名第一的漏洞类型,指的是系统在处理对象访问时,没有正确验证用户是否具备访问该对象的权限。
挑战 1 - 获取其他用户车辆的详细信息
目标: 枚举获得其他用户车辆的敏感信息。
访问:https://127.0.0.1:8443/ 注册用户并登录。
访问:http://127.0.0.1:8025/ 找到需要添加的车辆信息,将其添加到用户信息中。

点击 Refresh Location 可查看车辆位置信息。

通过 burp 抓取整个过程的数据包,发现其通过 API 请求 carId 可获车辆位置信息。

抓包访问社区模块可发现大量车辆 carId,修改数据包 carId 可遍历其余用户车辆位置信息。



挑战 2 - 获取其他用户的维修报告
目标: 访问其他用户提交的维修报告。
在联系技工的位置,输入任意内容,然后点击历史维修记录,抓包查看报告,通过更改请求 ID 可获取其他用户报告内容。


新提交的报告 ID 为 6,可以向前进行枚举,发现 ID 为 5 是 james 用户的车辆报告。


用户身份验证失效(Broken Authentication)
系统在用户身份验证流程中存在缺陷,导致攻击者可以绕过登录、冒充他人身份或接管账户。
挑战 3 - 重置其他用户密码
目标: 重置他人密码并接管账户。
通过挑战 1 可以得到其他用户的邮箱信息,利用忘记密码功能,输入用户邮箱,使用 burp 不断枚举验证码,可更改任意用户密码。



使用 v3 接口尝试枚举爆破验证码会存在次数限制。


尝试更改 API 版本至 v2,可一直执行爆破,并成功修改用户密码。


登录 Robot 用户后台。

过度数据泄露(Excessive Data Exposure)
后端返回了超过业务所需的敏感数据,而前端仅做了隐藏处理,没有真正限制数据输出。
挑战 4 - 找到泄露敏感信息的 API
目标: 发现返回其他用户敏感信息的接口。
该挑战在挑战 1 中已经体现,通过社区功能可查看用户的车辆 ID 信息。
挑战 5 - 泄露视频内部属性
目标: 找到视频对象中不应暴露的内部属性。
在个人中心上传 mp4 视频,然后抓包刷新访问,在响应头泄漏了视频属性信息。


速率限制(Lack of Rate Limiting)
系统没有限制单位时间内的请求次数,导致攻击者可以无限制地自动化发送请求进行攻击。
挑战 6 - 执行 L7 DoS 攻击
目标: 利用联系技工接口发起应用层拒绝服务攻击。
抓取联系技工数据包,在数据包 POST 请求中发现存在是否重试和重试次数的参数,修改参数请求不存在的 API 可实现 DOS 攻击。

功能级权限控制缺失(BFLA)
系统没有对不同角色的功能权限进行严格控制,导致低权限用户可以访问高权限功能接口。
挑战 7 - 删除其他用户的视频
目标: 删除他人视频。
在用户设置界面,测试修改视频名称会使用 PUT 方法,尝试在该接口使用 DELETE 方法,系统提示需要 admin 接口,修改 API 接口为 admin,可成功删除视频,通过不断枚举 ID 可删除其他用户视频。



删除其他用户视频。

大量分配漏洞(Mass Assignment)
后端在接收用户输入时,未对可修改字段进行限制,导致攻击者可以修改本不应该由用户控制的属性。
挑战 8 - 免费获得商品
目标: 未实际退货却获得退款。
通过用户购买界面购买任意商品,然后点击商品退款选项,系统会提示需要审核。



分析整个过程抓取的数据包,发现购买成功后会返回商品 ID 和剩余价格。

之后根据商品 ID 执行退款操作。

此时再次访问商品可以发现商品处于待退款的状态,按照前面挑战的案例,可尝试 PUT 方法修改退款状态。

在 PUT 数据中指定任意状态字符串,系统提示仅允许三种状态,很明显 returned 代表成功退款状态。

利用 PUT 方法修改商品为成功退款,即使没有通过二维码的验证也可以实现商品的退款,这意味着不需要管理员审核也可以成功退款,实现了零元购。

此时的账户依然是 100 美元。

挑战 9 - 增加余额 1000+ 美元
目标: 在挑战 8 基础上扩大收益。
通过挑战 8 成功实现了零元购,猜测是否可以使用单个商品的价格购买多个商品,既然通过 PUT 方法可以修改购买商品的退款状态,大概率也可以修改商品的购买数量。
重新购买商品,然后点击商品详情界面,抓取商品详情界面数据包,通过 PUT 方法修改购买的商品数量。


将数量修改为 10000,按照挑战 9 的步骤,执行退款即可获得 100090 美元。


挑战 10 - 修改视频内部属性
目标: 修改视频隐藏字段。
用户偏好设置中设置完视频后,存在更改视频名称的功能,该功能依然通过 PUT 方法更改,同理,也可以通过 PUT 方法修改视频的内部属性。


思考: 这里可通过 PUT 方法修改视频属性为反弹 shell,但一直没有找到触发执行的条件,有师傅知道如何利用可以留言告知一下,非常感谢。
服务器端请求伪造(SSRF)
攻击者诱导服务器向任意地址发起请求,从而访问内部网络或敏感资源。
挑战 11 - 触发 SSRF
目标: 让 crAPI 请求:百度。
在联系工程师的地方通过抓包发现 POST 数据包含指定的 API URL,将请求的 URL 更换为百度,可触发 SSRF 攻击。


NoSQL 注入(NoSQL Injection)
攻击者通过构造特殊输入,操控 NoSQL 查询语句,从而绕过认证或获取未授权数据。
挑战 12 - 免费优惠券
目标: 绕过验证直接获取优惠券。
容器使用了 MongoDB 数据库,对于 NoSQl 类型的数据库注入,可尝试通过 $ne、$mg 关键词注入。
常用 payload:
$gt:"":非空字符串$ne:null:非 null$regex:".+":至少 1 字符
1 | |

SQL 注入(SQL Injection)
攻击者通过构造恶意输入,干扰数据库查询逻辑,从而读取、修改或破坏数据库数据。
挑战 13 - 重复兑换优惠券
目标: 通过数据库修改重复兑换优惠券。
一旦成功领取了优惠券,再次输入会提示已经领取,请尝试其他优惠券。
抓取输入优惠券的数据包,发现会跳转至另外一个 API 接口。

我们输入单引号服务器会返回 500 错误,而输入恒成立语句则返回正常。

1 | |

按照靶机的原本思路需要执行 SQL 注入得到一些表信息,但是尝试查询服务器总返回 500,这里执行去容器执行查看。
1 | |
查看数据库 applied_coupon 表,发现 ID 为 8 的用户已经申请了邀请码,二 ID 为 8 正式我们注册的用户,所以系统才会提示我们无法重新领取。

只需要利用 SQL 注入堆叠查询删除该表即可重复领取。
1 | |

虽然服务器 500 错误,但实际在数据库已经成功删除,可以再次领取优惠券。

未经身份验证的访问(Unauthenticated Access)
挑战 14 - 未鉴权接口
系统未对接口进行身份验证,攻击者无需登录即可直接访问敏感功能或数据。
目标: 发现无需身份验证的 API。
有很多不需要鉴权就能访问的 API 接口,比如挑战 2 中查看其他用户报告。
JWT 漏洞(JWT Vulnerabilities)
在 JSON Web Token 的生成、验证或使用过程中存在安全缺陷,导致攻击者可伪造身份、绕过认证或提权。
挑战 15 - 伪造 JWT
目标: 构造合法 JWT 获取完全访问权限。
JWT 由三部分组成:Header(头部)、Payload(载荷)和 Signature(签名)。
- Header 和 Payload 使用 Base64URL 编码,可以被解码查看内容,因此默认不具备保密性。
- Signature 是根据 Header 中声明的签名算法(如 HS256、RS256),对
base64url(header) + "." + base64url(payload)进行数字签名生成的,用于保证数据的完整性和来源可信性。 - 服务端在接收到 JWT 后,会重新计算签名并进行比对,若签名一致,则说明 Token 未被篡改且由可信方签发,从而基于 Payload 中的身份信息完成鉴权。
可以尝试直接修改 JWT 头部,将签名算法设置为 none,这样服务器就会直接信任载荷部分。
1 | |
分别将第一部分和第二部分使用 base64 编码,然后通过点进行拼接组成新的 JWT。


1 | |
通过新生成的 JWT 可登录任意用户。

Thanks
如果我的文章对您有帮助或您希望与我更多交流,欢迎点击「关于我」,通过页面中的微信公众号、邮箱或 Discord 与我联系;若您发现文章中存在任何错误或不足之处,也非常欢迎通过以上方式指出,在此一并致以衷心的感谢。 😊🫡
最后,祝您生活愉快!🌞✨