PHP伪协议
在对网站进行安全测试时,常常会通过目标站点存在的文件包含漏洞读取目标服务器中的重要配置文件信息上传木马文件从而达到最理想的控制目标服务器的效果。为了更好的利用该漏洞,对相关知识进行总结
0x00 常见文件包含函数
- include、include_once、require、require_once
# 当一个文件被包含时,语法解析器在目标文件的开头脱离 PHP 模式并进入 HTML 模式,到文件结尾处恢复,由于此原因,目标文件中需要作为 PHP 代码执行的任何代码都必须被包括在有效的PHP起始和结束标记之中。
- highlight_file、show_source
# 读取目标filename的文件内容,返回高亮版本的代码
- readfile
# 读取文件并写入到输出缓冲,成功时返回从文件中读入的字节数。可使用该函数通过设置header强制下载文件
- file、file_get_contents
# 把整个文件读入一个数组中,后者则是以字符串形式获取文件的内容
- fopen
# 如果参数 filename
是 "scheme://..." 的格式,则被当成一个 URL,如果 PHP 认为 filename
指定的是一个已注册的协议,而该协议被注册为一个网络 URL,PHP 将检查并确认 allow_url_fopen 已被激活。如果关闭了,PHP 将发出一个警告,而 fopen 的调用则失败
PS:以上函数在一些情况下均受 safe_mode、open_basedir、allow_url_fopen、allow_url_include 限制。然而,在 PHP 5.4 中 safe_mode 被移除
0x01 进行文件包函时的两种情况
- 不需对被包含的文件名进行截断
<?php include($_GET['file']) ?>
包含方式:http://www.example.com?file=filename
- 需对被包含的文件名进行截断
<?php include($_GET['file'].'.php') ?>
包含方式:http://www.example.com?file=filename%00
或使用 ? 号截断:在路径最后输入 ? 号:ep: "http://www.xxx.com/xxx.php?parameter=value?" ,这时服务器会将 ?号后的内容解析为GET方法传递的参数
或使用 #(%23)、空格(%20)绕过
PS:PHP在5.3.4中已修复了%00截断的问题,因此%00截断适用于<5.3.4版本
0x02 PHP常用伪协议
- 【 file:// 】协议:
说明:文件系统 是 PHP 使用的默认封装协议,用于读取本地文件系统,当指定了一个相对路径(不以/、\、\\或 Windows 盘符开头的路径)提供的路径将基于当前的工作目录
用法:
协议概要:
- 【php://】协议:
说明:访问各个输入/输出流。允许访问 PHP 的输入输出流、标准输入输出和错误描述符, 内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器
-
- 【php://input】----->访问请求的原始数据的只读流
说明:可以读取到发送的请求没有被解析的原始数据,enctype="multipart/form-data"
的时候 php://input 是无效的(可以将其认为是远程文件包含的一种,为什么是远程文件呢,以下示例做出验证)
验证:
# 测试文件 include.php
<?php include('<?php phpinfo(); ?>'); ?>
# 修改测试文件 <?php $file = $_GET['file']; include($file); ?>
用法:
# 测试文件
<?php echo $postdata = file_get_contents($_GET["a"]); ?>
利用该协议写入木马文件到目标服务器:(写入位置以当前被访问文件位置做参考)
# 测试文件 include.php <?php $file = $_GET['file']; include($file); ?>
利用该协议执行系统命令:
协议概要:allow_url_fopen:不受该项限制
allow_url_include:必须为开启状态
-
- 【php://filter】---->元封装器, 设计用于数据流打开时的筛选过滤应用。
说明:这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。此时该协议就可发挥作用,常使用该函数读取一些关键文件源代码
参数介绍:
用法:
# 测试文件 include.php <?php $file = $_GET['file']; include($file); ?>
# 测试文件 phpinfo.php
<?php
phpinfo();
?>
协议概要:
- 【data://协议】---->允许将小的数据项作为“即时”数据包含在内
说明:将原本的include的文件流重定向到了用户可控制的输入流中,简单来说就是在进行文件包含时包含了自定义的输入流,通过自定义输入payload来实现目的
用法:
# 测试文件 include.php <?php $file = $_GET['file']; include($file); ?>
协议概要:
经过测试PHP版本5.2,5.3,5.5,7.0;data:// 协议是是受限于allow_url_fopen的,官方文档上给出的是NO,所以要使用data://协议需要满足双on条件
- 【phar://协议】
说明:php解压缩包的一个函数,不管后缀是什么,都会当做压缩包来解压;PHP > =5.3.0 压缩包需要是zip协议压缩,rar不行,将木马文件压缩后,改为其他任意格式的文件都可以正常使用
用法:可将一句话木马文件压缩后,改为任意后缀名(这里依然使用指针测试)
# 测试文件 include.php <?php $file = $_GET['file']; include($file); ?>
协议概要:
- 【zlib://、bzip2://、zip://协议】---->压缩流
说明:【zlib://、bzip2://、zip://】协议可以访问压缩文件中的子文件
用法:compress.zlib://file.gz
compress.bzip2://file.bz2
zip://archive.zip#dir/file.txt //使用该方法时需在url中将 '#' 改为URL编码形式的%23,否则使用失败
# 测试文件 include.php <?php $file = $_GET['file']; include($file); ?>
zip://协议
协议概要:
声明:本文参考:
https://www.freebuf.com/column/148886.html
https://blog.csdn.net/Vansnc/article/details/82528395