SMB3.kerberosLogin(mutualAuth=True) uses the full AP-REP subkey as Session.SessionKey instead of its first 16 bytes (breaks AES-256 encrypted sessions)
Description
In impacket/smb3.py, SMB3.kerberosLogin() with mutualAuth=True sets Session.SessionKey to the entire AP-REP sub-session key returned by the server. Per [MS-SMB2] §3.2.5.3, Session.SessionKey MUST be the first 16 bytes of the key obtained from the GSS context. The sibling (non-mutual) branch a few lines below already does this correctly with [:16].
For an AES-256 service ticket the sub-session key is 32 bytes, so Session.SessionKey becomes 32 bytes instead of 16. All SMB3 signing/encryption keys are then derived (KDF_CounterMode) from the wrong input, and against a server that requires SMB signing/encryption the session fails immediately after login (the server rejects/resets the first protected request). AES-128 tickets happen to work only because the key is already 16 bytes.
Affected code
impacket/smb3.py, SMB3.kerberosLogin() (line numbers as of master @ 8ea54feb; identical in the 0.13.1 release):
880: apCipher = _enctype_table[int(encAPRepPart['subkey']['keytype'])]()
881: apSessionKey = Key(apCipher.enctype, encAPRepPart['subkey']['keyvalue'].asOctets())
882:
883: sequenceNumber = int(encAPRepPart['seq-number'])
884: self._Session['SessionKey'] = apSessionKey.contents # <-- full key (32 B for AES-256)
885:
886: else:
887: self._Session['SessionKey'] = sessionKey.contents[:16] # <-- correct: first 16 bytes
Note the inconsistency between line 884 (mutual-auth branch, full key) and line 887 (non-mutual branch, [:16]).
Steps to reproduce
Against a DC/server that issues AES-256 tickets and requires SMB signing or encryption:
from impacket.smbconnection import SMBConnection
c = SMBConnection(dc_host, dc_host)
c._SMBConnection.kerberosLogin(user, '', domain, kdcHost=kdc_ip,
useCache=True, mutualAuth=True)
c.connectTree('IPC$') # first protected op -> server resets / rejects the session
With an AES-128 ticket the same flow works, which isolates the cause to the key length.
Expected behavior
Session.SessionKey is the first 16 bytes of the AP-REP sub-session key ([MS-SMB2] §3.2.5.3), so the derived signing/encryption keys match the server and the mutual-auth session works for all supported enctypes (including AES-256).
Actual behavior
The mutual-auth session negotiates successfully but the first signed/encrypted request fails; typical symptom is a connection reset ([Errno 104]) or an SMB error immediately after kerberosLogin, only when the ticket enctype is AES-256.
Suggested fix
Truncate to 16 bytes, matching the non-mutual branch and the spec:
sequenceNumber = int(encAPRepPart['seq-number'])
- self._Session['SessionKey'] = apSessionKey.contents
+ # [MS-SMB2] 3.2.5.3: Session.SessionKey is the first 16 bytes of the GSS key.
+ self._Session['SessionKey'] = apSessionKey.contents[:16]
Environment
- Impacket: confirmed present in the latest release 0.13.1 (tag
impacket_0_13_1, 2026-05-15) and on master (8ea54feb).
- Python: 3.12
- File:
impacket/smb3.py
- Reference: [MS-SMB2] §3.2.5.3 (Session.SessionKey = first 16 bytes of the GSS key).
SMB3.kerberosLogin(mutualAuth=True)uses the full AP-REP subkey asSession.SessionKeyinstead of its first 16 bytes (breaks AES-256 encrypted sessions)Description
In
impacket/smb3.py,SMB3.kerberosLogin()withmutualAuth=TruesetsSession.SessionKeyto the entire AP-REP sub-session key returned by the server. Per [MS-SMB2] §3.2.5.3,Session.SessionKeyMUST be the first 16 bytes of the key obtained from the GSS context. The sibling (non-mutual) branch a few lines below already does this correctly with[:16].For an AES-256 service ticket the sub-session key is 32 bytes, so
Session.SessionKeybecomes 32 bytes instead of 16. All SMB3 signing/encryption keys are then derived (KDF_CounterMode) from the wrong input, and against a server that requires SMB signing/encryption the session fails immediately after login (the server rejects/resets the first protected request). AES-128 tickets happen to work only because the key is already 16 bytes.Affected code
impacket/smb3.py,SMB3.kerberosLogin()(line numbers as ofmaster@8ea54feb; identical in the 0.13.1 release):Note the inconsistency between line 884 (mutual-auth branch, full key) and line 887 (non-mutual branch,
[:16]).Steps to reproduce
Against a DC/server that issues AES-256 tickets and requires SMB signing or encryption:
With an AES-128 ticket the same flow works, which isolates the cause to the key length.
Expected behavior
Session.SessionKeyis the first 16 bytes of the AP-REP sub-session key ([MS-SMB2] §3.2.5.3), so the derived signing/encryption keys match the server and the mutual-auth session works for all supported enctypes (including AES-256).Actual behavior
The mutual-auth session negotiates successfully but the first signed/encrypted request fails; typical symptom is a connection reset (
[Errno 104]) or an SMB error immediately afterkerberosLogin, only when the ticket enctype is AES-256.Suggested fix
Truncate to 16 bytes, matching the non-mutual branch and the spec:
Environment
impacket_0_13_1, 2026-05-15) and onmaster(8ea54feb).impacket/smb3.py