Ruby on Rails路径穿越与任意文件读取漏洞分析(CVE-2019-5418)
Ruby on Rails是一个 Web 应用程序框架,是一个相对较新的 Web 应用程序框架,构建在 Ruby 语言之上。它被宣传为现有企业框架的一个替代,而它的目标,就是让 Web 开发方面的生活,变得更轻松。
【CVE-2019-5418】漏洞公告: 公告地址。
Versions Affected: All.
Not affected: None.
Fixed Versions: 6.0.0.beta3, 5.2.2.1, 5.1.6.2, 5.0.7.2, 4.2.11.1
Impact
There is a possible file content disclosure vulnerability in Action View.
Specially crafted accept headers in combination with calls to render file:
can cause arbitrary files on the target server to be rendered, disclosing the
file contents.
The impact is limited to calls to render which render file contents without
a specified accept format. Impacted code in a controller looks something like
this:
class UserController < ApplicationController
def index render file: "#{Rails.root}/some/file"
end
end
这个漏洞主要是由于网站使用了为指定参数的render file来渲染应用之外的视图,我们可以通过修改访问某控制器的请求包,通过“../../../../”来达到路径穿越的目的,然后再通过“{{”来进行模板查询路径的闭合,使得所要访问的文件被当做外部模板来解析。
实验环境
Centos7桌面版,装有Ruby On Rails环境。
Ruby On Rails环境搭建
1. 安装git #yum install git
2. 安装rbenv到~/.rbenv目录
git clonegit://github.com/sstephenson/rbenv.git~/.rbenv
3. 安装rbenv的插,用来编译安装 ruby
git clonegit://github.com/sstephenson/ruby-build.git~/.rbenv/plugins/ruby-build
4. 用来管理 gemset, 可选, 因为有 bundler 也没什么必要
git clone git://github.com/jamis/rbenv-gemset.git ~/.rbenv/plugins/rbenv-gemset
5. 通过 gem 命令安装完 gem 后无需手动输入 rbenv rehash 命令
git clonegit://github.com/sstephenson/rbenv-gem-rehash.git~/.rbenv/plugins/rbenv-gem-rehash
6. 通过 rbenv update 命令来更新 rbenv 以及所有插件
git clone git://github.com/rkh/rbenv-update.git~/.rbenv/plugins/rbenv-update
7. 使用 Ruby China 的镜像安装 Ruby, 国内用户推荐
git clonegit://github.com/AndorChen/rbenv-china-mirror.git~/.rbenv/plugins/rbenv-china-mirror
8. 然后需要将下面两句代码放在bash的配置文件中:
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
9. 位置是在.bash_profile(Ubuntu中应该是.bashrc)修改完成后,执行下面的命令使其生效
source ~/.bashrc
10. 安装ruby
rbenv install --list # 列出所有ruby 版本
rbenv install 2.3.3 #安装2.3.3版本Ruby
11. 设置使用的ruby版本
rbenv global 2.3.3 # 默认使用2.3.3,此步骤不能省略
ruby –v #查看安装的Ruby版本
12. 安装rails
设置ruby版本后,安装rails(指定rails版本):
1)在当前的ruby版本中安装rails
gem install rails -v 5.2.1 #指定版本
2)查看rails安装版本
rails –v
3)修改bundle的源地址(可能需要修改,视情况而定。)
bundle config mirror.https://rubygems.orghttps://gems.ruby-china.org
执行bundleinstall
在项目根目录执行bundleinstall
问题解决(在安装和运行的过程中,可能会出现各种各样的问题, 链接文字我就是安装下面的这些依赖的,但是不一定和我这个一样,大家还是根据自己的提示来吧):
yum -y install gcc
yum install flex autoconf zlib curlzlib-devel curl-devel bzip2 bzip2-develncurses-devel libjpeg-devel libpng-devel libtiff-develfreetype-devel pam-develgcc+ gcc-c++ libxml2 libxml2-devel libxslt libxslt-devel
yum install sqlite*
漏洞复现
1. 先下载原码(;">路径“/root /CVE-2019-5418/”), 源码地址。
2. 进入“/root”路径下,执行“source .bash_profile”
3. 将下载得到的压缩包进行解压,进入demo路径下执行:
bundle install
4. 在demo路径下执行“rails s”,开启服务。
5. 此时漏洞环境已搭建完成且开始运行,使用浏览器测试能否访问。如下图表示可正常访问
6. 访问“chybeta”路径:
7. 我们使用浏览器自带的开发者工具进行漏洞复现,按“f12”打开工具,修改这条请求,修改内容如下:
../../../../../../etc/passwd{{
8. 漏洞复现成功,成功读取到passwd文件的内容:
9. 或者,我们也可以使用burp suite来抓包,设置好浏览器代理,访问“/chybeta”路径抓包.我们只要修改好流量包的内容重新发送即可。用浏览器自带的工具实现功能,我就不想在使用Burp suite了。之后就可以很简单的得到目标主机的passwd文件内容。
漏洞分析
漏洞影响所有版本的rails,但是目前已经有几个版本修复了此漏洞:
6.0.0.beta3,
5.2.2.1
5.1.6.2
5.0.7.2
4.2.11.1
我们先看一下正常访问时什么样的吧:
可以看到我们每获取一个请求,Ruby On Rails就会使用Render file(没有指定参数)的渲染模式来渲染目标。这样就会在我们攻击的时候,将目标文件当做模板来渲染,然后返回给浏览器:哈哈哈哈。
rails在控制器中通过render file形式来渲染应用之外的视图,因此在“.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/actionview-5.2.1/lib/action_view/renderer/template_renderer.rb”中会根据“options.key?(:file)”,调用“find_file”函数来寻找视图。代码如下:
module ActionView
class TemplateRenderer < AbstractRenderer#:nodoc:
# Determine the template to be renderedusing the given options.
def determine_template(options)
keys = options.has_key?(:locals) ?options[:locals].keys : []
if options.key?(:body)
...
elsif options.key?(:file)
with_fallbacks {find_file(options[:file], nil, false, keys, @details) }
...
end
end
“find_file”代码如下(路径为:“.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/actionview-5.2.1/lib/action_view/lookup_context.rb”)
发现“find_file”又调用了“*args_for_lookup”,所以我们继续跟入查看“args_for_lookup”函数,代码如下:
此函数会生成用于查找文件的参数,当其最终返回时会把payload保存在details[formats]中(大家自己做实验的时候可以直接访问一个不存在的文件,这样会直接显示访问的详细信息)。
再回到“find_file”函数,跟进之后,会进入到:“.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/actionview-5.2.1/lib/action_view/path_set.rb”。
class PathSet #:nodoc:
def find_file(path, prefixes = [], *args)
_find_all(path, prefixes, args, true).first ||raise(MissingTemplate.new(self, path, prefixes, *args))
end
private
#注,这里的 args 即前面args_for_lookup生成的details
def _find_all(path, prefixes, args, outside_app)
prefixes = [prefixes] if String === prefixes
prefixes.each do |prefix|
paths.each do |resolver|
if outside_app
templates =resolver.find_all_anywhere(path, prefix, *args)
else
templates =resolver.find_all(path, prefix, *args)
end
return templates unlesstemplates.empty?
end
end
[]
end
由于要渲染的视图在应用之外(outside_app,因此跟入“find_all_anywhere”(在“.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/actionview-5.2.1/lib/action_view/template/resolver.rb”):
def find_all_anywhere(name, prefix, partial= false, details = {}, key = nil, locals = [])
cached(key, [name, prefix, partial], details, locals) do
find_templates(name, prefix, partial, details, true)
end
end
进入find_templates,这就是根据条件来查找要渲染的模板:
从代码便可以看到,所查找的模板会赋值给details[:formats],如果建立建立查询后,查询内容就会如下:
利用../与前缀组合造成路径穿越,利用最后的{{完成闭合。
最后“/etc/passwd”被当成模板文件进行渲染,最后造成了任意文件读取。
使用IDE环境进行调试,最后组成的路径应该是:
/etc/passwd{{},}{+{},}{.{raw,erb,html,builder,ruby,coffee,jbuilder},}
漏洞修复
1. 使用已经修复该漏洞的版本
2. 补丁:补丁地址
Ruby on Rails路径穿越与任意文件读取漏洞分析(CVE-2019-5418)相关推荐
- 修复路径穿越、任意文件写入漏洞
修复路径穿越.任意文件写入漏洞 背景 前段时间随手写的一个文件上传服务,在公司的渗透测试下漏洞百出,其中少不了路径穿越和任意文件写入漏洞.其实这两个漏洞的修复并不复杂,只要对入参进行两个条件的校验就可 ...
- 安全研究 | Jenkins 任意文件读取漏洞分析
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由云鼎实验室 发表于云+社区专栏 一.漏洞背景 漏洞编号:CVE-2018-1999002 漏洞等级:高危 Jenkins 7 月 18 ...
- FFmpeg任意文件读取漏洞分析
6月24号的时候hackerone网站上公布了一个ffmpeg的本地文件泄露的漏洞,可以影响ffmpeg很多版本,包括3.2.2.3.2.5.3.1.2.2.6.8等等. hackerone网站上的漏 ...
- contactform7 ajax,Wordpress contact_form_7_v5.0.3 插件 权限提升、任意文件读取漏洞分析...
简介 看到了国外有大佬发了关于WordPress的一个非常有名的插件,contact form 7的漏洞,之前见到过很多WordPress站点使用这个插件,大佬写的比较笼统,一些详细的利用方式没有说的 ...
- 任意文件读取漏洞知识梳理
文章目录 1.概述 2.开发语言触发点 2.1 PHP 2.2 Python 2.3 Java 2.4 Ruby 2.5 Node 3.中间件/服务器相关触发点 3.1 Nginx错误配置 3.2 数 ...
- 《从0到1:CTFer成长之路》1.3 任意文件读取漏洞
文章目录 1.3.1 文件读取漏洞常见触发点 1.3.1.1 web语言 1. PHP 2.python 3.Java 4.Ruby 5.Node 1.3.1.2 中间件.服务件相关 1.Nginx错 ...
- php mail执行命令,PHPMailer 命令执行 任意文件读取漏洞利用 【含POC】
PHPMailer 命令执行漏洞(CVE-2016-10033) 漏洞编号:CVE-2016-10033 影响版本:PHPMailer< 5.2.18 漏洞级别: 高危 漏洞POC: PHPMa ...
- gitlab 更新文件_GitLab任意文件读取漏洞公告
2020年4月28日,GitLab的一个任意文件读取漏洞的漏洞细节被公开.该漏洞补丁于2020年3月26号由GitLab官方发布.深信服安全研究团队依据漏洞重要性和影响力进行评估,作出漏洞通告. 漏洞 ...
- CISCO ASA任意文件读取漏洞复现 (CVE-2020-3452)
CISCO ASA任意文件读取漏洞复现 (CVE-2020-3452) 一.漏洞描述: Cisco Adaptive Security Appliance (ASA) 防火墙设备以及Cisco Fir ...
最新文章
- 如何调试分析Android中发生的tombstone
- metaprogramming笔记
- xss攻击中受影响的是服务器还是客户端,安全测试基础之 XSS
- Eclipse RCP使用SWT.EMBEDDED方式显示batik的svgCanvas后窗口最大化变白问题
- 现代科技概论_现代科技概论课程:力与运动1
- 样本方差的期望_如何理解方差和偏差
- C#学习笔记(二十一):使用文件基础
- HTML5、css3、js实现3D相册
- 赵一新:通勤研究与城市治理
- 【KNIME案例】参数化驱动工作流调用业务人员建立的脚本
- C++ 中的:“引用” 和“取地址符”的区别和作用
- mysql中signed是什么类型_mysql|unsigned 与 signed 类型
- 【luogu P1456 Monkey King】 题解
- 用select多路io复用实现简单聊天程序
- 大功率的用电电器为什么要用三孔插座?
- 支付宝小程序获取用户信息及手机号
- hdu 3949(线性基模版) 异或和中第k小的数
- 直达眼前!UC桌面抢先体验
- 微软e5服务器,Windows 10 Enterprise E3/E5两种选择,你要哪个
- 手写字体识别(3) 训练及测试
热门文章
- SmartNIC/DPU — 主流厂商
- LDO的最小输入输出压差和最小负载电流
- JTAG error:can not read register while CPU is running该如何解决
- NR 5G 网络切片
- Android性能优化:手把手教你如何让App更快、更稳、更省(含内存、布局优化等)...
- 2019年企业云呈现五大技术发展趋势
- 使用PHP处理POST上传时$_FILES数组为何为空
- RIM 将在今天发布新的 BlackBerry 7 OS 手机
- 除了速度,5G还能带来什么?
- 5G NR - 总体架构与物理层