From 949b63ef3ec12a98ac23d248c5f7e41349c02b84 Mon Sep 17 00:00:00 2001 From: Conor Hunt Date: Sat, 10 Nov 2012 15:57:24 -0500 Subject: [PATCH] make sure to save server challenge bytes --- src/ntlm/messages/av_pairs.go | 2 +- src/ntlm/messages/challenge.go | 34 +++++++++++++++++------------ src/ntlm/messages/challenge_test.go | 2 +- src/ntlm/ntlmv1.go | 4 ++-- src/ntlm/ntlmv2.go | 23 +++++++++---------- src/ntlm/ntlmv2_test.go | 12 +++++----- 6 files changed, 42 insertions(+), 35 deletions(-) diff --git a/src/ntlm/messages/av_pairs.go b/src/ntlm/messages/av_pairs.go index 465ec84..c952971 100644 --- a/src/ntlm/messages/av_pairs.go +++ b/src/ntlm/messages/av_pairs.go @@ -46,7 +46,7 @@ type AvPairs struct { func (p *AvPairs) AddAvPair(avId AvPairType, bytes []byte) { a := &AvPair{AvId: avId, AvLen: uint16(len(bytes)), Value: bytes} - p.List = append(p.List, *a) + p.List = append(p.List, *a) } func ReadAvPairs(data []byte) *AvPairs { diff --git a/src/ntlm/messages/challenge.go b/src/ntlm/messages/challenge.go index da73494..aaacdbe 100644 --- a/src/ntlm/messages/challenge.go +++ b/src/ntlm/messages/challenge.go @@ -48,7 +48,7 @@ type Challenge struct { // version - 8 bytes Version *VersionStruct // payload - variable - Payload []byte + Payload []byte } func ParseChallengeMessage(body []byte) (*Challenge, error) { @@ -67,7 +67,9 @@ func ParseChallengeMessage(body []byte) (*Challenge, error) { var err error challenge.TargetName, err = ReadStringPayload(12, body) - if err != nil { return nil, err } + if err != nil { + return nil, err + } challenge.NegotiateFlags = binary.LittleEndian.Uint32(body[20:24]) @@ -76,7 +78,9 @@ func ParseChallengeMessage(body []byte) (*Challenge, error) { challenge.Reserved = body[32:40] challenge.TargetInfoPayloadStruct, err = ReadBytePayload(40, body) - if err != nil { return nil, err } + if err != nil { + return nil, err + } challenge.TargetInfo = ReadAvPairs(challenge.TargetInfoPayloadStruct.Payload) @@ -84,7 +88,9 @@ func ParseChallengeMessage(body []byte) (*Challenge, error) { if NTLMSSP_NEGOTIATE_VERSION.IsSet(challenge.NegotiateFlags) { challenge.Version, err = ReadVersionStruct(body[offset : offset+8]) - if err != nil { return nil, err } + if err != nil { + return nil, err + } offset = offset + 8 } @@ -103,24 +109,24 @@ func (c *Challenge) Bytes() []byte { buffer.Write(c.Signature) binary.Write(buffer, binary.LittleEndian, c.MessageType) - + c.TargetName.Offset = payloadOffset buffer.Write(c.TargetName.Bytes()) payloadOffset += uint32(c.TargetName.Len) binary.Write(buffer, binary.LittleEndian, c.NegotiateFlags) buffer.Write(c.ServerChallenge) - buffer.Write(make([]byte, 8)) + buffer.Write(make([]byte, 8)) - c.TargetInfoPayloadStruct.Offset = payloadOffset - buffer.Write(c.TargetInfoPayloadStruct.Bytes()) - payloadOffset += uint32(c.TargetInfoPayloadStruct.Len) + c.TargetInfoPayloadStruct.Offset = payloadOffset + buffer.Write(c.TargetInfoPayloadStruct.Bytes()) + payloadOffset += uint32(c.TargetInfoPayloadStruct.Len) - if(c.Version != nil) { - buffer.Write(c.Version.Bytes()) - } else { - buffer.Write(make([]byte, 8)) - } + if c.Version != nil { + buffer.Write(c.Version.Bytes()) + } else { + buffer.Write(make([]byte, 8)) + } // Write out the payloads buffer.Write(c.TargetName.Payload) diff --git a/src/ntlm/messages/challenge_test.go b/src/ntlm/messages/challenge_test.go index 624615e..8cffa8b 100644 --- a/src/ntlm/messages/challenge_test.go +++ b/src/ntlm/messages/challenge_test.go @@ -46,7 +46,7 @@ func TestDecodeChallenge(t *testing.T) { } challenge.String() - + outBytes := challenge.Bytes() if len(outBytes) > 0 { diff --git a/src/ntlm/ntlmv1.go b/src/ntlm/ntlmv1.go index 4981e44..4f786d8 100644 --- a/src/ntlm/ntlmv1.go +++ b/src/ntlm/ntlmv1.go @@ -23,7 +23,7 @@ func (n *V1Session) SetUserInfo(username string, password string, domain string) } func (n *V1Session) SetMode(mode Mode) { - n.mode = mode + n.mode = mode } func (n *V1Session) fetchResponseKeys() (err error) { @@ -214,7 +214,7 @@ func (n *V1ClientSession) ProcessChallengeMessage(cm *messages.Challenge) (err e flags := uint32(0) flags = messages.NTLMSSP_NEGOTIATE_KEY_EXCH.Set(flags) // NOTE: Unsetting this flag in order to get the server to generate the signatures we can recognize - // flags = messages.NTLMSSP_NEGOTIATE_VERSION.Set(flags) + // flags = messages.NTLMSSP_NEGOTIATE_VERSION.Set(flags) flags = messages.NTLMSSP_NEGOTIATE_TARGET_INFO.Set(flags) flags = messages.NTLMSSP_NEGOTIATE_IDENTIFY.Set(flags) flags = messages.NTLMSSP_NEGOTIATE_ALWAYS_SIGN.Set(flags) diff --git a/src/ntlm/ntlmv2.go b/src/ntlm/ntlmv2.go index 04880c2..78fb80c 100644 --- a/src/ntlm/ntlmv2.go +++ b/src/ntlm/ntlmv2.go @@ -23,7 +23,7 @@ func (n *V2Session) SetUserInfo(username string, password string, domain string) } func (n *V2Session) SetMode(mode Mode) { - n.mode = mode + n.mode = mode } func (n *V2Session) fetchResponseKeys() (err error) { @@ -62,7 +62,7 @@ func (n *V2Session) Seal(message []byte) ([]byte, error) { func (n *V2Session) Sign(message []byte) ([]byte, error) { return nil, nil } -func (n *V2Session) Mac(message []byte,sequenceNumber int) ([]byte, error) { +func (n *V2Session) Mac(message []byte, sequenceNumber int) ([]byte, error) { // TODO: Need to keep track of the sequence number for connection oriented NTLM return nil, nil } @@ -84,13 +84,13 @@ func (n *V2ServerSession) GenerateChallengeMessage() (cm *messages.Challenge, er cm = new(messages.Challenge) cm.Signature = []byte("NTLMSSP\x00") cm.MessageType = uint32(2) - cm.TargetName,_ = messages.CreateBytePayload(make([]byte, 0)) + cm.TargetName, _ = messages.CreateBytePayload(make([]byte, 0)) flags := uint32(0) flags = messages.NTLMSSP_NEGOTIATE_KEY_EXCH.Set(flags) - // NOTE: Unsetting this in order for the signatures to work - // flags = messages.NTLMSSP_NEGOTIATE_VERSION.Set(flags) - flags = messages.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY.Set(flags) + // NOTE: Unsetting this in order for the signatures to work + flags = messages.NTLMSSP_NEGOTIATE_VERSION.Set(flags) + flags = messages.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY.Set(flags) flags = messages.NTLMSSP_NEGOTIATE_TARGET_INFO.Set(flags) flags = messages.NTLMSSP_NEGOTIATE_IDENTIFY.Set(flags) flags = messages.NTLMSSP_NEGOTIATE_ALWAYS_SIGN.Set(flags) @@ -101,21 +101,22 @@ func (n *V2ServerSession) GenerateChallengeMessage() (cm *messages.Challenge, er flags = messages.NTLMSSP_NEGOTIATE_UNICODE.Set(flags) cm.NegotiateFlags = flags - cm.ServerChallenge = randomBytes(8) + n.serverChallenge = randomBytes(8) + cm.ServerChallenge = n.serverChallenge cm.Reserved = make([]byte, 8) - + // Create the AvPairs we need pairs := new(messages.AvPairs) pairs.AddAvPair(messages.MsvAvNbDomainName, messages.StringToUtf16("REUTERS")) pairs.AddAvPair(messages.MsvAvNbComputerName, messages.StringToUtf16("UKBP-CBTRMFE06")) pairs.AddAvPair(messages.MsvAvDnsDomainName, messages.StringToUtf16("Reuters.net")) pairs.AddAvPair(messages.MsvAvDnsComputerName, messages.StringToUtf16("ukbp-cbtrmfe06.Reuters.net")) - pairs.AddAvPair(messages.MsvAvDnsTreeName, messages.StringToUtf16("Reuters.net")) + pairs.AddAvPair(messages.MsvAvDnsTreeName, messages.StringToUtf16("Reuters.net")) pairs.AddAvPair(messages.MsvAvEOL, make([]byte, 0)) cm.TargetInfo = pairs - cm.TargetInfoPayloadStruct,_ = messages.CreateBytePayload(pairs.Bytes()) + cm.TargetInfoPayloadStruct, _ = messages.CreateBytePayload(pairs.Bytes()) - cm.Version = &messages.VersionStruct{ProductMajorVersion: uint8(5), ProductMinorVersion: uint8(1), ProductBuild: uint16(2600), NTLMRevisionCurrent: uint8(10)} + cm.Version = &messages.VersionStruct{ProductMajorVersion: uint8(6), ProductMinorVersion: uint8(0), ProductBuild: uint16(2600), NTLMRevisionCurrent: uint8(10)} return cm, nil } diff --git a/src/ntlm/ntlmv2_test.go b/src/ntlm/ntlmv2_test.go index 2b714b7..3003e6e 100644 --- a/src/ntlm/ntlmv2_test.go +++ b/src/ntlm/ntlmv2_test.go @@ -62,14 +62,14 @@ func TestNTLMv2(t *testing.T) { challengeMessageBytes, _ := hex.DecodeString("4e544c4d53535000020000000c000c003800000033828ae20123456789abcdef00000000000000002400240044000000060070170000000f53006500720076006500720002000c0044006f006d00610069006e0001000c0053006500720076006500720000000000") challengeMessage, err := messages.ParseChallengeMessage(challengeMessageBytes) if err == nil { - challengeMessage.String() + challengeMessage.String() } else { - t.Errorf("Could not parse challenge message: %s", err) + t.Errorf("Could not parse challenge message: %s", err) } err = client.ProcessChallengeMessage(challengeMessage) if err != nil { - t.Errorf("Could not process challenge message: %s", err) + t.Errorf("Could not process challenge message: %s", err) } server := new(V2ServerSession) @@ -113,16 +113,16 @@ func TestNTLMv2(t *testing.T) { checkV2Value(t, "client seal key", server.clientSealingKey, "59f600973cc4960a25480a7c196e4c58", nil) checkV2Value(t, "client seal key", server.clientSigningKey, "4788dc861b4782f35d43fd98fe1a2d39", nil) - + // Have the server generate an initial challenge message challenge, err := server.GenerateChallengeMessage() challenge.String() - // Have the client process this server challenge message + // Have the client process this server challenge message client = new(V2ClientSession) client.SetUserInfo("User", "Password", "Domain") err = client.ProcessChallengeMessage(challenge) if err != nil { - t.Errorf("Could not process server generated challenge message: %s", err) + t.Errorf("Could not process server generated challenge message: %s", err) } }