内容简介:谈一谈文件包含漏洞
[TOC]
什么是文件包含
文件包含这个漏洞,简单来说既是程序猿在开发中为了方便,会将在多个页面重复使用的代码单独写到一个文件中,在需要用到的地方直接包含进来,包含后的文件既相当于将被包含的整个文件内容复制到了包含处。因为在开发中是经常用到的,因此成为了攻击者的目标,便衍生了多种文件包含的攻击。
本地文件包含
先来感受一下,当包含值可被直接控制的情况下是怎么样的如以下代码:
<?php $file = $_GET['file']; include($file);
可看到以上代码,直接包含的 $file
这种情况下呢,就是可控的情况。
先说一下文件包含的一个要点:文件包含可以包含任意文件,即便被包含的文件并不是与当前编程语言相关,甚至为图片,只要被包含的文件,其内容会被包含文件包含,并以包含文件当前语言执行。
首先在当前文件夹内随便创建任意后缀格式的文件,如: file.txt
(就算是图片格式那么效果也是如下)文件内容如下:
<?php phpinof();
文件包含漏洞在支持包含 web
应用内的目录的同时也直冲包含当前服务器内的其它文件,如下: 尝试包含 C盘
里的某个内容。如: C:\WINDOWS\system.ini
可看到是直接被包含进来的。
那么上面说的是传入的文件值为全部可控的情况下的方法,那么如果程序猿在开发中固定死了所包含的文件后缀的话,怎么办?代码如下:
<?php $file = $_GET['file'] . '.php'; echo $file; include($file);
这种情况下,我们按照上面的方法尝试一下,为了方便看到直观效果,这里是将 $file
输出了。
我们可以看到,如果在程序中固定死了后缀,那么就像上图一样,将会找不到需要包含的文件。可看到最后所包含的文件名为: ./include.txt.php
。
因此这就可以使用另一种方法,就是: %00
截断。那么 %00
截断呢,是可以使用在非常多的地方的,这里不多讲。想了解的童鞋可以网上查一查相关资料。
这里先说一下 PHP 中使用 %00
的前提:
- PHP版本 < 5.3 (不包括5.3) ;
- PHP
magic_quotes_gpc = off
; - PHP对所接收的参数,如以上代码的
$_GET['file']
未使用addslashes
函数
因为PHP大于等于5.3的版本已经修复了这个问题,如果开启了 gpc
或者使用了 addslashes
函数的话则会对其进行转义。 首先我们可以试试如果在 gpc
开启的情况下会出现什么情况(效果与使用函数的为一致)
可以看到了。效果是非常的明显。
接下来看看在5.3的情况是什么样的
也可以看到。是没有任何效果的。
因此我们可以得知只要满足以上三种情况,那么就可以使用 %00
; 首先我们将PHP版本更换为5.2,然后在 php.ini
将 magic_quotes_gpc = on
改为 magic_quotes_gpc = off
之后重启 Apache
,在尝试下使用截断。
成功使用截断包含。那么文件包含就只有包含的功能吗?那肯定不是的,既然是文件包含,那么我们可以直接包含一句话。先创建一个文件: shell.txt
内容为一句话。
可以看到,拿 shell
不是什么问题。
那么这两种包含有什么区别呢?其实是没有区别的,原理都一样,只不过第一种是将后缀一起传入,第二种则在程序内固定死了后缀。但是可以使用 %00
因为当程序流遇到 %00
终止符的时候将直接终止。
远程文件包含
本地文件包含与远程文件包含的原理是相同的,不同点就是前者只能包含服务器内存在的文件,后者则可包含远程服务器内的文件。
远程文件包含的注意点:
- 需要
php.ini
内的allow_url_include = on
以及allow_url_fopen=on
- 所需包含的远程文件后缀格式不能以目标服务器的语言相同,如(目标服务器解析PHP代码,那么远程文件后缀格式则不能为
PHP
)
来解释一下第二点:因为如果你的远程文件是 php
后缀的话,那么如果你远程文件内容为:
<?php phpinfo();
那么在目标服务器内拿到的内容则是你的远程服务器执行 phpinfo()
后的一个内容,并不是这段代码,因此包含得到的信息并不是目标服务器的而是你远程服务器的。如下:
这个是我远程机的信息,为php5.6版本,目标机的是5.2版本。接下来包含一下。
可以看到,包含后得到的结果就是我们远程机的,为什么呢?? 因为目标服务器包含的代码并不是:
<?php phpinfo();?>
而是远程服务器执行完这段代码的源代码,如下图:
所以说远程文件包含只有符合了以上两点才能正常包含。 先来修改下:
-
修改配置
-
修改文件后缀
再来包含一下。
可以看到这次包含后返回的信息就是我们目标机的信息。
接下来继续尝试拿shell
远程文件包含的利用前提其实就是符合本地文件包含的前提并且符合远程文件包含本身的前提即可利用。
文件包含之伪协议
伪协议在文件包含的利用,本文演示以下伪协议: data:text/plain
或 data:text/plain;base64
php://input
php://filter
file://
zip://
其它协议可阅读官方文档: 直通车
data:text/plain
直接在对应URL参数内输出:data:text/plain,需要执行的php代码 如下图:
这个伪协议还有另一种使用方法,那么就是将需要执行的php代码使用base64编码:data:text/plain;base64,需要执行的base64php代码 如下图:
php://input
php://input
可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行。
可以看到程序内是固定死后缀的,那么在包含 php://input
的时候就会自动拼接上 .php
所以肯定是不能正常使用 php://input
的。所以我们也是可以使用 %00
截断的
可以看到终止符是非常强大的。
php://filter
php://filter
该伪协议可以读取php文件代码以base64编码输出,比如说我们想读取一个php文件但是不想让它正常php执行代码后的结果,我们想要这个php文件的代码的时候就可以使用这个伪协议。 使用方法:php://filter/read=convert.base64-encode/resource=需要读取的文件代码内容
解码后可得到内容
file://
file://
用于访问本地文件系统,且不受 allow_url_fopen
与 allow_url_include
的影响。 使用方法:file://文件绝对路径
zip://
zip://
可以访问压缩文件中的文件。但是需要绝对路径。 使用方法:zip://[压缩包绝对路径]#[压缩文件内的文件名]
在本地创建一个文件,并且压缩成zip压缩包。
可以看到我已经填写了绝对路径以及文件名称,但是为什么不能成功包含呢,可以看到它的报错 Warning: include(zip://C:/phpStudy/WWW/include/phpinfo.zip.php)
我们并不是包含这个文件,我们是要包含这个zip里面的文件,为什么 #
后面的值没了呢,是因为#会忽略后边的参数,所以我们需要使用编码 %23
的形式,还有一点就是程序里固定死了 php后缀,因为我们压缩的文件是为php后缀的。所以我们就不用带后缀了,如下图:
相关资料
[代码审计]EMLOG v5.3.1 超鸡肋 SQL 注入+本地文件包含 : http://www.bugsafe.cn/archives/130.html
以上所述就是小编给大家介绍的《谈一谈文件包含漏洞》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 60% 的企业代码库包含开源漏洞
- 宜家PDF下载过程本地文件包含漏洞披露
- 甲骨文例行更新修复了301个安全漏洞 包含45个严重漏洞
- 甲骨文例行更新修复了301个安全漏洞 包含45个严重漏洞
- GCC 7.3 发布,包含变种 Spectre 漏洞补丁
- 2018开源代码安全报告:每个代码库平均包含64个漏洞
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。