0%

文件包含漏洞笔记

参考:Web安全实战系列:文件包含漏洞

文件包含简介

服务器执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当PHP来执行,这会为开发者节省大量的时间。这意味着您可以创建供所有网页引用的标准页眉或菜单文件。当页眉需要更新时,您只更新一个包含文件就可以了,或者当您向网站添加一张新页面时,仅仅需要修改一下菜单文件(而不是更新所有网页中的链接)。

文件包含函数

PHP中文件包含函数有以下四种:

1
2
3
require():执行到include时才包含文件,找不到被包含文件时只会产生警告,脚本将继续执行
nclude():只要程序一运行就包含文件,找不到被包含的文件时会产生致命错误,并停止脚本
require_once(), include_once():若文件中代码已被包含则不会再次包含

漏洞产生原因

文件包含函数加载的参数没有经过过滤或者严格的定义,可以被用户控制,包含其他恶意文件,导致了执行了非预期的代码。

示例代码

1
2
3
4
<?php
$filename = $_GET['filename'];
include($filename);
?>

例如:

$_GET['filename']参数开发者没有经过严格的过滤,直接带入了include的函数,攻击者可以修改$_GET['filename']的值,执行非预期的操作。

文件包含分类

本地文件包含(LFI)

包含服务器上的资源

远程文件包含(RFI)

PHP的配置文件allow_url_fopen和allow_url_include设置为ON,include/require等包含函数可以加载远程文件,如果远程文件没经过严格的过滤,导致了执行恶意文件的代码,这就是远程文件包含漏洞。

1
2
allow_url_fopen = On(是否允许打开远程文件)
allow_url_include = On(是否允许include/require远程文件)

漏洞利用

读取敏感文件

测试代码:

1
2
3
4
<?php
$a = $_GET['id'];
include($a);
?>

网页测试:

其它文件:

常见的敏感信息路径:

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 配置文件

文件包含可以结合文件上传漏洞,上传一句话木马图片,然后利用文件包含漏洞来包含这个文件

session文件包含漏洞

利用条件: session的存储位置可以获取

session文件包含漏洞复现

PHP伪协议

php://filter(本地磁盘文件进行读取)

元封装器,设计用于”数据流打开”时的”筛选过滤”应用,对本地磁盘文件进行读写。

用法:

1
2
?filename=php://filter/convert.base64-encode/resource=xxx.php 
?filename=php://filter/read=convert.base64-encode/resource=xxx.php

php://input (读取POST数据)

碰到file_get_contents()就要想到用php://input绕过,因为php伪协议也是可以利用http协议的,即可以使用POST方式传数据,具体函数意义下一项;

data://伪协议

数据流封装器,和php://相似都是利用了流的概念,将原本的include的文件流重定向到了用户可控制的输入流中,简单来说就是执行文件的包含方法包含了你的输入流,通过你输入payload来实现目的;

其它参考:PHP伪协议总结

漏洞绕过

测试代码:

1
2
3
4
<?php
$a=$_GET['id'];
include($a.".html");
?>

利用条件

magic_quotes_gpc = Off && php版本<5.3.4

网页测试:

参考:任意文件包含漏洞的绕过方式

漏洞防御

  • 设置白名单
    代码在进行文件包含时,如果文件名可以确定,可以设置白名单对传入的参数进行比较。
  • 过滤危险字符
    由于Include/Require可以对PHP Wrapper形式的地址进行包含执行(需要配置php.ini),在Linux环境中可以通过”../../”的形式进行目录绕过,所以需要判断文件名称是否为合法的PHP文件。
  • 设置文件目录
    PHP配置文件中有open_basedir选项可以设置用户需要执行的文件目录,如果设置目录的话,PHP仅仅在该目录内搜索文件。
  • 关闭危险配置
    PHP配置中的allow_url_include选项如果打开,PHP会通过Include/Require进行远程文件包含,由于远程文件的不可信任性及不确定性,在开发中禁止打开此选项,PHP默认是关闭的。