文章目录
一、任意文件读取概述
一些网站的需求,可能会提供文件查看与下载的功能。如果对用户查看或下载的文件没有限制或者限制绕过,就可以查看或下载任意文件。这些文件可以是源代码文件,配置文件,敏感文件等等。
-
任意文件读取会造成(敏感)信息泄露;
-
任意文件读取大多数是由于其他漏洞引发的,如,RCE、目录遍历、文件包含等。
-
任意文件读取与任意文件下载本质上没有区别,信息都是从服务端流向浏览器的。
文件读取与下载可能形式不同,但是从本质上讲读取与下载没有区别,从权限角度来讲,读取与下载都
需要读权限。
1.1 漏洞成因
不管是任意文件读取还是任意文件下载,触发漏洞的条件都是相同的:
- 存在读取文件的功能(函数),也就是说,Web应用开放了文件读取功能;
- 读取文件的路径客户端可控,完全控制或影响文件路径参数;
- 没有对文件路径进行校验或者校验不严导致校验被绕过;
- 输出了文件的内容。
1.2 漏洞危害
下载服务器任意文件,包括源代码文件、系统敏感文件、配置文件等等。
可以配合其他漏洞,构成完整攻击链。对源代码文件进行代码审计,查找更多的漏洞。
任意文件读取与下载重点关注的文件:
- 源代码
- 配置文件
- 敏感文件
- 日志文件
- …
1.3 漏洞分类
- 任意文件读取
- 任意文件下载
1.4 任意文件读取
以PHP脚本为例子,有一些函数可以实现文件读取功能。
1.4.1 文件读取
读取文件的函数 | 函数特点 |
---|---|
readfile() | 直接读取文件内容 自带输出功能 |
file_get_contents() | 直接读取文件内容 需要输出读取内容 |
fread() | 打开文件 计算文件大小 读取文件 输出文件 关闭文件 |
readfile :
// readfile.php
$fp="../phpinfo.php";
readfile($fp);
解释:
readfile()
:函数读取一个文件,并写入到输出缓冲。
file_get_contents:
// file_get_contents.php
$fp = "../phpinfo.php";
echo file_get_contents($fp);
解释:
file_get_contents()
:把整个文件读入一个字符串中语法:
file_get_contents(path)
参数 描述 path 必需。规定要读取的文件。
fread:
// fread.php
$fp = "../phpinfo.php"; #文件路径
$f = fopen($fp,'r'); #打开文件,操作是读文件
$f_size = filesize($fp); #指定返回文件的大小
echo fread($f, $f_size); #读文件
fclose($f); #关闭
解释:
fopen()
:函数打开一个文件或 URL。 语法:
fopen(filename,mode,include_path,context)
参数 描述 filename 必需。规定要打开的文件或 URL。 mode 必需。规定您请求到该文件/流的访问类型。
可能的值:
“r” (只读方式打开,将文件指针指向文件头)include_path 可选。如果您还想在 include_path(在 php.ini 中)中搜索文件的话,请设置该参数为 ‘1’。 context 可选。规定文件句柄的环境。context 是一套可以修改流的行为的选项。
filesize()
:函数返回指定文件的大小。语法:
filesize(filename)
参数 描述 filename 必需。规定要检查的文件。
fread()
:函数读取打开的文件 语法:
string fread ( resource $handle , int $length )
参数 描述 handle 文件系统指针,是典型地由 fopen() 创建的 resource(资源)。 length 必需。规定要读取的最大字节数。
1.4.2 任意文件读取
把路径换成变量
变量$fp,会捕获GET 方式传递过来的filepath 参数。
$fp = @$_GET['filepath'];
filepath 客户端可控,并且没有经过校验,会造成任意文件读取漏洞。我们就可以利用这一漏洞查看host文件、password文件、日志文件等。
?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=../../../../../../../../windows\system32\drivers\etc\hosts
?filePath=../../../../../../etc/hosts
?filepath=../test.php
?filePath=../../../../../../../../windows\system32\drivers\etc\hosts
1.5 任意文件下载
1.5.1 一般情况
直接下载:例如图片另存为。
a标签下载:
<a href = './a.jpg'>IMG Download</a>
1.5.2 PHP实现
PHP 文件下载实现过程:
-
先读取文件
-
在输出文件
-
提供下载
// file-download.php
$fp = './a.jpg';
header('Content-Type:image/jpg');
header('Content-Disposition:attachment;fileName='.basename($fp)); readfile($fp);
1.5.3 任意文件下载
任意文件下载的条件:
- 已知目标文件路径
- 目标文件路径,客户端可控
- 没有经过校验或校验不严格
$fp = $_GET['filepath'];
?filepath=c:/windows/system32/drivers/etc/hosts ?filepath=/etc/passwd
二、任意文件读取攻防
2.1 路径过滤
2.1.1 过滤../
$fp = @$_GET['filepath'];
$fp = str_replace("../","",$fp);
readfile($fp);
突破该过滤可以采用双写或者绝对路径的方式绕过过滤:
2.2 简单绕过
2.2.1 双写绕过
#双写
?file_path=....//....//....//....//....//....//windows\system32\drivers\etc\hosts
2.2.2 绝对路径
?filepath=c:/windows\system32\drivers\etc\hosts
2.2.3 使用..\
?filepath=..\..\..\..\..\windows\system32\drivers\etc\hosts
现在想要进行防守可以考虑限制文件访问范围
例:只让访问a.php,b.php和c.php
<?php
$fp=@$_GET['file_path'];
if($fp=='a.php' or $fp=='b.php' or $fp=='c.php'){
readfile($fp);
}else{
echo "Please stop!";
}
?>
限制文件访问范围也可以通过ini_set
进行设置:
<?php
ini_set("open_basedir","c:\phpStudy\WWW")
$fp=@$_GET['file_path'];
readfile($fp);
}
?>
说明:
ini_set("open_basedir","c:\phpStudy\WWW")
:这行代码用于设置 PHP 的open_basedir
配置选项,限制脚本能够访问的目录。在这里,设置的目录是c:\phpStudy\WWW
,表示脚本只能访问该目录下的文件。
$fp=@$_GET['file_path'];
:这行代码从 GET 参数中获取名为file_path
的值,并赋给变量$fp
。@
符号用于抑制可能的错误提示。
readfile($fp);
:这行代码使用readfile()
函数读取$fp
变量所指定的文件,并将文件内容输出到浏览器。
三、 任意文件读取挖掘
3.1 手动挖掘
从文件名上看 | 从参数名上看 |
---|---|
readfile.php filedownload.php filelist.php | f= file= fp= readfile= path= readpath= rul= menu= META-INF= WEB-INF= content= |
3.2 经典案例
四、漏洞修复方案
4.1 输入验证
- 让web用户只能访问(读取),所需要的文件和路径。
4.2 避免其他漏洞
- 不能有文件包含漏洞,目录遍历漏洞或其他漏洞。
4.3 限定文件的访问范围
-
让用户不能访问Web 根目录以外的路径。
-
php.ini 配置文件中,可以通过选项open_basedir 来限定文件访问的范围
open_basedir = c:\www\
五、参考连接
https://github.com/lijiejie/ds_store_exp https://blog.youkuaiyun.com/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