Module: Msf::Exploit::Remote::SMB::Client::KerberosAuthentication
- Defined in:
- lib/msf/core/exploit/remote/smb/client/kerberos_authentication.rb
Overview
This class implements an override for RubySMB’s default authentication method to instead use a kerberos authenticator
Instance Method Summary collapse
- #authenticate ⇒ Object
- #kerberos_authenticator=(kerberos_authenticator) ⇒ Object
-
#smb1_authenticate ⇒ Object
Handles SMB1 Kerberos Authentication by delegating to a kerberos_authenticator implementation to generate a GSS security blob with an embedded AP_REQ.
-
#smb1_kerberos_authenticate(security_buffer) ⇒ String
The raw binary response from the server.
-
#smb1_kerberos_authenticate_packet(security_blob) ⇒ RubySMB::SMB1::Packet::SessionSetupRequest
Generates the RubySMB::SMB1::Packet::SessionSetupRequest packet with the NTLM Type 3 (Auth) message in the security_blob field.
-
#smb2_authenticate ⇒ Object
Handles SMB2 Kerberos Authentication by delegating to a kerberos_authenticator implementation to generate a GSS security blob with an embedded AP_REQ.
- #smb2_kerberos_authenticate(security_blob) ⇒ Object
- #smb2_kerberos_authenticate_packet(security_blob) ⇒ Object
Instance Method Details
#authenticate ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/msf/core/exploit/remote/smb/client/kerberos_authentication.rb', line 13 def authenticate raise ::RubySMB::Error::AuthenticationFailure, "Missing negotiation security buffer" if negotiation_security_buffer.nil? gss_api = OpenSSL::ASN1.decode(negotiation_security_buffer) mech_types = RubySMB::Gss.asn1dig(gss_api, 1, 0, 0, 0)&.value || [] has_kerberos_gss_mech_type = mech_types&.any? { |mech_type| mech_type.value == ::Rex::Proto::Gss::OID_MICROSOFT_KERBEROS_5.value } error = "Unable to negotiate kerberos with the remote host. Expected oid #{::Rex::Proto::Gss::OID_MICROSOFT_KERBEROS_5.value} in #{mech_types.map(&:value).inspect}" raise ::RubySMB::Error::AuthenticationFailure, error unless has_kerberos_gss_mech_type if smb1 smb1_authenticate else smb2_authenticate end end |
#kerberos_authenticator=(kerberos_authenticator) ⇒ Object
9 10 11 |
# File 'lib/msf/core/exploit/remote/smb/client/kerberos_authentication.rb', line 9 def kerberos_authenticator=(kerberos_authenticator) @kerberos_authenticator = kerberos_authenticator end |
#smb1_authenticate ⇒ Object
Handles SMB1 Kerberos Authentication by delegating to a kerberos_authenticator implementation to generate a GSS security blob with an embedded AP_REQ. On success information is stored about the peer/server.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/msf/core/exploit/remote/smb/client/kerberos_authentication.rb', line 37 def smb1_authenticate raise ::RubySMB::Error::AuthenticationFailure, 'Missing kerberos authenticator' unless @kerberos_authenticator kerberos_result = @kerberos_authenticator.authenticate @application_key = @session_key = kerberos_result[:session_key].value[0...16] raw_kerberos_response = smb1_kerberos_authenticate(kerberos_result[:security_blob]) response = smb1_session_setup_response(raw_kerberos_response) @kerberos_authenticator.validate_response!(response.data_block.security_blob) response_code = response.status_code # Store the available OS information before going forward. @peer_native_os = response.data_block.native_os.to_s @peer_native_lm = response.data_block.native_lan_man.to_s @user_id = response.smb_header.uid if response_code == WindowsError::NTStatus::STATUS_SUCCESS response_code end |
#smb1_kerberos_authenticate(security_buffer) ⇒ String
Returns the raw binary response from the server.
63 64 65 66 |
# File 'lib/msf/core/exploit/remote/smb/client/kerberos_authentication.rb', line 63 def smb1_kerberos_authenticate(security_buffer) packet = smb1_kerberos_authenticate_packet(security_buffer) send_recv(packet) end |
#smb1_kerberos_authenticate_packet(security_blob) ⇒ RubySMB::SMB1::Packet::SessionSetupRequest
Generates the RubySMB::SMB1::Packet::SessionSetupRequest packet with the NTLM Type 3 (Auth) message in the security_blob field.
74 75 76 77 78 79 80 81 82 |
# File 'lib/msf/core/exploit/remote/smb/client/kerberos_authentication.rb', line 74 def smb1_kerberos_authenticate_packet(security_blob) packet = RubySMB::SMB1::Packet::SessionSetupRequest.new # packet.smb_header.uid = user_id packet.set_security_buffer(security_blob) packet.parameter_block.max_buffer_size = self.max_buffer_size packet.parameter_block.max_mpx_count = 50 packet.smb_header.flags2.extended_security = 1 packet end |
#smb2_authenticate ⇒ Object
Handles SMB2 Kerberos Authentication by delegating to a kerberos_authenticator implementation to generate a GSS security blob with an embedded AP_REQ. On success information is stored about the peer/server.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/msf/core/exploit/remote/smb/client/kerberos_authentication.rb', line 91 def smb2_authenticate raise ::RubySMB::Error::AuthenticationFailure, 'Missing kerberos authenticator' unless @kerberos_authenticator kerberos_result = @kerberos_authenticator.authenticate raw_kerberos_response = smb2_kerberos_authenticate(kerberos_result[:security_blob]) response = smb2_session_setup_response(raw_kerberos_response) @kerberos_authenticator.validate_response!(response.buffer) @session_id = response.smb2_header.session_id if @encryption_algorithm.present? key_len = OpenSSL::Cipher.new(@encryption_algorithm).key_len else key_len = 16 end @application_key = @session_key = kerberos_result[:session_key].value[0...key_len] @session_is_guest = response.session_flags.guest == 1 if @smb3 if response.session_flags.encrypt_data == 1 # if the server indicates that encryption is required, enable it @session_encrypt_data = true elsif (@session_is_guest && password != '') || (username == '' && password == '') # disable encryption when necessary @session_encrypt_data = false end # see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/7fd079ca-17e6-4f02-8449-46b606ea289c if @dialect == '0x0300' || @dialect == '0x0302' @application_key = RubySMB::Crypto::KDF.counter_mode( @session_key, "SMB2APP\x00", "SmbRpc\x00" ) else @application_key = RubySMB::Crypto::KDF.counter_mode( @session_key, "SMBAppKey\x00", @preauth_integrity_hash_value ) end # otherwise, leave encryption to the default value that it was initialized to end ###### # DEBUG #puts "Session ID = #{@session_id.to_binary_s.each_byte.map {|e| '%02x' % e}.join}" #puts "Session key = #{@session_key.each_byte.map {|e| '%02x' % e}.join}" #puts "PreAuthHash = #{@preauth_integrity_hash_value.each_byte.map {|e| '%02x' % e}.join}" if @preauth_integrity_hash_value ###### response.status_code end |
#smb2_kerberos_authenticate(security_blob) ⇒ Object
152 153 154 155 156 157 158 159 |
# File 'lib/msf/core/exploit/remote/smb/client/kerberos_authentication.rb', line 152 def smb2_kerberos_authenticate(security_blob) packet = smb2_kerberos_authenticate_packet(security_blob) response = send_recv(packet) if @dialect == '0x0311' update_preauth_hash(packet) end response end |
#smb2_kerberos_authenticate_packet(security_blob) ⇒ Object
145 146 147 148 149 150 |
# File 'lib/msf/core/exploit/remote/smb/client/kerberos_authentication.rb', line 145 def smb2_kerberos_authenticate_packet(security_blob) packet = RubySMB::SMB2::Packet::SessionSetupRequest.new packet.set_security_buffer(security_blob) packet.security_mode.signing_enabled = 1 packet end |