【CTF实战】极客大挑战Secret File:PHP文件包含与伪协议的艺术

张开发
2026/4/15 7:17:22 15 分钟阅读

分享文章

【CTF实战】极客大挑战Secret File:PHP文件包含与伪协议的艺术
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这个神器了。为什么它能绕过过滤它的字符串中不包含被禁的关键词它支持编码转换可以避免PHP文件被执行它是PHP内置协议不需要额外扩展具体payload长这样php://filter/readconvert.base64-encode/resourceflag.php这个payload的精妙之处在于用base64编码读取文件内容避免直接执行PHP代码完全避开了所有被过滤的关键词3. 完整漏洞利用实战3.1 构造攻击载荷现在我们知道要使用php://filter但具体怎么用完整的URL应该是/secr3t.php?filephp://filter/readconvert.base64-encode/resourceflag.php访问这个URL后我们会得到flag.php文件的base64编码内容。这时候找个在线base64解码工具或者用命令行echo PD9waHAKJGZsYWcgPSAiZmxhZ3s3ZjFiYzVhNS1hM2ZlLTQ3YjAtOTYzYi1mYjU1ODAwNGJiNTV9IjsKPz4 | base64 -d就能看到flag.php的原始内容了。在我实际测试中得到的flag通常是这样的格式?php $flag flag{7f1bc5a5-a3fe-47b0-963b-fb558004bb55}; ?3.2 为什么这个利用方式有效这个利用方式之所以能成功核心在于PHP文件包含机制的特性include函数不仅可以包含PHP文件还能处理各种流php://filter会在文件内容被包含前先进行编码转换base64编码后的内容不再是有效PHP代码所以不会被执行我们拿到的是文件源码的编码形式安全可靠4. 从攻击看防御4.1 漏洞根源分析这个漏洞的根源在于开发者犯了几个常见错误直接使用用户输入作为包含路径没有校验黑名单过滤机制不完善容易被绕过没有限制包含的文件路径范围4.2 正确的防护措施如果我要修复这个漏洞会采取这些措施使用白名单机制只允许包含特定目录下的文件完全禁用动态包含或者限制包含的文件扩展名如果必须使用动态包含应该这样写$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中我们研究漏洞利用但在实际开发中这些防护经验才是真正宝贵的财富。

更多文章