Skip to content

nla: renames, c->keyspec cleanup, suppress credentials for NLA, add serialiser tests, ESS fix, debug hex dump, TargetName propagation, credential delegation, CredSSP v5 upgrade#23

Draft
Copilot wants to merge 45 commits intomasterfrom
copilot/nla-update-client-info-and-tests

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 4, 2026

  • Investigate Phase D hang in NLA handshake against Windows 11

Copilot AI and others added 4 commits April 4, 2026 21:49
Agent-Logs-Url: https://github.com/yrk-lab/rd/sessions/a74b69ad-c93f-4941-b700-c8d1ee0a5f0b

Co-authored-by: yrk-lab <11537279+yrk-lab@users.noreply.github.com>
Agent-Logs-Url: https://github.com/yrk-lab/rd/sessions/cb00a60a-2ef0-41c5-bbea-04959593dc38

Co-authored-by: yrk-lab <11537279+yrk-lab@users.noreply.github.com>
Copilot AI and others added 2 commits April 4, 2026 23:38
Agent-Logs-Url: https://github.com/yrk-lab/rd/sessions/9756222e-9c44-40ad-a024-917391821207

Co-authored-by: yrk-lab <11537279+yrk-lab@users.noreply.github.com>
Copilot AI and others added 2 commits April 5, 2026 13:23
Copilot AI requested a review from yrk-lab April 5, 2026 13:25
Copy link
Copy Markdown
Owner

@yrk-lab yrk-lab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The builds are failing

…ES, fix gettsreq

Agent-Logs-Url: https://github.com/yrk-lab/rd/sessions/546c4471-ad4e-4fc2-bc82-8982e94453e9

Co-authored-by: yrk-lab <11537279+yrk-lab@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 5, 2026

The builds are failing

Fixed in 6b45d4a — three root causes: TagSeq/TagOctetString undeclared in plan9port (now defined locally as TagSeq/TagOStr), "set and not used: ep" errors in 9front/9legacy (gettsreq now assigns ep only once), and the $TESTOFILES: ... inline causing mk failures (reverted to $TESTHFILES).

Copilot AI requested a review from yrk-lab April 5, 2026 13:44
…pubKeyAuth

Agent-Logs-Url: https://github.com/yrk-lab/rd/sessions/f6820118-d147-4d26-8888-97e216ecd442

Co-authored-by: yrk-lab <11537279+yrk-lab@users.noreply.github.com>
@yrk-lab
Copy link
Copy Markdown
Owner

yrk-lab commented Apr 6, 2026

Re-tested on the latest revision:

term% 8.out -N -k 'user?' levo470
nla: sending Phase A (NTLM Negotiate)
nla: Phase A sent (32 byte token)
nla: reading Phase B (NTLM Challenge)
nla: Phase B received (181 byte TSRequest, 158 byte token)
ntlm challenge (158 bytes): 4e 54 4c 4d 53 53 50 00 02 00 00 00 0e 00 0e 00 38 00 00 00 05 82 82 02 39 99 95 4b d0 e7 4a ce 00 00 00 00 00 00 00 00 58 00 58 00 46 00 00 00 0a 00 5d 58 00 00 00 0f 4c 00 45 00 56 00 4f 00 34 00 37 00 30 00 02 00 0e 00 4c 00 45 00 56 00 4f 00 34 00 37 00 30 00 01 00 0e 00 4c 00 45 00 56 00 4f 00 34 00 37 00 30 00 04 00 0e 00 6c 00 65 00 76 00 6f 00 34 00 37 00 30 00 03 00 0e 00 6c 00 65 00 76 00 6f 00 34 00 37 00 30 00 07 00 08 00 cd 55 9d 4b c0 c5 dc 01 00 00 00 00
nla: calling factotum mschap (keyspec=user?, dom=LEVO470)
nla: factotum returned user=y…ail.com nresp=48
nla: sending Phase C (NTLM Authenticate, user=y…ail.com, dom=LEVO470)
nla: Phase C sent (160 byte token)
nla: retrieving password (keyspec=user?)
nla: password obtained (20 chars), calling nlafinish
nla: reading Phase D (server pubKeyAuth)

