文件上传漏洞¶
文件上传漏洞的本质:服务器没有严格校验上传文件的类型,导致攻击者可以上传 Webshell(.php、.jsp、.asp 等脚本文件)并执行。
前端绕过¶
前端校验就是个纸老虎,全靠浏览器端的 JavaScript 检查,绕过方式很多:
- 删除浏览器事件 — 直接在 DOM 里删掉
onsubmit或onchange的校验函数 - Burp 抓包改后缀 — 先把文件改成
.jpg通过前端,Burp 里再把后缀改回.php - 构造本地表单 — 自己写一个不带校验的 HTML 表单,直接提交到上传接口
- 禁用 JS — Chrome DevTools → Settings → Debugger → 勾选 Disable JavaScript
后端绕过¶
后端校验才是真正的防线,但实现得不好一样能绕。
黑名单绕过¶
黑名单的思路是"禁止 .php、.jsp 这些危险后缀",但总有漏网之鱼:
特殊后缀名¶
有些后缀名不在黑名单里,但服务器照样当代码执行:
| 语言 | 可尝试的后缀 |
|---|---|
| PHP | .php3 .php5 .phtml .pht .phps |
| ASP | .asa .cer .cdx |
| JSP | .jspx .jspf |
前提条件:Apache 配置了这些后缀的处理器,比如:
# 如果有这行配置,上面那些后缀都能当 PHP 执行
AddHandler application/x-httpd-php .php .php3 .php4 .php5 .phtml
# 修复方式:只保留 .php
AddHandler application/x-httpd-php .php
大小写绕过¶
Windows 不区分大小写,.PhP、.pHp 都能被当 PHP 执行,但黑名单可能只禁了小写的 .php。
双写绕过¶
如果后端只做了一次替换(把 php 替换为空),可以用 .pphphp — 替换后变成 .php。
点和空格绕过(Windows)¶
Windows 会自动去掉文件名末尾的点和空格:
shell.php.→ 保存为shell.phpshell.php→ 保存为shell.phpshell.php::$DATA→ NTFS 数据流,保存为shell.php
.htaccess 绕过¶
如果能上传 .htaccess,就能让任意后缀被当 PHP 执行:
上传这个 .htaccess 后,再上传一个 .jpg 的 Webshell 就能执行了。
白名单绕过¶
白名单比黑名单安全得多,但也不是绝对的:
%00 截断¶
PHP < 5.3.4 且 magic_quotes_gpc = Off 时有效:
解析漏洞¶
不同 Web 服务器的解析特性可以利用:
| 服务器 | 解析漏洞 | 示例 |
|---|---|---|
| Apache | 从右往左解析后缀,遇到不认识的继续往左 | shell.php.xxx → 当 PHP 执行 |
| IIS 6.0 | 分号截断 | shell.asp;.jpg → 当 ASP 执行 |
| IIS 6.0 | 目录解析 | /shell.asp/1.jpg → 当 ASP 执行 |
| Nginx | 路径解析(配置不当时) | /upload/1.jpg/1.php → 当 PHP 执行 |
MIME 类型绕过¶
如果只检查 Content-Type,Burp 里改成图片类型就行:
文件头绕过¶
如果检查文件内容的魔术字节(Magic Number),在 Webshell 前面加上图片文件头:
或者用 copy 命令把图片和 Webshell 合并:
防御建议¶
| 措施 | 说明 |
|---|---|
| 白名单校验 | 只允许业务需要的文件类型 |
| 文件内容检查 | 校验 Magic Number,不能只看后缀和 MIME |
| 重命名文件 | 用随机文件名,去掉原始后缀 |
| 存储隔离 | 上传目录不给执行权限,最好放对象存储(OSS) |
| 独立域名 | 上传文件用单独域名提供访问,防止同域 Cookie 泄露 |