diff --git a/lib/metasploit/framework/login_scanner/base.rb b/lib/metasploit/framework/login_scanner/base.rb index bba193fe25..7c4e90555b 100644 --- a/lib/metasploit/framework/login_scanner/base.rb +++ b/lib/metasploit/framework/login_scanner/base.rb @@ -77,6 +77,19 @@ module Metasploit raise NotImplementedError end + + def each_cred_adjusted_for_realm(credential) + unless credential.kind_of?(Metasploit::Framework::Credential) && credential.valid? + raise ArgumentError, "#{credential.inspect} is not a valid Metasploit::Framework::Credential" + end + + if credential.realm.present? && REALM_KEY.present? + credential.realm_key = REALM_KEY + yield credential + end + + end + # Attempt to login with every {Credential credential} in # {#cred_details}, by calling {#attempt_login} once for each. # diff --git a/lib/metasploit/framework/login_scanner/ftp.rb b/lib/metasploit/framework/login_scanner/ftp.rb index 27cf88739a..c5b63a9972 100644 --- a/lib/metasploit/framework/login_scanner/ftp.rb +++ b/lib/metasploit/framework/login_scanner/ftp.rb @@ -18,7 +18,7 @@ module Metasploit LIKELY_PORTS = [ DEFAULT_PORT, 2121 ] LIKELY_SERVICE_NAMES = [ 'ftp' ] PRIVATE_TYPES = [ :password ] - REALM_TYPE = nil + REALM_KEY = nil # @!attribute ftp_timeout # @return [Fixnum] The timeout in seconds to wait for a response to an FTP command diff --git a/lib/metasploit/framework/login_scanner/mssql.rb b/lib/metasploit/framework/login_scanner/mssql.rb index 11576d7f8c..186346c415 100644 --- a/lib/metasploit/framework/login_scanner/mssql.rb +++ b/lib/metasploit/framework/login_scanner/mssql.rb @@ -23,7 +23,7 @@ module Metasploit # Lifted from lib/msf/core/exploit/mssql.rb LIKELY_SERVICE_NAMES = [ 'ms-sql-s', 'ms-sql2000', 'sybase' ] PRIVATE_TYPES = [ :password, :ntlm_hash ] - REALM_TYPE = Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN + REALM_KEY = Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN # @!attribute windows_authentication # @return [Boolean] Whether to use Windows Authentication instead of SQL Server Auth. diff --git a/lib/metasploit/framework/login_scanner/mysql.rb b/lib/metasploit/framework/login_scanner/mysql.rb index 91ac2d0247..734d7304d3 100644 --- a/lib/metasploit/framework/login_scanner/mysql.rb +++ b/lib/metasploit/framework/login_scanner/mysql.rb @@ -19,7 +19,7 @@ module Metasploit LIKELY_PORTS = [ 3306 ] LIKELY_SERVICE_NAMES = [ 'mysql' ] PRIVATE_TYPES = [ :password ] - REALM_TYPE = nil + REALM_KEY = nil def attempt_login(credential) result_options = { diff --git a/lib/metasploit/framework/login_scanner/pop3.rb b/lib/metasploit/framework/login_scanner/pop3.rb index b9512213f1..5f3fbfe5c1 100644 --- a/lib/metasploit/framework/login_scanner/pop3.rb +++ b/lib/metasploit/framework/login_scanner/pop3.rb @@ -18,7 +18,7 @@ module Metasploit LIKELY_PORTS = [ 110, 995 ] LIKELY_SERVICE_NAMES = [ 'pop3', 'pop3s' ] PRIVATE_TYPES = [ :password ] - REALM_TYPE = nil + REALM_KEY = nil # This method attempts a single login with a single credential against the target # @param credential [Credential] The credential object to attempt to login with diff --git a/lib/metasploit/framework/login_scanner/postgres.rb b/lib/metasploit/framework/login_scanner/postgres.rb index a6cb33ce43..dcd29cbd62 100644 --- a/lib/metasploit/framework/login_scanner/postgres.rb +++ b/lib/metasploit/framework/login_scanner/postgres.rb @@ -16,7 +16,7 @@ module Metasploit LIKELY_PORTS = [ DEFAULT_PORT ] LIKELY_SERVICE_NAMES = [ 'postgres' ] PRIVATE_TYPES = [ :password ] - REALM_TYPE = Metasploit::Model::Realm::Key::POSTGRESQL_DATABASE + REALM_KEY = Metasploit::Model::Realm::Key::POSTGRESQL_DATABASE # This method attempts a single login with a single credential against the target # @param credential [Credential] The credential object to attmpt to login with diff --git a/lib/metasploit/framework/login_scanner/smb.rb b/lib/metasploit/framework/login_scanner/smb.rb index af1f31b133..0aeb90cd44 100644 --- a/lib/metasploit/framework/login_scanner/smb.rb +++ b/lib/metasploit/framework/login_scanner/smb.rb @@ -22,7 +22,7 @@ module Metasploit LIKELY_PORTS = [ 139, 445 ] LIKELY_SERVICE_NAMES = [ "smb" ] PRIVATE_TYPES = [ :password, :ntlm_hash ] - REALM_TYPE = Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN + REALM_KEY = Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN module StatusCodes CORRECT_CREDENTIAL_STATUS_CODES = [ diff --git a/lib/metasploit/framework/login_scanner/snmp.rb b/lib/metasploit/framework/login_scanner/snmp.rb index 8d78d100ec..8816a1888b 100644 --- a/lib/metasploit/framework/login_scanner/snmp.rb +++ b/lib/metasploit/framework/login_scanner/snmp.rb @@ -15,7 +15,7 @@ module Metasploit LIKELY_PORTS = [ 161, 162 ] LIKELY_SERVICE_NAMES = [ 'snmp' ] PRIVATE_TYPES = [ :password ] - REALM_TYPE = nil + REALM_KEY = nil # This method attempts a single login with a single credential against the target # @param credential [Credential] The credential object to attmpt to login with diff --git a/lib/metasploit/framework/login_scanner/ssh.rb b/lib/metasploit/framework/login_scanner/ssh.rb index 0875af98b5..bf9dbd9b71 100644 --- a/lib/metasploit/framework/login_scanner/ssh.rb +++ b/lib/metasploit/framework/login_scanner/ssh.rb @@ -21,7 +21,7 @@ module Metasploit LIKELY_PORTS = [ DEFAULT_PORT ] LIKELY_SERVICE_NAMES = [ 'ssh' ] PRIVATE_TYPES = [ :password, :ssh_key ] - REALM_TYPE = nil + REALM_KEY = nil VERBOSITIES = [ :debug, diff --git a/lib/metasploit/framework/login_scanner/telnet.rb b/lib/metasploit/framework/login_scanner/telnet.rb index 2411aa6965..d6aa3b9b9a 100644 --- a/lib/metasploit/framework/login_scanner/telnet.rb +++ b/lib/metasploit/framework/login_scanner/telnet.rb @@ -18,7 +18,7 @@ module Metasploit LIKELY_PORTS = [ DEFAULT_PORT ] LIKELY_SERVICE_NAMES = [ 'telnet' ] PRIVATE_TYPES = [ :password ] - REALM_TYPE = nil + REALM_KEY = nil # @!attribute verbosity # The timeout to wait for the telnet banner. diff --git a/lib/metasploit/framework/login_scanner/vnc.rb b/lib/metasploit/framework/login_scanner/vnc.rb index ab21ba64b6..e393668887 100644 --- a/lib/metasploit/framework/login_scanner/vnc.rb +++ b/lib/metasploit/framework/login_scanner/vnc.rb @@ -22,7 +22,7 @@ module Metasploit LIKELY_PORTS = (5900..5910).to_a LIKELY_SERVICE_NAMES = [ 'vnc' ] PRIVATE_TYPES = [ :password ] - REALM_TYPE = nil + REALM_KEY = nil # Error indicating retry should occur for UltraVNC ULTRA_VNC_RETRY_ERROR = 'connection has been rejected' diff --git a/lib/metasploit/framework/login_scanner/winrm.rb b/lib/metasploit/framework/login_scanner/winrm.rb index 16693b8fb3..af079b262e 100644 --- a/lib/metasploit/framework/login_scanner/winrm.rb +++ b/lib/metasploit/framework/login_scanner/winrm.rb @@ -25,7 +25,7 @@ module Metasploit PRIVATE_TYPES = [ :password ] LIKELY_PORTS = [ 80, 443, 5985, 5986 ] - REALM_TYPE = Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN + REALM_KEY = Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN # Inherit LIKELY_SERVICE_NAMES, since a scanner will see it as # just HTTP. diff --git a/spec/support/shared/examples/metasploit/framework/login_scanner/login_scanner_base.rb b/spec/support/shared/examples/metasploit/framework/login_scanner/login_scanner_base.rb index 48c2d05b71..1b0895cd2f 100644 --- a/spec/support/shared/examples/metasploit/framework/login_scanner/login_scanner_base.rb +++ b/spec/support/shared/examples/metasploit/framework/login_scanner/login_scanner_base.rb @@ -5,6 +5,8 @@ shared_examples_for 'Metasploit::Framework::LoginScanner::Base' do let(:public) { 'root' } let(:private) { 'toor' } + let(:realm) { 'myrealm' } + let(:realm_key) { Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN } let(:pub_blank) { Metasploit::Framework::Credential.new( @@ -38,6 +40,16 @@ shared_examples_for 'Metasploit::Framework::LoginScanner::Base' do ) } + let(:ad_cred) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: private, + realm: realm, + realm_key: realm_key + ) + } + let(:detail_group) { [ pub_blank, pub_pub, pub_pri] } @@ -280,4 +292,27 @@ shared_examples_for 'Metasploit::Framework::LoginScanner::Base' do end end + + context '#each_cred_adjusted_for_realm' do + context 'when given an invalid credential' do + it 'raises an ArgumentError' do + expect{ login_scanner.each_cred_adjusted_for_realm(invalid_detail)}.to raise_error ArgumentError + end + end + + context 'when the credential has a realm' do + if described_class::REALM_KEY.present? + context 'when the login_scanner has a REALM_KEY' do + it 'set the realm_key on the credential to that of the scanner' do + output_cred = ad_cred.dup + output_cred.realm_key = described_class::REALM_KEY + expect{ |b| login_scanner.each_cred_adjusted_for_realm(ad_cred, &b)}.to yield_with_args(output_cred) + end + + end + end + + end + end + end