打破状态机:Web 竞态条件的真正潜力
打破状态机:Web 竞态条件的真正潜力
长期以来,Web 竞态条件攻击仅局限于少数场景。由于复杂的工作流程、工具缺失以及网络抖动等因素,其真正潜力一直被掩盖,只有最明显简单的案例才能被发现。
本文中,我将介绍远超传统限制溢出漏洞的新型竞态条件类别,并利用这些技术成功入侵多个知名网站以及 Rails 流行认证框架 Devise。同时还将介绍单包攻击技术——一种能够规避网络抖动的策略,可实现从墨尔本到都柏林的 30 个请求在 1 毫秒内同时执行。
背景知识:竞态条件基础
大多数网站使用多线程处理并发请求,所有线程都从同一个共享数据库读写数据。应用程序代码很少考虑并发风险,因此竞态条件问题在 Web 领域普遍存在。
典型的利用方式是限制溢出攻击——通过同步请求突破某种限制,例如:
多次兑换礼品卡
重复使用单个折扣码
多次评价同一产品
超额提取或转账
重复使用验证码
绕过暴力破解防护
这些问题都源于安全检查与被保护操作之间存在时间差。例如两个线程可能同时查询数据库确认"TOP10"折扣码尚未使用,然后都尝试应用该折扣,导致重复使用。
超越限制溢出漏洞
通过深入研究,我发现竞态条件的真正潜力可以用一句话概括:渗透测试人员都知道多步骤流程是漏洞温床,但在竞态条件下,所有操作都是多步骤的。
为说明这点,让我们分析一个我偶然发现的严重漏洞。当用户登录时,会看到"角色选择"页面,其中包含分配角色并重定向到特定应用的按钮。请求流程如下:
我最初错误地假设 GET /role 请求不会改变应用状态。实际上,应用会为每个会话初始化管理员权限,然后在浏览器获取角色选择页面时覆盖这些权限。通过跳过/role 直接访问应用,任何人都能获得超级管理员权限。
单包攻击技术
子状态是应用在处理单个请求时经历的短暂隐藏状态,通常仅持续约 1 毫秒。要发现子状态,需要一个初始 HTTP 请求触发状态转换,以及第二个在时间窗口内与相同资源交互的请求。
传统方法受网络抖动影响极大。为此我开发了"单包攻击"技术,使用该技术可以让 20-30 个请求无视网络抖动同时到达服务器。在 Turbo Intruder 中实现后,从墨尔本到都柏林发送 20 个请求的测试显示,单包攻击比传统最后字节同步技术效率高 4-10 倍。
技术实现要点:
预发送请求主体:对于无正文请求发送所有头部但不设置 END_STREAM 标志;对于有正文请求发送除最后一字节外的所有数据
准备发送最终帧:等待 100ms 确保初始帧已发送,禁用 TCP_NODELAY 以利用 Nagle 算法
发送保留帧:验证它们是否在单个数据包中
方法论
发现可利用子状态的系统方法:
预测潜在冲突:识别具有安全控制的对象及关联端点
探测线索:发送大量请求寻找异常行为
验证概念:将线索转化为可行攻击
案例研究
Gitlab 对象掩蔽漏洞
通过竞态条件,可以创建低权限邀请函,当被撤销时会被管理员级别邀请函替换。
多端点碰撞
在 Gitlab 的邮件验证流程中,通过同时验证邮件地址和修改地址,可使系统错误标记错误地址为已验证状态。
单端点碰撞
在 Gitlab 修改邮件地址功能中,同时向两个不同地址发送修改请求,导致确认邮件被发送到错误地址但包含有效令牌。
延迟碰撞
某些关键数据处理会定期批量执行,此时不需要精确的时间控制即可触发竞态条件。
防御建议
避免混合不同来源的数据
使用数据存储的并发功能确保敏感端点状态变更的原子性
利用数据存储的完整性/一致性特性
不要用一个数据存储层保护另一个
确保会话处理框架保持内部一致性
关键结论
HTTP 请求处理不是原子性的,任何端点都可能使应用经历不可见的子状态
单包攻击解决了网络抖动问题,使攻击如同在本地系统进行
发现异常是找到竞态条件的最重要技能
[完整技术细节和案例分析请参阅原文]更多精彩内容 请关注我的个人公众号 公众号(办公 AI 智能小助手)公众号二维码

评论