文章目录
文件包含(File Inclusion)
参考链接:文件包含漏洞全面详解
什么是文件包含漏洞?
指程序在使用包含文件的函数时,用户可以控制文件包含的参数,而且程序未对传入的值进行严格审查,导致包含了一些具有危害性的脚本代码的漏洞。
常用的文件包含函数有哪些?
require():找不到被包含的文件会产生致命错误,并停止脚本运行
include():找不到被包含的文件只会产生警告,脚本继续执行
require_once()与require()类似:唯一的区别是如果该文件的代码已经被包含,则不会再次包含
include_once()与include()类似:唯一的区别是如果该文件的代码已经被包含,则不会再次包含
文件包含漏洞的分类?
- 本地文件包含漏洞(LFI)
- 远程文件包含(RFI)
文件包含漏洞有哪些防护措施?
1、使用str_replace等方法过滤掉危险字符
2、配置open_basedir,防止目录遍历(open_basedir 将php所能打开的文件限制在指定的目录树中)
3、php版本升级,防止%00截断
4、对上传的文件进行重命名,防止被读取
5、对于动态包含的文件可以设置一个白名单,不读取非白名单的文件。
6、做好管理员权限划分,做好文件的权限管理,allow_url_include和allow_url_fopen最小权限化
DVWA靶场下的文件包含漏洞
Low
查看源码:未作任何防护,存在严重的文件包含漏洞
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
?>
利用文件上传漏洞,我们之前已经上传了图片马webshell3.jpg,于是在这里直接包含,并用hackbar插件给一句话木马的x传值,最终爆出了php版本信息。
payload:
http://192.168.124.91/DVWA/vulnerabilities/fi/?page=../../hackable/uploads/webshell3.jpg
Medium
查看源码:str_replace()函数对【http://】、【https://】、【…/】、【…\】都进行了过滤,替换为空。
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\\" ), "", $file );
?>
绕过方式:
1、双写绕过
2、大小写绕过
3、使用绝对路径
这里我们直接使用绝对路径,同样成功包含图片马webshell.jpg,爆出php版本信息
payload:
http://192.168.124.91/DVWA/vulnerabilities/fi/?page=D:\phpstudy_pro\WWW\DVWA\hackable\uploads\webshell3.jpg
High
查看源码:fnmatch函数对page参数进行了过滤,即上传的文件名必须以file开头才行。如果文件名没有以file开头,并且文件名不等于include.php(即还没有点击时候所在的页面),那么就会返回错误信息,包含失败。
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
// This isn't the page we want!
echo "ERROR: File not found!";
exit;
}
?>
绕过方法:利用本地文件传输协议file,基本格式为 file:///文件路径,于是可以构造url
http://192.168.124.91/DVWA/vulnerabilities/fi/?page=file:///D:\phpstudy_pro\WWW\DVWA\hackable\uploads\webshell3.jpg
同样成功包含图片马webshell.jpg,爆出php版本信息
Impossible
查看源码:发现采用了白名单过滤,规定了传入的文件只能是include.php、file1.php、file2.php、file3.php,那么就杜绝了文件包含漏洞。
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Only allow include.php or file{1..3}.php
if( $file != "include.php" && $file != "file1.php" && $file != "file2.php" && $file != "file3.php" ) {
// This isn't the page we want!
echo "ERROR: File not found!";
exit;
}
?>