文件上传

知识点一览

  • 前端 js 验证,pass01,抓包改包/禁用js

  • content_type验证,pass02,抓包改包

  • 黑名单验证

    • windows :自动删除这些符号
      • 空格,pass06
      • ::$DATA,
      • .(点),
    • 大小写,pass05,
    • php%00截断(php5.2),
    • .htaccess 伪静态,pass04
    • user.ini
    • 修改配置项,使得.php3/.phtml/.任意后缀,被当作.php,pass03
  • replace过滤

    • 双写绕过
  • 白名单

    • 上传路径可控
      • %00截断(php5.2),只会执行%00之前的内容
  • 文件包含

    • 图片码

      image-20251124155206375

  • 图片码防御

    • 取消 upload 文件夹可执行权限
    • imagecreatefromjpeg 图片打散
  • 图片打散

  • 文件竞争,逻辑漏洞

文件上传漏洞

定义

文件上传漏洞是指 Web 应用未对上传文件的类型、内容、路径等做严格校验,导致攻击者可上传恶意文件(如 PHP 后门、图片马)到服务器,进而执行代码、控制服务器的高危漏洞,是渗透测试中最常见的攻击手段之一。

校验维度与绕过方法

(一)前端校验(客户端校验)

  1. 校验方式

通过 JavaScript 校验文件后缀、大小、类型(如onchange事件判断扩展名),仅在浏览器端拦截,无服务端验证。

  1. 绕过方法(pass01)
  • 禁用 JavaScript:浏览器 F12→设置→禁用 JS,或用插件(如 NoScript);
  • 抓包改包:先上传合法文件(如1.jpg),通过 Burp Suite 拦截请求,修改文件名 / 内容为恶意文件(如1.php);
  • 本地修改 HTML:删除前端校验的 JS 代码,再上传。

(二)Content-Type 校验

  1. 校验方式

服务端读取请求头Content-Type(如image/jpegapplication/x-php)判断文件类型,仅校验头信息不校验文件内容。

  1. 绕过方法(pass02)

抓包修改Content-Type

  • 上传1.php时,Burp 拦截后将Content-Type: application/x-php改为image/jpeg/image/png等合法图片类型;
  • 常见合法 Content-Type:image/jpegimage/pngimage/gifapplication/octet-stream

(三)黑名单校验(服务端核心校验)

服务端维护 “禁止上传的后缀列表”(如phpaspjsp),拦截匹配的文件,绕过核心是 “绕开黑名单规则”。

