文件上传漏洞之条件竞争

免责声明:用户因使用公众号内容而产生的任何行为和后果,由用户自行承担责任。本公众号不承担因用户误解、不当使用等导致的法律责任


目录

文件上传漏洞原理

1. 客户端校验不足

2. 服务端校验缺陷

3. 文件解析漏洞

4. 服务器配置错误

5. 攻击场景与利用方式

关键防御措施

案例一:upload-labs靶场18关

1.打开bp抓包,利用间隔将木马文件上传

2.设置进程

3.上传一句话木马成功

4.然后使用蚁剑连接

案例二:upload-labs靶场19关

1.设置上传包线程数等

2.设置访问包线程数等

3.上传成功

4.然后使用蚁剑连接

​编辑案例三:攻防世界靶场的wzsc_文件上传题目

1.打开靶场

2.上传文件实验

3.找到文件存储路径

4.打开bp验证

5.得知为条件竞争漏洞

6.设置bp上传包和访问包的线程

7.成功上传到upload目录下

8.然后使用蚁剑连接

9.找到falg

总结


文件上传漏洞原理

文件上传漏洞是指Web应用程序未对用户上传的文件进行充分的安全验证,导致攻击者可上传恶意文件(如WebShell、木马,图片,简历,附件等),进而控制服务器或实施其他攻击。以下是其核心原理及技术细节


1. 客户端校验不足

  • 原理:仅依赖前端(如JavaScript)校验文件类型、扩展名或大小。

  • 绕过方式

    • 禁用浏览器JavaScript。

    • 使用代理工具(如Burp Suite)修改请求包中的文件名、MIME类型或内容。


2. 服务端校验缺陷

  • 文件类型校验不严

    • 仅检查HTTP头中的Content-Type(如image/jpeg),攻击者可伪造该字段。

    • 仅校验文件扩展名:攻击者可上传.php.jpg或使用大小写(如.PhP)绕过。

  • 未校验文件内容

    • 图片马攻击:在图片文件中插入恶意代码(如<?php system($_GET['cmd']); ?>),结合文件包含漏洞执行。

    • 仅检查文件头标识(如GIF89a),未验证完整文件内容。

  • 黑名单机制缺陷

    • 未覆盖所有危险扩展名(如.phtml.phar.htaccess)。

    • 允许特殊字符绕过:如利用空字节(test.php%00.jpg)、空格(test.php .jpg)或双扩展名(test.php.jpg)。


3. 文件解析漏洞

  • 服务器中间件特性

    • Apache:若存在.htaccess文件覆盖权限,攻击者可上传配置使图片解析为PHP(如AddHandler application/x-httpd-php .jpg)。

    • IIS 6.0:分号解析漏洞(test.asp;.jpg视为ASP文件)、目录路径解析(/upload/test.asp/test.jpg)。

    • Nginx/PHP:路径截断(test.jpg/xxx.php)或错误配置fastcgi导致文件解析异常。

  • Web容器特性

    • 某些旧版本Tomcat可能将test.jsp/test.jsp::$DATA视为合法JSP文件。


4. 服务器配置错误

  • 上传目录权限不当:Web目录下的上传文件夹允许执行脚本(如未限制execute权限)。

  • 文件存储路径可预测:如按时间或用户名生成文件名,攻击者可枚举路径访问恶意文件。

  • 未重命名文件:保留用户定义的文件名,可能导致覆盖系统文件或直接访问恶意文件。


5. 攻击场景与利用方式

  • WebShell上传:上传包含恶意代码的脚本(如.php.jsp),通过浏览器访问该文件执行命令。

  • 恶意文件分发:上传包含病毒、木马的文件供其他用户下载。

  • 挂黑链

  • 挂马(广告、刷点击)或者挖矿

  • 文件数据泄露

  • 配合其他漏洞

    • 文件包含漏洞:利用include函数执行图片马中的代码。

    • XXE(XML外部实体注入):通过上传恶意XML文件读取服务器文件。

    • 覆盖配置文件:如修改.htaccessweb.config改变服务器行为。

    • 挂黑链 挂马(广告、刷点击)或者挖矿 文件数据泄露


关键防御措施

  1. 白名单校验:严格限制扩展名(如仅允许.jpg.png)及MIME类型。

  2. 文件内容检测:使用图像处理库(如GD库)二次渲染文件,或检查二进制内容。

  3. 重命名文件:使用随机哈希值命名,避免用户控制存储路径。

  4. 隔离上传目录:禁止直接执行上传目录中的脚本,并设置最小权限。

  5. 安全配置:禁用危险中间件特性(如Apache的AllowOverride),及时升级修复解析漏洞。


