1. 项目背景与核心价值
"Warmup"是网络安全竞赛平台"攻防世界"中的一道经典入门级题目,这道题被戏称为"胎教版"是因为其难度极低,相当于给完全零基础的新手准备的启蒙教程。作为CTF(夺旗赛)领域的Hello World级别题目,它完美呈现了Web安全中最基础的目录遍历漏洞原理。
我第一次接触这道题时,虽然最终解出了答案,但过程中走了不少弯路——因为当时根本不知道什么是"源码审计",也不懂如何系统性地寻找Web应用的脆弱点。这道题的价值就在于:用最简化的场景,让新手理解黑客如何像"侦探"一样,通过观察、推理、验证来发现系统漏洞。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 题目环境准备与初步侦查
2.1 题目访问与基础信息收集
首先访问题目提供的URL(假设为http://111.198.29.45:31123/),我们看到一个极简的网页,页面上只有一张微笑的GIF图片和"Can you find the flag?"的文字提示。这种 minimalist 的设计本身就是线索——出题人刻意隐藏了所有不必要的信息。
用浏览器开发者工具(F12)检查:
- Network标签显示加载了/index.php和/source.php
- Elements标签显示图片路径为/img/1.gif
- Console和Sources标签没有特别信息
关键技巧:永远先检查/source.php、/robots.txt、/www.zip等常见泄露点,很多CTF题目会故意在这些位置留线索。
2.2 源码审计突破点
访问/source.php果然获取到关键源码:
php复制<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
?>
同时访问/hint.php得到提示:"flag在ffffllllaaaagggg文件中"。现在我们需要理解这段代码的逻辑漏洞。
3. 漏洞原理深度解析
3.1 白名单校验机制分析
代码的核心是checkFile方法,其安全逻辑如下:
- 定义白名单:只允许访问source.php和hint.php
- 检查输入是否为字符串
- 三种验证方式:
- 直接匹配白名单
- 截取?前的部分匹配白名单
- URL解码后截取?前的部分匹配白名单
3.2 目录遍历漏洞利用
关键突破点在于白名单校验的宽松性。虽然限制了文件名,但没有限制路径穿越:
- 尝试访问
/source.php/../../ffffllllaaaagggg - 代码处理流程:
- 提取
source.php/../../ffffllllaaaagggg中?前的部分:source.php source.php在白名单中,通过校验- 实际服务器处理时,
../会返回上级目录,最终访问到根目录下的flag文件
- 提取
原理类比:就像告诉门卫"我是住302室的",但实际拿着302室钥匙去了顶楼机房——门卫只检查了前半句的真实性。
4. 完整解题步骤实录
4.1 构造Payload
根据漏洞原理,我们需要构造一个路径:
- 以白名单文件开头(source.php或hint.php)
- 包含足够的../返回根目录
- 指向真实的flag文件
最终Payload:
code复制http://111.198.29.45:31123/source.php/../../../../ffffllllaaaagggg
4.2 为什么需要四个../?
在Linux系统中:
- /var/www/html/ ← 网站通常部署在这里
- 需要从html目录返回到根目录/
- 每个../返回一级:
- 1个../ → /var/www/
- 2个../ → /var/
- 3个../ → /
- 4个../保证即使路径层级不同也能到根目录
4.3 获取flag
访问构造的URL后,页面直接显示了flag内容,格式通常为:
code复制flag{th1s_1s_4_w4rmup_fl4g}
5. 防御方案与学习延伸
5.1 如何修复这个漏洞?
开发者应该:
- 禁用目录穿越:在php.ini中设置
open_basedir - 严格路径校验:
php复制$realpath = realpath($page);
if(strpos($realpath, '/var/www/') !== 0){
die('非法访问');
}
- 使用绝对路径白名单而非相对路径
5.2 相关漏洞拓展学习
- 文件包含漏洞:require/include的不安全使用
- 任意文件读取:file_get_contents等函数未过滤输入
- PHP封装协议:php://filter的利用技巧
5.3 推荐练习题目
- 攻防世界-Web_php_include:考察php文件包含
- BugKu-文件包含2:需要绕过特殊过滤
- NCTF-2018-easy_upload:结合上传与包含漏洞
6. 新手常见误区与排坑指南
6.1 为什么我的Payload不工作?
可能原因:
- 路径层级不对:尝试增加/减少../数量
- URL编码问题:确保/没有被编码为%2F
- 服务器配置差异:有些环境会过滤../
6.2 进阶技巧:如何确定所需../数量?
- 先尝试访问/source.php/../(应返回400错误或相同页面)
- 逐步增加../直到报错变化
- 使用Burp Suite的Intruder模块自动化测试
6.3 其他可能的flag位置
除了直接访问,还可以尝试:
- 查看页面注释:
- 检查HTTP响应头:X-Flag: ...
- 图片隐写:steghide分析图片
7. 从解题到实战的思维转变
这道题教会我们的核心方法论:
- 信息收集:永远先检查robots.txt、源码注释、常见备份文件
- 代码审计:找到所有用户输入点,分析处理逻辑
- 边界测试:尝试极端输入(超长字符串、特殊字符等)
- 路径操作:注意./和../在不同环境中的表现差异
在实际渗透测试中,这类目录遍历漏洞常出现在:
- 文件下载功能(?file=xxx参数)
- 日志查看接口
- 静态资源加载处
我建议新手在解决这道题后,立即尝试在DVWA或WebGoat等靶场中实践类似漏洞,从解题思维转向实战思维最关键的一步就是:永远多问"如果这个过滤不存在会怎样?"
