文件包含漏洞(更新)
什么是文件包含漏洞?
在PHP中,我们为了使代码更灵活,往往将可重复使用的代码通过文件包含函数包含起来,进行动态调用,文件包含函数的参数没有经过严格的过滤,可以包含其他恶意文件,造成文件包含漏洞。
代码分析
|
把一个GET请求的参数name传给了一个变量file,然后包含了这个变量。但是,PHP并没有对$_GET[‘name’]参数进行严格过滤,被include函数直接包含,我们可以修改$_GET[‘name’]的值,包含自己想看的文件。
文件包含函数
- include():遇到包含文件不存在,或是出错的时候,不停止运行,并报错,
include
结构会发出一条E_WARNING
- include_once():唯一区别是如果该文件中已经被包含过,则不会再次包含,且 include_once 会返回
true
- require():遇到包含文件不存在,或是出错的时候,就停止运行,并报错,在出错时产生
E_COMPILE_ERROR
级别的错误 - require_once:唯一区别是 PHP 会检查该文件是否已经被包含过,如果是则不会再次包含
读取文件函数
highlight_file(高亮),show_source,readfile,file_get_contents(读取远程文件),fopen,file
文件包含漏洞利用条件
1.需要在php.ini中设置两个参数:
allow_url_fopen=on file_get_contents()读取
allow _url_include=on include,require包含远程文件
2.文件包含函数中存在动态变量
3.能够控制动态变量
版本
PHP4存在远程和本地包含,PHP5只存在本地包含(bushi),应该是开启allow _url_include=on 都可以进行远程文件包含
感谢订正,i了😍 传送门
文件包含漏洞分类
LFI(Local File Inclusion)
本地文件包含漏洞,顾名思义,指的是能打开并包含本地文件的漏洞。大部分情况下遇到的文件包含漏洞都是LFI。
- 包含同目录下的文件
- 目录遍历 ../../../../
- 包含图片木马
- 包含日志
- 00截断
- 日志默认路径
- web中间件默认配置
- 包含session
- 包含/proc/self/environ文件
- 包含临时文件
- 包含data:或php://input等伪协议
在本地文件WWW目录下面新建一个文件夹为include
include.php
|
index.php
|
在include.php里面写入一句话木马,用蚁剑连接,就会得到整个目录
查看上传日志文件,也可以把一句话木马传到日志里面
RFI(Remote File Inclusion)
远程文件包含漏洞。是指能够包含远程服务器上的文件并执行。由于远程服务器的文件是我们可控的,因此漏洞一旦存在危害性会很大。
要实现远程文件包含需要allow_url_fopen和allow_url_include都开启
- http
- https
- ftp
文件包含漏洞姿势
PHP伪协议
1 file:// — 访问本地文件系统 |
php://filter
php://filter是一种元封装器,是PHP中特有的协议流,设计用于数据流打开时的筛选过滤应用,作用是作为一个“中间流”来处理其他流。
php://filter四个参数:
名称 | 描述 |
---|---|
resource=<要过滤的数据流> | 这个参数是必须的。它指定了你要筛选过滤的数据流。 |
read=<读链的筛选列表> | 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。 |
write=<写链的筛选列表> | 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。 |
<;两个链的筛选列表> | 任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。 |
过滤器:
1.字符串过滤器
字符串过滤器 | 作用 |
---|---|
string.rot13 | 等同于str_rot13() ,rot13变换 |
string.toupper | 等同于strtoupper() ,转大写字母 |
string.tolower | 等同于strtolower() ,转小写字母 |
string.strip_tags | 等同于strip_tags() ,去除html、PHP语言标签 |
2.转换过滤器
转换过滤器 | 作用 |
---|---|
convert.base64-encode & convert.base64-decode | 等同于base64_encode() 和base64_decode() ,base64编码解码 |
convert.quoted-printable-encode & convert.quoted-printable-decode | quoted-printable 字符串与 8-bit 字符串编码解码 |
3.压缩过滤器
压缩过滤器 | 作用 |
---|---|
zlib.deflate & zlib.inflate | 在本地文件系统中创建 gzip 兼容文件的方法,但不产生命令行工具如 gzip的头和尾信息。只是压缩和解压数据流中的有效载荷部分。 |
bzip2.compress & bzip2.decompress | 同上,在本地文件系统中创建 bz2 兼容文件的方法。 |
4.加密过滤器
加密过滤器 | 作用 |
---|---|
mcrypt.* | libmcrypt 对称加密算法 |
mdecrypt.* | libmcrypt 对称解密算法 |
读取数据: |
php://input
php://input是php语言中一个只读的数据流;通过”php://input”,可以读取从Http客户端以POST方式提交、请求头“Content-Type”值非*”multipart/form-data*“**的所有数据;”php://input”一般用来读取POST上来,除已被处理以外的剩余数据。
include($_GET['file']); |
php://input + [POST DATA]
执行PHP代码
GET: ?file=php://input |
file:// 协议
用于访问本地文件系统,在CTF中通常用来读取本地文件
file://
文件系统是 PHP 使用的默认封装协议,展现了本地文件系统。当指定了一个相对路径(不以/、、\或 Windows 盘符开头的路径)提供的路径将基于当前的工作目录。在很多情况下是脚本所在的目录,除非被修改了。使用 CLI 的时候,目录默认是脚本被调用时所在的目录。在某些函数里,例如fopen()
和file_get_contents()
,include_path
会可选地搜索,也作为相对的路径。
linux下:?file=file:///etc/passwd |
/path/to/file.ext |
- [文件的相对路径和文件名] ?file=./phpinfo.txt
- file://[文件的绝对路径和文件名] ?file=file://D:\phpstudy\www\phpinfo.txt
- [http://网络路径和文件名] ?file=http://127.0.0.1/phpinfo.txt (常规 URL 形式,允许通过
HTTP 1.0
的 GET方法,以只读访问文件或资源。CTF中通常用于远程包含。)
data:// 协议
自
PHP>=5.2.0
起,可以使用data://
数据流封装器,以传递相应格式的数据。通常可以用来执行PHP代码。
data://text/plain, |
zip:// & bzip2:// & zlib:// 协议
zip:// & bzip2:// & zlib://
均属于压缩流,可以访问压缩文件中的子文件,更重要的是不需要指定后缀名,可修改为任意后缀:jpg png gif xxx
等等。
zip://[压缩文件绝对路径]%23[压缩文件内的子文件名]
(#编码为%23)
压缩 phpinfo.txt 为 phpinfo.zip ,压缩包重命名为 phpinfo.jpg ,并上传
http://127.0.0.1/include.php?file=zip://E:\phpStudy\PHPTutorial\WWW\phpinfo.jpg%23phpinfo.txt |
compress.bzip2://file.bz2 |
压缩 phpinfo.txt 为 phpinfo.bz2 并上传(同样支持任意后缀名)
http://127.0.0.1/include.php?file=compress.bzip2://E:\phpStudy\PHPTutorial\WWW\phpinfo.bz2 |
compress.zlib://file.gz |
压缩 phpinfo.txt 为 phpinfo.gz 并上传(同样支持任意后缀名)
http://127.0.0.1/include.php?file=compress.zlib://E:\phpStudy\PHPTutorial\WWW\phpinfo.gz |
ftp://
ftp:// – ftps:// — 访问 FTP(s) URLs
允许通过 FTP 读取存在的文件,以及创建新文件。 如果服务器不支持被动(passive)模式的 FTP,连接会失败。
打开文件后你既可以读也可以写,但是不能同时进行。 当远程文件已经存在于 ftp 服务器上,如果尝试打开并写入文件的时候, 未指定上下文(context)选项 overwrite,连接会失败。 如果要通过 FTP 覆盖存在的文件, 指定上下文(context)的 overwrite 选项来打开、写入。 另外可使用 FTP 扩展来代替。
如果你设置了 php.ini 中的 from 指令, 这个值会作为匿名(anonymous)ftp 的密码。
http://example.com |
phar:// 协议
这个就是php解压缩报的一个函数,不管后缀是什么,都会当做压缩包来解压,用法:?file=phar://压缩包/内部文件
http://127.0.0.1/include.php?file=phar://E:/phpStudy/PHPTutorial/WWW/phpinfo.zip/phpinfo.txt |