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))
|
||||||
|
|
||||||
|
if a.Version != nil {
|
||||||
buffer.Write(a.Version.Bytes())
|
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 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
n.serverHandle, err = rc4Init(n.serverSealingKey)
|
n.serverHandle, err = rc4Init(n.serverSealingKey)
|
||||||
if err != nil { return err }
|
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 {
|
||||||
|
if n.ByteData != nil {
|
||||||
|
return n.ByteData
|
||||||
|
} else {
|
||||||
return concat(n.Version, n.RandomPad, n.CheckSum, n.SeqNum)
|
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