【CTF实战】极客大挑战Secret File:PHP文件包含与伪协议的艺术
2026/4/15 7:17:20 网站建设 项目流程

1. 从一道CTF题看PHP文件包含漏洞

第一次看到这道题的时候,我差点被它简单的界面给骗了。题目页面就一个静态页面,连个输入框都没有,这怎么玩?但CTF老手都知道,越是这样的题目,越要仔细检查每一个细节。按下F12打开开发者工具,果然在源码里发现了一个隐藏路径"/network"。

这种藏在源码里的线索在CTF中很常见,就像寻宝游戏里的第一个提示。顺着这个路径,我们找到了一个交互页面,但点击按钮后却只显示"查阅结束"。这里就有点意思了——明明什么都没看到,为什么说查阅结束?这时候就该祭出抓包神器Burp Suite了。

2. 深入分析漏洞利用链

2.1 信息收集与漏洞发现

通过Burp抓包,我发现页面加载时还悄悄请求了一个叫"secr3t.php"的文件。访问这个文件后,惊喜来了——直接看到了PHP源码!这种好事在真实渗透测试中可不常见,但在CTF里就是典型的漏洞提示。

源码里最关键的是这行:

include($file);

配合GET参数file,典型的文件包含漏洞。但往下看就发现问题了——开发者设置了过滤规则:

strstr($file,"../") || stristr($file, "tp") || stristr($file,"input") || stristr($file,"data")

这个过滤规则把常见的利用方式都封死了:

  • "../"被禁,不能目录穿越
  • "tp"被禁(不区分大小写),意味着包含".php"文件会被拦截
  • "input"和"data"被禁,封杀了php://input和data://协议

2.2 突破过滤的关键思路

遇到这种过滤,新手可能会卡住。但老司机都知道,PHP的伪协议可不止input和data。这里就要用到php://filter这个神器了。

为什么它能绕过过滤?

  1. 它的字符串中不包含被禁的关键词
  2. 它支持编码转换,可以避免PHP文件被执行
  3. 它是PHP内置协议,不需要额外扩展

具体payload长这样:

php://filter/read=convert.base64-encode/resource=flag.php

这个payload的精妙之处在于:

  • 用base64编码读取文件内容
  • 避免直接执行PHP代码
  • 完全避开了所有被过滤的关键词

3. 完整漏洞利用实战

3.1 构造攻击载荷

现在我们知道要使用php://filter,但具体怎么用?完整的URL应该是:

/secr3t.php?file=php://filter/read=convert.base64-encode/resource=flag.php

访问这个URL后,我们会得到flag.php文件的base64编码内容。这时候找个在线base64解码工具,或者用命令行:

echo "PD9waHAKJGZsYWcgPSAiZmxhZ3s3ZjFiYzVhNS1hM2ZlLTQ3YjAtOTYzYi1mYjU1ODAwNGJiNTV9IjsKPz4=" | base64 -d

就能看到flag.php的原始内容了。在我实际测试中,得到的flag通常是这样的格式:

<?php $flag = "flag{7f1bc5a5-a3fe-47b0-963b-fb558004bb55}"; ?>

3.2 为什么这个利用方式有效

这个利用方式之所以能成功,核心在于PHP文件包含机制的特性:

  1. include函数不仅可以包含PHP文件,还能处理各种流
  2. php://filter会在文件内容被包含前先进行编码转换
  3. base64编码后的内容不再是有效PHP代码,所以不会被执行
  4. 我们拿到的是文件源码的编码形式,安全可靠

4. 从攻击看防御

4.1 漏洞根源分析

这个漏洞的根源在于开发者犯了几个常见错误:

  1. 直接使用用户输入作为包含路径,没有校验
  2. 黑名单过滤机制不完善,容易被绕过
  3. 没有限制包含的文件路径范围

4.2 正确的防护措施

如果我要修复这个漏洞,会采取这些措施:

  1. 使用白名单机制,只允许包含特定目录下的文件
  2. 完全禁用动态包含,或者限制包含的文件扩展名
  3. 如果必须使用动态包含,应该这样写:
$allowed = ['header.php', 'footer.php']; if(in_array($file, $allowed)) { include(__DIR__.'/templates/'.$file); }

在实际开发中,我还遇到过更安全的做法是使用映射表:

$templates = [ 'home' => 'home.tpl', 'about' => 'about.tpl' ]; if(isset($templates[$_GET['page']])) { include(__DIR__.'/templates/'.$templates[$_GET['page']]); }

这种设计既保持了灵活性,又杜绝了任意文件包含的风险。在CTF中我们研究漏洞利用,但在实际开发中,这些防护经验才是真正宝贵的财富。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询