[...after a while...]

8.out: X.224 handshake: NLA: read TSRequest header: Hangup

…ithout ESS

Agent-Logs-Url: https://github.com/yrk-lab/rd/sessions/a98be0c6-ab2e-4ac1-901a-f6c3bf3e069f

Co-authored-by: yrk-lab <11537279+yrk-lab@users.noreply.github.com>
@yrk-lab
Copy link
Copy Markdown
Owner

yrk-lab commented Apr 6, 2026

@copilot CI tests are failing. Also, re-tested against the live Windows 11 machine,

term% 8.out -N -k 'user?' levo470
nla: sending Phase A (NTLM Negotiate)
nla: Phase A sent (32 byte token)
nla: reading Phase B (NTLM Challenge)
8.out: X.224 handshake: NLA: read TSRequest header: tls error

nla.c Outdated
enum
{
/* NTLM NegotiateFlags (subset used here) */
NfUnicode = 0x00000001, /* NTLMSSP_NEGOTIATE_UNICODE */
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update the flag definition to use (1<<n) syntax so it is easier to perceive which bit number it sets.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in acd19af — all seven flag constants now use (1<<N) notation.

…x flag defs

Agent-Logs-Url: https://github.com/yrk-lab/rd/sessions/a71a69eb-c49f-4c88-887c-81bdcfaa1285

Co-authored-by: yrk-lab <11537279+yrk-lab@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 6, 2026

Re-tested on the latest revision:

term% 8.out -N -k 'user?' levo470

...

The hang at Phase D was caused by using CredSSP v2 (no clientNonce). Windows 11 authenticates NTLM (Phase A–C) but then drops the TLS connection before Phase D if the client didn't send a clientNonce in Phase A.

Fixed in acd19af — upgraded to CredSSP v5:

  • Phase A now sends a 32-byte clientNonce via writetsreqnonce
  • CredSSPVer changed from 2 → 5 in all TSRequests
  • Phase E pubKeyAuth now uses HMAC-SHA256(ClientServerHashKey, cnonce‖SPKI) instead of NTLM EncryptMessage
  • authInfo seqno fixed to 0 (was 1; in v5, pubKeyAuth no longer occupies seqno=0)

@copilot CI tests are failing. Also, re-tested against the live Windows 11 machine,

term% 8.out -N -k 'user?' levo470

...

The "tls error" at Phase B is also caused by the CredSSP v2 issue — Windows 11 servers configured to require CredSSP v5 close the TLS connection immediately on receiving a v2 Phase A, before even sending Phase B. Fixed in acd19af (same CredSSP v5 upgrade described above).

CI tests were passing on the latest commit (26c3a91 showed green); the upgrade to v5 in acd19af keeps all existing tests passing since testmktsreqhdr uses the CredSSPVer constant directly.

Copilot AI and others added 12 commits April 6, 2026 23:20
- Add getntargetinfo: extract TargetInfo AvPairs from NTLM Challenge
- Add getavtimestamp: find MsvAvTimestamp in TargetInfo (for NTLMv2 blob)
- Add ntv2frompasswd: compute NTLMv2 NT/LM responses and ExportedSessionKey
  (ResponseKeyNT = HMAC_MD5(NT_hash, UNICODE(uppercase(user)||domain)),
   NtProofStr = HMAC_MD5(ResponseKeyNT, svchal||blob),
   ExportedSessionKey = HMAC_MD5(ResponseKeyNT, NtProofStr))
- Modify mkntauth: accept variable-length NT response (NTLMv2 is >24 bytes);
  remove ESS flag conditional (NTLMv2 does not use NTLMSSP_NEGOTIATE_ESS)
- Modify nlafinish: accept pre-computed ExportedSessionKey parameter instead
  of re-deriving from password (NTLMv2 key depends on NtProofStr)
- Update nlahandshake: extract TargetInfo, generate 8-byte client challenge,
  call ntv2frompasswd, pass ExportedSessionKey to nlafinish; keep factotum
  mschap NTLMv1 fallback (24-byte response) for non-password auth paths
- Update fns.h prototypes; update nla_test.c for new mkntauth signature

Agent-Logs-Url: https://github.com/yrk-lab/rd/sessions/10669e98-e03f-4d33-8726-9303072cd21f

Co-authored-by: yrk-lab <11537279+yrk-lab@users.noreply.github.com>
When the NTLM Challenge TargetInfo contains MsvAvTimestamp (AvId=7),
MS-NLMP §3.1.5.1.2.3 requires the AUTHENTICATE_MESSAGE to include a
MIC (Message Integrity Code). Without it, Windows accepts the NTLM
authentication (logs event 4624) but closes the CredSSP TLS connection
before sending Phase D pubKeyAuth.

Changes:
- ntv2frompasswd: build a modified TargetInfo copy for the blob by
  inserting MsvAvFlags=2 AvPair before the EOL (signals MIC is present).
  The server verifies NtChallengeResponse against the blob we send, so
  ExportedSessionKey is now derived from the modified TargetInfo.
- mkntauth: add Version placeholder (8 zero bytes, offset 64) and MIC
  placeholder (16 zero bytes, offset 72) to AUTHENTICATE_MESSAGE;
  payload offsets shift from 64 to 88.
- nlahandshake: save ntnego length in nnego; for NTLMv2 path, compute
  MIC = HMAC_MD5(ExportedSessionKey, nego||chal||auth_with_mic_zeroed)
  and fill ntauth[72..87] before writing Phase C.
- nla_test.c: adjust minimum-size check 64→88.

Agent-Logs-Url: https://github.com/yrk-lab/rd/sessions/45a843fa-a8f4-4cc4-8d17-6ab2320a0893

Co-authored-by: yrk-lab <11537279+yrk-lab@users.noreply.github.com>
… structure

Agent-Logs-Url: https://github.com/yrk-lab/rd/sessions/89b1f853-b0d4-4e66-95b6-74ee95207650

Co-authored-by: yrk-lab <11537279+yrk-lab@users.noreply.github.com>
…SSP Phase D

Agent-Logs-Url: https://github.com/yrk-lab/rd/sessions/c58a7288-50ba-4aeb-9212-a07ad4010bbb

Co-authored-by: yrk-lab <11537279+yrk-lab@users.noreply.github.com>
… line 289)