文件上传漏洞的本质是信任用户输入而未实施多层防御。通过组合校验、安全配置和最小权限原则,可有效降低风险。

本文以条件竞争为例,深入分析文件上传漏洞原理


案例一:upload-labs靶场18关

根据源代码得知后台逻辑为:现将上传的文件进行保存后再审查其合法性,不合法将其删除。

所以我们可以利用文件上传漏洞之条件竞争,在它没有删除之前访问木马文件,这样就可以成功上传一句话木马(如下)。

<?php

fputs(fopen("heihei.php", "w"), '<?php @eval($_POST["aqlw"]); ?>');

?>

  1. fopen("heihei.php", "w")

    • 以写入模式(w)打开文件 heihei.php,若文件不存在则创建,存在则清空内容。

  2. fputs() 写入内容

    • 向文件中写入字符串 <?php @eval($_POST["aqlw"]); ?>,其本质是一个WebShell

      • @eval($_POST["aqlw"]):通过POST参数 aqlw 接收攻击者输入的任意代码并执行(eval函数),@符号用于抑制错误输出。

  3. 访问上传的 shell.php,代码自动执行并生成 heihei.php。此时,攻击者可通过POST请求操控服务器

1.打开bp抓包,利用间隔将木马文件上传

2.设置进程

首先,需要设置两个,一个为上传包进程,一个为访问包进程,只要在没有被删除前访问到木马文件就可以上传一句话木马。其中访问进程需大于上传进程。

3.上传一句话木马成功

4.然后使用蚁剑连接


 

案例二:upload-labs靶场19关

//index.php
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
{
    require_once("./myupload.php");
    $imgFileName =time();
    $u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);
    $status_code = $u->upload(UPLOAD_PATH);
    switch ($status_code) {
        case 1:
            $is_upload = true;
            $img_path = $u->cls_upload_dir . $u->cls_file_rename_to;
            break;
        case 2:
            $msg = '文件已经被上传,但没有重命名。';
            break; 
        case -1:
            $msg = '这个文件不能上传到服务器的临时文件存储目录。';
            break; 
        case -2:
            $msg = '上传失败,上传目录不可写。';
            break; 
        case -3:
            $msg = '上传失败,无法上传该类型文件。';
            break; 
        case -4:
            $msg = '上传失败,上传的文件过大。';
            break; 
        case -5:
            $msg = '上传失败,服务器已经存在相同名称文件。';
            break; 
        case -6:
            $msg = '文件无法上传,文件不能复制到目标目录。';
            break;      
        default:
            $msg = '未知错误!';
            break;
    }
}

//myupload.php
class MyUpload{
......
......
...... 
  var $cls_arr_ext_accepted = array(
      ".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",
      ".html", ".xml", ".tiff", ".jpeg", ".png" );

......
......
......  
  /** upload()
   **
   ** Method to upload the file.
   ** This is the only method to call outside the class.
   ** @para String name of directory we upload to
   ** @returns void
  **/
  function upload( $dir ){
    
    $ret = $this->isUploadedFile();
    
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->setDir( $dir );
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->checkExtension();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->checkSize();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }
    
    // if flag to check if the file exists is set to 1
    
    if( $this->cls_file_exists == 1 ){
      
      $ret = $this->checkFileExists();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }

    // if we are here, we are ready to move the file to destination

    $ret = $this->move();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }

    // check if we need to rename the file

    if( $this->cls_rename_file == 1 ){
      $ret = $this->renameFile();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }
    
    // if we are here, everything worked as planned :)

    return $this->resultUpload( "SUCCESS" );
  
  }
......
......
...... 
};

根据源代码得知:对上传的文件进行白名单后缀过滤、判断文件大小的合法性、对上传的文件改名。也就是说只有绕过了后缀的白名单的过滤,才会保存文件。这里注意,保存文件后会对文件进行改名操作了,比如上传了shell.php.xx,他会对shell.php进行改名。我们要利用的就是apache的解析漏洞结合条件竞争,在上传成功之后和改名之前的时间差内对shell.php.xx发起访问,使得一句话木马文件写入目录中。

1.设置上传包线程数等

2.设置访问包线程数等

3.上传成功

4.然后使用蚁剑连接



案例三:攻防世界靶场的wzsc_文件上传题目

1.打开靶场

2.上传文件实验

我们先进行实验,将我们事先准备好的一句话木马文件shell.php上传查看有何变化

