Generated from Manticore v1.1.6 • 388 packages. View on pkg.go.dev

authenticate

import "github.com/TheManticoreProject/Manticore/crypto/spnego/ntlm/message/authenticate"

Index

Constants

Unmarshal deserializes a byte slice into an AuthenticateMessage MICLength is the length in bytes of the AUTHENTICATE_MESSAGE message integrity code.

const MICLength = 16

type AuthenticateMessage

AuthenticateMessage is the third message in NTLM authentication Source: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/033d32cc-88f9-4483-9bf2-b273055038ce

type AuthenticateMessage struct {
    header.Header

    // LmChallengeResponseFields (8 bytes): A field containing LmChallengeResponse information.
    LmChallengeResponseFields datafields.DataFields

    // NtChallengeResponseFields (8 bytes): A field containing NtChallengeResponse information.
    NtChallengeResponseFields datafields.DataFields

    // DomainNameFields (8 bytes): A field containing DomainName information.
    DomainNameFields datafields.DataFields

    // UserNameFields (8 bytes): A field containing UserName information.
    UserNameFields datafields.DataFields

    // WorkstationFields (8 bytes): A field containing Workstation information.
    WorkstationFields datafields.DataFields

    // EncryptedRandomSessionKeyFields (8 bytes): A field containing EncryptedRandomSessionKey information.
    EncryptedRandomSessionKeyFields datafields.DataFields

    // NegotiateFlags (4 bytes): In connectionless mode, a NEGOTIATE structure that contains a set of flags (section 2.2.2.5) and represents the conclusion of negotiation—the choices the client has made from the options the server offered in the CHALLENGE_MESSAGE. In connection-oriented mode, a NEGOTIATE structure (section 2.2.2.5) that contains the set of bit flags negotiated in the previous messages.
    NegotiateFlags flags.NegotiateFlags

    // Version (8 bytes): A VERSION structure (section 2.2.2.10) that SHOULD be populated only when the NTLMSSP_NEGOTIATE_VERSION flag is set in the NegotiateFlags field; otherwise, it MUST be set to all zero. This structure is used for debugging purposes only. In normal protocol messages, it is ignored and does not affect the NTLM message processing.
    Version *version.Version

    // MIC (16 bytes): The message integrity for the NTLM NEGOTIATE_MESSAGE, CHALLENGE_MESSAGE, and AUTHENTICATE_MESSAGE.
    MIC [16]byte

    // NeedsMIC indicates that the server's CHALLENGE carried an MsvAvTimestamp, so
    // the client MUST provide a MIC (MS-NLMP 3.1.5.1.2). When set, the AV_PAIRs in
    // the NtChallengeResponse also carry MsvAvFlags with the MIC-present bit.
    NeedsMIC bool

    // MICOffset is the byte offset the MIC was read from, set by Unmarshal when a
    // MIC was present. A verifier needs it to zero the field in the bytes as
    // received: re-marshalling to recompute the digest would only reproduce the
    // original if this implementation encodes the message identically to whoever
    // sent it, which is not something a verifier can assume.
    MICOffset int

    // LmChallengeResponse (16 bytes): A payload containing LmChallengeResponse data.
    LmChallengeResponse []byte

    // NtChallengeResponse (16 bytes): A field containing NtChallengeResponse data.
    NtChallengeResponse []byte

    // DomainName (variable): A field containing DomainName data.
    DomainName []byte

    // UserName (variable): A field containing UserName data.
    UserName []byte

    // Workstation (variable): A field containing Workstation data.
    Workstation []byte

    // EncryptedRandomSessionKey (variable): A field containing EncryptedRandomSessionKey data.
    EncryptedRandomSessionKey []byte

    // SessionKey (16 bytes): The exported session key derived during authentication.
    // This is not transmitted on the wire; it is retained so callers (e.g. SMB message
    // signing) can use it as the MAC key. When no key exchange is negotiated it equals
    // the NTLMv2 SessionBaseKey. It is nil for the NTLMv1 path.
    SessionKey []byte
}

func CreateAuthenticateMessage

func CreateAuthenticateMessage(challenge *challenge.ChallengeMessage, username, password, domain, workstation string) (*AuthenticateMessage, error)

CreateAuthenticateMessage creates an NTLM AUTHENTICATE message from a cleartext password. When the server negotiated extended session security it uses NTLMv2; otherwise it falls back to NTLMv1.

func CreateAuthenticateMessageWithNTHash

func CreateAuthenticateMessageWithNTHash(challenge *challenge.ChallengeMessage, username string, ntHash [16]byte, domain, workstation string) (*AuthenticateMessage, error)

CreateAuthenticateMessageWithNTHash creates an NTLM AUTHENTICATE message from an NT hash instead of a cleartext password (pass-the-hash). It requires the server to have negotiated extended session security, as the derived session key needed for RPC/SMB signing and sealing only exists on the NTLMv2 path; NTLMv1 pass-the-hash is not supported.

func (*AuthenticateMessage) ComputeMIC

func (msg *AuthenticateMessage) ComputeMIC(negotiateMessage, challengeMessage []byte) error

ComputeMIC computes the AUTHENTICATE_MESSAGE message integrity code and stores it in the MIC field (MS-NLMP 3.1.5.1.2). The MIC is HMAC_MD5(ExportedSessionKey, NEGOTIATE_MESSAGE || CHALLENGE_MESSAGE || AUTHENTICATE_MESSAGE), where the AUTHENTICATE_MESSAGE is serialized with a zeroed MIC field. When no key exchange is negotiated, the exported session key equals the SessionBaseKey retained in msg.SessionKey.

It must be called after the message is fully populated and only when NeedsMIC is set (the server’s challenge carried an MsvAvTimestamp).

func (*AuthenticateMessage) GetMessageType

func (msg *AuthenticateMessage) GetMessageType() uint32

GetMessageType returns the message type of the AuthenticateMessage

func (*AuthenticateMessage) Marshal

func (msg *AuthenticateMessage) Marshal() ([]byte, error)

Marshal serializes the AuthenticateMessage into a byte slice

func (*AuthenticateMessage) Unmarshal

func (msg *AuthenticateMessage) Unmarshal(data []byte) (int, error)

func (*AuthenticateMessage) VerifyMIC

func (msg *AuthenticateMessage) VerifyMIC(exportedSessionKey, negotiateMessage, challengeMessage, rawAuthenticate []byte) bool

VerifyMIC reports whether the message integrity code carried by the message verifies against an exported session key, the acceptor-side counterpart of ComputeMIC.

The digest is taken over the message as received, with only the 16 MIC bytes zeroed, rather than over a re-marshalling of the parsed fields: the MIC covers the sender’s exact encoding, and any difference in how this implementation would lay the message out would produce a mismatch that looks identical to a forged MIC.

MIC = HMAC_MD5(ExportedSessionKey, NEGOTIATE || CHALLENGE || AUTHENTICATE)

The comparison is constant-time.

Parameters:

  • exportedSessionKey: the key derived from the verified NT response
  • negotiateMessage: the raw NEGOTIATE_MESSAGE of this exchange
  • challengeMessage: the raw CHALLENGE_MESSAGE of this exchange
  • rawAuthenticate: this message exactly as received

Returns:

  • true when the MIC verifies