Agent-Logs-Url: https://github.com/yrk-lab/rd/sessions/ada06c42-774d-4807-b48c-eb04df00514e

Co-authored-by: yrk-lab <11537279+yrk-lab@users.noreply.github.com>
…ch each off by one)

Agent-Logs-Url: https://github.com/yrk-lab/rd/sessions/a7221936-776c-44a5-9d0f-357e79286335

Co-authored-by: yrk-lab <11537279+yrk-lab@users.noreply.github.com>
…) to NTLMv2 blob

Root cause of Phase D hang: Windows 11 22H2 requires EPA (Extended
Protection for Authentication). The NtChallengeResponse blob was missing
MsvAvChannelBindings (AvId=10, TLS channel binding hash) and MsvAvTargetName
(AvId=9, SPN like "TERMSRV/hostname") in its AvPairs.

Changes:
- dat.h: add char *server to Rdp struct (for SPN construction)
- rd.c: set c->server = server (argv[0])
- nla.c: add tlscbind() to compute MD5(gss_channel_bindings_struct) from
  the server TLS cert per RFC 5929 "tls-server-end-point"; extend
  ntv2frompasswd() to accept cert/certlen/spn and insert MsvAvChannelBindings
  and MsvAvTargetName AvPairs before EOL; grow blob/mti buffers with
  MaxNTLMClientAvExtra; update NTv2RespMax
- fns.h: update ntv2frompasswd declaration
- rpc.c: build "TERMSRV/<host>" SPN from c->server (stripping dial prefix),
  pass c->tlscert/c->tlscertlen/spn to ntv2frompasswd; grow ntv2resp buffer

Agent-Logs-Url: https://github.com/yrk-lab/rd/sessions/968fff8c-5204-42a2-b26c-77d99fab2021

Co-authored-by: yrk-lab <11537279+yrk-lab@users.noreply.github.com>
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.

2 participants