您现在的位置是:网站首页> php专栏 扩展知识

浅析php文件包含漏洞

亦然2019-07-04 16:40:59扩展知识人已围观

简介php文件包含漏洞是一个很常见的php漏洞,文件包含漏洞的产生原因是在通过 PHP 的函数引入文件时,由于传入的文件名没有经过合理的校验,从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意的代码注入。

1.php文件包含漏洞介绍

文件包含漏洞是“代码注入”的一种。其原理就是注入一段用户能控制的脚本或代码,并让服务端执行。“代码注入”的典型代表就是文件包含。文件包含漏洞可能出现在JSP、PHP、ASP等语言中,原理都是一样的,本文只介绍PHP文件包含漏洞。要想成功利用文件包含漏洞进行攻击,需要满足以下两个条件:

  • 1>程序采用include()等文件包含函数通过动态获取变量的方式引入需要包含的文件;
  • 2> 用户能够控制该动态变量。

2.php文件包含函数

在PHP中,有四个用于包含文件的函数,当使用这些函数包含文件时,文件中包含的PHP代码会被执行。下面对它们之间的区别进行解释:

include(): 当使用该函数包含文件时,只有代码执行到include()函数时才将文件包含进来,发生错误时只给出一个警告,继续向下执行。

include_once(): 功能和include()相同,区别在于当重复调用同一文件时,程序只调用一次。

require(): 1.require()与include()的区别在于require()执行如果发生错误,函数会输出错误信息,并终止脚本的运行。

2.使用require()函数包含文件时,只要程序一执行,立即调用文件,而include()只有程序执行到该函数时才调用。

require_once(): 它的功能与require()相同,区别在于当重复调用同一文件时,程序只调用一次。

下面来看一段简单的示例代码:

<?php
    $filename  = $_GET[\'filename\'];
    include($filename);
?>
php

通过上面的代码可以看到,拿到$filename的值后开发者没有进行过滤,直接使用include(),那么攻击者可以修改filename的值,来达到目的。

3.文件包含漏洞利用技巧

远程文件包含漏洞之所以能够执行命令,就是因为攻击者可以自定义被包含的文件内容。因此,本地文件包含漏洞要想执行命令,也需要找一个攻击者能够控制内容的本地文件。

目前主要有几下几种常见的技巧:

1 >包含用户上传的文件

这个很好理解,也是最简单的一种办法。如果用户上传的文件内容中包含PHP代码,那么这些代码被文件包含函数加载后将会被执行。但能否攻击成功,取决于上传功能的设计,比如需要知道上传文件存放的物理路径,还需要上传的文件有执行权限。

2>包含data://或php://input等伪协议

这需要目标服务器支持,同时要求allow_url_fopen为设置为ON。在PHP5.2.0之后的版本中支持data: 伪协议,可以很方便的执行代码。

p3>包含Session文件p

这部分需要攻击者能够控制部分Session文件的内容。PHP默认生成的Session文件一般存放在/tmp目录下。

比如 通过phpinfo的信息,获取到session.save_path为/var/lib/php/session:

p4> 包含日志文件

比如Web服务器的访问日志文件,这是一种通用的技巧。因为几乎所有网站都会将用户的访问记录到访问日志中。因此,攻击者可以向Web日志中插入PHP代码,通过文件包含漏洞来执行包含在Web日志中的PHP代码。下面的安例中就是利用该技巧成功获取到目标网站的WebShell的。但需要注意的是,如果网站访问量大的话,日志文件可能会非常大,这时如果包含一个这么大的文件时,PHP进程可能会卡死。一般网站通常会每天生成一个新的日志文件,因此在凌晨时进行攻击相对来说容易成功。

5>包含/proc/self/environ文件

这个也是一种通用的技巧。因为它根本不需要猜测被包含文件的路径,同时用户也能控制它的内容。常见的做法是向User-Agent中注入PHP代码来完成攻击。

4.文件包含漏洞防范

首先来从代码层来讲,在开发过程中应该尽量避免动态的变量,尤其是用户可以控制的变量。一种保险的做法是采用“白名单”的方式将允许包含的文件列出来,只允许包含白名单中的文件,这样就可以避免任意文件包含的风险。可参考下面的代码实现:

<?php
    $filename = $_GET['filename'];
    switch($filename){
        case 'header';
        case 'footer';
        case 'main';
              include 'var/www/html'.$filename.'php';
              break;
        default:
              include 'var/www/html/main.php';
    }
?>
php

还有一种做法是将文件包含漏洞利用过程中的一些特殊字符定义在黑名单中,对传入的参数进行过滤,但这样有时会因为过滤不全,导致被有经验的攻击者绕过。

很赞哦!()

亦然

亦然(共32篇文章)

愿你我既可以朝九晚五,也可以浪迹天涯;愿你我既可以拈花把酒,也能围炉诗书茶。