简介
PHP伪协议:是php支持的协议和封装协议。
协议:是通信双方的约定
封装协议:是在实际的数据通信系统中通过对协议的不同的加密方式,实现双方连接
php支持的伪协议
1 | 1 file:// — 访问本地文件系统 |
php://filter
allow_url_fopen off/on
allow_url_include off/on
php://filter可以获取指定文件源码。当它与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,让其不执行,从而任意文件读取
协议参数:
1 | resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流。 |
常用
1 | php://filter/read=convert.base64-encode/resource=xxx.php |
使用的convert.base64-encode,就是一种过滤器
具体一些过滤器请参照本文参考文章:
https://blog.csdn.net/cosmoslin/article/details/120695429
过滤器嵌套php://filter/read=convert.base64-encode/index/resource=flag
,因为要读取,所以是read=过滤器(convert.base64-encode),后面用/隔开index,index是过滤器吗,但是可以嵌套,绕过这样的白名单,实现flag的读取,这里后面会自动加上.php所以不需要加
1 | if(isset($file)) |
死亡exit
死亡exit指的是在进行写入PHP文件操作时,执行了以下函数:
1 | file_put_contents($content, '<?php exit();' . $content); |
1 |
|
$content在开头增加了exit过程,导致即使我们成功写入一句话,也执行不了。那么这种情况下,如何绕过这个“死亡exit”?
思路其实也很简单我们只要将content前面的那部分内容使用某种手段(编码等)进行处理,导致php不能识别该部分就可以了。
这里的$_POST[‘filename’]
是可以控制协议的.
这里就介绍一种绕过,即我们刚学的php://filter配合base64编码:
base64绕过
1 | 首先我们需要清楚的是base64编码中只包含64个可打印字符,而PHP在解码base64时,遇到不在其中的字符时,将会跳过这些字符,仅将合法字符组成一个新的字符串进行解码 |
这里有个疑问,为什么exit那段代码解码后会改变,而我们传入的编码后的一句话解码后为正常php代码
data://
allow_url_fopen on
allow_url_include on
数据流封装器,以传递相应格式的数据。可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行。
示例用法:
1 | 1、data://text/plain, |
范例
#1 打印 data:// 的内容
1 | <?php |
file://
allow_url_fopen off/on
allow_url_include off/on
用于访问本地文件系统
file://协议主要用于访问文件(绝对路径、相对路径以及网络路径)
比如:http://www.xx.com?file=file:///etc/passsword
php://input
allow_url_fopen off/on
allow_url_include on
php://input允许开发者从请求体中获取原始的 POST 数据
1 | eg: |
PHP file_get_contents() 函数:把整个文件读入一个字符串中
注意:碰到file_get_contents()就要想到用php://input绕过
碰到file_get_contents()就要想到用php://input绕过,因为php伪协议也是可以利用http协议的,即可以使用POST方式传数据。file_get_contents():这个函数就是把一个文件里面的东西 (字符)全部return出来作为字符串。除此之外,通过实践我发现这个函数如果直接把字符串当作参数会报错,但如果包含的是http协议的网址,则会像curl命令一样,把源码读出来。而php伪协议也是识别http协议的,所以说上面php://input可以将POST的数据读过来来赋值给参数。
1 | <?php |
php://input(写入木马):
这里有些不理解
学习网址:https://blog.csdn.net/qq_51524329/article/details/121439731