PHP官方文档
file:// — 访问本地文件系统 http:// — 访问 HTTP(s) 网址 ftp:// — 访问 FTP(s) URLs php:// — 访问各个输入/输出流(I/O streams) zlib:// — 压缩流 data:// — 数据(RFC 2397) glob:// — 查找匹配的文件路径模式 phar:// — PHP 归档 ssh2:// — 安全外壳协议 2 rar:// — RAR ogg:// — 音频流 expect:// — 处理交互式的流
描述之前,我们先把php.ini的allow_url_fopen 和allow_url_include设置为On。以便对这些伪协议进行分析。
php:// — 访问各个输入/输出流(I/O streams)
php://input:访问请求的原始数据的只读流。 注:当enctype=”multipart/form-data”时,php://input是无效的。
示例:
include会把参数’info’当作文件执行 正常情况下,除非输入的参数刚好是这个目录下的某个文件, 比如我有个名为alert.php的文件 否则就会报错 现在我们利用php://input协议 截取数据包 在最后面,我们加入要执行的代码<?php echo phpinfo(); ?> 这里输入的实际上就是请求的数据,然后它被当作代码执行了。 放包 扩展
<?php echo phpinfo(); ?>
这里有道关于php://input的ctf题,我们提取部分代码进行分析。 链接 简单的代码示例: file_get_contens($data):将文件内容以字符串形式输出
这里的data被当作文件读取,而实际上,后台并不能找到名为"a"的这个文件,所以会报错。
利用php://input绕过
现在我们输入的值为空,返回false
用burpsite进行抓包,在最后面输入我们要传进去的值“xxx”(因为根据源代码,只有data为xxx时,才会返回true) 放包 这个时候,后台得到的数据应该是这样子的 若是修改参数 则会发生和最初一样的报错,文件不存在 也就是说,file_get_contents("php://input")能够获取请求原始数据流。 按照函数的检测逻辑,"php://input"被当作了空的文件来读取,输出的自然也是空字符串。然后,当我们在burpsite上抓包,POST中输入data的时候,后台看见的代码应该是$a ="".$data 但是具体是否如此我也不太清楚,网上并没有找到准确的答案。 像这样的:
file_get_contents("php://input")
$a ="".$data
这样子也可以
经过测试,我发现还有其他一些php伪协议也可以被file_get_contents执行,例如: php://stdout,php://stdin,php://stderr php://output,php://memory,php://temp
示例: 内容并没有被写入。因为php://input是只读流。 换成php://output,只写的数据流
所谓缓冲区就是,临时存放数据的地方。当我们重新访问时,它就会刷新; 当我们修改文件中的内容时,它也会刷新自己的内容。像这里的 $f 实际上并没有被创建到相对路径下,而是被放置在缓冲区。
php://filter是一种元封装器,是PHP中特有的协议流,设计用于数据流打开时的筛选过滤应用,作用是作为一个“中间流”来处理其他流。
php://filter目标使用以下的参数作为它路径的一部分。复合过滤链能够在一个路径上指定。
page=php://filter/read=convert.base64-encode/resource=../../../../../../phpstudy_pro\WWW\feng\php_output.php
得到: PD9waHANCgkNCgkkZj1mb3BlbigicGhwOi8vb3V0cHV0IiwiYSIpOw0KCWZ3cml0ZSgkZiwidGhpcyBpcyBhIHNlbnRlbmNlIik7DQoJZmNsb3NlKCRmKTsNCj8+ 进行base64解码 但是如果是有中文的文件,就不好读取了。base64对中文支持并不友好,需要对中文进行编码之后再转base64。这里我就不尝试了。读取的文件都是非中文的。
PD9waHANCgkNCgkkZj1mb3BlbigicGhwOi8vb3V0cHV0IiwiYSIpOw0KCWZ3cml0ZSgkZiwidGhpcyBpcyBhIHNlbnRlbmNlIik7DQoJZmNsb3NlKCRmKTsNCj8+
php://filter可用于读取包含有敏感信息的PHP等源⽂件,使用base64加密是了防止被浏览器当作XML语言解析,导致出错。
格式:?file=data://text/plain,payload ?> 例1: ?page=data://text/plain,<script>alert(document.cookie)</script> 例2: ?page=data://text/plain,<?php system("ping 127.0.0.1");?> 例3: 如果对特殊字符进行了过滤,可以通过base64编码后再输入 ?page=data://text/plain;base64,PD9waHAgZWNobyBwaHBpbmZvKCk7Pz4=
?file=data://text/plain,payload ?>
?page=data://text/plain,<script>alert(document.cookie)</script>
?page=data://text/plain,<?php system("ping 127.0.0.1");?>
?page=data://text/plain;base64,PD9waHAgZWNobyBwaHBpbmZvKCk7Pz4=
?file=phar://压缩包名/内部文件名 例:phar://x.zip/x.php 步骤:写一个一句话木马shell.php,然后用zip协议压缩为shell.zip, 再将后缀改为png等其他格式
注:php 版本大于等于5.3.0,压缩包需要是zip协议压缩,rar不行,将木马文件压缩后,改为其他任意格式的文件都可以正常使用。
源代码: 压缩(zip) 为了验证zip函数可以将任意文件当作压缩包来解压,我们修改后缀为bb.txt 访问(绝对路径)
这里貌似可以直接访问本地文件(但是phar不能)
更多的协议与相关测试,以后有时间再补充