3.找到文件存储路径

多次上传发现都会调用upload.php。所以我们猜测文件是否被传到了upload路径下呢?

我们猜测正确,但是我们上传的一句话木马不在此路径下,应该是被删除了。尝试上传随意的一张图片

我们上传的图片确实被存放在此路径下,但是上传一句话木马文件却被删除了。是否是php文件不能上传。我们打开bp进行验证。

4.打开bp验证

5.得知为条件竞争漏洞

我们可以看到响应头为200说明可以上传php文件,但为什么我们看不到呢,我们猜测是因为上传成功后服务器立即删除了这个php文件所以我们看不见。既然这样我们就使用条件竞争。我们使用bp快速发送php文件同时访问这个木马文件,只要有一次被访问成功,木马文件就会生成一句话木马。这样就上传成功了。但需要注意访问的线程需要大于上传的线程,否则难以成功。

6.设置bp上传包和访问包的线程

设置上传包线程数为30,清空载荷payload,设置攻击载荷为无限重复。

设置访问包访问线程为80,无payloa,无限重复。

开始攻击当访问包状态码为200时上传成功

7.成功上传到upload目录下

8.然后使用蚁剑连接

连接成功

9.找到falg


总结

通过三个案例我们了解到文件上传漏洞之条件竞争漏洞的利用方法,攻击者通过快速重复上传恶意文件并触发访问,在文件被删除前完成代码执行,绕过安全检测。条件竞争只是文件上传漏洞的一部分,剩下的部分如图片马的上传,大小写绕过,双写绕过,后缀名.htaccess绕过,文件扩展名等文件上传漏洞,自行到upload-labs靶场学习。

(需要资料关注免费领取!!还希望多多关注点赞支持,你的支持就是我的最大动力)!!!

 

 

 

### 条件竞争文件上传漏洞解析 #### 概念定义 条件竞争(Race Condition)是指两个或多个进程在同一时间段内试图访问和修改同一资源的情况。当这种情况发生在文件上传过程中时,可能会导致严重的安全隐患。具体来说,在多线程或多进程中,如果程序未能正确同步对共享资源的操作,则可能导致不一致的状态或未预期的行为。 对于文件上传过程中的条件竞争漏洞而言,通常表现为服务器端处理客户端提交的数据包存在时间差窗口期内被其他请求干扰的可能性。这种情况下,攻击者可能利用精心构造的时间序列来覆盖合法用户的文件或者篡改已存在的敏感文档[^1]。 #### 利用方式 要成功触发此类漏洞,攻击者需精确控制两次独立HTTP POST请求之间的时间间隔以及它们到达Web应用服务实例的具体顺序。这要求具备一定的网络环境和技术手段支持,比如低延迟连接、可预测的服务响应模式等特性。一旦满足这些前提条件,攻击者可以通过快速连续发送带有相同名称参数的不同版本文件来进行碰撞尝试,最终实现非法替换目标位置上的现有对象[^2]。 #### 防护策略 为了有效防范上述提到的风险因素,建议采取如下综合性的防御措施: - **输入验证**:严格校验所有来自外部源的输入项,特别是那些涉及路径名的部分;确保只允许特定类型的文件格式通过审核机制。 - **原子化操作**:尽可能使整个保存流程成为一个不可分割的整体动作,即要么全部完成要么完全失败,以此消除中间状态的存在机会。 - **临时存储区隔离**:创建专门用于暂存待处理材料的空间,并将其与正式仓库隔离开来;经过充分审查后再迁移至指定目录下。 - **权限管理加强**:合理配置操作系统层面及应用程序内部的角色划分体系,限制不必要的读写许可范围,减少潜在危害扩散途径。 - **日志记录详尽**:保持详细的活动轨迹追踪习惯,便于事后审计分析异常事件发生的原因所在;同时也有助于及时发现可疑行为并作出反应。 ```python import os from werkzeug.utils import secure_filename def save_file(file, upload_folder): filename = secure_filename(file.filename) temp_path = os.path.join(upload_folder, 'temp', filename) final_path = os.path.join(upload_folder, filename) try: file.save(temp_path) # Save to temporary location first # Perform necessary checks here (e.g., virus scan, content validation) if not check_virus(temp_path): # Hypothetical function for checking viruses raise Exception("File contains malicious code.") os.rename(temp_path, final_path) # Atomically move the file into place except Exception as e: if os.path.exists(temp_path): os.remove(temp_path) raise e ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安全瞭望Sec

感谢您的打赏,您的支持让我更加

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值