白帽故事 · 2024年8月22日 0

【$2000】由于缓存配置错误导致授权绕过

起因

目标为一个电子商务网站,赏金范围有两个域名,分别是target.com 和 admin.target.com

target.com是面向用户的门户,用户可以在这里购买商品。

admin.target.com基本上是卖家的管理门户,他们可以在其中列出他们的商品、跟踪订单、客户信息等。

白帽小哥一般喜欢测试业务逻辑和访问控制,通常使用 Autorize 来进行自动化测试。

如果权限较低的用户能够访问管理端点,Autorize 就会将其标记为“bypassed”。

file

将target.com中普通用户的 Cookie 放入 Autorize 后,白帽小哥使用admin.target.com检查普通用户是否可以访问管理端点。

在测试过程中,发生了一些有趣的事情,每次访问https://admin.target.com/orders 端点时,会发出以下 GraphQL 请求:

POST /graphql
Host: admin.target.com

{"operationName":"GetOrders","variables":{"shop_id":"X"},"query":"query X"}

响应中包含了店铺的所有订单信息(这是正常的业务行为)。

然而奇怪的是,Autorize 却将端点标记为了“bypassed”,这意味着即使是普通用户也能够发出此请求并访问商店的订单信息。

但将该请求发送到 repeater 并尝试使用用户 Cookie 发出请求时,响应包却给出了错误。

file

autorize 标记为 bypassed,repeater 却显示 forbidden。emmm…

此后的测试中,Autorize 不断地将GetOrders端点显示为“bypassed”,但将请求发送到repeater测试时,却得到的是 403 forbidden 错误。

那么会不会是因为 Autorize 和 Repeater 是由于时间间隔所导致的?

于是小哥立即使用管理令牌向GetOrders端点发出请求:

POST /graphql
Host: admin.target.com
Auth: Bearer admin

{"operationName":"GetOrders","variables":{"shop_id":"X"},"query":"query X"}

然后立即使用用户令牌发出相同的请求:

POST /graphql
Host: admin.target.com
Auth: Bearer user

{"operationName":"GetOrders","variables":{"shop_id":"X"},"query":"query X"}

成功获得该商店的所有订单信息(包括客户详细信息)。

问题所在

服务器将GetOrders响应缓存了非常短暂的 3/4 秒,因此,如果攻击者在普通商店管理员使用其管理门户的同时发出请求,则攻击者只需使用shop_id即可获取属于任何商店的所有订单/客户信息。

而 shop_id 是一个可公开访问的 ID。

漏洞利用

只需创建一个简单的 bash 脚本,该脚本将全天连续向GetOrders端点发出请求。

当管理员访问他们的门户时,订单/客户信息会被缓存 3/4 秒的窗口,允许攻击者获取它们并绕过所有访问限制。

利用 intruder 使用用户令牌向GetOrders端点发出请求,由于存在访问控制,最初都是收到的 403 forbidden 响应。

file

与此同时,小哥以 adminUser 身份登录admin.target.com并正常访问admin.target.com/orders

对GetOrders的 graphql 请求是代表管理员在后台发出的,可缓存 3/4 秒。

缓存的响应最终被一分钟前给出 403 错误的 intruder 获取!

file

该漏洞被列为严重级并在数小时内进行了修复。

file

以上内容由骨哥翻译并整理。

原文:https://rikeshbaniya.medium.com/authorization-bypass-due-to-cache-misconfiguration-fde8b2332d2d