文件包含漏洞
漏洞简介
- 简介:服务器在执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当PHP来执行,这会为开发者节省大量的时间。程序开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,直接调用此文件,无需再次编写,这种调用文件的过程一般被称为文件包含。
- 漏洞原理(成因):在通过动态变量的方式引入需要包含的文件时,用户对这个变量可控而且服务端又没有做合理的校验或者校验被绕过,这就造成了文件包含漏洞。
- 常见包含函数
-
include():找不到被包含的文件时会产生致命错误,并停止脚本运行。
-
include_once():找不到被包含的文件时会产生致命错误,并停止脚本运行。如果该文件中的代码已经被包含,则不会再次包含,即程序只调用一次。
-
require():找不到被包含的文件时只会产生警告,脚本将继续运行。
-
require_once():找不到被包含的文件时只会产生警告,脚本将继续运行。如果该文件中的代码已经被包含,则不会再次包含,即程序只调用一次。
需要注意的是当利用这四个函数来包含文件时,不管文件是什么类型 都会直接作为php文件进行解析。所以不管你怎么修改后缀名都可被解析成功。
-
- 文件包含分类
- 本地文件包含 LFI(Local File Include)
- 远程文件包含 RFI(Remote File Include):需要注意的是php.ini 中的 allow_url_include=on、allow_url_fopen = On
漏洞利用
读取敏感文件
- **访问**`/etc/passwd`:如果目标主机文件存在,并且有相应的权限,那么就可读出文件内容;否则会得到一个类似于:open_basedir restriction in effect的警告
- **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 配置信息
c:\windows\my.ini // MySQL 配置文件
- **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 配置文件
远程包含shell
- 前提:目标主机allow_url_fopen选项是激活的
- 尝试使用一句话木马
- 会在index.php所在的目录下生成shell.php
- eg:
本地包含配合文件上传
使用PHP封装协议
http://cn2.php.net/manual/zh/wrappers.php
file:///var/www/html 访问本地文件系统
ftp://<login>:<password>@<ftpserveraddress> 访问 FTP(s) URLs
data:// 数据流 http:// — 访问 HTTP(s) URLs
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流
zlib:// — 压缩流 data:// — Data (RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP Archive
ssh2:// — Secure Shell 2
rar:// — RAR ogg:// — Audio streams
expect:// — 处理交互式的流
包含Apache日志文件
截断包含
绕过waf防火墙
如何防御
- PHP中使用open_basedir限制访问在指定的目录区域
- 过滤 点 . 反斜杠 / \,防止跨目录
- 禁止服务器远程文件包含
- 尽量不要使用动态包含,可以在需要包含的页面固定写好