@@ -177,17 +177,21 @@ def run_host(ip)
177177 case result . status
178178 when Metasploit ::Model ::Login ::Status ::SUCCESSFUL
179179 print_brute :level => :good , :ip => ip , :msg => "Success: '#{ result . credential } ' '#{ result . proof . to_s . gsub ( /[\r \n \e \b \a ]/ , ' ' ) } '"
180- credential_core = create_credential ( credential_data )
181- credential_data [ :core ] = credential_core
182- create_credential_login ( credential_data )
183- tmp_key = result . credential . private
184- ssh_key = SSHKey . new tmp_key
180+ require 'pry-byebug' ; binding . pry
181+ ssh_key = Net ::SSH ::KeyFactory . load_data_private_key ( credential_data [ :private_data ] , datastore [ 'key_pass' ] , false )
182+
183+ begin
184+ credential_core = create_credential ( credential_data )
185+ credential_data [ :core ] = credential_core
186+ create_credential_login ( credential_data )
187+ rescue ::StandardError => e
188+ print_error ( "Failed to create credential: #{ e . class } #{ e } " )
189+ credential_core = nil
190+ end
191+
185192 if datastore [ 'CreateSession' ]
186- if credential_core . is_a? Metasploit ::Credential ::Core
187- session_setup ( result , scanner , ssh_key . fingerprint , credential_core . private_id )
188- else
189- session_setup ( result , scanner , ssh_key . fingerprint , nil )
190- end
193+ cred_id = credential_core . is_a? ( Metasploit ::Credential ::Core ) ? credential_core . private_id : nil
194+ session_setup ( result , scanner , ssh_key . public_key . fingerprint , cred_id )
191195 end
192196 if datastore [ 'GatherProof' ] && scanner . get_platform ( result . proof ) == 'unknown'
193197 msg = "While a session may have opened, it may be bugged. If you experience issues with it, re-run this module with"
@@ -224,7 +228,7 @@ class KeyCollection < Metasploit::Framework::CredentialCollection
224228
225229 # Override CredentialCollection#has_privates?
226230 def has_privates?
227- ! @key_data . empty ?
231+ @key_data . present ?
228232 end
229233
230234 def realm
@@ -235,49 +239,62 @@ def valid?
235239 @error_list = [ ]
236240 @key_data = Set . new
237241
238- unless @private_key . present? || @key_path . present?
242+ if @private_key . present?
243+ results = validate_private_key ( @private_key )
244+ elsif @key_path . present?
245+ results = validate_key_path ( @key_path )
246+ else
247+ @error_list << "No key path or key provided"
239248 raise RuntimeError , "No key path or key provided"
240249 end
241250
242- if @key_path . present?
243- if File . directory? ( @key_path )
244- @key_files ||= Dir . entries ( @key_path ) . reject { |f | f =~ /^\x2e |\x2e pub$/ }
245- @key_files . each do |f |
246- begin
247- data = read_key ( File . join ( @key_path , f ) )
248- @key_data << data if valid_key? ( data )
249- rescue StandardError => e
250- @error_list << "#{ File . join ( @key_path , f ) } : #{ e } "
251- end
252- end
253- elsif File . file? ( @key_path )
254- begin
255- data = read_key ( @key_path )
256- @key_data << data if valid_key? ( data )
257- rescue StandardError => e
258- @error_list << "#{ @key_path } could not be read, #{ e } "
259- end
260- else
261- raise RuntimeError , "Invalid key path"
262- end
251+ if results [ :key_data ] . present?
252+ @key_data . merge ( results [ :key_data ] )
253+ else
254+ @error_list . concat ( results [ :error_list ] ) if results [ :error_list ] . present?
263255 end
264256
265- if @private_key . present?
266- data = Net ::SSH ::KeyFactory . load_data_private_key ( @private_key , @password , false ) . to_s
267- if valid_key? ( data )
268- @key_data << data
269- else
270- raise RuntimeError , "Invalid private key"
257+ @key_data . present?
258+ end
259+
260+ def validate_private_key ( private_key )
261+ key_data = Set . new
262+ error_list = [ ]
263+ begin
264+ if Net ::SSH ::KeyFactory . load_data_private_key ( private_key , @password , false ) . present?
265+ key_data << private_key
271266 end
267+ rescue StandardError => e
268+ error_list << "Error validating private key: #{ e } "
272269 end
273-
274- !@key_data . empty?
270+ { key_data : key_data , error_list : error_list }
275271 end
276272
277- def valid_key? ( key_data )
278- !!( key_data . match ( /BEGIN [RECD]SA PRIVATE KEY/ ) && !key_data . match ( /Proc-Type:.*ENCRYPTED/ ) )
273+ def validate_key_path ( key_path )
274+ key_data = Set . new
275+ error_list = [ ]
276+
277+ if File . file? ( key_path )
278+ key_files = [ key_path ]
279+ elsif File . directory? ( key_path )
280+ key_files = Dir . entries ( key_path ) . reject { |f | f =~ /^\x2e |\x2e pub$/ } . map { |f | File . join ( key_path , f ) }
281+ else
282+ return { key_data : nil , error : "#{ key_path } Invalid key path" }
283+ end
284+
285+ key_files . each do |f |
286+ begin
287+ if read_key ( f ) . present?
288+ key_data << File . read ( f )
289+ end
290+ rescue StandardError => e
291+ error_list << "#{ f } : #{ e } "
292+ end
293+ end
294+ { key_data : key_data , error_list : error_list }
279295 end
280296
297+
281298 def each
282299 prepended_creds . each { |c | yield c }
283300
@@ -307,7 +324,7 @@ def each_key
307324
308325 def read_key ( file_path )
309326 @cache ||= { }
310- @cache [ file_path ] ||= Net ::SSH ::KeyFactory . load_data_private_key ( File . read ( file_path ) , password , false , key_path ) . to_s
327+ @cache [ file_path ] ||= Net ::SSH ::KeyFactory . load_private_key ( file_path , password , false )
311328 @cache [ file_path ]
312329 end
313330 end
0 commit comments