一个条件竞争漏洞,让我用TurboIntruder刷爆登录接口|赏金技巧

admin 2026-08-23 05:16:30 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文介绍利用条件竞争漏洞绕过登录接口的失败次数锁定机制。通过并行发送大量登录请求,在服务器更新失败计数器之前完成多次尝试,从而突破三次锁定限制。作者使用TurboIntruder工具配合单数据包攻击脚本实现并发爆破,并成功获取目标账户密码。该技术展示了看似严密的限制在并发面前可能存在的破绽,为渗透测试提供了一种绕过登录限速的实战技巧。 综合评分: 76 文章分类: 渗透测试,漏洞分析,web安全,红队,安全工具


cover_image

一个条件竞争漏洞,让我用Turbo Intruder刷爆登录接口|赏金技巧

原创

升斗安全XiuXiu 升斗安全XiuXiu

升斗安全

2026年8月18日 07:45 广东

在小说阅读器读本章

去阅读

【文章说明】

  • 目的:本文内容仅为网络安全技术研究与教育目的而创作。
  • 红线:严禁将本文知识用于任何未授权的非法活动。使用者必须遵守《网络安全法》等相关法律。
  • 责任:任何对本文技术的滥用所引发的后果自负,与本公众号及作者无关。
  • 免责:内容仅供参考,作者不对其准确性、完整性作任何担保。

阅读即代表您同意以上条款。

锁得住三次,锁不住同一秒:一个登录限速的竞态(条件竞争)绕过

今天聊一个很有意思的场景:目标站点的登录接口做了防爆破,同一个用户名连续错三次就会被临时锁定。表面上看,这条路被堵死了。但如果换个思路:我不跟你拼次数,我跟你拼速度,在你的“计数器”还没反应过来之前,把所有尝试同时砸过去,会怎样?

先摸清它的防御逻辑

我先拿自己的账户做实验,故意连续输入错误密码。三次之后,账户果然被临时禁止登录了。

接着我换了一个随便编的用户名去试,返回的是正常的“用户名或密码无效”,而不是什么“账户已锁定”之类的提示。这说明限速逻辑不是按会话或者 IP 来做的,而是按用户名单独计数的。换句话说,服务器端为每个用户名维护着一个“失败次数计数器”。

这时候,一个经典的竞态问题就浮出水面了:

从“我提交登录请求”到“服务器把失败次数加一”之间,是否存在一个极短的时间窗口?

如果能抢在这个窗口内把一堆请求同时塞进去,那“三次锁定”这个限制可能就形同虚设了。

先按正常节奏走一遍

在 Burp 的历史记录里,我找到了那条带着自己账户错误密码的 POST /login 请求,把它送进 Repeater。

为了后面做对比,我先按顺序发送一组请求。操作上很简单:

  • 把这个请求的标签页放进一个分组里
  • 右键选择“复制标签页”,一口气复制出 19 个副本
  • 然后让这 20 个请求按顺序、各自走独立连接发出去

结果完全在意料之中:在之前已经累积了两次失败的基础上,再错两次,账户就被锁了,后面的请求全部被拒。这个表现非常“守规矩”,防御逻辑工作得很正常。

关键一步:同时发出去

接下来,我把同一组请求再发一遍,但这次不是排队走,而是让它们并行,也就是几乎同时发出。

观察响应的时候,有意思的事情出现了:虽然账户已经触发了锁定,但依然有好几个请求拿到了正常的“用户名或密码无效”响应。也就是说,即使在“账户应该已经被锁”的状态下,依然有请求成功进入了密码校验流程。

这说明我们的猜想是对的:服务器在更新失败计数器之前,确实存在一个极小的窗口期。只要速度足够快,就能在锁定真正生效之前,多塞进去好几次尝试。

把窗口期变成武器

既然并行能突破三次限制,那接下来就把这个思路武器化。

我选中请求里的 password 参数,右键把它送到 Turbo Intruder。它会自动把密码位置标记成 %s,当作爆破点。

然后把用户名改成目标账户 admin,在模板下拉框里选择 examples/race-single-packet-attack.py。这个脚本的核心思路非常直接:把所有候选密码的请求先排队,但一个都不发;等所有请求都准备就绪之后,调用一次 engine.openGate(‘1’),让它们在同一个瞬间全部冲出去。

因为目标支持 HTTP/2,所以这里用 Engine.BURP2 配合单连接模式,效果最好。

完整的脚本逻辑如下,密码字典直接从你复制到剪贴板中读取:

def queueRequests(target, wordlists):    # 目标支持 HTTP/2,使用单数据包攻击    # engine=Engine.BURP2 和 concurrentConnections=1 是关键    engine = RequestEngine(endpoint=target.endpoint,                           concurrentConnections=1,                           engine=Engine.BURP2                           )    # 从剪贴板读取候选密码列表    passwords = wordlists.clipboard    # 把每个密码对应的登录请求排队    # 'gate' 参数会拦住所有请求,直到 openGate() 被调用    for password in passwords:        engine.queue(target.req, password, gate='1')    # 所有请求就绪后,打开闸门,同时发送    engine.openGate('1')def handleResponse(req, interesting):    table.add(req)

把准备好的候选密码复制到剪贴板,然后启动攻击。

如果一轮下来没有成功,就等账户锁定重置,把已经确认错误的密码从列表里删掉,再跑一轮。一旦看到某个请求返回了 302,就说明登录成功了,对应的密码就在“有效载荷”那一列里。

拿到密码之后,等锁定时间过去,就能正常登录 admin 的账户了,这样就完成了已知账号,在有限制的情况下,也能成功爆破。

整个过程的本质就是在跟服务器抢时间:它想锁,我们比它锁得更快。这种条件竞争型的漏洞,往往就藏在“校验”和“计数”之间那几毫秒的缝隙里。很多看似严密的限制,在并发面前都会露出破绽。

如果你觉得这篇文章对你有帮助,别忘了一键三连,点赞、在看、转发走一波!你们的支持是我持续更新更多实战技巧的最大动力。也欢迎把文章推荐给身边一起挖洞的朋友,说不定下次他们遇到类似目标时,就能用上这套思路。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:升斗安全 升斗安全XiuXiu 升斗安全XiuXiu《一个条件竞争漏洞,让我用Turbo Intruder刷爆登录接口|赏金技巧》

评论:0   参与:  0