绕过场景原理与绕过方法(对应笔记 pass)适用环境 / 注意事项
1. 大小写绕过(pass05)黑名单仅匹配小写(如php),修改为Php/PHP/pHp适用于未统一大小写的校验逻辑(如仅用strtolower但未处理)
2. 特殊符号绕过(Windows)Windows 系统对文件名的特殊处理:- 空格绕过:1.php(后缀后加空格,Windows 自动忽略)- 点绕过:1.php.(后缀后加点,Windows 自动截断)- ::$DATA绕过:1.php::$DATA(Windows 保留数据流,仅执行::$DATA前内容)仅适用于 Windows 服务器;部分中间件(如 IIS)兼容此特性
3. 截断绕过(%00)利用 PHP 解析器漏洞(PHP5.2 及以下),%00代表字符串结束符:- 文件名:1.php%00.jpg(服务端仅识别1.php,后缀显示为jpg)- 路径截断:上传路径可控时,upload/1.php%00/1.jpgPHP5.3 及以上已修复;需确保magic_quotes_gpc=off
4. 后缀变种绕过(pass03)黑名单仅拦截php,利用 PHP 解析后缀:- 变种后缀:php3/php4/php5/phtml/phps- 配置修改:攻击者通过漏洞修改httpd.conf,使.xxx后缀被解析为 PHP需服务器配置支持(如 Apache 开启AddType application/x-httpd-php .php3
5. .htaccess 绕过(pass04)上传.htaccess文件(Apache 配置文件),强制服务器解析指定后缀为 PHP:apache<br><FilesMatch "1.jpg"> <br>SetHandler application/x-httpd-php <br></FilesMatch><br>上传1.jpg(内含 PHP 代码),会被解析为 PHP仅适用于 Apache 服务器;需上传目录可写、.htaccess未被黑名单拦截
6. user.ini 绕过user.ini是 PHP 的用户级配置文件,可设置auto_prepend_file=1.jpg(自动包含1.jpg),上传1.jpg(含 PHP 代码)即可执行适用于 PHP 环境(FastCGI 模式);user.ini需放在网站根目录 / 上传目录,且目录有执行权限
7. 双写绕过(replace 过滤)校验逻辑用str_replace('php', '', $name)删除php,双写后缀:1.pphphp(替换后变为1.php适用于仅单次替换的过滤逻辑(多次替换需多层双写)

(四)白名单校验

服务端仅允许 “指定后缀列表”(如jpg/png/gif),绕过核心是 “在合法后缀文件中嵌入恶意代码”。

  1. 核心绕过手段:图片马(文件包含配合)
  • 原理:将 PHP 恶意代码嵌入图片文件(如1.png),上传后通过 “文件包含漏洞” 执行图片中的 PHP 代码;
  • 制作方法(Windows):copy 1.png /b + shell.php /a malicious.png(二进制合并图片和 PHP 代码);
  • 执行条件:需存在文件包含漏洞(如include($_GET['file'])),访问?file=upload/malicious.png即可执行代码。
  1. 路径可控 %00 截断(笔记补充)

白名单限制后缀为jpg,但上传路径可控时:

  • 上传文件名:1.jpg,抓包修改路径为upload/1.php%00/1.jpg
  • 服务器保存路径为upload/1.php%00截断),后缀仍符合白名单,文件实际为 PHP 恶意文件。

文件包含漏洞

(图片马执行的核心依赖)

定义

服务端使用include/require等函数包含文件时,未校验文件路径 / 类型,导致攻击者可包含恶意文件(如图片马)执行代码。

图片马执行流程

1
制作图片马(png+PHP代码)→ 上传图片马到服务器 → 利用文件包含漏洞(如?file=upload/malicious.png)→ 服务器解析图片中的PHP代码 → 执行恶意操作

文件包含函数

include()require()include_once()require_once()file_get_contents()(配合eval执行)。

防御方案

(一)基础防御(通用规则)

  1. 前后端双重校验:前端校验仅做体验优化,核心校验在服务端;
  2. 统一校验规则:
    • 文件名统一转为小写(strtolower),避免大小写绕过;
    • 过滤 / 转义特殊字符(空格、点、::$DATA%00);
  3. 后缀校验优先用白名单:仅允许jpg/png/gif等合法后缀,拒绝黑名单;
  4. 独立上传目录:
    • 上传目录与网站执行目录分离(如/upload/www分开);
    • 取消上传目录可执行权限(核心!):chmod 644 upload/(仅读 / 写,无执行权限);
  5. 重命名文件:上传后随机重命名(如md5(时间戳+随机数).jpg),避免攻击者控制文件名 / 路径。

(二)图片马专项防御

  1. 图片内容校验(核心):

    • 使用imagecreatefromjpeg()/imagecreatefrompng()/imagecreatefromgif()重新渲染图片(图片打散):读取图片像素重新生成,清除嵌入的 PHP 代码;
    • 校验文件头:图片文件头固定(PNG:89 50 4E 47,JPG:FF D8 FF,GIF:47 49 46),非合法头直接拦截;
  2. 图片打散进阶:

    • 原理:重新绘制图片像素,破坏嵌入的文本代码(如笔记中 “比对后修改未打散部分”);

    • 示例代码(PHP GD 库):

      1
      2
      3
      4
      // 打散PNG图片,清除嵌入代码
      $img = imagecreatefrompng('malicious.png');
      imagepng($img, 'safe.png'); // 重新生成图片,代码被清除
      imagedestroy($img);
  3. 禁止文件包含上传目录:配置php.ini,设置open_basedir限制包含路径,禁止包含upload目录。

(三)逻辑漏洞防御(文件竞争)

  1. 文件竞争漏洞原理

服务端逻辑:先上传文件到临时目录→校验文件→合法则保留,非法则删除;攻击者利用 “上传后 - 删除前” 的时间差,快速访问文件执行代码。

  1. 防御方法
  • 先校验后上传:先读取文件内容校验,合法再写入服务器,而非先上传再校验;
  • 临时文件加密:上传的临时文件重命名为随机字符串,攻击者无法猜测路径;
  • 缩短校验窗口期:优化代码逻辑,减少 “上传 - 校验 - 删除” 的时间间隔。

漏洞利用流程

  1. 信息收集:判断服务器系统(Windows/Linux)、Web 中间件(Apache/Nginx/IIS)、PHP 版本;
  2. 校验探测:依次测试前端校验、Content-Type、黑名单 / 白名单规则;
  3. 制作恶意文件:根据规则制作图片马 / 变种后缀 PHP 文件;
  4. 上传文件:抓包改包绕过校验,上传到服务器;
  5. 执行代码:通过文件包含 / 路径访问执行恶意文件,获取服务器权限。

工具与辅助技巧

  1. 抓包工具:Burp Suite(拦截修改请求)、Fiddler;
  2. 图片马制作:
    • Windows:copy 1.png /b + shell.php /a 1.png
    • Linux:cat 1.png shell.php > 1.png
  3. 后缀检测:通过phpinfo()查看extensionmime.types配置;
  4. 权限检测:上传后通过file_exists()/is_executable()判断文件状态。

总结

文件上传漏洞的核心是 “校验逻辑的缺陷”,防御需从 “源头控制”(白名单)、“过程拦截”(内容校验)、“结果限制”(权限 / 路径)三层入手;而攻击者的核心思路是 “逐层突破校验”,结合服务器环境特性(Windows/Linux、PHP 版本)选择绕过方法,最终通过文件包含等漏洞执行恶意代码。