SMB2 Session Setup Error

Parent Previous Next

SMB Session Setup Error


Basic SMB2 Workflow


NEGOTIATE →

client and server agree on SMB version/features.

SESSION_SETUP →

client authenticates (user login).

TREE_CONNECT →

client connects to a share (like \\server\share).

CREATE / READ / WRITE →

client performs file operations inside that share.




Session setup with Kerberos Auth


1 SMB2 NEGOTIATE PROTOCOL



2 SMB2 SESSION_SETUP Request (first packet)


The client now wants to authenticate.

It sends a Session Setup Request, which wraps a GSS-API (Generic Security Service API) token using Kerberos.


Important fields in SMB2 header:


Field        Meaning

Command        0x0001 (SESSION_SETUP)

SessionId        0 (no session yet)

SecurityBufferLength        Length of GSS token

SecurityBuffer        Contains GSS-API/Kerberos blob


Security Buffer contains:


GSS-API token →

  Mechanism: Kerberos (OID 1.2.840.113554.1.2.2)

  AP_REQ message (Application Request)



The AP_REQ message contains:


Ticket: encrypted by KDC with server’s key (CIFS/servername@REALM)


Authenticator: timestamp encrypted with client’s session key


Optional checksum with SMB session info (channel bindings, etc.)


3️ Server validates the Kerberos ticket


The SMB server (if domain-joined) forwards the ticket to the Local Security Authority (LSASS) via the Security Support Provider Interface (SSPI).


LSASS checks:


The ticket was issued by a trusted KDC (same AD domain or trusted forest)


The service principal name (SPN) matches the server’s CIFS name

→ e.g. cifs/fileserver.corp.local


The authenticator timestamp is valid and not reused (prevents replay)


If all good, LSASS extracts:


User SID


Group memberships


Privileges (token)


This becomes the user’s access token for the SMB session.


4️ SMB2 SESSION_SETUP Response (STATUS_SUCCESS)


If authentication succeeds, the server replies:


Field        Value

Status        STATUS_SUCCESS (0x00000000)

SessionId        Unique ID assigned to the user session

SecurityBuffer        Optional AP_REP (for mutual authentication)


If mutual authentication is requested, server includes:


AP_REP message with timestamp encrypted by client’s key.


Otherwise, this field may be empty.


Now the session is authenticated and ready to open tree connections (shares).



Session setup with NTLM


1️ SMB2 SESSION_SETUP Request (1st packet)


The client sends a SESSION_SETUP Request to start authentication.


Important fields:


Field        Description

SecurityMode        Flags like signing required

Capabilities        e.g. DFS support, encryption

Channel        Usually 0 (for main session)

SecurityBufferOffset / Length        Contains the auth blob (NTLM/Kerberos token)

SecurityBuffer        GSS-API token (first NTLMSSP Negotiate or Kerberos AP_REQ)


Example for NTLM:


Contains NTLMSSP_NEGOTIATE message inside GSS-API wrapper.


2️ SMB2 SESSION_SETUP Response (1st response)


Server responds with:


STATUS_MORE_PROCESSING_REQUIRED → authentication not complete


SecurityBuffer → contains server’s challenge (e.g., NTLMSSP_CHALLENGE)


At this point, client extracts challenge info (nonce, target name, etc.).


3️ SMB2 SESSION_SETUP Request (2nd packet)


Client replies with another SESSION_SETUP Request:


SecurityBuffer now contains NTLMSSP_AUTH (for NTLM)

or Kerberos AP_REP (if using Kerberos)


Includes authentication proof.


4️ SMB2 SESSION_SETUP Response (final)


Server validates authentication data:


If success → returns STATUS_SUCCESS

and assigns a valid SessionId


If failure → STATUS_LOGON_FAILURE or other error


Session is now established and all future SMB2 commands use this SessionId.



NTLM Authentication Flow in SMB2

Step        Message        Direction        Description

1        NTLMSSP_NEGOTIATE        Client → Server        Client proposes NTLM features

2        NTLMSSP_CHALLENGE        Server → Client        Server sends challenge nonce

3        NTLMSSP_AUTH        Client → Server        Client responds with proof (hash of nonce+password)


After step 3, the server verifies the hash with the user’s password (via domain controller or local SAM).


Kerberos Authentication Flow (if domain joined)


If both client and server are in the same AD domain:


Step        Message        Direction        Description

1        AP_REQ        Client → Server        Includes Kerberos service ticket for CIFS/servername

2        AP_REP        Server → Client        Optional mutual authentication reply


Kerberos is faster (fewer SMB exchanges) since authentication happens using tickets issued by the KDC.




Typical Packet Capture Example (Wireshark)

| Packet | Description                                  | Notes                    |

