diff --git a/src/ntlm/ntlm.go b/src/ntlm/ntlm.go index b20d33c..11283e7 100644 --- a/src/ntlm/ntlm.go +++ b/src/ntlm/ntlm.go @@ -80,6 +80,7 @@ type ServerSession interface { GenerateChallengeMessage() (*messages.Challenge, error) ProcessAuthenticateMessage(*messages.Authenticate) error + Version() int Seal(message []byte) ([]byte, error) Sign(message []byte) ([]byte, error) Mac(message []byte, sequenceNumber int) ([]byte, error) diff --git a/src/ntlm/ntlmv1.go b/src/ntlm/ntlmv1.go index f535c51..ce05649 100644 --- a/src/ntlm/ntlmv1.go +++ b/src/ntlm/ntlmv1.go @@ -32,6 +32,10 @@ func (n *V1Session) SetMode(mode Mode) { n.mode = mode } +func (n *V1Session) Version() int { + return 1 +} + func (n *V1Session) fetchResponseKeys() (err error) { n.responseKeyLM, err = lmowfv1(n.password) if err != nil { @@ -109,7 +113,7 @@ func (n *V1Session) Sign(message []byte) ([]byte, error) { return nil, nil } -func ntlmV1Mac(message []byte, sequenceNumber int, handle *rc4P.Cipher, sealingKey, signingKey []byte, negotiateFlags uint32) []byte { +func ntlmV1MacOld(message []byte, sequenceNumber int, handle *rc4P.Cipher, sealingKey, signingKey []byte, negotiateFlags uint32) []byte { // TODO: Need to keep track of the sequence number for connection oriented NTLM if messages.NTLMSSP_NEGOTIATE_DATAGRAM.IsSet(negotiateFlags) { handle, _ = reinitSealingKey(sealingKey, sequenceNumber) @@ -118,6 +122,19 @@ func ntlmV1Mac(message []byte, sequenceNumber int, handle *rc4P.Cipher, sealingK return sig.Bytes() } +func ntlmV1Mac(message []byte, sequenceNumber int, handle *rc4P.Cipher, sealingKey, signingKey []byte, negotiateFlags uint32) []byte { + // TODO: Need to keep track of the sequence number for connection oriented NTLM + if messages.NTLMSSP_NEGOTIATE_DATAGRAM.IsSet(negotiateFlags) && messages.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY.IsSet(negotiateFlags) { + handle, _ = reinitSealingKey(sealingKey, sequenceNumber) + } else if messages.NTLMSSP_NEGOTIATE_DATAGRAM.IsSet(negotiateFlags) { + // CONOR: Reinitializing the rc4 cipher on every requst, but not using the + // algorithm as described in the MS-NTLM document. Just reinitialize it directly. + handle, _ = rc4Init(sealingKey) + } + sig := mac(negotiateFlags, handle, signingKey, uint32(sequenceNumber), message) + return sig.Bytes() +} + func (n *V1ServerSession) Mac(message []byte, sequenceNumber int) ([]byte, error) { mac := ntlmV1Mac(message, sequenceNumber, n.serverHandle, n.serverSealingKey, n.serverSigningKey, n.negotiateFlags) return mac, nil diff --git a/src/ntlm/ntlmv2.go b/src/ntlm/ntlmv2.go index 4d89fd6..59e4626 100644 --- a/src/ntlm/ntlmv2.go +++ b/src/ntlm/ntlmv2.go @@ -34,6 +34,10 @@ func (n *V2Session) SetMode(mode Mode) { n.mode = mode } +func (n *V2Session) Version() int { + return 2 +} + func (n *V2Session) fetchResponseKeys() (err error) { // Usually at this point we'd go out to Active Directory and get these keys // Here we are assuming we have the information locally