SMB协议详解
⼀、概述
SMB(ServerMessage Block)通信协议是微软(Microsoft)和英特尔(Intel)在1987年制定的协议,主要是作为Microsoft⽹络的通讯协议。SMB 是在会话层(session layer)和(presentation layer)以及⼩部分(application layer)的协议。SMB使⽤了NetBIOS的 (Application Program Interface,简称API),⼀般端⼝使⽤为139,445。另外,它是⼀个开放性的协议,允许了协议扩展——使得它变得更⼤⽽且复杂;⼤约有65个最上层的作业,⽽每个作业都超过120个函数,甚⾄Windows NT也没有全部⽀持到,最近微软⼜把 SMB 改名为 CIFS(CommonInternet File System),并且加⼊了许多新的特⾊。
⼆、协议分析
SMB包头部分,分布如下:
SMB Header的长度为32字节:
typedef unsigned charUCHAR;
typedef unsigned shortUSHORT;
typedef unsigned longULONG;
typedef struct {
ULONG LowPart;
LONG HighPart;
} LARGE_INTEGER;
typedef struct  {
UCHAR Protocol[4];              // Contains 0xFF,'SMB'
UCHAR Command;                // Command code
union {
struct {
UCHAR ErrorClass;        // Error class
UCHAR Reserved;          // Reserved for future use
USHORT Error;            // Error code
} DosError;
ULONG Status;                // 32-bit error code
} Status;
UCHAR Flags;                    // Flags
USHORT Flags2;                  // More flags
union {
USHORT Pad[6];              // Ensure section is 12 bytes long
struct {
USHORTPidHigh;          // High part of PID
ULONG Unused;            // Not used
ULONG Unused2;
} Extra;
};
USHORT Tid;                      // Tree identifier
USHORT Pid;                      // Caller's process id
USHORT Uid;                      // Unauthenticated user id
USHORT Mid;                      // multiplex id
} SMB_HEADER;
NETBIOS Header的长度为4字节:
typedef struct netbiosHeader
{
UCHAR Type; // Type of the packet
UCHAR Flags; // Flags
USHORT Length; // Count of data bytes (netbios header not included)
} NETBIOSHEADER,*PNETBIOSHEADER;
TCP Header为20字节。SMBCommand Header的长度不是固定的,不同的命令有不同的长度。具体命令详解参考下⼀章节。
三、SMB 命令
1、 SMB_COM_DELETE_DIRECTORY (0x01)
这是原始核⼼协议的⼀个命令,⽤来删除⼀个空的⽬录。
、 SMB_COM_CLOSE (0x04)
这是原始核⼼协议的⼀个命令,⽤来关闭和⼀个有效的FID关联的对象的⼀个实例。
、 SMB_COM_FLUSH (0x05)
这是原始核⼼协议的⼀个命令,⽤来要求服务器将当前⽂件的所有数据和信息都写回到存储器上。
、SMB_COM_DELETE (0x06)
这是原始核⼼协议的⼀个命令,⽤来删除⼀个或多个常规⽂件。⽀持⽂件名中有通配符,允许⼀次删除多个⽂件。
、SMB_COM_RENAME (0x07)
这是原始核⼼协议的⼀个命令,⽤来重命名⼀个或多个⽂件或⽬录。允许⽂offset命令
、SMB_COM_CHECK_DIRECTORY (0x10)
这是原始核⼼协议的⼀个命令。⽤来检查指定的路径是否在服务器上存在。
7、SMB_COM_LOCKING_ANDX (0x24)
此命令在LAN Manager 1.0中引⼊,不适⽤⼤于32-bit的⽂件。⽀持最⼤64-bit的实现在NT LAN Manager中引⼊。
此命令⽤来锁定⼀个普通⽂件中⼀段连续的数据。⽀持锁定任⼀指定⽂件中任意多的数据段,前提是这些数据段没有重叠的部分。锁定可以防⽌其他进程使⽤⼀个独⽴的⽂件句柄(FID)对⽂件锁定部分进⾏锁、读和写操作。任何进程使⽤获取锁的⽂件的FID都可以访问被锁定的数据。
此命令也可以被服务器⽤来发送⼀个OpLock中断通知消息给客户端,客户端收到后发送确认消息。这是CIFS协议中服务器发送请求消息的⼀个例⼦。
下⾯列举的是SMB_COM_LOCKING_ANDX后可能发送的命令
·        SMB_COM_CLOSE
·        SMB_COM_FLUSH
·        SMB_COM_LOCKING_ANDX
·        SMB_COM_READ
·        SMB_COM_READ_ANDX
·        SMB_COM_WRITE
·        SMB_COM_WRITE_ANDX
、SMB_COM_TRANSACTION (0x25)
此命令在LAN Manager 1.0中引⼊。为事务处理协议的传输⼦协议服务。这些命令可以⽤于CIFS⽂件系统内部通信的邮箱和命名管道。如果出书的数据超过了会话建⽴时规定的MaxBufferSize,必须使⽤SMB_COM_TRANSACTION_SECONDARY命令来传输超出的部分:SMB_Data.Trans_Data 和 SMB_Data.Trans_Parameter。这两部分在初始化消息中没有固定。
如果客户端没有发送完所有的SMB_Data.Trans_Data,会将DataCount设置为⼩于TotalDataCount的⼀个值。同样的,如果
SMB_Data.Trans_Parameters没有发送完,会设置ParameterCount为⼀个⼩于TotalParameterCount的值。参数部分优先级⾼于数据部分,客户端在每个消息中应该尽量多的发送数据。服务器应该可以接收⽆序到达的
SMB_Data.Trans_Parameters 和 SMB_Data.Trans_Data,不论是⼤量还是少量的数据。
在请求和响应消息中,SMB_Data.Trans_Parameters和SMB_Data.Trans_Data的位置和长度都是由
SMB_Parameters.ParameterOffset、SMB_Parameters.ParameterCount,SMB_Parameters.DataOffset和
SMB_Parameters.DataCount决定。另外需要说明的是,SMB_Parameters.ParameterDisplacement和
SMB_Parameters.DataDisplacement可以⽤来改变发送数据段的序号。服务器应该优先发送SMB_Data.Trans_Parameters。客户端应该准备好组装收到的SMB_Data.Trans_Parameters和SMB_Data.Trans_Data,即使它们是乱序到达的。
、SMB_COM_TRANSACTION_SECONDARY (0x26)
此命令在LAN Manager 1.0中引⼊。⽤来完成SMB_COM_TRANSACTION中未传输完毕数据的传输。
在请求和响应消息中,SMB_Data.Trans_Parameters和SMB_Data.Trans_Data的位置和长度都是由
SMB_Parameters.ParameterOffset、SMB_Parameters.ParameterCount,SMB_Parameters.DataOffset和
SMB_Parameters.DataCount决定。另外需要说明的是,SMB_Parameters.ParameterDisplacement和
SMB_Parameters.DataDisplacement可以⽤来改变发送数据段的序号。服务器应该优先发送SMB_Data.Trans_Parameters。客户端应该准备好组装收到的SMB_Data.Trans_Parameters和SMB_Data.Trans_Data,即使它们是乱序到达的。
、SMB_COM_ECHO (0x2B)
此命令在LAN Manager 1.0中引⼊。客户端发送此命令测试和服务器的传输层连接。
11、SMB_COM_OPEN_ANDX (0x2D)
此命令在LAN Manager 1.0中引⼊。⽤来创建并打开⼀个⽂件,或者打开⼀个已存在的普通⽂件,并执⾏命令链中的命令。命令中包含客户端要打开的⽂件名,命名管道或设备。如果执⾏成功,服务器响应消息中要携带⼀个合法的FID。客户端在后续对此⽂件的操作请求中要提供相同的FID。
下⾯这些命令是可以放在SMB_COM_OPEN_ANDX命令的AndX链中:
·        SMB_COM_READ
·        SMB_COM_READ_ANDX
·        SMB_COM_IOCTL
·        SMB_COM_NO_ANDX_COMMAND
、SMB_COM_READ_ANDX (0x2E)
此命令在LAN Manager 1.0中引⼊,在NT LAN Manager中对其进⾏了扩展。⽤来读取数据,可以读取普通⽂件,命名管道,或直接访问设别,⽐如串⼝(COM)或打印机接⼝(LPT)。如果客户端⽤NT LAN Manager或以后的版本协商,应该发送带有12个参数的请求,这个版本⽀持最⼤64-bit的⽂件。此命令是唯⼀⼀个⽀持读取64-bit⼤⼩⽂件的读取命令。
下⾯这些命令是可以放在SMB_COM_READ_ANDX命令的AndX链中:
·        SMB_COM_CLOSE
、SMB_COM_WRITE_ANDX (0x2F)
此命令在LAN Manager 1.0中引⼊。⽤来向普通⽂件,命名管道,或直接访问设别,⽐如串⼝(COM)
或打印机接⼝(LPT)中写⼊数据。如果客户端⽤NT LAN Manager或以后的版本协商,应该发送带有14个参数的请求,这个版本⽀持最⼤64-bit的⽂件。此命令是唯⼀⼀个⽀持写64-bit⼤⼩⽂件的读取命令。
下⾯这些命令是可以放在SMB_COM_WRITE_ANDX命令的AndX链中:
·        SMB_COM_READ
·        SMB_COM_READ_ANDX
·        SMB_COM_LOCK_AND_READ
·        SMB_COM_CLOSE
、SMB_COM_TRANSACTION2 (0x32)
此命令在LAN Manager 1.2中引⼊。⽀持服务器⽂件系统更丰富的语义集。允许客户端设置和获取扩展的key/value属性对,⽀持长⽂件名(⽐原始的8.3名字格式要长),可以执⾏⽬录搜索及其他任务。
如果客户端没有发送完所有的SMB_Data.Trans_Data,会将DataCount设置为⼩于TotalDataCount的⼀个值。同样的,如果
SMB_Data.Trans_Parameters没有发送完,会设置ParameterCount为⼀个⼩于TotalParameterCount的值。参数部分优先级⾼于数据部分,客户端在每个消息中应该尽量多的发送数据。服务器应该可以接收⽆序到达的
SMB_Data.Trans_Parameters 和 SMB_Data.Trans_Data,不论是⼤量还是少量的数据。
在请求和响应消息中,SMB_Data.Trans2_Parameters和SMB_Data.Trans2_Data的位置和长度都是由
SMB_Parameters.ParameterOffset、SMB_Parameters.ParameterCount,SMB_Parameters.DataOffset和
SMB_Parameters.DataCount决定。另外需要说明的是,SMB_Parameters.ParameterDisplacement和
SMB_Parameters.DataDisplacement可以⽤来改变发送数据段的序号。服务器应该优先发送SMB_Data.Trans2_Parameters。客户端应该准备好组装收到的SMB_Data.Trans2_Parameters和SMB_Data.Trans2_Data,即使它们是乱序到达的。
、SMB_COM_TRANSACTION2_SECONDARY (0x33)
此命令在LAN Manager 1.2中引⼊。⽤来完成SMB_COM_TRANSACTION2中未传完的数据。
、SMB_COM_FIND_CLOSE2 (0x34)
此命令在LAN Manager 1.2中引⼊。⽤来关闭由命令TRANS2_FIND_FIRST2⽽打开的搜索句柄,服务器释放所有和此句柄相关的资源。
、SMB_COM_TREE_DISCONNECT (0x71)
这是⼀个原始核⼼协议命令。⽤来关闭客户端访问服务器资源时使⽤的⼀条逻辑连接,连接依靠SMB头部的TID识别,断开后服务器将此TID视为⽆效的TID。所有和此TID相关的⽂件、⽬录及其他资源都被释放,⽂件和⽬录的锁也会被释放。
、SMB_COM_NEGOTIATE (0x72)
这是⼀个原始核⼼协议命令。⽤来初始化服务器和客户端之间的SMB会话,必须在其他任何SMB命令发送之前完成。
每个SMB会话只能有⼀次协商过程,后续的SMB_COM_NEGOTIATE会被服务器拒绝并返回⼀个错误响应。
、SMB_COM_SESSION_SETUP_ANDX (0x73)
此命令在LAN Manager 1.0中引⼊。相⽐最初的定义,请求和响应消息的格式都有所改变。本⽂介绍CIFS格式,在NT LAN Manager 中定义。当协商使⽤NT LAN Manager时必须使⽤此格式。
此命令⽤来配置⼀个SMB会话。如果服务器运⾏在user级访问控制模式,⾄少发送⼀个SMB_COM_SESSION_SETUP_ANDX命令,执⾏⽤户登录服务器并建⽴⼀个有效的UID。
在CIFS协议中,在SMB_COM_SESSION_SETUP_ANDX命令执⾏成功之前发送SMB_COM_TREE_CONNECT或
SMB_COM_TREE_CONNECT_ANDX是违反协议的,即使服务器运⾏在share级的访问控制模式。在
SMB_COM_SESSION_SETUP_ANDX请求之后,包含SMB_COM_TREE_CONNECT_ANDX批处理请求的AndX链可以满⾜这⼀需求,匿名认证也可以满⾜这⼀需求。
⼀个SMB会话⽤允许有多个SMB_COM_SESSION_SETUP_ANDX,⽤来建⽴额外的UID或建⽴额外的虚拟链路。
下⾯的命令可以放在SMB_COM_SESSION_SETUP_ANDX后⾯的AndX链中:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。