generate challenge messages
This commit is contained in:
		
							parent
							
								
									a9e17c39f6
								
							
						
					
					
						commit
						d5082d0f01
					
				| @ -5,7 +5,6 @@ import ( | ||||
| 	"encoding/binary" | ||||
| 	"encoding/hex" | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| ) | ||||
| 
 | ||||
| type AvPairType uint16 | ||||
| @ -45,6 +44,11 @@ type AvPairs struct { | ||||
| 	List []AvPair | ||||
| } | ||||
| 
 | ||||
| func (p *AvPairs) AddAvPair(avId AvPairType, bytes []byte) { | ||||
| 	a := &AvPair{AvId: avId, AvLen: uint16(len(bytes)), Value: bytes} | ||||
|   p.List = append(p.List, *a) | ||||
| } | ||||
| 
 | ||||
| func ReadAvPairs(data []byte) *AvPairs { | ||||
| 	pairs := new(AvPairs) | ||||
| 
 | ||||
| @ -153,10 +157,26 @@ func (a *AvPair) String() string { | ||||
| 	switch a.AvId { | ||||
| 	case MsvAvEOL: | ||||
| 		outString = "MsvAvEOL" | ||||
| 	case MsvAvNbComputerName, MsvAvNbDomainName, MsvAvDnsComputerName, MsvAvDnsDomainName, MsvAvDnsTreeName, MsvAvTargetName: | ||||
| 		outString = fmt.Sprintf("%s: %s", reflect.TypeOf(a.AvId).Name(), a.UnicodeStringValue()) | ||||
| 	case MsvAvFlags, MsvAvTimestamp, MsAvRestrictions, MsvChannelBindings: | ||||
| 		outString = fmt.Sprintf("%s: %s", reflect.TypeOf(a.AvId).Name(), hex.EncodeToString(a.Value)) | ||||
| 	case MsvAvNbComputerName: | ||||
| 		outString = "MsAvNbComputerName: " + a.UnicodeStringValue() | ||||
| 	case MsvAvNbDomainName: | ||||
| 		outString = "MsvAvNbDomainName: " + a.UnicodeStringValue() | ||||
| 	case MsvAvDnsComputerName: | ||||
| 		outString = "MsvAvDnsComputerName: " + a.UnicodeStringValue() | ||||
| 	case MsvAvDnsDomainName: | ||||
| 		outString = "MsvAvDnsDomainName: " + a.UnicodeStringValue() | ||||
| 	case MsvAvDnsTreeName: | ||||
| 		outString = "MsvAvDnsTreeName: " + a.UnicodeStringValue() | ||||
| 	case MsvAvFlags: | ||||
| 		outString = "MsvAvFlags: " + hex.EncodeToString(a.Value) | ||||
| 	case MsvAvTimestamp: | ||||
| 		outString = "MsvAvTimestamp: " + hex.EncodeToString(a.Value) | ||||
| 	case MsAvRestrictions: | ||||
| 		outString = "MsAvRestrictions: " + hex.EncodeToString(a.Value) | ||||
| 	case MsvAvTargetName: | ||||
| 		outString = "MsvAvTargetName: " + a.UnicodeStringValue() | ||||
| 	case MsvChannelBindings: | ||||
| 		outString = "MsvChannelBindings: " + hex.EncodeToString(a.Value) | ||||
| 	default: | ||||
| 		outString = fmt.Sprintf("unknown pair type: '%d'", a.AvId) | ||||
| 	} | ||||
|  | ||||
| @ -95,7 +95,7 @@ func ParseChallengeMessage(body []byte) (*Challenge, error) { | ||||
| 
 | ||||
| func (c *Challenge) Bytes() []byte { | ||||
| 	payloadLen := int(c.TargetName.Len + c.TargetInfoPayloadStruct.Len) | ||||
| 	messageLen := 8 + 4 + 12 + 4 + 8 + 8 + 12 + 8 | ||||
| 	messageLen := 8 + 4 + 8 + 4 + 8 + 8 + 8 + 8 | ||||
| 	payloadOffset := uint32(messageLen) | ||||
| 
 | ||||
| 	messageBytes := make([]byte, 0, messageLen+payloadLen) | ||||
| @ -105,18 +105,21 @@ func (c *Challenge) Bytes() []byte { | ||||
| 	binary.Write(buffer, binary.LittleEndian, c.MessageType) | ||||
|    | ||||
| 	c.TargetName.Offset = payloadOffset | ||||
| 	payloadOffset += uint32(c.TargetName.Len) | ||||
| 	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)) | ||||
| 
 | ||||
|   c.TargetInfoPayloadStruct.Offset = payloadOffset | ||||
|   payloadOffset += uint32(c.TargetInfoPayloadStruct.Len) | ||||
|   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)) | ||||
|   } | ||||
| 
 | ||||
