Apache 默认原生支持 .phtml/.pht 直接解析 PHP,Nginx/IIS 默认不识别,根源是三者 PHP 运行架构、后缀匹配规则、默认配置完全不同。
.phtml 全称 PHP-HTML,是Apache+PHP环境里可以被 PHP 解析器执行 PHP 代码的后缀。
.pht 本身并不是普通文件后缀,能否执行 PHP 完全取决于 Apache 的 PHP 模块配置。所以 .pht 一般作为次一级试探后缀。
phtml:Apache 为什么默认能解析 phtml
1. 架构:Apache 用 mod_php 内置 PHP 模块
老版本 Apache 采用嵌入式 PHP 模块 mod_php,安装 PHP 后会自动写入一套完整后缀映射正则到配置文件 httpd.conf:
# 内置正则,匹配全部PHP家族后缀
AddHandler application/x-httpd-php .php .php3 .php4 .php5 .pht .phtml
正则简化写法:.+.ph(p[345]?|t|tml) 只要后缀是 .pht / .phtml,Apache 直接交给 PHP 引擎执行,无需额外配置。
2. Apache 独有的「从右往左多后缀解析规则」
识别文件后缀逻辑:从文件名最右侧依次判断,遇到认识的后缀就按该脚本执行。 例如 shell.jpg.phtml → 最右 .phtml 被识别,直接解析 PHP; shell.phtml.123 → 123 不认识,往左读到 .phtml 执行 PHP。
3. 历史原因:phtml 是早年标准混合页后缀
早期 PHP 用来写「HTML+PHP 混编页面」,官方推荐 .phtml 后缀,Apache 配套内置支持,属于历史遗留默认配置。
pht:为什么后端是Apache会考虑次一级试探pht后缀
1. 历史定义层级更低
早期 PHP 后缀谱系:
.php(主程序)> .phtml(HTML 混编页面)> .pht(简易短脚本)
Apache 内置规则虽同时包含三者,但早年网站极少主动使用 .pht,很多管理员会下意识只删除 .phtml 映射、忽略 .pht,存在漏配置空间。
2. 黑名单过滤常只拦截主流后缀
开发做上传黑名单时,大多只写:php、phtml,容易遗忘冷门的 .pht。
- 若后端黑名单:禁止
.php、.phtml,上传shell.pht就能绕过,Apache 依旧解析执行。
3. 部分精简 / 新版 Apache 配置会删减 phtml,但保留 pht
部分运维为安全删减危险后缀映射,注释掉 .phtml,但没清理干净,.pht 仍存在于解析列表,成为备用后门。
4. 区分于 Nginx,仅 Apache 有效,兜底试探
Nginx 默认完全不解析二者,一旦 .phtml 访问返回源码 / 下载,说明不是 Apache 或无 mod_php; 此时尝试 .pht 是最后一次验证中间件:
.pht可执行 → Apache、存在遗漏解析规则;.pht同样下载源码 → 判定为 Nginx/IIS,放弃这类后缀,改用畸形路径、分号截断等其他上传绕过方式。
渗透测试里后缀尝试顺序(Apache 环境)
按成功率由高到低:
.phtml > .pht > .php5 > .phar > .pnt。
- 网站黑名单只过滤
.php,开发忘记过滤这些变种后缀,就是上传漏洞突破口。