Server Message Block (SMB) is one of the most important protocols in computer history – it facilitates the sharing of multiple resources in IT networks – printers, computers, files, and much more. It is one of the most widely used protocols in modern networks.

It’s also a protocol that has caused a huge amount of problems globally for many years – weaknesses in the protocol itself, but also in how IT administrators have implemented the protocol have caused many security breaches and facilitated the network traversal of threat actors – Who remembers Wannacry?

This mini series of posts will show the love / hate relationship SMB has within the IT / Cyber industry.

What is SMB?

Server Message Block (SMB) was originally developed at IBM in 1983 by Barry Alan Feigenbaum, the protocol was designed to share access to files and printers across a network of systems running IBM’s OS/2 operating system.

Since its conception, SMB has been implemented and updated many times, across various different platforms:

  • In 1987, Microsoft and 3Com implemented SMB in the (now defunct) Lan Manager OS/2 operating system
  • In 1991, Andrew Tridgell reverse engineered SMB for his Samba protocol which provides similar functionality for Unix-like systems. Samba is now implemented in all Linux distributions, and allows Linux devices to interact in a Windows domain. Samba4 systems can even act as an Active Directory Domain Controller.
    Other SMB implementations for Unix-like systems include NQ, MoSMB, Fusion Share, Likewise, and KSMBD
  • Microsoft’s first implementation of SMB in Windows was with NT 3.1 in 1992. Since then, Microsoft have been updating the the protocol allowing it to interact with newer, underlying transportation protocols, such as Google’s QUIC protocol.
  • NetSMB is the implementation of SMB first used in the FreeBSD operating system with version 4.4 in 2001. This version is also used in MacOS.

SMB is a higher-layer communications protocol – this means that on its own, the protocol does not have the ability to communicate directly across a network, it must use a lower-layer transportation protocol to allow its commands to be passed back and forth.

SMB v1.0 was originally designed to communicate via NetBIOS Frames, but subsequent revisions have allowed the protocol to communicate using transport protocols such as NetBIOS over IPX/SPX (NBX), and NetBIOS over TCP/IP (NetBT). With the release of Windows 2000, SMB now runs via TCP using port 445, a feature known as SMB direct.

Microsoft deprecated SMB v1.0 in 2013 and whilst still able to be installed for backwards compatibility with legacy systems, SMB v1.0 is no longer installed by default on Windows operating systems.

Windows 11 option to install SMB v1.0

In 1996, Microsoft decided to rename their implementation of SMB as CIFS – The Common Internet File System. During this reworking, they introduced many new capabilities to the protocol including support for long filenames, symbolic and hard links, and larger file sizes.

In 2006, Microsoft released SMB v2.0 which improved performance, reduced network noise, and added the ability to send multiple commands in one transaction.

2009 saw the release of SMB v2.1 which had some minor performance upgrades, but introduced the ability to utilise opportunistic locks, whereby the client device requests the server to lock the file for others so that the requesting client can cache the data locally whist using it to save time and networking resources sending updates back and forth. The lock is removed once the client finishes its operation on the file.

SMB v3.0 was released in 2012 with the release of Windows 8.1 / Server 2012R2 with more functionality and increased performance when used in virtualised environments.

SMB v3.0.2 was released with Windows 8.1 in 2013 with some minor performance upgrades. Windows 8.1 allowed for the option to disable SMB v1.0

The release of Windows 10 / Server 2016 in 2015 came with SMB v3.1.1 which at the time of writing, is the current latest version.

SMB structure

The specifications for SMB v1.0 are proprietary and were initially closed, thereby forcing others, such as the previously mentioned Andrew Tridgell to reverse-engineer the protocol to develop systems to interoperate with it.

The SMB v1.0 protocol was eventually published some time after it was reverse engineered, whereas the SMB v2.0 protocol was made available from Microsoft’s Open Specifications Developer Center from the outset.

Microsoft have an in-depth knowledge-base article for SMB/CIFS:
https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/d416ff7c-c536-406e-a951-4f04b2fd1d2b

SMB messages

