PHP 提供了一些杂项输入/输出(IO)流,允许访问 PHP 的输入输出流、标准输入输出和错误描述符, 内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器。(不明白啥子鬼意思)
就是PHP伪协议可以用来作为输入输出,以此来占为己用
php://stdin
相当于打开一个文件指针,可以从输入缓冲区读取输入。
注意要通过命令行打开文件,如果用浏览器访问,输入缓冲区会一直有一个空值造成while永远为真,导致系统卡死
输入的值就赋给变量使用了
php://input
利用该协议可以对某些变量进行赋值使用,在ctf中可能会使用
例子:
!!!!在chrome中的hackbar会把空格POST为+号,具体原因不清楚
通过POST和input伪协议,可以直接给user赋值了
file_get_contents()是用来将文件的内容读入到一个字符串中的首选方法,file_get_contents()的$filename参数不仅仅为文件路径,还可以是一个URL(伪协议)。
file_get_contents() 解析传入字符串发现是伪协议中的php://input,便读取了[POSTDATA]的数据保存为一个字符串。 即通过了验证。
!!!通常这种方法可以用于将文件包含漏洞变成代码执行漏洞。
data://
该伪协议可以用来用get方法给变量传值,可以将文件包含漏洞变成代码执行漏洞并绕过360网站卫士的WAF(需要用base64)。
要求配置文件PHP.ini:
allow_url_fopen No
allow_url_include Yes
用base64
data://text/plain;base64,后面跟base64加密的信息,就可以实现赋值。
不用base64
例如该题:
将后面的php代码传给了page,不仅躲过了while循环,而且进入include执行了代码。
通过该方法就可以获取webshell
php://filter
是php中独有的一个协议,可以作为一个中间流来处理其他流,可以进行任意文件的读取.
例如采用php://filter以base64编码的方式读取指定文件的内容:
php://filter/read=convert.base64-encode/resource=[文件路径]
1、可以利用文件包含漏洞进行源码读取(前提是必须知道文件名).
因为include可以对伪协议进行解析,获得test.php中的源码
然后进行base64解码即可
!!当然也可以不用read进行base64编码,编码的目的是为了绕过
2、进行代码绕过
<?php
show_source(__FILE__);
$c="<?php exit;?>";
@$c.=$_POST['c'];
@$filename=$_POST['file'];
if(!isset($filename))
{
file_put_contents('tmp.php', '');
}
@file_put_contents($filename, $c);
include('tmp.php');
?>
这里<?php exit; ?>会让文件被包含进去时直接退出,所以需要绕过这个代码
首先想到的就可以是base64编码,用filter绕过
因为base64在<?php exit;?>中"<、?、;、>"等符号解码时都会被忽略,所以命令就变成了–> “phpexit”。也就达到了我们绕过了这个函数。之后我们要想执行我们所想的代码,可以在phpexit这七个字符后任意加一个字母(因为base64是4个字符一组进行解码的)。
例如如果要tmp.php内容为:
则将其变为base64:PD9waHAgZWNobyAnaGVsbG8nID8+
然后在phpexit后面加个a,所以c=aPD9waHAgZWNobyAnaGVsbG8nID8+
filename=php://filter/read=convert.base64-decode/resource=tmp.php
file_put_contents函数会建立一个名为tmp.php的文件,然后将c的内容解码后放入tmp.php中
最后include函数执行tmp.php文件中的代码
hello就被打印出来了,前面的乱码是因为前面的exit造成的。
总结
php://input主要用于post,通过某些函数达到文件执行漏洞的目的,并且php不区分大小写
data://主要用于get方式达到文件执行漏洞,多一个传值的方法
php://filter主要就是能对源码进行编/解码,进行合理的绕过。