0%

任意文件读取

0x01 前言

忙于换工作,又不知道写啥,又弃更了一段时间,看了Nu1l战队编写的从0到1 CTFER成长之路,于是记录下任意文件读取来凑个数吧。

0x02 任意文件读取产生的原因

  1. 开发者调用API时,未明确可接受的参数范围,并未对参数进行限制。
  2. Web Server自身问题或不安全的服务器配置

0x03 常见触发点

Web语言

PHP

常见函数:

  • file_get_contents()、file()、fopen()(及其文件指针操作函数fread()、gets())
  • 文件包含相关函数:include()、require()、include_once()、require_once()等
  • 执行系统命令:system()、exec()等
  • PHP扩展:php-curl扩展、XML模块等

PHP特色:

  • Wrapper:指功能不同但形式相似的协议的统称,开发者可自定义。如php://协议。
  • Filter:开发者通过stream_filter_register进行注册,Filter对目前的Wripper进行一定的处理。内置的Wrapper会自带一些Filter。

两者都可以通过php.ini禁用。

实际问题中可能遇到三种情况:

  1. 文件路径前面可控,后面不可控

    在较低PHP版本及容器版本中使用“\x00”截断,对应的url编码为”%00”。当服务器存在上传文件功能时,也可以尝试zip或者phar协议直接进行文件包含进而执行php代码。

  2. 文件路径后面可控,前面不可控

    通过符号”../“进行目录穿越来直接读取文件,但这种情况无法使用Wrapper。如果服务端使用include等文件包含类函数,我们将无法读取PHP文件中的PHP代码。

  3. 文件路径中间可控

    与第一种类似,但是无法通过Wrapper进行文件包含。

Python

Python的Web应用更多地倾向于通过其自身的模块启动服务,同时搭配中间件、代理服务将整个Web应用呈现给用户。用户和Web应用交互的过程本身就是含有对服务器资源文件的请求,因此Python某框架任意文件读取漏洞也是因为缺乏统一的资源文件交互的标准。

常见漏洞点:

框架请求静态资源文件部分,也就是最后读取文件内容的open函数,但直接导致漏洞的成因往往是开发者忽略了python函数的feature,如os.path.join()函数

1
2
>>> os.path.join("/a","/b")
'/b'

过滤”.”时,可以通过传入“/”穿越到根目录。(绝对路径)

Java

除了Java本身的文件读取函数FileInputStream,XXE导致的文件读取,Java的一些模块也支持”file://“协议。

Ruby

通常与Rails框架有关。

Node

已知Node.js的express模块曾存在任意文件读取漏洞(CVE-2017-14849)。

中间件/服务器相关

Nginx错误配置

搭配Python-Web应用一起出现,例如:

1
2
3
location /static{
alias /home/myapp/static/;
}

如果配置文件中包含了上述配置,有可能是开发人员想让用户访问到静态资源目录,但是如果用户输入的路径是/static../,拼接到alias上就变成了/home/myapp/static/../,这时就产生了目录穿越漏洞,穿越到了上一级的myapp目录。

数据库

以MySQL为例:load_file()函数进行文件读取。另一种load data infield,需要执行完整的SQL语句

软链接

使用ln -s创建软链接,上传服务器。访问链接文件即访问指向的服务器文件。

FFmpeg

2017年6月,FFmpeg被爆出存在任意文件读取漏洞。

Docker-API

SSRF漏洞进行UNIX Socket通信的时候,就可以通过操控Docker-API把本地文件载入Docker新容器进行读取(利用Docker的ADD、COPY操作)

客户端相关

浏览器/Flash XSS

网站同源策略阻止JavaScript使用File协议读取客户的本地文件。Safari浏览器2017年8月被爆出客户端的本地文件读取漏洞。

MarkDown语法解析器XSS

Markdown解析器具有一定的解析JavaScript的能力。

0x04 常见读取路径

Linux

  • /etc目录
    /etc目录下多是各种应用或系统配置文件,所以其下的文件是文件读取的首要目标

  • /etc/passwd
    /etc/passwd文件是Linux系统保存用户信息及其工作目录的文件,权限是所有用户/组可读,一般被用作Linux系统下文件读取漏洞存在性判断的基准。读到这个文件我们就可以知道系统存在哪些用户,它们的组是什么,他们的工作目录是什么。

  • /etc/shadow
    /etc/shadow是Linux系统保存用户信息及(可能存在)密码(hash)的文件,权限是root可读写,shadow组可读。所以一般情况下,这个文件是不可读的。

  • /etc/apache2/
    /etc/apache2/
    是Apache配置文件,可以获知Web目录、服务端口等信息。

  • /etc/nginx/*

    Nginx配置文件,可获知Web目录、服务端口等信息

  • /etc/apparmor(.d)/*

    Apparmor配置文件,获知各应用系统调用的白名单、黑名单。

  • /etc/(cron.d/*|crontab)

    定时任务文件。

  • /etc/environment

    环境变量配置文件之一,泄漏大量目录信息,甚至可能出现secret key。

  • /etc/hostname

    主机名

  • /etc/hosts

    主机名查询静态表,包含指定域名解析IP的成对信息。

  • /etc/issue

    指明系统版本

  • /etc/mysql/*

    MySQL配置文件

  • /etc/php/*

    PHP配置文件

  • /proc目录

    虚拟目录,存储进程动态允许的各种信息。/proc/[pid]/可以爆破pid进程号,/proc/self/查看当前进程。

对应目录下的cmdline可读出比较敏感的信息,如使用mysql -uxxx -pxxx登录MySQL,会在cmdline中显示明文密码:

  • /proc/[pid]/cmdline

通过cwd命令可以直接跳转到当前目录:

  • /proc/[pid]/cwd/

环境变量中可能存在secret_key,这时可以通过environ进行读取:

  • /proc/[pid]/environ
  • /proc/[pid]/fd(1|2…). 读取pid指向进程的stdout或stderror或其他
  • /proc/[pid]/maps 内存映射
  • /proc/[pid]/(mounts|mountinfo) 文件系统挂载情况
  • /proc/[pid]/net/* 网络信息
  • /usr/local/nginx/conf/*

    Nginx配置文件可能存在其他路径

  • /var/log/* (apache2的web应用可读/var/log/apache2/access.log分析日志)

    日志文件

  • /var/www/html/

    Apache默认Web根目录

  • /var/lib/php(5)/sessions

    PHP session目录

  • [user]/.bash_history (历史执行命令)

  • [user]/.bashrc (部分环境变量)

  • [user]/.ssh/id_rsa(.pub) (ssh登录私钥/公钥)

  • [user]/.viminfo (vim使用记录)

    用户目录

-------本文结束  感谢您的阅读-------