| ------ | -------------------------------------------- | ------------------------ |

| 1      | SMB2 Negotiate Protocol Request              | client proposes dialects |

| 2      | SMB2 Negotiate Protocol Response             | server confirms dialect  |

| 3      | SMB2 Session Setup Request (NTLM Negotiate)  | start auth               |

| 4      | SMB2 Session Setup Response (NTLM Challenge) | challenge issued         |

| 5      | SMB2 Session Setup Request (NTLM Auth)       | client responds          |

| 6      | SMB2 Session Setup Response (STATUS_SUCCESS) | session established      |




SMB2 NTStatus


Below are the most common NTSTATUS codes you’ll see in SMB, grouped by category.

(There are hundreds defined in ntstatus.h, but SMB only uses a subset.)


| Code (Hex)   | Name                                    | Meaning / Cause                               |

| ------------ | --------------------------------------- | --------------------------------------------- |

| `0x00000000` | **STATUS_SUCCESS**                      | Operation completed successfully              |

| `0x00000103` | **STATUS_PENDING**                      | Operation is in progress (async I/O)          |

| `0xC0000001` | **STATUS_UNSUCCESSFUL**                 | Generic failure                               |

| `0xC0000002` | **STATUS_NOT_IMPLEMENTED**              | Server doesn’t support the command            |

| `0xC0000008` | **STATUS_INVALID_HANDLE**               | Handle is invalid                             |

| `0xC000000D` | **STATUS_INVALID_PARAMETER**            | Invalid argument or malformed packet          |

| `0xC0000010` | **STATUS_INVALID_DEVICE_REQUEST**       | Request not valid for this device             |

| `0xC0000022` | **STATUS_ACCESS_DENIED**                | Access denied — insufficient permissions      |

| `0xC0000034` | **STATUS_OBJECT_NAME_NOT_FOUND**        | File/folder/share not found                   |

| `0xC0000035` | **STATUS_OBJECT_NAME_COLLISION**        | File already exists                           |

| `0xC000003A` | **STATUS_OBJECT_PATH_NOT_FOUND**        | Directory path doesn’t exist                  |

| `0xC000006D` | **STATUS_LOGON_FAILURE**                | Invalid credentials                           |

| `0xC000006E` | **STATUS_ACCOUNT_RESTRICTION**          | Account restricted (logon type not allowed)   |

| `0xC000006F` | **STATUS_INVALID_LOGON_HOURS**          | Login outside allowed hours                   |

| `0xC0000070` | **STATUS_INVALID_WORKSTATION**          | Login not allowed from this client            |

| `0xC0000071` | **STATUS_PASSWORD_EXPIRED**             | Password expired                              |

| `0xC0000072` | **STATUS_ACCOUNT_DISABLED**             | Account disabled                              |

| `0xC00000BB` | **STATUS_NOT_SUPPORTED**                | Operation not supported by server             |

| `0xC0000120` | **STATUS_CANCELLED**                    | Operation cancelled                           |

| `0xC0000133` | **STATUS_TIME_DIFFERENCE_AT_DC**        | Clock skew between client and DC              |

| `0xC000018D` | **STATUS_TRUSTED_RELATIONSHIP_FAILURE** | Computer trust relationship failed (Kerberos) |

| `0xC0000193` | **STATUS_ACCOUNT_EXPIRED**              | Account expired                               |

| `0xC000020C` | **STATUS_BAD_NETWORK_NAME**             | Share name invalid or unavailable             |

| `0xC0000225` | **STATUS_NOT_FOUND**                    | Object not found                              |

| `0xC0000234` | **STATUS_ACCOUNT_LOCKED_OUT**           | Account locked due to bad password attempts   |

| `0xC000035C` | **STATUS_NETWORK_NAME_DELETED**         | Share was disconnected                        |

| `0xC00000DF` | **STATUS_USER_SESSION_DELETED**         | SMB session no longer valid                   |

| `0xC00000CA` | **STATUS_FILE_IS_A_DIRECTORY**          | Tried to open directory as file               |

| `0xC00000CC` | **STATUS_INVALID_LEVEL**                | Invalid information level                     |

| `0xC00000D0` | **STATUS_FILE_CLOSED**                  | File handle closed                            |

| `0xC00000E5` | **STATUS_PIPE_BROKEN**                  | Named pipe disconnected                       |

| `0xC00000F0` | **STATUS_NO_SUCH_USER**                 | User doesn’t exist                            |

| `0xC00000F4` | **STATUS_FATAL_APP_EXIT**               | Fatal error during execution                  |

| `0xC00000FD` | **STATUS_STACK_OVERFLOW**               | Stack overflow (rare in SMB)                  |


www.traceinside.com