Generated from Manticore v1.1.6 • 388 packages. View on pkg.go.dev

ntlmv2

import "github.com/TheManticoreProject/Manticore/crypto/ntlmv2"

Index

Constants

HashcatMode is the hashcat hash-mode number for a NetNTLMv2 response, so a caller writing captured material to a file can label it correctly.

const HashcatMode = 5600

LmChallengeResponseLength is the length in bytes of an LMv2 response: a 16-byte HMAC-MD5 followed by the 8-byte client challenge. Unlike the NT response it is fixed-size, and it is all zeroes when the server’s TargetInfo carried a timestamp.

const LmChallengeResponseLength = 24

NTProofStrLength is the length in bytes of the NTProofStr that prefixes an NTLMv2 NtChallengeResponse. It is the HMAC-MD5 taken over the server challenge concatenated with the blob that follows it ([MS-NLMP] 3.3.2).

const NTProofStrLength = 16

func LMOWFv2

func LMOWFv2(Passwd, User, UserDomain string) []byte

LMOWFv2 computes the LMOWFv2 hash for a given password, username, and domain Source: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/5e550938-91d4-459f-b67d-75d70009e3f3

Returns:

  • The LMOWFv2 hash as a byte slice
  • An error if the computation fails

func NTOWFv2

func NTOWFv2(Passwd, User, UserDomain string) []byte

NTOWFv2 computes the NTOWFv2 hash (ResponseKeyNT) for a given password, username, and domain. Source: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/5e550938-91d4-459f-b67d-75d70009e3f3

func SessionBaseKeyFromResponse

func SessionBaseKeyFromResponse(responseKeyNT []byte, ntChallengeResponse []byte) []byte

SessionBaseKeyFromResponse derives the SessionBaseKey for a verified NTLMv2 response: HMAC_MD5(ResponseKeyNT, NTProofStr) ([MS-NLMP] 3.3.2). It is the acceptor’s route to the key material, taking the NTProofStr from the response as received rather than from a computation of its own.

Parameters:

  • responseKeyNT: the NTOWFv2 for the claimed identity
  • ntChallengeResponse: the response as received, NTProofStr(16) || blob

Returns:

  • The 16-byte SessionBaseKey, or nil if the response carries no NTProofStr

func VerifyNTChallengeResponse

func VerifyNTChallengeResponse(responseKeyNT []byte, serverChallenge [8]byte, ntChallengeResponse []byte) bool

VerifyNTChallengeResponse reports whether an NTLMv2 NT challenge response was produced by a party holding responseKeyNT.

It is the acceptor-side counterpart of ComputeNTChallengeResponse. The two cannot share an implementation: the computing side builds the blob itself from a timestamp and a TargetInfo, whereas a verifier is handed a blob the client chose and must recompute the proof over exactly those bytes. Reconstructing the blob instead would reject every legitimate client whose blob differs in any detail from the one this implementation would have built.

NTProofStr = HMAC_MD5(ResponseKeyNT, ServerChallenge || blob)

where the response is NTProofStr(16) || blob(variable) ([MS-NLMP] 3.3.2). The comparison is constant-time.

Parameters:

  • responseKeyNT: the NTOWFv2 for the claimed identity, as computed by NewNTLMv2CtxWithNTHash
  • serverChallenge: the 8-byte challenge the response answers
  • ntChallengeResponse: the response as received, NTProofStr(16) || blob

Returns:

  • true when the response verifies against responseKeyNT

type NTLMv2Ctx

NTLMv2 represents the components needed for NTLMv2 authentication https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/5e550938-91d4-459f-b67d-75d70009e3f3

type NTLMv2Ctx struct {
    Domain   string
    Username string
    Password string

    ServerChallenge [8]byte
    ClientChallenge [8]byte

    NTHash [16]byte
    LMHash [16]byte

    ResponseKeyNT [16]byte
    ResponseKeyLM [16]byte
}

func NewNTLMv2CtxWithNTHash

func NewNTLMv2CtxWithNTHash(domain, username string, nthash [16]byte, serverChallenge, clientChallenge [8]byte) (*NTLMv2Ctx, error)

NewNTLMv2CtxWithNTHash creates a new NTLMv2 instance with the provided credentials and challenges

Parameters:

  • domain: The domain name
  • username: The username
  • nthash: The 16-byte NT hash
  • serverChallenge: The 8-byte server challenge
  • clientChallenge: The 8-byte client challenge

func NewNTLMv2CtxWithPassword

func NewNTLMv2CtxWithPassword(domain, username, password string, serverChallenge, clientChallenge [8]byte) (*NTLMv2Ctx, error)

NewNTLMv2CtxWithPassword creates a new NTLMv2 instance with the provided credentials and challenges

Parameters:

  • domain: The domain name
  • username: The username
  • password: The plaintext password
  • serverChallenge: The 8-byte server challenge
  • clientChallenge: The 8-byte client challenge

func (*NTLMv2Ctx) ComputeLMChallengeResponse

func (ntlm *NTLMv2Ctx) ComputeLMChallengeResponse(hasTimestamp bool) []byte

ComputeLMChallengeResponse computes the LmChallengeResponse per MS-NLMP 3.1.5.1.2.

When hasTimestamp is true (MsvAvTimestamp was present in the server TargetInfo), the spec requires LmChallengeResponse to be Z(24). Otherwise it is:

HMAC-MD5(ResponseKeyLM, ServerChallenge || ClientChallenge) || ClientChallenge  (24 bytes)

