PHP伪协议相关

Track-1   ·   发表于 2018-11-12   ·   漏洞文章

首先我要说一句,PHP是世界上最好的语言。


伪协议

PHP官方文档:php.net/manual/zh/wrapp

file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流

我们从最常用的开始分析。 要注意,先把php.ini的allow_url_fopenallow_url_include设置为On,不然会影响伪协议的使用。



php://

php:// — 访问各个输入/输出流(I/O streams)

php://input 访问请求的原始数据的只读流

php://input可以获取到POST的数据,这一点在CTF中常常用到。

这是一道此类题目的wp:blog.csdn.net/niexinmin

也许你还疑惑,为什么用伪协议就可以绕过那个函数的限制? 我们来做个实验,在php文件里写入:

<?php
error_reporting(0);
$str = $_GET['cmd'];

if (isset($str))
{
    $a = file_get_contents($str,'r');
    echo $a;
    echo "</br>";
    var_dump($a);
}
?>

访问http://localhost/test/?cmd=1,页面会输出:



而当你使用php://input绕过时:


会输出:



$data = file_get_contents("php://input");

如果你还有问题,可以去具体翻阅一下PHP的官方文档。

要注意:enctype=”multipart/form-data” 的时候 php://input 是无效的。

php://output 只写的数据流

php://output允许你以 printecho 一样的方式 写入到输出缓冲区。

php://filter 元封装器

重点来了,php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。

我们先看看它的语法:

resource=<要过滤的数据流>   //这个参数是必须的。它指定了你要筛选过滤的数据流。
read=<读链的筛选列表>       //该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
write=<写链的筛选列表>      //该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
<;两个链的筛选列表>        //任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。

我们平时是这样利用它来读取任意文件的:

php://filter/read=convert.base64-encode/resource=flag.php

在这个payload里,convert.base64-encode就是一个过滤器,而flag.php就是要过滤的数据流,也就是要读取的文件。

再来看看我们常会用到的过滤器有哪些。

转换过滤器 convert.*

convert.* 是PHP 5.0.0 添加的,作用顾名思义就是转换==

base64

convert.base64-encode和 convert.base64-decode使用这两个过滤器等同于分别用 base64_encode()和 base64_decode()函数处理所有的流数据。

我们来写个例子:

<?php
error_reporting(0);
$files = $_GET['a'];
include($files);
?>

//flag.php
<?php
echo "Bingo!";
?>

构造payload:

?a=php://filter/read=convert.base64-encode/resource=flag.php



解密后是:



但如果我们把payload换成这样: ?a=php://filter//resource=flag.php



如果你给file参数赋一个字符串,那样会报如下错误:

Warning: include(test): failed to open stream: No such file or directory in C:\phpStudy\WWW\test.php on line 4

可以看到,include函数的运作是这样的:

当有“流”时,包含字符变量时会被直接输出,上面的例子我们可以看作是包含了一个字符变量,即经过base64编码的整个php代码;包含PHP代码时,则会解析执行。

当没有“流”时,则会直接报错。

字符串过滤器 string.*

这个过滤器的作用是对字符串进行各种转换。

有加密的,转换大小写的等等。

更丰富具体的过滤器可以参阅官方文档:php.net/manual/zh/filte

再贴一个p牛的php://filter姿势文章:leavesongs.com/PENETRAT

data://

data:// — 数据(RFC 2397)

data:// 的常用方法一般是: data://text/plain;(base64,base64编码后的字符串)

如利用?file=data:text/plain,<?php phpinfo();?>就可以执行phpinfo().

phar://

phar:// — PHP 归档

官方文档:php.net/manual/zh/wrapp

利用方式:假设你成功上传了一个zip压缩包,里面是一个txt文件,内容是:

<?php phpinfo(); ?>

且存在文件包括漏洞,那么你就可以利用phar://来执行这段代码了,payload为:?phar://test.zip/test.txt



用途

php://input和data://常在CTF里用来绕过一些判断语句;

php://filter可以做任意文件读写

phar://可以留隐藏后门

总结

PHP真是世界上最好的语言。


打赏我,让我更有动力~

0 Reply   |  Until 2018-11-12 | 607 View
LoginCan Publish Content
返回顶部

掌控者 © 2016. All Rights Reserved. 掌控者

Powered by 掌控者 Version 2.1.3