文件上传
文件上传
知识点一览
前端 js 验证,pass01,抓包改包/禁用js
content_type验证,pass02,抓包改包
黑名单验证
- windows :自动删除这些符号
- 空格,pass06
- ::$DATA,
- .(点),
- 大小写,pass05,
- php%00截断(php5.2),
- .htaccess 伪静态,pass04
- user.ini
- 修改配置项,使得.php3/.phtml/.任意后缀,被当作.php,pass03
- windows :自动删除这些符号
replace过滤
- 双写绕过
白名单
- 上传路径可控
- %00截断(php5.2),只会执行%00之前的内容
- 上传路径可控
文件包含
图片码

图片码防御
- 取消 upload 文件夹可执行权限
- imagecreatefromjpeg 图片打散
图片打散
- 比对后,修改未打散部分
- 找大佬代码,Injection points in popular image formats
文件竞争,逻辑漏洞
文件上传漏洞
定义
文件上传漏洞是指 Web 应用未对上传文件的类型、内容、路径等做严格校验,导致攻击者可上传恶意文件(如 PHP 后门、图片马)到服务器,进而执行代码、控制服务器的高危漏洞,是渗透测试中最常见的攻击手段之一。
校验维度与绕过方法
(一)前端校验(客户端校验)
- 校验方式
通过 JavaScript 校验文件后缀、大小、类型(如onchange事件判断扩展名),仅在浏览器端拦截,无服务端验证。
- 绕过方法(pass01)
- 禁用 JavaScript:浏览器 F12→设置→禁用 JS,或用插件(如 NoScript);
- 抓包改包:先上传合法文件(如
1.jpg),通过 Burp Suite 拦截请求,修改文件名 / 内容为恶意文件(如1.php); - 本地修改 HTML:删除前端校验的 JS 代码,再上传。
(二)Content-Type 校验
- 校验方式
服务端读取请求头Content-Type(如image/jpeg、application/x-php)判断文件类型,仅校验头信息不校验文件内容。
- 绕过方法(pass02)
抓包修改Content-Type:
- 上传
1.php时,Burp 拦截后将Content-Type: application/x-php改为image/jpeg/image/png等合法图片类型; - 常见合法 Content-Type:
image/jpeg、image/png、image/gif、application/octet-stream。
(三)黑名单校验(服务端核心校验)
服务端维护 “禁止上传的后缀列表”(如php、asp、jsp),拦截匹配的文件,绕过核心是 “绕开黑名单规则”。
| 绕过场景 | 原理与绕过方法(对应笔记 pass) | 适用环境 / 注意事项 |
|---|---|---|
| 1. 大小写绕过(pass05) | 黑名单仅匹配小写(如php),修改为Php/PHP/pHp | 适用于未统一大小写的校验逻辑(如仅用strtolower但未处理) |
| 2. 特殊符号绕过(Windows) | Windows 系统对文件名的特殊处理:- 空格绕过:1.php(后缀后加空格,Windows 自动忽略)- 点绕过:1.php.(后缀后加点,Windows 自动截断)- ::$DATA绕过:1.php::$DATA(Windows 保留数据流,仅执行::$DATA前内容) | 仅适用于 Windows 服务器;部分中间件(如 IIS)兼容此特性 |
| 3. 截断绕过(%00) | 利用 PHP 解析器漏洞(PHP5.2 及以下),%00代表字符串结束符:- 文件名:1.php%00.jpg(服务端仅识别1.php,后缀显示为jpg)- 路径截断:上传路径可控时,upload/1.php%00/1.jpg | PHP5.3 及以上已修复;需确保magic_quotes_gpc=off |
| 4. 后缀变种绕过(pass03) | 黑名单仅拦截php,利用 PHP 解析后缀:- 变种后缀:php3/php4/php5/phtml/phps- 配置修改:攻击者通过漏洞修改httpd.conf,使.xxx后缀被解析为 PHP | 需服务器配置支持(如 Apache 开启AddType application/x-httpd-php .php3) |
| 5. .htaccess 绕过(pass04) | 上传.htaccess文件(Apache 配置文件),强制服务器解析指定后缀为 PHP:apache<br><FilesMatch "1.jpg"> <br>SetHandler application/x-httpd-php <br></FilesMatch><br>上传1.jpg(内含 PHP 代码),会被解析为 PHP | 仅适用于 Apache 服务器;需上传目录可写、.htaccess未被黑名单拦截 |
| 6. user.ini 绕过 | user.ini是 PHP 的用户级配置文件,可设置auto_prepend_file=1.jpg(自动包含1.jpg),上传1.jpg(含 PHP 代码)即可执行 | 适用于 PHP 环境(FastCGI 模式);user.ini需放在网站根目录 / 上传目录,且目录有执行权限 |
| 7. 双写绕过(replace 过滤) | 校验逻辑用str_replace('php', '', $name)删除php,双写后缀:1.pphphp(替换后变为1.php) | 适用于仅单次替换的过滤逻辑(多次替换需多层双写) |
(四)白名单校验
服务端仅允许 “指定后缀列表”(如jpg/png/gif),绕过核心是 “在合法后缀文件中嵌入恶意代码”。
- 核心绕过手段:图片马(文件包含配合)
- 原理:将 PHP 恶意代码嵌入图片文件(如
1.png),上传后通过 “文件包含漏洞” 执行图片中的 PHP 代码; - 制作方法(Windows):
copy 1.png /b + shell.php /a malicious.png(二进制合并图片和 PHP 代码); - 执行条件:需存在文件包含漏洞(如
include($_GET['file'])),访问?file=upload/malicious.png即可执行代码。
- 路径可控 %00 截断(笔记补充)
白名单限制后缀为jpg,但上传路径可控时:
- 上传文件名:
1.jpg,抓包修改路径为upload/1.php%00/1.jpg; - 服务器保存路径为
upload/1.php(%00截断),后缀仍符合白名单,文件实际为 PHP 恶意文件。
文件包含漏洞
(图片马执行的核心依赖)
定义
服务端使用include/require等函数包含文件时,未校验文件路径 / 类型,导致攻击者可包含恶意文件(如图片马)执行代码。
图片马执行流程
1 | 制作图片马(png+PHP代码)→ 上传图片马到服务器 → 利用文件包含漏洞(如?file=upload/malicious.png)→ 服务器解析图片中的PHP代码 → 执行恶意操作 |
文件包含函数
include()、require()、include_once()、require_once()、file_get_contents()(配合eval执行)。
防御方案
(一)基础防御(通用规则)
- 前后端双重校验:前端校验仅做体验优化,核心校验在服务端;
- 统一校验规则:
- 文件名统一转为小写(
strtolower),避免大小写绕过; - 过滤 / 转义特殊字符(空格、点、
::$DATA、%00);
- 文件名统一转为小写(
- 后缀校验优先用白名单:仅允许
jpg/png/gif等合法后缀,拒绝黑名单; - 独立上传目录:
- 上传目录与网站执行目录分离(如
/upload和/www分开); - 取消上传目录可执行权限(核心!):
chmod 644 upload/(仅读 / 写,无执行权限);
- 上传目录与网站执行目录分离(如
- 重命名文件:上传后随机重命名(如
md5(时间戳+随机数).jpg),避免攻击者控制文件名 / 路径。
(二)图片马专项防御
图片内容校验(核心):
- 使用
imagecreatefromjpeg()/imagecreatefrompng()/imagecreatefromgif()重新渲染图片(图片打散):读取图片像素重新生成,清除嵌入的 PHP 代码; - 校验文件头:图片文件头固定(PNG:
89 50 4E 47,JPG:FF D8 FF,GIF:47 49 46),非合法头直接拦截;
- 使用
图片打散进阶:
原理:重新绘制图片像素,破坏嵌入的文本代码(如笔记中 “比对后修改未打散部分”);
示例代码(PHP GD 库):
1
2
3
4// 打散PNG图片,清除嵌入代码
$img = imagecreatefrompng('malicious.png');
imagepng($img, 'safe.png'); // 重新生成图片,代码被清除
imagedestroy($img);
禁止文件包含上传目录:配置
php.ini,设置open_basedir限制包含路径,禁止包含upload目录。
(三)逻辑漏洞防御(文件竞争)
- 文件竞争漏洞原理
服务端逻辑:先上传文件到临时目录→校验文件→合法则保留,非法则删除;攻击者利用 “上传后 - 删除前” 的时间差,快速访问文件执行代码。
- 防御方法
- 先校验后上传:先读取文件内容校验,合法再写入服务器,而非先上传再校验;
- 临时文件加密:上传的临时文件重命名为随机字符串,攻击者无法猜测路径;
- 缩短校验窗口期:优化代码逻辑,减少 “上传 - 校验 - 删除” 的时间间隔。
漏洞利用流程
- 信息收集:判断服务器系统(Windows/Linux)、Web 中间件(Apache/Nginx/IIS)、PHP 版本;
- 校验探测:依次测试前端校验、Content-Type、黑名单 / 白名单规则;
- 制作恶意文件:根据规则制作图片马 / 变种后缀 PHP 文件;
- 上传文件:抓包改包绕过校验,上传到服务器;
- 执行代码:通过文件包含 / 路径访问执行恶意文件,获取服务器权限。
工具与辅助技巧
- 抓包工具:Burp Suite(拦截修改请求)、Fiddler;
- 图片马制作:
- Windows:
copy 1.png /b + shell.php /a 1.png; - Linux:
cat 1.png shell.php > 1.png;
- Windows:
- 后缀检测:通过
phpinfo()查看extension、mime.types配置; - 权限检测:上传后通过
file_exists()/is_executable()判断文件状态。
总结
文件上传漏洞的核心是 “校验逻辑的缺陷”,防御需从 “源头控制”(白名单)、“过程拦截”(内容校验)、“结果限制”(权限 / 路径)三层入手;而攻击者的核心思路是 “逐层突破校验”,结合服务器环境特性(Windows/Linux、PHP 版本)选择绕过方法,最终通过文件包含等漏洞执行恶意代码。