Parameters:

  • hasTimestamp: true when MsvAvTimestamp was present in the server’s TargetInfo

func (*NTLMv2Ctx) ComputeNTChallengeResponse

func (ntlm *NTLMv2Ctx) ComputeNTChallengeResponse(timestamp []byte, targetInfo []byte) ([]byte, []byte, error)

ComputeNTChallengeResponse builds the full NTChallengeResponse (NTProofStr || blob) as specified in MS-NLMP section 3.3.2.

The blob structure (called “temp” in the spec):

RespType(1) | HiRespType(1) | Z(2) | Z(4) | Timestamp(8) | ClientChallenge(8) | Z(4) | TargetInfo(var) | Z(4)

targetInfo should already have MsvAvFlags set (use targetinfo.BuildBlobTargetInfo to prepare it).

Parameters:

  • timestamp: 8-byte Windows FILETIME from MsvAvTimestamp or derived from current time
  • targetInfo: raw TargetInfo bytes prepared for the blob

Returns:

  • ntChallengeResponse: NTProofStr(16) || blob(variable)
  • ntProofStr: the 16-byte NTProofStr (needed for ComputeSessionBaseKey)
  • error

func (*NTLMv2Ctx) ComputeResponse

func (ntlm *NTLMv2Ctx) ComputeResponse(ResponseKeyNT, ResponseKeyLM, ServerChallenge, ClientChallenge, timestamp []byte, ServerName []byte) ([]byte, error)

ComputeResponse computes the combined NTLMv2 challenge response (low-level, explicit params). Prefer ComputeNTChallengeResponse and ComputeLMChallengeResponse for new code.

Parameters:

  • ResponseKeyNT: the 16-byte ResponseKeyNT (NTOWFv2 result)
  • ResponseKeyLM: the 16-byte ResponseKeyLM (same as ResponseKeyNT for NTLMv2)
  • ServerChallenge: the 8-byte server challenge
  • ClientChallenge: the 8-byte client challenge
  • timestamp: the 8-byte Windows FILETIME timestamp
  • ServerName: the raw TargetInfo bytes for the blob

Returns:

  • NTChallengeResponse || LmChallengeResponse concatenated

func (*NTLMv2Ctx) ComputeSessionBaseKey

func (ntlm *NTLMv2Ctx) ComputeSessionBaseKey(ntProofStr []byte) []byte

ComputeSessionBaseKey derives the SessionBaseKey from the NTProofStr.

SessionBaseKey = HMAC-MD5(ResponseKeyNT, NTProofStr)

This key is RC4-encrypted with a random session key when KEY_EXCH is negotiated.

Parameters:

  • ntProofStr: the 16-byte NTProofStr returned by ComputeNTChallengeResponse

type NTLMv2Response

NTLMv2Response is a NetNTLMv2 authentication: the identity that was claimed, the server challenge it answered, and the responses it carried.

NtChallengeResponse is variable-length by construction — NTProofStr(16) || blob(variable), exactly what NTLMv2Ctx.ComputeNTChallengeResponse produces — where the blob holds the response type, a timestamp, the client challenge and the server’s TargetInfo AV_PAIR list. In practice it runs from roughly 44 bytes to a few hundred, so it cannot be held in a fixed-size array.

An NtChallengeResponse of exactly 24 bytes is an NTLMv1 response rather than an NTLMv2 one, and belongs in crypto/ntlmv1.NTLMv1Response, which renders the different layout hashcat expects for it.

type NTLMv2Response struct {
    Username string // Username for authentication
    Domain   string // Domain name

    ServerChallenge     [8]byte  // 8-byte challenge from the server
    LmChallengeResponse [24]byte // 24-byte LMv2 challenge response
    NtChallengeResponse []byte   // NTProofStr(16) || blob(variable)
}

func NewNTLMv2Response

func NewNTLMv2Response(username, domain string, serverChallenge [8]byte, lmChallengeResponse [24]byte, ntChallengeResponse []byte) *NTLMv2Response

NewNTLMv2Response creates a new NTLMv2 response.

Parameters:

  • username: The username
  • domain: The domain name
  • serverChallenge: The 8-byte server challenge
  • lmChallengeResponse: The 24-byte LMv2 challenge response
  • ntChallengeResponse: The NT challenge response, NTProofStr(16) || blob

Returns:

  • A pointer to the new NTLMv2Response

func (*NTLMv2Response) Blob

func (r *NTLMv2Response) Blob() []byte

Blob returns the variable-length blob that follows the NTProofStr in the NT challenge response, or nil when the response is too short to carry one. The blob is what the NTProofStr is computed over, together with the server challenge, so cracking needs both.

Returns:

  • The blob, or nil

func (*NTLMv2Response) HashcatString

func (r *NTLMv2Response) HashcatString() (string, error)

HashcatString renders the response in the format hashcat mode 5600 expects:

username::domain:serverchallenge:ntproofstr:blob

The hex is uppercased for consistency with the rest of this repository; hashcat parses hex case-insensitively.

Returns:

  • The hashcat string
  • An error if the NT challenge response cannot form a mode-5600 line

func (*NTLMv2Response) NTProofStr

func (r *NTLMv2Response) NTProofStr() []byte

NTProofStr returns the 16-byte NTProofStr prefix of the NT challenge response, or nil when the response is too short to carry one.

Returns:

  • The NTProofStr, or nil

func (*NTLMv2Response) String

func (r *NTLMv2Response) String() string

String returns the NTLMv2 response in hashcat mode 5600 form, or the empty string when it cannot be rendered.

Returns:

  • The hashcat string, or ""