SMB / NetBIOS
Impacket’s SMB implementation is both a packet construction library and
a session implementation. Most CLIs use only SMBConnection, which hides
differences between dialects.
| Module | Role |
|---|---|
nmb.py | NetBIOS name resolution and session framing |
smb.py | SMB1 (NT LM 0.12), \xffSMB |
smb3.py + smb3structs.py | SMB2 and SMB3, \xfeSMB / \xfdSMB when encrypted |
smbconnection.py | Client facade that hides dialect differences |
smbserver.py | Test server (SMBSERVER / SimpleSMBServer) |
Related commands: smbclient, smbserver, DumpNTLMInfo, psexec, ntlmrelayx
Layers
Section titled “Layers”flowchart TB
App["SMBConnection / DCERPC SMBTransport"] --> NMB["NetBIOSTCPSession"]
NMB --> TCP["TCP 445 or 139"]
App --> Neg["NEGOTIATE"]
Neg -->|magic FE| SMB23["smb3.SMB3"]
Neg -->|magic FF| SMB1["smb.SMB"]
SMB23 --> Auth["SESSION_SETUP with NTLM or Kerberos"]
SMB1 --> Auth
Auth --> Tree["TREE_CONNECT"]
Tree --> File["create / read / write"]
Tree --> Pipe["IPC$ named pipe / FSCTL_PIPE_*"]
Even on port 445, messages are wrapped in a NetBIOS session message (type 0x00).
Only port 139 starts with a SESSION REQUEST (0x81); *SMBSERVER obtains the real name through NBSTAT.
Port constants: SMB_SESSION_PORT=445, NETBIOS_SESSION_PORT=139,
NETBIOS_NS_PORT=137.
Negotiation
Section titled “Negotiation”When no preferred dialect is set, SMBConnection.negotiateSession() places
the following in an SMB1 SMB_COM_NEGOTIATE request:
NT LM 0.12 / SMB 2.002 / SMB 2.???On port 139, it omits SMB 2.???. If the first response byte is \xfe, it selects SMB2/3;
otherwise, it stays with SMB1.
smb3.SMB3.negotiateSession() maintains the [MS-SMB2] Connection state.
- Offered dialects, unless specified:
0x0202/0x0210/0x0300/0x0302/0x0311 - If 3.1.1 is offered: negotiation contexts for Preauth Integrity (SHA-512) and Encryption (AES-128-GCM, AES-128-CCM)
RequireSigningif the server setsSIGNING_REQUIREDor the dialect is 3.1.1- Switch to
SMB3Packetwhen the dialect is at least 3.0 (StatusbecomesChannelSequencein requests)
For 3.1.1, it prefers AES-128-GCM and also offers AES-128-CCM. Versions 3.0 / 3.0.2 do not negotiate the cipher and use AES-128-CCM. Compression is not supported.
Authentication
Section titled “Authentication”Both carry NTLM or a Kerberos AP-REQ inside SPNEGO.
| Path | Entry Point | Key Detail |
|---|---|---|
| NTLM | login() | Type1 → Type2 → Type3; exportedSessionKey is the basis for signing and encryption |
| Kerberos | kerberosLogin() | TGS for cifs/<ServerName>; on KDC_ERR_ETYPE_NOSUPP, retry with an NT hash |
| Legacy SMB1 | login_standard() | DES(challenge, LM/NT hash) when extended security is absent |
The extended SMB1 login temporarily disables Unicode.
ntlmFallback applies only to SMB1. When NativeLanMan is Windows 2000 / Samba,
it falls back to NTLMv1.
Signing and Encryption
Section titled “Signing and Encryption”signSMB():
SecurityFeatures = LE64(seq)MD5(SigningSessionKey || SigningChallengeResponse || packet)[:8]seq += 2With an NTLMv2 exported key, the challenge-response portion is empty.
SMB2 / SMB3
Section titled “SMB2 / SMB3”| Dialect | Signing |
|---|---|
| 2.0.2 / 2.1 | HMAC-SHA256(SessionKey, packet)[:16] |
| 3.x | AES_CMAC(SigningKey, packet) (crypto.AES_CMAC) |
Key derivation for 3.x uses crypto.KDF_CounterMode (HMAC-SHA256, 128 bits).
| Key | 3.0 / 3.0.2 | 3.1.1 |
|---|---|---|
| SigningKey | Label SMB2AESCMAC\0, Context SmbSign\0 | Label SMBSigningKey\0, Context = PreauthHash |
| ApplicationKey | SMB2APP\0 / SmbRpc\0 | SMBAppKey\0 / PreauthHash |
| EncryptionKey (C2S) | SMB2AESCCM\0 / ServerIn \0 | SMBC2SCipherKey\0 |
| DecryptionKey (S2C) | SMB2AESCCM\0 / ServerOut\0 | SMBS2CCipherKey\0 |
When the dialect is at least 3.0 and the server advertises GLOBAL_CAP_ENCRYPTION,
the client forces SMB2_SESSION_FLAG_ENCRYPT_DATA unless it is a guest or anonymous session.
Encrypted PDUs use the SMB2_TRANSFORM_HEADER marked by \xfdSMB and
AES-128-GCM or AES-128-CCM, as selected during negotiation.
RPC over SMB3 uses the ApplicationKey returned by getSessionKey().
It does not use the raw NTLM session key.
Tree Connections and Named Pipes
Section titled “Tree Connections and Named Pipes”connectTree() builds \\host\SHARE and retains the TreeID.
The typical DCERPC path is:
connectTree('IPC$')- If needed, call
waitNamedPipe(SMB1 TRANS_WAIT_NMPIPEorFSCTL_PIPE_WAIT) - Open
\pipe\<name>usingcreate/nt_create_andx - Use
transactNamedPipe(TRANS_TRANSACT_NMPIPE=0x26) orFSCTL_PIPE_TRANSCEIVE=0x0011C017
listShares() enumerates shares through srvsvc RPC (NetrShareEnum info
level 1) on the same session, not through SMB1 LANMAN. listSharesWithPrivs()
uses info level 502 and returns share privilege fields; it requires
administrator privileges. The SMB3 client’s list_shared is unimplemented.
Server Implementation Scope
Section titled “Server Implementation Scope”SimpleSMBServer / SMBSERVER:
- SMB1 uses
NT LM 0.12and offers NTLMSSP with extended security - SMB2/3 response dialects are 2.0.2, 2.1, and 3.1.1; 3.1.1 supports preauth hashes and AES-128-GCM / AES-128-CCM encryption
- If the credential store is empty, a path through SMB1 standard security may treat authentication as successful
registerNamedPipecan attach in-process DCERPC (srvsvc/wkssvc)- Hooks (
hookSmbCommand/hookSmb2Command) are used by tools such as karmaSMB
Check individually for unsupported features such as SMB 3.0 / 3.0.2 and multichannel.
Implementation Limitations
Section titled “Implementation Limitations”- Oplock breaks and multichannel binding are not implemented. Some compound requests are handled, but do not assume every pattern works
- Transform decryption verifies GCM / CCM authentication tags
- The client’s encryption nonce is an 11-character ASCII string for AES-CCM or
a 12-character string for AES-GCM, generated with
random.choicerather than a CSPRNG negoexis not connected to SMB login
Checks When Making Changes
Section titled “Checks When Making Changes”- Keep dialect branching inside
SMBConnection - Preserve signing sequences, preauth hashes, and EncryptData per tree
- For new create options or information classes, check constants for both SMB1 and SMB2
- Related tests:
tests/SMB_RPC/

