一文理解条件竞争漏洞

文化   2024-12-24 12:01   韩国  

扫码领资料

获网安教程


Track安全社区投稿~  

赢千元稿费!还有保底奖励~(https://bbs.zkaq.cn)

理解竞争条件的基本概念

竞争条件(也就是条件竞争,一个意思)是一种常见的漏洞类型,与业务逻辑缺陷密切相关。当网站在没有足够保护措施的情况下并发处理请求时,就会发生竞争条件。多个独立的线程同时与同一数据交互,会导致“碰撞”,从而引发应用程序的意外行为。竞争条件攻击通过精心设计的请求时序引发这些碰撞,利用意外行为进行恶意攻击。

img

发生碰撞的时间段被称为“竞争窗口”(race window)。例如,这可能是两次与数据库交互之间的一瞬间。

与其他逻辑缺陷类似,竞争条件的影响在很大程度上取决于漏洞所在的应用程序及其具体功能。

在本节中,您将学习如何识别和利用不同类型的竞争条件。我们将向您介绍如何利用 Burp Suite 的内置工具克服执行经典攻击的挑战,同时还会提供一种经过验证的方法,帮助您在隐藏的多步骤流程中检测新型竞争条件。这些方法远远超出了您可能已经熟悉的限制超越(limit overrun)攻击。

限制超越型竞争条件

最广为人知的竞争条件类型之一是允许您突破应用程序业务逻辑所施加的某种限制。

例如,假设一家在线商店允许您在结账时输入促销代码,以获得订单的一次性折扣。为了应用这个折扣,应用程序可能执行以下高级步骤:

1.检查您是否已经使用过该促销代码。
2.将折扣应用于订单总额。
3.更新数据库中的记录,以反映您已经使用过该促销代码。
如果您稍后尝试再次使用该代码,流程开始时执行的初始检查应会阻止您这样做:
img
现在想象一下,如果一个从未使用过该折扣代码的用户尝试几乎在同一时间两次使用该代码,会发生什么:
img
正如您所见,应用程会经历一个临时的子状态,即在完成请求处理之前进入并退出的状态。在这种情况下,子状态开始于服务器处理第一个请求时,并在更新数据库以表明您已使用该代码时结束。这会引入一个小的竞态窗口,在此期间,您可以反复多次领取折扣。
这种攻击有许多变种,包括:
    多次兑换同一礼品卡
    多次为产品评分
    提取或转账超出账户余额的金额
    重复使用同一个 CAPTCHA 验证答案
    绕过防暴力破解的限速限制
限制超限(Limit Overrun)是所谓“检查时间与使用时间”(Time-of-Check to Time-of-Use, TOCTOU)漏洞的一个子类型。在本主题的后续部分,我们将看到一些竞态条件漏洞的例子,这些例子不属于上述两种类型中的任何一种。

使用 Burp Repeater 检测和利用限制超限竞态条件

检测和利用限制超限竞态条件的过程相对简单。从高层次上来说,您只需执行以下步骤:
        找到一个具有单次使用或限速限制的端点,该端点具有某种安全影响或其他有用的功能。
        快速连续地向该端点发出多个请求,看看是否可以突破限制。
主要的挑战在于让请求的时机对准,使得至少两个竞态窗口重叠,从而引发冲突。这个窗口通常只有几毫秒,有时甚至更短。
即使您完全同时发送所有请求,实际上,服务器处理每个请求的时间和顺序仍然会受到各种不可控和不可预测的外部因素的影响。
img
Burp Suite 2023.9[1] 为 Burp Repeater 增加了强大的新功能,使您能够轻松地以并行方式发送一组请求,从而大大降低其中一个关键因素——网络抖动的影响。Burp 会根据服务器支持的 HTTP 版本自动调整使用的技术:
    对于 HTTP/1,使用经典的“最后字节同步”技术。
    对于 HTTP/2,使用“单包攻击”技术,这项技术由 PortSwigger Research 团队首次在 2023 年 Black Hat USA 大会上展示。
“单包攻击”通过使用一个 TCP 包同时完成 20–30 个请求,能够完全中和网络抖动带来的干扰。
img
尽管通常只需两个请求即可触发利用,但发送大量请求有助于缓解内部延迟(即服务器端抖动)。这在初始发现阶段特别有用。我们将在后续内容中详细介绍这一方法论。

方法论

为了检测和利用隐藏的多步骤序列,我们推荐以下方法论,该方法总结自 PortSwigger Research 的白皮书 《Smashing the state machine: The true potential of web race conditions》[2]
img

1 — 预测潜在的冲突

测试每个端点是不现实的。在正常绘制目标网站地图后,可以通过以下问题减少需要测试的端点数量:
        这个端点是否对安全至关重要? 许多端点不会涉及关键功能,因此不值得测试。
        是否存在冲突的潜在可能性? 为了成功触发冲突,通常需要两个或多个请求对同一记录进行操作。例如,以下是密码重置实现的几种变体:
img
在第一个例子中,同时请求为两个不同用户重置密码不太可能导致冲突,因为它会修改两个不同的记录。然而,第二种实现允许通过针对两个不同用户的请求修改同一条记录。

2 — 线索

为了识别线索,首先需要基准测试端点在正常条件下的行为。可以通过在 Burp Repeater 中将所有请求分组并使用 按顺序发送分组请求(独立连接) 选项完成。有关更多信息,请参阅按顺序发送请求[3]
接下来,使用单包攻击(或如果不支持 HTTP/2 则使用最后字节同步)同时发送同一组请求,以最大限度减少网络抖动。可以通过在 Burp Repeater 中选择 并行发送分组请求 选项完成此操作。有关更多信息,请参阅并行发送请求[4]。或者,可以使用 Turbo Intruder 扩展,该扩展可从 BApp Store[5] 下载。
任何细节都可能成为线索。只需观察与基准测试期间的行为是否存在某种形式的偏差。这可能是一个或多个响应的变化,但不要忽略二次效应,例如电子邮件内容的差异或应用程序后续行为的可见变化。

3 — 概念验证

尝试理解正在发生的情况,移除多余的请求,并确保仍然可以复现结果。
高级竞态条件可能导致异常和独特的利用原语,因此最大化影响的路径可能并不总是显而易见。可以将每个竞态条件视为一种结构性弱点,而不是一个孤立的漏洞。

如何防止竞态条件漏洞

当单个请求可以让应用程序经历不可见的子状态时,理解和预测其行为非常困难,这使得防御变得不切实际。为了正确保护应用程序,我们建议通过以下策略消除所有敏感端点的子状态:
避免混合来自不同存储位置的数据。
使用数据存储的并发功能确保敏感端点的状态更改是原子的。例如,使用单个数据库事务验证支付与购物车金额一致并确认订单。
作为深度防御措施,利用数据存储完整性和一致性功能,例如列的唯一性约束。
不要使用一个数据存储层来保护另一个数据存储层。例如,会话不适合防止数据库的超限攻击。
确保会话处理框架保持会话的内部一致性。逐个更新会话变量而不是批量更新可能是一个诱人的优化,但非常危险。对于 ORM 来说也是如此;通过隐藏事务等概念,它们完全承担了相应责任。
在某些架构中,可能适合完全避免服务器端状态。相反,可以使用加密将状态推送到客户端,例如使用 JWT
原文:https://medium.com/infosecmatrix/how-to-find-and-identify-race-condition-vulnerabilities-as-a-penetration-tester-9d9ecce6ed56

References

[1] Burp Suite 2023.9: https://portswigger.net/burp/releases#professional
[2] 《Smashing the state machine: The true potential of web race conditions》: https://portswigger.net/research/smashing-the-state-machine
[3] 按顺序发送请求: https://portswigger.net/burp/documentation/desktop/tools/repeater/send-group#sending-requests-in-sequence
[4] 并行发送请求: https://portswigger.net/burp/documentation/desktop/tools/repeater/send-group#sending-requests-in-parallel
[5] BApp Store: https://portswigger.net/bappstore/9abaa233088242e8be252cd4ff534988

声明:⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。所有渗透都需获取授权

如果你是一个网络安全爱好者,欢迎加入我的知识星球:zk安全知识星球,我们一起进步一起学习。星球不定期会分享一些前沿漏洞,每周安全面试经验、SRC实战纪实等文章分享,微信识别二维码,即可加入。


白帽子左一
零基础也能学渗透!关注我,跟我一启开启渗透测试工程师成长计划.专注分享网络安全知识技能.
 最新文章