Skip to content

fix: echo server TargetInfo in NTLMv2 AUTHENTICATE to fix STATUS_LOGON_FAILURE#2

Open
nima-sayadi wants to merge 1 commit into
drudge:mainfrom
nima-sayadi:fix/ntlmv2-targetinfo-authentication
Open

fix: echo server TargetInfo in NTLMv2 AUTHENTICATE to fix STATUS_LOGON_FAILURE#2
nima-sayadi wants to merge 1 commit into
drudge:mainfrom
nima-sayadi:fix/ntlmv2-targetinfo-authentication

Conversation

@nima-sayadi

Copy link
Copy Markdown

Summary

NTLMv2 authentication fails against real SMB servers even with correct
credentials, returning STATUS_LOGON_FAILURE (0xC000006D) during session setup.
This affects Windows 10/11 and Samba-based NAS (e.g. AVM FritzBox).

Root cause

  • decodeChallengeMessage returned only the 8-byte server challenge and threw
    away the server's TargetInfo (AV_PAIR list) from the CHALLENGE.
  • encodeAuthenticationMessage therefore fabricated its own TargetInfo
    from the client hostname/domain. Per MS-NLMP, the NTLMv2 NTProofStr is an
    HMAC over (among other things) the server's TargetInfo, so a fabricated one
    makes the proof mismatch and the server rejects the logon.
  • The AUTHENTICATE message also advertised negotiateFlags = 0 (stripping
    Unicode / extended session security) and, for unqualified users, hashed with
    an empty/guessed domain.

Fix

  • decodeChallengeMessage now returns the full challenge: server challenge,
    raw TargetInfo, target name, and the parsed domain/timestamp.
  • encodeAuthenticationMessage echoes the server's TargetInfo verbatim,
    derives the domain from the challenge when the caller supplies none, prefers
    the server-supplied timestamp, and advertises correct negotiate flags.
  • createNtlmV2Response includes the trailing reserved field so the blob is
    byte-exact per MS-NLMP.
  • Removed the fabricated-TargetInfo helper and the console.log handshake noise.

Testing

Added test/ntlm.test.ts (run with npm test) validating against the official
MS-NLMP 4.2.4 test vectors:

  • NT hash, NTOWFv2, and the NTLMv2 NTProofStr (68cd0ab8…)
  • CHALLENGE decoding (server challenge, target name, TargetInfo)

Verified end-to-end against a live FritzBox SMB share (previously failing with
STATUS_LOGON_FAILURE, now authenticates and performs file operations).

Notes

  • decodeChallengeMessage now returns an object instead of a Buffer. The only
    in-repo caller (Session) is updated; external callers using it directly would
    need to read .serverChallenge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant