make sure to save server challenge bytes
This commit is contained in:
parent
d5082d0f01
commit
949b63ef3e
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -46,7 +46,7 @@ func TestDecodeChallenge(t *testing.T) {
|
||||
}
|
||||
|
||||
challenge.String()
|
||||
|
||||
|
||||
outBytes := challenge.Bytes()
|
||||
|
||||
if len(outBytes) > 0 {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user