前言
Ruby on Rails 是一个基于MVC架构的开源WEB框架,使用Ruby编写,意在使WEB应用的开发、部署、维护变得简单。自 2004 年出现之后,Rails 迅速成为动态 Web 应用开发领域功能最强大、最受欢迎的框架之一。近日,Ruby on Rails 被发现存在目录穿越和任意文件读取漏洞,攻击者无需认证即可读取服务器上的任意文件内容。
漏洞分析
漏洞出现在 Sprockets 插件中,Sprockets 用来解决 JavaScript 文件的依赖,它检查引入的 js 文件,通过整理合并以提升 rails 的性能。当用户对服务器上的 js 发起请求后,会触发 Sprockets 对这个 js 的检查,代码位于 lib/sprockets/server.rb 内:
解析请求中的文件路径后,赋值给 path,然后调用 forbidden_request 函数对 path 进行检查:
forbidden_request 函数判断了 path 中是否包含 “..”,以防止发生目录穿越漏洞。如果 path 中包含 ”..”,服务器会返回 forbidden,如果不含有 ”..”,代码向下执行,path 被传递到了 find_asset 函数,find_asset 函数位于 /lib/sprockets/base.rb 中:
Path 经过 url 解码之后传入 load 函数:
uri 被传入到 UnloadedAsset.new 中
UnloadedAsset 中调用了 URIUtils.parse_asset_uri 方法,
其中 parse_asset_uri 调用 split_file_uri 对 path 进行了第二次 url 解码,然后返回最终的路径,处理后的 path 接下来被传递到 load 函数中的 load_from_unloaded 中
load_from_unloaded 使用 paths_split 对传入的 path 进行判断,判断其是否在合法的目录里。
判断结束后,如果通过了检查,便会继续执行 load_from_unloaded 函数后面的文件读取操作。因此只要构造出能通过以上一系列检查的请求,就可以读取服务器上的任意文件。
漏洞复现
搭建好 rails 环境。
构建恶意的请求,因为检查流程中会对 path 中的 ”..” 进行判断,但由于检查流程中会对 path 进行两次 url 解码,因此可以先对两个 ”.” 中的其中一个 . 进行两次 url 编码。Payload 构造完成后,发起请求:
成功读取 windows 系统中 C:/Windows/win.ini 文件。
参考
作者: JenI 转载请注明出处,谢谢
Comments !