fixes from NTLM real world testing
This commit is contained in:
		
							parent
							
								
									949b63ef3e
								
							
						
					
					
						commit
						d2a17e1782
					
				| @ -62,7 +62,7 @@ func sealKey(flags uint32, randomSessionKey []byte, mode string) (sealKey []byte | |||||||
| 		if messages.NTLMSSP_NEGOTIATE_56.IsSet(flags) { | 		if messages.NTLMSSP_NEGOTIATE_56.IsSet(flags) { | ||||||
| 			sealKey = concat(randomSessionKey[0:7], []byte{0xA0}) | 			sealKey = concat(randomSessionKey[0:7], []byte{0xA0}) | ||||||
| 		} else { | 		} else { | ||||||
| 			sealKey = concat(randomSessionKey[0:4], []byte{0xE5, 0x38, 0xB0}) | 			sealKey = concat(randomSessionKey[0:5], []byte{0xE5, 0x38, 0xB0}) | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		sealKey = randomSessionKey | 		sealKey = randomSessionKey | ||||||
|  | |||||||
| @ -211,7 +211,12 @@ func (a *Authenticate) Bytes() []byte { | |||||||
| 	buffer.Write(a.EncryptedRandomSessionKey.Bytes()) | 	buffer.Write(a.EncryptedRandomSessionKey.Bytes()) | ||||||
| 
 | 
 | ||||||
| 	buffer.Write(Uint32ToBytes(a.NegotiateFlags)) | 	buffer.Write(Uint32ToBytes(a.NegotiateFlags)) | ||||||
| 	buffer.Write(a.Version.Bytes()) | 
 | ||||||
|  | 	if a.Version != nil { | ||||||
|  | 		buffer.Write(a.Version.Bytes()) | ||||||
|  | 	} else { | ||||||
|  | 		buffer.Write(make([]byte, 8)) | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	if a.Mic != nil { | 	if a.Mic != nil { | ||||||
| 		buffer.Write(a.Mic) | 		buffer.Write(a.Mic) | ||||||
|  | |||||||
| @ -122,11 +122,11 @@ func (c *Challenge) Bytes() []byte { | |||||||
| 	buffer.Write(c.TargetInfoPayloadStruct.Bytes()) | 	buffer.Write(c.TargetInfoPayloadStruct.Bytes()) | ||||||
| 	payloadOffset += uint32(c.TargetInfoPayloadStruct.Len) | 	payloadOffset += uint32(c.TargetInfoPayloadStruct.Len) | ||||||
| 
 | 
 | ||||||
| 	if c.Version != nil { | 	// if(c.Version != nil) { | ||||||
| 		buffer.Write(c.Version.Bytes()) | 	buffer.Write(c.Version.Bytes()) | ||||||
| 	} else { | 	// } else { | ||||||
| 		buffer.Write(make([]byte, 8)) | 	//  buffer.Write(make([]byte, 8)) | ||||||
| 	} | 	//} | ||||||
| 
 | 
 | ||||||
| 	// Write out the payloads | 	// Write out the payloads | ||||||
| 	buffer.Write(c.TargetName.Payload) | 	buffer.Write(c.TargetName.Payload) | ||||||
|  | |||||||
| @ -38,7 +38,7 @@ func (v *VersionStruct) Bytes() []byte { | |||||||
| 	binary.Write(buffer, binary.LittleEndian, v.ProductMinorVersion) | 	binary.Write(buffer, binary.LittleEndian, v.ProductMinorVersion) | ||||||
| 	binary.Write(buffer, binary.LittleEndian, v.ProductBuild) | 	binary.Write(buffer, binary.LittleEndian, v.ProductBuild) | ||||||
| 	buffer.Write(make([]byte, 3)) | 	buffer.Write(make([]byte, 3)) | ||||||
| 	binary.Write(buffer, binary.LittleEndian, uint8(0x0F)) | 	binary.Write(buffer, binary.LittleEndian, uint8(v.NTLMRevisionCurrent)) | ||||||
| 
 | 
 | ||||||
| 	return buffer.Bytes() | 	return buffer.Bytes() | ||||||
| } | } | ||||||
|  | |||||||
| @ -71,6 +71,7 @@ func CreateServerSession(version Version, mode Mode) (n ServerSession, err error | |||||||
| type ServerSession interface { | type ServerSession interface { | ||||||
| 	SetUserInfo(username string, password string, domain string) | 	SetUserInfo(username string, password string, domain string) | ||||||
| 	SetMode(mode Mode) | 	SetMode(mode Mode) | ||||||
|  | 	SetServerChallenge(challege []byte) | ||||||
| 
 | 
 | ||||||
| 	ProcessNegotiateMessage(*messages.Negotiate) error | 	ProcessNegotiateMessage(*messages.Negotiate) error | ||||||
| 	GenerateChallengeMessage() (*messages.Challenge, error) | 	GenerateChallengeMessage() (*messages.Challenge, error) | ||||||
|  | |||||||
| @ -79,7 +79,15 @@ func (n *V1Session) computeKeyExchangeKey() (err error) { | |||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (n *V1Session) calculateKeys() (err error) { | func (n *V1Session) calculateKeys(ntlmRevisionCurrent uint8) (err error) { | ||||||
|  | 	// This lovely piece of code comes courtesy of an the excellent Open Document support system from MSFT | ||||||
|  | 	// In order to calculate the keys correctly when the client has set the NTLMRevisionCurrent to 0xF (15) | ||||||
|  | 	// We must treat the flags as if NTLMSSP_NEGOTIATE_LM_KEY is set. | ||||||
|  | 	// This information is not contained (at least currently, until they correct it) in the MS-NLMP document | ||||||
|  | 	if ntlmRevisionCurrent == 15 { | ||||||
|  | 		n.negotiateFlags = messages.NTLMSSP_NEGOTIATE_LM_KEY.Set(n.negotiateFlags) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	n.clientSigningKey = signKey(n.negotiateFlags, n.exportedSessionKey, "Client") | 	n.clientSigningKey = signKey(n.negotiateFlags, n.exportedSessionKey, "Client") | ||||||
| 	n.serverSigningKey = signKey(n.negotiateFlags, n.exportedSessionKey, "Server") | 	n.serverSigningKey = signKey(n.negotiateFlags, n.exportedSessionKey, "Server") | ||||||
| 	n.clientSealingKey = sealKey(n.negotiateFlags, n.exportedSessionKey, "Client") | 	n.clientSealingKey = sealKey(n.negotiateFlags, n.exportedSessionKey, "Client") | ||||||
| @ -97,6 +105,9 @@ func (n *V1Session) Sign(message []byte) ([]byte, error) { | |||||||
| 
 | 
 | ||||||
| func (n *V1Session) Mac(message []byte, sequenceNumber int) ([]byte, error) { | func (n *V1Session) Mac(message []byte, sequenceNumber int) ([]byte, error) { | ||||||
| 	// TODO: Need to keep track of the sequence number for connection oriented NTLM | 	// TODO: Need to keep track of the sequence number for connection oriented NTLM | ||||||
|  | 	if messages.NTLMSSP_NEGOTIATE_DATAGRAM.IsSet(n.negotiateFlags) { | ||||||
|  | 		n.serverHandle, _ = reinitSealingKey(n.serverSealingKey, sequenceNumber) | ||||||
|  | 	} | ||||||
| 	sig := mac(n.negotiateFlags, n.serverHandle, n.serverSigningKey, uint32(sequenceNumber), message) | 	sig := mac(n.negotiateFlags, n.serverHandle, n.serverSigningKey, uint32(sequenceNumber), message) | ||||||
| 	return sig.Bytes(), nil | 	return sig.Bytes(), nil | ||||||
| } | } | ||||||
| @ -119,6 +130,10 @@ func (n *V1ServerSession) GenerateChallengeMessage() (cm *messages.Challenge, er | |||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (n *V1ServerSession) SetServerChallenge(challenge []byte) { | ||||||
|  | 	n.serverChallenge = challenge | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (n *V1ServerSession) ProcessAuthenticateMessage(am *messages.Authenticate) (err error) { | func (n *V1ServerSession) ProcessAuthenticateMessage(am *messages.Authenticate) (err error) { | ||||||
| 	n.authenticateMessage = am | 	n.authenticateMessage = am | ||||||
| 	n.negotiateFlags = am.NegotiateFlags | 	n.negotiateFlags = am.NegotiateFlags | ||||||
| @ -159,7 +174,7 @@ func (n *V1ServerSession) ProcessAuthenticateMessage(am *messages.Authenticate) | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = n.calculateKeys() | 	err = n.calculateKeys(am.Version.NTLMRevisionCurrent) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @ -214,7 +229,8 @@ func (n *V1ClientSession) ProcessChallengeMessage(cm *messages.Challenge) (err e | |||||||
| 	flags := uint32(0) | 	flags := uint32(0) | ||||||
| 	flags = messages.NTLMSSP_NEGOTIATE_KEY_EXCH.Set(flags) | 	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 | 	// 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_EXTENDED_SESSIONSECURITY.Set(flags) | ||||||
| 	flags = messages.NTLMSSP_NEGOTIATE_TARGET_INFO.Set(flags) | 	flags = messages.NTLMSSP_NEGOTIATE_TARGET_INFO.Set(flags) | ||||||
| 	flags = messages.NTLMSSP_NEGOTIATE_IDENTIFY.Set(flags) | 	flags = messages.NTLMSSP_NEGOTIATE_IDENTIFY.Set(flags) | ||||||
| 	flags = messages.NTLMSSP_NEGOTIATE_ALWAYS_SIGN.Set(flags) | 	flags = messages.NTLMSSP_NEGOTIATE_ALWAYS_SIGN.Set(flags) | ||||||
| @ -251,7 +267,7 @@ func (n *V1ClientSession) ProcessChallengeMessage(cm *messages.Challenge) (err e | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = n.calculateKeys() | 	err = n.calculateKeys(cm.Version.NTLMRevisionCurrent) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -3,9 +3,11 @@ package ntlm | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
|  | 	"encoding/binary" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"ntlm/messages" | 	"ntlm/messages" | ||||||
| 	"strings" | 	"strings" | ||||||
|  | 	"time" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| /******************************* | /******************************* | ||||||
| @ -48,7 +50,15 @@ func (n *V2Session) computeKeyExchangeKey() (err error) { | |||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (n *V2Session) calculateKeys() (err error) { | func (n *V2Session) calculateKeys(ntlmRevisionCurrent uint8) (err error) { | ||||||
|  | 	// This lovely piece of code comes courtesy of an the excellent Open Document support system from MSFT | ||||||
|  | 	// In order to calculate the keys correctly when the client has set the NTLMRevisionCurrent to 0xF (15) | ||||||
|  | 	// We must treat the flags as if NTLMSSP_NEGOTIATE_LM_KEY is set. | ||||||
|  | 	// This information is not contained (at least currently, until they correct it) in the MS-NLMP document | ||||||
|  | 	if ntlmRevisionCurrent == 15 { | ||||||
|  | 		n.negotiateFlags = messages.NTLMSSP_NEGOTIATE_LM_KEY.Set(n.negotiateFlags) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	n.clientSigningKey = signKey(n.negotiateFlags, n.exportedSessionKey, "Client") | 	n.clientSigningKey = signKey(n.negotiateFlags, n.exportedSessionKey, "Client") | ||||||
| 	n.serverSigningKey = signKey(n.negotiateFlags, n.exportedSessionKey, "Server") | 	n.serverSigningKey = signKey(n.negotiateFlags, n.exportedSessionKey, "Server") | ||||||
| 	n.clientSealingKey = sealKey(n.negotiateFlags, n.exportedSessionKey, "Client") | 	n.clientSealingKey = sealKey(n.negotiateFlags, n.exportedSessionKey, "Client") | ||||||
| @ -62,9 +72,14 @@ func (n *V2Session) Seal(message []byte) ([]byte, error) { | |||||||
| func (n *V2Session) Sign(message []byte) ([]byte, error) { | func (n *V2Session) Sign(message []byte) ([]byte, error) { | ||||||
| 	return nil, nil | 	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 | 	// TODO: Need to keep track of the sequence number for connection oriented NTLM | ||||||
| 	return nil, nil | 	if messages.NTLMSSP_NEGOTIATE_DATAGRAM.IsSet(n.negotiateFlags) && messages.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY.IsSet(n.negotiateFlags) { | ||||||
|  | 		n.serverHandle, _ = reinitSealingKey(n.serverSealingKey, sequenceNumber) | ||||||
|  | 	} | ||||||
|  | 	sig := mac(n.negotiateFlags, n.serverHandle, n.serverSigningKey, uint32(sequenceNumber), message) | ||||||
|  | 	return sig.Bytes(), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /************** | /************** | ||||||
| @ -75,6 +90,10 @@ type V2ServerSession struct { | |||||||
| 	V2Session | 	V2Session | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (n *V2ServerSession) SetServerChallenge(challenge []byte) { | ||||||
|  | 	n.serverChallenge = challenge | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (n *V2ServerSession) ProcessNegotiateMessage(nm *messages.Negotiate) (err error) { | func (n *V2ServerSession) ProcessNegotiateMessage(nm *messages.Negotiate) (err error) { | ||||||
| 	n.negotiateMessage = nm | 	n.negotiateMessage = nm | ||||||
| 	return | 	return | ||||||
| @ -88,7 +107,6 @@ func (n *V2ServerSession) GenerateChallengeMessage() (cm *messages.Challenge, er | |||||||
| 
 | 
 | ||||||
| 	flags := uint32(0) | 	flags := uint32(0) | ||||||
| 	flags = messages.NTLMSSP_NEGOTIATE_KEY_EXCH.Set(flags) | 	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_VERSION.Set(flags) | ||||||
| 	flags = messages.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY.Set(flags) | 	flags = messages.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY.Set(flags) | ||||||
| 	flags = messages.NTLMSSP_NEGOTIATE_TARGET_INFO.Set(flags) | 	flags = messages.NTLMSSP_NEGOTIATE_TARGET_INFO.Set(flags) | ||||||
| @ -99,6 +117,7 @@ func (n *V2ServerSession) GenerateChallengeMessage() (cm *messages.Challenge, er | |||||||
| 	flags = messages.NTLMSSP_NEGOTIATE_SIGN.Set(flags) | 	flags = messages.NTLMSSP_NEGOTIATE_SIGN.Set(flags) | ||||||
| 	flags = messages.NTLMSSP_REQUEST_TARGET.Set(flags) | 	flags = messages.NTLMSSP_REQUEST_TARGET.Set(flags) | ||||||
| 	flags = messages.NTLMSSP_NEGOTIATE_UNICODE.Set(flags) | 	flags = messages.NTLMSSP_NEGOTIATE_UNICODE.Set(flags) | ||||||
|  | 
 | ||||||
| 	cm.NegotiateFlags = flags | 	cm.NegotiateFlags = flags | ||||||
| 
 | 
 | ||||||
| 	n.serverChallenge = randomBytes(8) | 	n.serverChallenge = randomBytes(8) | ||||||
| @ -116,7 +135,7 @@ func (n *V2ServerSession) GenerateChallengeMessage() (cm *messages.Challenge, er | |||||||
| 	cm.TargetInfo = pairs | 	cm.TargetInfo = pairs | ||||||
| 	cm.TargetInfoPayloadStruct, _ = messages.CreateBytePayload(pairs.Bytes()) | 	cm.TargetInfoPayloadStruct, _ = messages.CreateBytePayload(pairs.Bytes()) | ||||||
| 
 | 
 | ||||||
| 	cm.Version = &messages.VersionStruct{ProductMajorVersion: uint8(6), ProductMinorVersion: uint8(0), ProductBuild: uint16(2600), NTLMRevisionCurrent: uint8(10)} | 	cm.Version = &messages.VersionStruct{ProductMajorVersion: uint8(5), ProductMinorVersion: uint8(1), ProductBuild: uint16(2600), NTLMRevisionCurrent: uint8(15)} | ||||||
| 	return cm, nil | 	return cm, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -158,7 +177,7 @@ func (n *V2ServerSession) ProcessAuthenticateMessage(am *messages.Authenticate) | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = n.calculateKeys() | 	err = n.calculateKeys(am.Version.NTLMRevisionCurrent) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @ -213,6 +232,7 @@ func (n *V2ClientSession) ProcessChallengeMessage(cm *messages.Challenge) (err e | |||||||
| 	flags := uint32(0) | 	flags := uint32(0) | ||||||
| 	flags = messages.NTLMSSP_NEGOTIATE_KEY_EXCH.Set(flags) | 	flags = messages.NTLMSSP_NEGOTIATE_KEY_EXCH.Set(flags) | ||||||
| 	flags = messages.NTLMSSP_NEGOTIATE_VERSION.Set(flags) | 	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_TARGET_INFO.Set(flags) | ||||||
| 	flags = messages.NTLMSSP_NEGOTIATE_IDENTIFY.Set(flags) | 	flags = messages.NTLMSSP_NEGOTIATE_IDENTIFY.Set(flags) | ||||||
| 	flags = messages.NTLMSSP_NEGOTIATE_ALWAYS_SIGN.Set(flags) | 	flags = messages.NTLMSSP_NEGOTIATE_ALWAYS_SIGN.Set(flags) | ||||||
| @ -221,6 +241,7 @@ func (n *V2ClientSession) ProcessChallengeMessage(cm *messages.Challenge) (err e | |||||||
| 	flags = messages.NTLMSSP_NEGOTIATE_SIGN.Set(flags) | 	flags = messages.NTLMSSP_NEGOTIATE_SIGN.Set(flags) | ||||||
| 	flags = messages.NTLMSSP_REQUEST_TARGET.Set(flags) | 	flags = messages.NTLMSSP_REQUEST_TARGET.Set(flags) | ||||||
| 	flags = messages.NTLMSSP_NEGOTIATE_UNICODE.Set(flags) | 	flags = messages.NTLMSSP_NEGOTIATE_UNICODE.Set(flags) | ||||||
|  | 	flags = messages.NTLMSSP_NEGOTIATE_128.Set(flags) | ||||||
| 
 | 
 | ||||||
| 	n.negotiateFlags = flags | 	n.negotiateFlags = flags | ||||||
| 
 | 
 | ||||||
| @ -229,25 +250,35 @@ func (n *V2ClientSession) ProcessChallengeMessage(cm *messages.Challenge) (err e | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// TODO: Create the AvPairs and timestamp | 	timestamp := timeToWindowsFileTime(time.Now()) | ||||||
| 	/* | 	err = n.computeExpectedResponses(timestamp, cm.TargetInfoPayloadStruct.Payload) | ||||||
| 		//err = n.computeExpectedResponses() | 	if err != nil { | ||||||
| 		//if err != nil { return err } | 		return err | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 		err = n.computeKeyExchangeKey() | 	err = n.computeKeyExchangeKey() | ||||||
| 		if err != nil { return err } | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 		err = n.computeEncryptedSessionKey() | 	err = n.computeEncryptedSessionKey() | ||||||
| 		if err != nil { return err } | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 		err = n.calculateKeys() | 	err = n.calculateKeys(cm.Version.NTLMRevisionCurrent) | ||||||
| 		if err != nil { return err } | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 		n.clientHandle, err = rc4Init(n.clientSealingKey) | 	n.clientHandle, err = rc4Init(n.clientSealingKey) | ||||||
| 		if err != nil { return err } | 	if err != nil { | ||||||
| 		n.serverHandle, err = rc4Init(n.serverSealingKey) | 		return err | ||||||
| 		if err != nil { return err } | 	} | ||||||
| 	*/ | 	n.serverHandle, err = rc4Init(n.serverSealingKey) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -262,7 +293,8 @@ func (n *V2ClientSession) GenerateAuthenticateMessage() (am *messages.Authentica | |||||||
| 	am.Workstation, _ = messages.CreateStringPayload("SQUAREMILL") | 	am.Workstation, _ = messages.CreateStringPayload("SQUAREMILL") | ||||||
| 	am.EncryptedRandomSessionKey, _ = messages.CreateBytePayload(n.encryptedRandomSessionKey) | 	am.EncryptedRandomSessionKey, _ = messages.CreateBytePayload(n.encryptedRandomSessionKey) | ||||||
| 	am.NegotiateFlags = n.negotiateFlags | 	am.NegotiateFlags = n.negotiateFlags | ||||||
| 	am.Version = &messages.VersionStruct{ProductMajorVersion: uint8(5), ProductMinorVersion: uint8(1), ProductBuild: uint16(2600), NTLMRevisionCurrent: uint8(15)} | 	am.Mic = make([]byte, 16) | ||||||
|  | 	am.Version = &messages.VersionStruct{ProductMajorVersion: uint8(5), ProductMinorVersion: uint8(1), ProductBuild: uint16(2600), NTLMRevisionCurrent: 0x0F} | ||||||
| 	return am, nil | 	return am, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -293,3 +325,15 @@ func ntowfv2(user string, passwd string, userDom string) []byte { | |||||||
| func lmowfv2(user string, passwd string, userDom string) []byte { | func lmowfv2(user string, passwd string, userDom string) []byte { | ||||||
| 	return ntowfv2(user, passwd, userDom) | 	return ntowfv2(user, passwd, userDom) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /******************************** | ||||||
|  |  Helper functions | ||||||
|  | *********************************/ | ||||||
|  | 
 | ||||||
|  | func timeToWindowsFileTime(t time.Time) []byte { | ||||||
|  | 	var ll int64 | ||||||
|  | 	ll = (int64(t.Unix()) * int64(10000000)) + int64(116444736000000000) | ||||||
|  | 	buffer := bytes.NewBuffer(make([]byte, 0, 8)) | ||||||
|  | 	binary.Write(buffer, binary.LittleEndian, ll) | ||||||
|  | 	return buffer.Bytes() | ||||||
|  | } | ||||||
|  | |||||||
| @ -6,6 +6,7 @@ import ( | |||||||
| 	"ntlm/messages" | 	"ntlm/messages" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"testing" | 	"testing" | ||||||
|  | 	"time" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func checkV2Value(t *testing.T, name string, value []byte, expected string, err error) { | func checkV2Value(t *testing.T, name string, value []byte, expected string, err error) { | ||||||
| @ -126,3 +127,15 @@ func TestNTLMv2(t *testing.T) { | |||||||
| 		t.Errorf("Could not process server generated challenge message: %s", err) | 		t.Errorf("Could not process server generated challenge message: %s", err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func TestWindowsTimeConversion(t *testing.T) { | ||||||
|  | 	// From http://davenport.sourceforge.net/ntlm.html#theType3Message | ||||||
|  | 	// Next, the blob is constructed. The timestamp is the most tedious part of this; looking at the clock on my desk,  | ||||||
|  | 	// it's about 6:00 AM EDT on June 17th, 2003. In Unix time, that would be 1055844000 seconds after the Epoch.  | ||||||
|  | 	// Adding 11644473600 will give us seconds after January 1, 1601 (12700317600). Multiplying by 107 (10000000)  | ||||||
|  | 	// will give us tenths of a microsecond (127003176000000000). As a little-endian 64-bit value, this is  | ||||||
|  | 	// "0x0090d336b734c301" (in hexadecimal). | ||||||
|  | 	unix := time.Unix(1055844000, 0) | ||||||
|  | 	result := timeToWindowsFileTime(unix) | ||||||
|  | 	checkV2Value(t, "Timestamp", result, "0090d336b734c301", nil) | ||||||
|  | } | ||||||
|  | |||||||
| @ -9,6 +9,7 @@ import ( | |||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type NtlmsspMessageSignature struct { | type NtlmsspMessageSignature struct { | ||||||
|  | 	ByteData []byte | ||||||
| 	// A 32-bit unsigned integer that contains the signature version. This field MUST be 0x00000001. | 	// A 32-bit unsigned integer that contains the signature version. This field MUST be 0x00000001. | ||||||
| 	Version []byte | 	Version []byte | ||||||
| 	// A 4-byte array that contains the random pad for the message. | 	// A 4-byte array that contains the random pad for the message. | ||||||
| @ -24,7 +25,12 @@ func (n *NtlmsspMessageSignature) String() string { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (n *NtlmsspMessageSignature) Bytes() []byte { | func (n *NtlmsspMessageSignature) Bytes() []byte { | ||||||
| 	return concat(n.Version, n.RandomPad, n.CheckSum, n.SeqNum) | 	if n.ByteData != nil { | ||||||
|  | 		return n.ByteData | ||||||
|  | 	} else { | ||||||
|  | 		return concat(n.Version, n.RandomPad, n.CheckSum, n.SeqNum) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Define SEAL(Handle, SigningKey, SeqNum, Message) as | // Define SEAL(Handle, SigningKey, SeqNum, Message) as | ||||||
| @ -78,7 +84,6 @@ func macWithoutExtendedSessionSecurity(handle *rc4P.Cipher, seqNum uint32, messa | |||||||
| 		sig.SeqNum[i] = sig.SeqNum[i] ^ seqNumBytes[i] | 		sig.SeqNum[i] = sig.SeqNum[i] ^ seqNumBytes[i] | ||||||
| 	} | 	} | ||||||
| 	sig.RandomPad = zeroBytes(4) | 	sig.RandomPad = zeroBytes(4) | ||||||
| 
 |  | ||||||
| 	return sig | 	return sig | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user