首页 > 技术文章 > 文件下载文件读取

zhaozhaomumu 2021-09-11 21:45 原文

文件下载文件读取漏洞介绍

一些网站提供文件查看或文件下载功能,若对用户查看或下载的文件不做限制,则恶意用户就能够查看或下载任意敏感文件,这就造成了文件查看与下载漏洞。

任意文件读取漏洞

任意文件读取是属于文件操作漏洞的一种,一般任意文件读取漏洞可以读取配置信息甚至系统重要文件。严重的话,就可能导致SSRF,进而漫游至内网。

漏洞产生原因

  • 有存读取文件的函数
  • 读取文件的路径用户可控,且未校验或校验不严
  • 输出了文件内容

PHP的文件读取函数

  • file_get_contents()
    使用file_get_contents()函数能在编译器编译后能显示出文件源代码,而在浏览器中打开时不能显示源代码。
<?php
$filename=”1.txt”;
echo file_get_contents($filename);
?>
  • readfile()
    使用readfile()函数能在编译器编译后能显示出文件源代码,而在浏览器中打开时不能显示源代码。
<?php
$filename=”1.txt”;
readfile($filename);
?>
  • highlight_file()
    使用highlight()函数能在编译器编译后能显示出文件源代码,并且在浏览器中打开时也能显示源代码。
<?php
echo highlight_file('文件路径');
?>
  • fopen()
    对文件进行数据存取的第一步操作就是要打开文件。在PHP中使用fopen()函数打开文件,fopen()函数的语法为:
fopen(filename,mode,include_path,context);

filename:必选。打开包含路径的文件名,路径可是相对路径,也可是绝对路径。无前缀则表示打开的是本地文件。 mode:必选。打开文件的方式(文件/流的访问类型)。
include_path:可选。该参数在配置文件php.ini中指定一个路径,若需要在 include_path 中检索文件的话,可以将该参数设为 1 或 TRUE。
context:文件句柄的环境。
mode参数的可取值:

"r":只读方式打开,将文件指针指向文件头。
"r+":读写方式打开,将文件指针指向文件头。
"w":写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
"w+":读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
"a":写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
"x":创建并以写入方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建之。这和给底层的 open(2) 系统调用指定 O_EXCL|O_CREAT 标记是等价的。此选项被 PHP 4.3.2 以及以后的版本所支持,仅能用于本地文件。
"x+":创建并以读写方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建之。这和给底层的 open(2) 系统调用指定 O_EXCL|O_CREAT 标记是等价的。此选项被 PHP 4.3.2 以及以后的版本所支持,仅能用于本地文件。

使用实例:

<?php

  $fp = fopen("/home/rasmus/file.txt", "r");

  $fp = fopen("c:\\mydata\\info.txt", "r");

  $fp = fopen("http://www.php.net/", "r");

  $fp = fopen("ftp://user:password/", "w");
?>

对文件的操作结束后记得要关闭该文件,以免引起错误。关闭文件可用fclose()函数。

任意文件下载漏洞

漏洞产生原因

  • 有读取文件的函数
  • 读取文件的路径用户可控,且没有经过校验,或者校验不严格
  • 输出文件内容
  • 网站存在下载文件的功能,还会从浏览器接收文件名字

文件下载的两种方式

  • 直接下载:
<a href=”http://www.a.com/xxx.rar”>下载</a>
  • 增加header头
<?php
    $filename = $_GET['filename'];
    echo '<h1>下载文件</h1><br /><br />';
    echo file_get_contents($filename);

    header('Content-Type: imgage/jpeg');
    header('Content-Disposition: attachment; filename='.$filename);
    header('Content-Lengh: '.filesize($filename));
?>

利用思路

信息收集信息、猜路径、下载配置文件/代码文件、利用服务器软件漏洞、shell、提权
首先收集系统信息,包括系统版本,中间件,cms版本,服务器用途,服务器使用者信息,端口,web路径等,然后根据收集到的信息,下载配置文件,如weblogic,ftp,ssh、mysql等, 根据下载到的配置文件进行渗透。

1. 读取程序源代码(如密码配置文件)
2. 读取程序配置文件(如数据库连接文件)
如weblogic,ssh,ftp,数据库配置文件等, 当解出密码后,进行登陆,getshell
3. 读取操作系统关键文件(如/etc/sadow,/ root/.bash_history等文件)
4. 读取运维配置文件(redis/rsync/ftp/ssh客 户端数据等)
5. 读取中间件配置文件(weblogic/tomcat等 密码文件,apache的httpd.conf文件)
6. 下载web日志文件(获取网站后台/上传文件 等)
 下载日志文件,找到登录/上传/后台/ 操作,找到登录入口 可以爆破,测试默认口令,弱口令,  找到文件上传点则测试文件上传漏洞,找到后台操作试试有没有未授权访问
7. 结合SSRF获取内网机器文件
8. 可以利用../返回到上级目录下载敏感文件

系统文件

1.Windows系统文件