| 	// Write out the payloads | ||||
|  | ||||
| @ -46,4 +46,18 @@ func TestDecodeChallenge(t *testing.T) { | ||||
| 	} | ||||
| 
 | ||||
| 	challenge.String() | ||||
| 	 | ||||
| 	outBytes := challenge.Bytes() | ||||
| 
 | ||||
| 	if len(outBytes) > 0 { | ||||
| 		reparsed, err := ParseChallengeMessage(outBytes) | ||||
| 		if err != nil { | ||||
| 			t.Error("Could not re-parse challenge message") | ||||
| 		} | ||||
| 		if reparsed.String() != challenge.String() { | ||||
| 			t.Error("Reparsed message is not the same") | ||||
| 		} | ||||
| 	} else { | ||||
| 		t.Error("Invalid challenge messsage bytes") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -138,6 +138,34 @@ func (f NegotiateFlag) String() string { | ||||
| 	return reflect.TypeOf(f).Name() | ||||
| } | ||||
| 
 | ||||
| func GetFlagName(flag NegotiateFlag) string { | ||||
| 	nameMap := map[NegotiateFlag]string{ | ||||
| 		NTLMSSP_NEGOTIATE_56:                       "NTLMSSP_NEGOTIATE_56", | ||||
| 		NTLMSSP_NEGOTIATE_KEY_EXCH:                 "NTLMSSP_NEGOTIATE_KEY_EXCH", | ||||
| 		NTLMSSP_NEGOTIATE_128:                      "NTLMSSP_NEGOTIATE_128", | ||||
| 		NTLMSSP_NEGOTIATE_VERSION:                  "NTLMSSP_NEGOTIATE_VERSION", | ||||
| 		NTLMSSP_NEGOTIATE_TARGET_INFO:              "NTLMSSP_NEGOTIATE_TARGET_INFO", | ||||
| 		NTLMSSP_REQUEST_NON_NT_SESSION_KEY:         "NTLMSSP_REQUEST_NON_NT_SESSION_KEY", | ||||
| 		NTLMSSP_NEGOTIATE_IDENTIFY:                 "NTLMSSP_NEGOTIATE_IDENTIFY", | ||||
| 		NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: "NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY", | ||||
| 		NTLMSSP_TARGET_TYPE_SERVER:                 "NTLMSSP_TARGET_TYPE_SERVER", | ||||
| 		NTLMSSP_TARGET_TYPE_DOMAIN:                 "NTLMSSP_TARGET_TYPE_DOMAIN", | ||||
| 		NTLMSSP_NEGOTIATE_ALWAYS_SIGN:              "NTLMSSP_NEGOTIATE_ALWAYS_SIGN", | ||||
| 		NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED: "NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED", | ||||
| 		NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED:      "NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED", | ||||
| 		NTLMSSP_ANONYMOUS:                          "NTLMSSP_ANONYMOUS", | ||||
| 		NTLMSSP_NEGOTIATE_NTLM:                     "NTLMSSP_NEGOTIATE_NTLM", | ||||
| 		NTLMSSP_NEGOTIATE_LM_KEY:                   "NTLMSSP_NEGOTIATE_LM_KEY", | ||||
| 		NTLMSSP_NEGOTIATE_DATAGRAM:                 "NTLMSSP_NEGOTIATE_DATAGRAM", | ||||
| 		NTLMSSP_NEGOTIATE_SEAL:                     "NTLMSSP_NEGOTIATE_SEAL", | ||||
| 		NTLMSSP_NEGOTIATE_SIGN:                     "NTLMSSP_NEGOTIATE_SIGN", | ||||
| 		NTLMSSP_REQUEST_TARGET:                     "NTLMSSP_REQUEST_TARGET", | ||||
| 		NTLM_NEGOTIATE_OEM:                         "NTLM_NEGOTIATE_OEM", | ||||
| 		NTLMSSP_NEGOTIATE_UNICODE:                  "NTLMSSP_NEGOTIATE_UNICODE"} | ||||
| 
 | ||||
| 	return nameMap[flag] | ||||
| } | ||||
| 
 | ||||
| func FlagsToString(flags uint32) string { | ||||
| 	allFlags := [...]NegotiateFlag{ | ||||
| 		NTLMSSP_NEGOTIATE_56, | ||||
| @ -166,7 +194,7 @@ func FlagsToString(flags uint32) string { | ||||
| 	var buffer bytes.Buffer | ||||
| 	for i := range allFlags { | ||||
| 		f := allFlags[i] | ||||
| 		buffer.WriteString(fmt.Sprintf("%s: %v\n", f.String(), f.IsSet(flags))) | ||||
| 		buffer.WriteString(fmt.Sprintf("%s: %v\n", GetFlagName(f), f.IsSet(flags))) | ||||
| 	} | ||||
| 	return buffer.String() | ||||
| } | ||||
|  | ||||
| @ -81,8 +81,42 @@ func (n *V2ServerSession) ProcessNegotiateMessage(nm *messages.Negotiate) (err e | ||||
| } | ||||
| 
 | ||||
| func (n *V2ServerSession) GenerateChallengeMessage() (cm *messages.Challenge, err error) { | ||||
| 	// TODO: Generate this challenge message | ||||
| 	return | ||||
| 	cm = new(messages.Challenge) | ||||
| 	cm.Signature = []byte("NTLMSSP\x00") | ||||
| 	cm.MessageType = uint32(2) | ||||
| 	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) | ||||
| 	flags = messages.NTLMSSP_NEGOTIATE_TARGET_INFO.Set(flags) | ||||
| 	flags = messages.NTLMSSP_NEGOTIATE_IDENTIFY.Set(flags) | ||||
| 	flags = messages.NTLMSSP_NEGOTIATE_ALWAYS_SIGN.Set(flags) | ||||
| 	flags = messages.NTLMSSP_NEGOTIATE_NTLM.Set(flags) | ||||
| 	flags = messages.NTLMSSP_NEGOTIATE_DATAGRAM.Set(flags) | ||||
| 	flags = messages.NTLMSSP_NEGOTIATE_SIGN.Set(flags) | ||||
| 	flags = messages.NTLMSSP_REQUEST_TARGET.Set(flags) | ||||
| 	flags = messages.NTLMSSP_NEGOTIATE_UNICODE.Set(flags) | ||||
| 	cm.NegotiateFlags = flags | ||||
| 
 | ||||
| 	cm.ServerChallenge = randomBytes(8) | ||||
| 	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.MsvAvEOL, make([]byte, 0)) | ||||
| 	cm.TargetInfo = pairs | ||||
|   cm.TargetInfoPayloadStruct,_ = messages.CreateBytePayload(pairs.Bytes()) | ||||
| 
 | ||||
| 	cm.Version = &messages.VersionStruct{ProductMajorVersion: uint8(5), ProductMinorVersion: uint8(1), ProductBuild: uint16(2600), NTLMRevisionCurrent: uint8(10)} | ||||
| 	return cm, nil | ||||
| } | ||||
| 
 | ||||
| func (n *V2ServerSession) ProcessAuthenticateMessage(am *messages.Authenticate) (err error) { | ||||
|  | ||||
| @ -113,4 +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 | ||||
| 	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) | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user