SMB Messages are divisible into three parts:

  • A fixed-length header
  • A variable length parameter block
  • A variable length data block

The SMB header

The SMB_Header is fixed at 32-bytes in length and includes a number of fields which are used for the transportation of data:

The Protocol field (4 bytes) MUST contain the 4-byte literal string ‘\xFF’, ‘S’, ‘M’, ‘B’, with the letters represented by their respective ASCII values in the order shown. In the earliest available SMB documentation, this field is defined as a one byte message type (0xFF) followed by a three byte server type identifier.

The Command field (1 byte) defines the SMB command being transmitted. There are 75 command types in SMB.

The Status field (4 bytes) is used to communicate error messages from the server to the client.

The Flags field (1 byte) and the Flags2 field (2 bytes) represent various features in effect in the message.

The PIDHigh field (2 bytes)  represents the high-order bytes of a process identifier (PID). It is combined with the PIDLow field below to form a full PID.

The SecurityFeatures field (8 bytes) has three possible interpretations:

  1. If security signatures are negotiated, then the following format must be used:
    SecuritySignature (8 bytes) must contain a cryptographic message signature which is used to check for message integrity.
  2. If the message is being transported over a connectionless transport, then the following format must be used:
    Key (4 bytes) must contain a cryptographic key for validating messages
    CID (2 bytes) must contain a Connection IDentifier
    SequenceNumber (2 bytes) must contain a sequence number for the message
  3. If neither of the two above apply, then the field must be treated as reserved and be set to zero and is ignored.

The Reserved field (2 bytes) is reserved for future use and must always be set to 0x0000.

The TID field is a Tree Identifier which represents an open connection to a share, otherwise known as a tree connect. An open TID MUST be unique within an SMB connection.

The PIDLow field (2 bytes) is the lower 16-bits of the PID, used in combination with the PIDHigh field.

The UID field (2 bytes) is a unique User IDentifier and is user to represent an authenticated SMB session.

The MID field (2 bytes) is a unique Multiplex IDentifier. The MID is assigned by the client, and all messages will include a MID along with a PID to uniquely identify groups of commands belonging to the same logical thread of operation on the client device. 

A Wireshark capture of SMB being used when a Windows device attempts to connect to another Windows device to access resources

The SMB Parameter block

Following the SMB header will be the SMB Parameters block. This block is used to convey SMB command dependent parameters. The parameters sent will differ dependant upon the SMB command being conveyed.

The structure of the parameters block is as follows:

The WordCount field (1 byte) can be zero, indicating that the Words field is empty. If the field is non-zero, then it represents the size of the Words field.

The Words field (variable) contains the message-specific parameters structure. The size of this field MUST be (2 x WordCount) bytes. If WordCount is 0x00, this field is not included.

The SMB Data block

The ByteCount field (2 bytes) can be zero, indicating that the Bytes field is empty. If the field is non-zero, then it represents the size of the Bytes field.

The Bytes field (variable) contains the message-specific data structure. The size of this field MUST be ByteCount bytes. If ByteCount is 0x0000, this field is not included.

In the example below, the client device is attempting to access another Windows device on the Local Network and has transmitted an SMB message containing the SMB_COM_NEGOTIATE data.

This is an original, core protocol command and is used to initiate the SMB connection between client and server (a handshake). The SMB_COM_NEGOTIATE exchange MUST be completed before any other SMB messages are sent to the server.

The process involves a request and a response phase:

During the request stage, the client sends a list of Dialects which is a list of the languages it supports

The dialects list a variable length list of identifiers in order of preference from least to most preferred. The client MUST list only dialects that it supports.

In the example shown, the client is stating that it supports All SMB v2** itterations as well as the older NT LanManager protocol.

For the love of…

Hopefully this post has shown what SMB is, and more importantly, its widespread use in its various incarnations as the primary way of sharing network resources within networks. SMB is vital in networks for the sharing of all manner of resources, and the world would be a very different place without it.

In the next post, I’ll detail some of the issues SMB has caused over the years, and the hate side of this love / hate tale.