C:\boot.ini //查看系统版本
C:\Windows\System32\inetsrv\MetaBase. xml //IIS配置文件
C:\Windows\repair\sam //存储系统初次安装的密码
C:\Program Files\mysql\my.ini //Mysql配置
C:\Program Files\mysql\data\mysql\user. MYD  //Mysql root
C:\Windows\php.ini //php配置信息
C:\Windows\my.ini //Mysql配置信息
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码 
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码 
c:\Program Files\Serv-U\ServUDaemon.ini 
c:\windows\system32\inetsrv\MetaBase.xml 查看IIS的虚拟主机配置 
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码 
c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此 
c:\Program Files\RhinoSoft.com\ServUDaemon.exe 
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件 //存储了pcAnywhere的登陆密码 
c:\Program Files\Apache Group\Apache\conf\httpd.conf 或C:\apache\conf\httpd.conf //查看WINDOWS系统apache文件 
c:/Resin-3.0.14/conf/resin.conf //查看jsp开发的网站 resin文件配置信息. 
c:/Resin/conf/resin.conf /usr/local/resin/conf/resin.conf 查看linux系统配置的JSP虚拟主机 
d:\APACHE\Apache2\conf\httpd.conf 
C:\Program Files\mysql\my.ini 
C:\mysql\data\mysql\user.MYD 存在MYSQL系统中的用户密码

2.linux/unix:

.bash_history` # 历史中可能带着用户的密码 ( 遇到过现实案例,是输错的情况下参数的,比如没 输入 su 却以为自己输了 su)
/etc/passwd # 用户情况
/etc/shadow # 直接 John the Ripper
/etc/hosts # 主机信息,通常配置了一些内网 域名
/root/.bash_history //root的bash历史记录
/root/.ssh/authorized_keys /root/.mysql_history //mysql的bash历史记录
/root/.wget-hsts /opt/nginx/conf/nginx.conf //nginx的配置文件
/var/www/html/index.html /etc/my.cnf /etc/httpd/conf/httpd.conf //httpd的配置文件
/proc/self/fd/fd[0-9]*(文件标识符)
/proc/mounts /porc/config.gz /proc/sched_debug // 提供cpu上正在运行的进程信息,可以获得进程的pid号,可以配合后面需要pid的利用
/proc/mounts // 挂载的文件系统列表
/proc/net/arp //arp表,可以获得内网其他机器的地址
/proc/net/route //路由表信息
/proc/net/tcp and /proc/net/udp // 活动连接的信息
/proc/net/fib_trie // 路由缓存
/proc/version // 内核版本
/proc/[PID]/cmdline // 可能包含有用的路径信息
/proc/[PID]/environ // 程序运行的环境变量信息,可以用来包含getshell
/proc/[PID]/cwd // 当前进程的工作目录
/proc/[PID]/fd/[#] // 访问file descriptors, 某写情况可以读取到进程正在使用的文件,比如 access.log /root/.ssh/id_rsa /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys /etc/ssh/sshd_config /var/log/secure /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/syscomfig/network-scripts/ifcfg-eth1
/usr/local/tomcat/conf/tomcat-users. xml # tomcat 用户配置文件
/root/.bashrc # 环境变量
/root/.bash_history # 还有root外的其他用户
/root/.viminfo # vim 信息
/root/.ssh/id_rsa # 拿私钥直接ssh
/proc/xxxx/cmdline # 进程状态枚举 xxxx 可以为0000-9999 使用burpsuite 数据库 config 文件     web 日志 access.log, error.log /var/lib/php/sess_PHPSESSID # 非常规问题 session 文件
/proc/net/arp /proc/net/tcp /proc/net/udp /proc/net/dev

漏洞检测

从链接上看,形如:

readfile.php?file=***.txt
download.php?file=***.rar

从参数名看,形如:

&RealPath=
&FilePath=
&filepath=
&Path=
&path=
&inputFile=
&url=
&urls=
&Lang=
&dis=
&data=
&readfile=
&filep=
&src=
&menu=
META-INF
WEB-INF

案例演示

1.pikachu靶场文件下载漏洞

界面显示
image
点击任意图片,出现下载,查看下载地址:

http://127.0.0.1/pikachu/vul/unsafedownload/execdownload.php?filename=kb.png

尝试下载execdownload.php文件,

http://127.0.0.1/pikachu/vul/unsafedownload/execdownload.php?filename=execdownload.php

image
报错,说明可能路劲不对,../上一级测试

http://127.0.0.1/pikachu/vul/unsafedownload/execdownload.php?filename=../execdownload.php

可下载
image
打开查看源码
image
默认图片存放在download目录下
尝试下载敏感文件
通过目录扫描得到配置文件config.inc.php
image
pikachu/vul/unsafedownload/download/xxx.xxx
与vul相差3个父目录,所以加3个…/
完整url:

http://127.0.0.1/pikachu/vul/unsafedownload/execdownload.php?filename=../../../inc/config.inc.php

image
可得到数据库用户名及密码
image

2.RoarCTF2019-文件读取真题复现

image
image
点击help,出现一串字符
image
是文件无法找到的异常信息。
通过观察url,猜测是文件下载

http://5b7d945a-9f67-40eb-99ea-be82483a21ef.node4.buuoj.cn:81/Download?filename=help.docx

此题是javaweb,可以联想到WEB-INF/web.xml泄露问题。
WEB-INF是Java的WEB应用的安全目录。如果想在页面中直接访问其中的文件,必须通过web.xml文件对要访问的文件进行相应映射才能访问。WEB-INF主要包含一下文件或目录:
/WEB-INF/web.xml:Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则。
/WEB-INF/classes/:含了站点所有用的 class 文件,包括 servlet class 和非servlet class,他们不能包含在 .jar文件中
/WEB-INF/lib/:存放web应用需要的各种JAR文件,放置仅在这个应用中要求使用的jar文件,如数据库驱动jar文件
/WEB-INF/src/:源码目录,按照包名结构放置各个java文件。
/WEB-INF/database.properties:数据库配置文件

找一下WEB-INF/web.xml,POST传值
image
下载查看文件
找到flag信息
image
servlet-class里面的.代表的是路径/
然后下载FlagController.class
image
发现一串base64,解码
image
得到flag。

推荐阅读