0x01 简介
程序员在通过函数进行文件引入时,对引入的文件名没有经过严格的过滤,从而产生了预想之外的文件操作(恶意文件),这就是文件包含漏洞。
文件包含漏洞分为本地文件包含漏洞(LFI)和远程文件包含漏洞(RFI)。
- 本地文件包含漏洞需要满足以下两个条件:
- allow_url_fopen=On
- 用户可以控制动态变量,写入恶意攻击语句
- 远程文件包含漏洞也需要满足两个条件:
- allow_url_fopen=On且allow_url_include=On
- 用户可以控制动态变量
在PHP5.2开始,allow_url_include是默认关闭的,而allow_url_include默认开启。
0x02 File Inclusion - Low
image.png
看到url中带有page、file、filename、dir等字符的时候,就可以随手测一下看是否存在文件包含。
随手尝试了下page=/etc/passwd,果然页面显示出了passwd文件的内容。
还可以page=file:///etc/passwd伪协议来读取文件
看下源代码:
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
?>
emmm,果然没做任何过滤。
0x03 File Inclusion -Medium
尝试了下page=/etc/passwd和page=file:///etc/passwd语句仍然可以获取敏感文件信息,看下源码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 );
?>
是将http://和https://做了转空,同时也将../和..\做了转空,这就限制了远程文件包含和跨目录包含文件。但可以使用双写进行绕过,过滤仍然不够严格。
0x04 File Inclusion -High
使用page=/etc/passwd语句时,提示ERROR: File not found!
image.png
page=file:///etc/passwd伪协议仍然可以成功读取到passwd文件的内容,看下源码先。
<?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://伪协议进行绕过。
0x05 伪协议
-
php://input(接收POST过来的值)
利用条件:- allow_url_include=On
- allow_url_fopen=On
- php版本小于5.3.0
-
php://filter
利用条件:- allow_url_include和allow_url_fopen都不做要求
用法示例:php://filter/read=convert.base64-encode/resource=filename.ext 使用base64编码可以更好的读取到源码
- allow_url_include和allow_url_fopen都不做要求
- data:URL schema
利用条件- allow_url_include=On
- allow_url_fopen=On
- php版本大于5.2
用法示例:data:text/plain,<?php phpinfo();?>
4.file://[绝对路径]
利用条件: - allow_url_include和allow_url_fopen都不做要求
0x06 防御方案
- 写死被包含的文件名,简单粗暴且有效
- 过滤../ ~/等敏感字符
- 关闭allow_url_include等危险参数