SMB详解

SMB详解

一、SMB是什么

SMB(全称是Server Message Block)是一个协议名,可用于在计算机间共享文件、打印机、串口等,电脑上的网上邻居就是靠它实现的。

SMB 是一种客户机/服务器、请求/响应协议。通过 SMB 协议,客户端应用程序可以在各种网络环境下读、写服务器上的文件,以及对服务器程序提出服务请求。此外通过 SMB 协议,应用程序可以访问远程服务器端的文件、以及打印机等资源。

SMB一开始的设计是在NetBIOS协议上运行的,而NetBIOS本身则运行在NetBEUI、IPX/SPX或TCP/IP协议上。

NetBIOS 使用下列端口:UDP/137(NetBIOS 名称服务)、UDP/138(NetBIOS 数据报服务)、TCP/139(NetBIOS 会话服务);SMB 使用下列端口:TCP/139、TCP/445。 #NetBIOS用于局域网内主机名发现

二、SMB连接过程

连接过程如下图,这是微软官网给出的连接过程。
在这里插入图片描述

1、首先通过TCP三次握手向远程目录PC的445端口发起连接,服务器使用任意空闲端口进行回应
在这里插入图片描述
2、客户端向服务器发起请求 Negotiate Protocol Request (0x00),并列出它所支持的所有SMB协议版本
在这里插入图片描述
3、服务器向客户端回应 Negotiate Protocol Response (0x00),并列出希望使用的协议版本。如果没有可使用的协议版本则返回0XFFFFH,结束通信。
在这里插入图片描述
4、确定协议后,在用户输入用户名和密码后,客户端进程向服务器发起一个用户或共享的认证:session setup request
在这里插入图片描述
5、服务器回应发送一个应答 Session setup response数据报来允许或拒绝本次连接。
在这里插入图片描述
建立会话的过程可能不止一次的请求/回复的网络包交换,具体的原因是由于NTLM认证的过程引起的。
6、建立会话完成后,客户端发送一个数据报:Tree connect rerquest SMB并列出它想访问网络资源的名称或者目录(IPC$为空链接)
在这里插入图片描述
7、服务器回应命令:tree connect response应答数据报以表示此次连接是否被接受或拒绝
在这里插入图片描述
8、到此连接完成,用户通过可以通过客户端对服务器远程共享目录进行一些操作(上传下载删除等)

三、应用层SMB协议分析

​ 1、NETBIOS会话服务
在这里插入图片描述

netbiosHeader头部信息共四字节,包括类型1字节,标志1字节,数据体长度。但是抓包出来的只有类型和数据体长度,具体原因目前还不清楚。并且抓包出来的Length字段不包括头长,从客户端读取到的长度是256,减去固定头长4字节,正好252,这是我的猜测。对应读取的buf分别是buf[0](%x)、buf[1](%x)、buf[3]
typedef struct netbiosHeader
{
     UCHAR Type;                 // Type of the packet 类型
     UCHAR Flags;                // Flags	标志位
     USHORT Length;              // Count of data bytes (netbios header not included)数据长度
} NETBIOSHEADER,*PNETBIOSHEADER;

2、SMB协议

2.1 SMB包头:

​ 主要有两种, SMB2_FLAGS_ASYNC_COMMAND 位在Flags中设置,则为异步,否则为同步,两者基本相同。

​ SMB请求头:
在这里插入图片描述
​ SMB回应头:

在这里插入图片描述
2.1.1 SMB2结构体分析

typedef struct smb2_header
{   
UINT        ProtocolId; // 是协议ID,SMB2必须是0xFE、’S’、’M’、’B’SMB对应ascill码表就是53 4d 42 
USHORT      StructureSize; // 是SMB2 Header的大小,必须是64
USHORT      CreditCharge; // 消耗的信用点数
USHORT      ChannelSequence; //该字段向服务器指示客户端的Channel更改。通常为0
USHORT      Reserved;//保留位
USHORT      Command; // 命令,具体见下面章节
USHORT      Credits;
UINT        Flags;
UINT        NextCommand;
LONGLONG    MessageID; //消息ID,在Request和Response中成对出现
UINT        ProcessID;
UINT        TreeID;
LONGLONG    SessionID;//唯一标识该命令建立的会话
LONGLONG    Signature1;
LONGLONG    Signature2;
}SMB2_HEADER,*PSMB2_HEADER;

1、 ProtocolId(4字节):分别对应读取的buf[4](%x)、[5](%c)、[6](%c)、[7](%c),正好是FE、’S’、’M’、’B’

2、smb headlenth(2字节):buf[8 9],此值为固定值

3、CreditCharge(2字节):消耗的信用数,此处值为1–buf[10 11]

4、ChannelSequence(2字节):通常为0—buf[12 13]

5、Reserved (2 bytes):通常为0 ---- buf[14 15]

6、Command命令(2字节):命令编号见下表。buf[16、17]

7、CreditRequest/CreditResponse(2字节):buf[18、19]

8、flags标志(4 个字节):buf[ 20 21 22 23]

9、NextCommand(4 字节):通常为0,不确定,没有逐个打印 buf[ 24 25 26 27]

10、MessageId(8 字节):从NEGOTIATE命令开始为0,其他顺延 buf[ 28 29 30 31 32 33 34 35]

11、Process Id(4 字节): 0x0000feff固定是这个值,一个进程一个值,猜测是。 buf[ 36 37 38 39]

12、TreeId(4字节):通常为0,连接目录后此值会变更 。 buf[ 40 41 42 43]

13、SessionId(8字节):唯一标识该命令建立的会话,在当前进程应该是唯一的。buf[ 44 45 46 47 48 49 50 51]

14、Signature(16bytes):消息签名,根据flags字段设置,通常为0

SMB命令编号:
SMB2 NEGOTIATE       0x0000    SMB2 SESSION_SETUP   0x0001    SMB2 LOGOFF 	       0x0002 
SMB2 TREE_CONNECT    0x0003    SMB2 TREE_DISCONNECT 0x0004    SMB2 CREATE 	       0x0005 
SMB2 CLOSE 	         0x0006    SMB2 FLUSH           0x0007    SMB2 READ 	       0x0008 
SMB2 WRITE 	         0x0009    SMB2 LOCK 	        0x000A    SMB2 IOCTL 	       0x000B
SMB2 CANCEL 	     0x000C    SMB2 ECHO            0x000D    SMB2 QUERY_DIRECTORY 0x000E    
SMB2 CHANGE_NOTIFY 	 0x000F    SMB2 QUERY_INFO 	    0x0010    SMB2 SET_INFO 	   0x0011 
SMB2 OPLOCK_BREAK 	 0x0012 
1、ProtocolId(4 字节):
	协议标识符。该值必须设置为 0x424D53FE,也表示为(按网络顺序)0xFE、“S”、“M”和“B”。但是抓包的值为0xfe534d42,可能是网络字节序的原因,大小端存储。
2、SMB头长(2 字节):必须设置为 64,即SMB2 标头 结构的大小(以字节为单位)。
3、Credit Charge(2字节):在 SMB2.0.2中,该字段不得使用且必须保留。发送方必须将此设置为 0,接收方必须忽略它,此字段表示此请求消耗的信用数。由SMB2协议服务器授予SMB2协议客户端的值,用于限制客户端可以发送到服务器的未完成请求的数量。
4和5只有Resquest有此字段,且由客户端发起,如果是Response,则下一字段为
4、ChannelSequence(2 字节):该字段向服务器指示客户端的Channel更改。
5、Reserved (2 bytes):该字段应该设置为零,服务器必须在收到时忽略它.
6、NT STATUS状态(4字节):只有Response会有此字段,对应的状态值:https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55
7、Command命令(2字节):此数据包的命令代码。该字段必须包含以下有效命令之一。		
    SMB2 NEGOTIATE		0x0000	SMB2 SESSION_SETUP 0x0001	SMB2 LOGOFF	         0x0002 SMB2 TREE_CONNECT  0x0003
    SMB2 TREE_DISCONNECT 0x0004	 SMB2 CREATE        0x0005   SMB2 CLOSE           0x0006 SMB2 FLUSH         0x0007
    SMB2 READ 			0x0008  SMB2 WRITE         0x0009   SMB2 LOCK            0x000A SMB2 IOCTL         0x000B
    SMB2 CANCEL          0x000C  SMB2 ECHO          0x000D   SMB2 QUERY_DIRECTORY 0x000E SMB2 CHANGE_NOTIFY 0x000F
    SMB2 QUERY_INFO      0x0010  SMB2 SET_INFO      0x0011   SMB2 OPLOCK_BREAK    0x0012
8、CreditRequest/CreditResponse(granted):在请求中,此字段指示客户端请求的信用数。在响应中,它指示授予客户的信用数量。
9、flags标志(4 个字节):指示如何处理操作。
10、NextCommand(4 字节):对于复合请求和响应,该字段必须设置为从该 SMB2 标头的开头到随后的8字节对齐的 SMB2 标头的开头的偏移量(以字节为单位)。如果这不是复合请求或响应,或者这是复合请求或响应中的最后一个标头,则此值必须为 0。
11、MessageId(8 字节):在同一 SMB 2 协议传输连接上发送的所有消息中唯一标识消息请求和响应的值。
12、Process Id: 0x0000feff
13、TreeId(4字节):唯一标识命令的树连接。对于SMB2 TREE_CONNECT Resquest,这必须为 0 。TreeId可以是从先前的SMB2 TREE_CONNECT Response接收的任何无符号32位整数。对于以下命令, TreeId应该设置为 0。
	SMB2 NEGOTIATE Request	SMB2 NEGOTIATE Response	SMB2 SESSION_SETUP Request	SMB2 SESSION_SETUP Response
	SMB2 LOGOFF Request	SMB2 LOGOFF Response	SMB2 ECHO Request	SMB2 ECHO Response	SMB2 CANCEL Request
14、SessionId(8字节):唯一标识该命令建立的会话。对于SMB2 NEGOTIATE Request和SMB2 NEGOTIATE Response该字段必须设置为 0。
15、Signature(16bytes):消息的16字节签名,如果SMB2_FLAGS_SIGNED设置在SMB2标头的Flags字段中并且消息未加密。如果消息未签名,则此字段必须为 0。

2.1.2 关键信息检索

2.1.2.1 MessageId

例如Negotiate Protocol Request的MID为0,那么Negotiate Protocol Response的MID也是0。主要用于请求和回应配对,根据MID

处理命令的顺序,因为在发送Request后不必等待Response就可以继续发送其他Request,这样就会造成多个Response返回到客户端,所以需要通过MID来区分哪个Response对应哪个Resquest。下图分别时请求和回应对应的MID。
在这里插入图片描述
在这里插入图片描述
2.1.2.2 FID

GUID handle File,某一文件标识符,在提取文件大小和内容等数据时用来区别该数据对应哪一个文件,在CREAT Response中携带当前访问文件的FILE ID。
在这里插入图片描述
2.1.2.3 文件名及文件信息提取
见2.2.1 SMB2 CREATE Request和2.2.2 SMB2 CREATE Response。主要是文件名和文件的FID以及文件大小
2.2 SMB命令(只描述部分,不详细描述所有,未描述到的部分可以到微软官网查看)

2.2.1 SMB2 CREATE Request
在这里插入图片描述

	1、StructureSize(2 字节):客户端必须将此字段设置为57(0x39),表示请求结构的大小,不包括标头。无论Buffer[]在发送的请求
	中实际存在多长时间,客户端都必须将其设置为该值。
	2、RequestedOplockLevel(1 字节):请求的oplock级别。该字段必须包含以下值之一。对于命名管道,无论该字段的值如何,服务器
	必须始终恢复为 SMB2_OPLOCK_LEVEL_NONE。
		SMB2_OPLOCK_LEVEL_NONE 0x00	不请求 oplock。	  SMB2_OPLOCK_LEVEL_EXCLUSIVE	 0x08	 请求独占 oplock。
		SMB2_OPLOCK_LEVEL_II   0x01 请求二级 oplock。 SMB2_OPLOCK_LEVEL_BATCH		0x09	请求批处理 oplock。
		SMB2_OPLOCK_LEVEL_LEASE	0xFF 请求租约。
	3、ImpersonationLevel(4 字节):该字段指定发出创建请求的应用程序请求的模拟级别,并且必须包含以下值之一。
		Anonymous 0          应用程序请求的模拟级别是匿名的。 Identification 1     应用程序请求的模拟级别是标识。
		Impersonation 2      应用程序请求的模拟级别是模拟。   Delegate 3           应用程序请求的模拟级别是委托。
	4、SmbCreateFlags(8 字节):该字段不得使用且必须保留。客户端应该将此字段设置为零,并且服务器必须在收到时忽略它。
	5、Reserved (8 bytes): 该字段不得使用且必须保留。客户端将此设置为任何值,服务器必须在收到时忽略它。
	6、DesiredAccess(4 个字节):所需的访问级别。	
		详情见:https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/b3af3aaf-9271-4419-b326-eba0341df7d2
	7、FileAttributes(4 字节):该字段必须是指定的值的组合,并且不得包含除该节中指定的值之外的任何值。
	8、ShareAccess(4 字节):指定open的共享模式。如果为打印机文件或命名管道设置了FILE_SHARE_READ、FILE_SHARE_WRITE和 
	FILE_SHARE_DELETE 的ShareAccess值,则服务器应该<35>忽略这些值。该字段必须使用零个或多个以下位值的组合来构造。
	FILE_SHARE_READ 0x00000001
    设置后,表示允许其他打开在此打开存在时读取此文件。不得为命名管道或打印机文件设置此位。每次打开都会创建一个命名管道的新实 
    例。同样,打开打印机文件总是会创建一个新文件。
    FILE_SHARE_WRITE 0x00000002
    设置时,表示在此打开存在时允许其他打开写入此文件。不得为命名管道或打印机文件设置此位。每次打开都会创建一个命名管道的新实
    例。同样,打开打印机文件总是会创建一个新文件。
    FILE_SHARE_DELETE 0x00000004
    设置时,表示允许其他打开在此打开存在时删除或重命名此文件。不得为命名管道或打印机文件设置此位。每次打开都会创建一个命名管道
    的新实例。同样,打开打印机文件总是会创建一个新文件。
    9、Disposition(4 字节):定义如果名称字段中指定的文件已经存在,服务器必须采取的操作。对于打开命名管道,该字段可以
    由客户端设置为任何值,并且必须被服务器忽略。对于其他文件,此字段必须包含以下值之一。
    FILE_SUPERSEDE      0x00000000  如果该文件已经存在,请替换它。否则,创建文件。此值不应用于打印机对象
    FILE_OPEN           0x00000001  如果文件已经存在,返回成功;否则,操作失败。不得用于打印机对象。
    FILE_CREATE         0x00000002  如果文件已经存在,则操作失败;否则,创建文件。
    FILE_OPEN_IF        0x00000003  如果文件已存在,请打开该文件;否则,创建文件。此值不应用于打印机对象
    FILE_OVERWRITE      0x00000004  如果文件已存在,则覆盖该文件;否则,操作失败。不得用于打印机对象
    FILE_OVERWRITE_IF   0x00000005  如果文件已存在,则覆盖该文件;否则,创建文件。此值不应用于打印机对象
    10、CreateOptions(4 个字节):指定创建或打开文件时要应用的选项
    11、Filename:文件名。包含文件名偏移量(2字节),文件名长度(2字节)

2.2.2 SMB2 CREATE Response
在这里插入图片描述

1、StructureSize(2 字节):服务器必须将此字段设置为 89,表示请求结构的大小,不包括标头。无论 Buffer [] 在发送的请求中实际存在多长时间,服务器都必须将此字段设置为该值。
2、OplockLevel(1 字节): 授予客户端此open的oplock级别。该字段必须包含以下值之一。
	0-没有授予oplock锁	1-授予二级oplock锁	8-授予独占oplock锁	9-授予批处理oplock锁	FF-请求租约。如果设置,响应数据
	包必须包含SMB2_CREATE_RESPONSE_LEASE 创建上下文。
3、Response flags(1字节):如果服务器实现SMB3系列,则必须使用以下值构造此字段。否则,该字段不得使用且必须保留。
	SMB2_CREATE_FLAG_REPARSEPOINT	0x01	设置时,指示文件路径的最后一部分是重解析点
4、CreateAction(4 字节):建立开放时采取的行动。该字段必须包含以下值之一
	0-删除了现有文件,并在其位置创建了一个新文件	1-现有文件已打开	2-创建了一个新文件	3-现有文件被覆盖
5、CreationTime(8字节):文件创建的时间
6、LastAccessTime(8字节):文件最后一次访问的时间
7、LastWriteTime(8字节):数据最后一次写入文件的时间
8、ChangeTime(8字节):文件最后一次修改的时间
9、AllocationSize(8 字节):分配给文件的数据的大小(以字节为单位)。这个更像是文件的大小
10、EndofFile(8 个字节):文件的大小,以字节为单位。
11、FileAttributes(4 个字节):文件的属性。https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/ca28ec38-f155-4768-81d6-4bfeb8586fc9
12、Reserved2(4 字节):该字段不得使用且必须保留。服务器应该将此设置为 0,并且客户端必须在收到时忽略它
13、GUID handle File(16 字节):文件名对应的FILE ID:一个文件的标识符

2.2.3 SMB2 SET_INFO Request
在这里插入图片描述

1、StructureSize(2 字节):客户端必须将此字段设置为 33,表示请求结构的大小,不包括标头
2、InfoType(1 字节)对应抓包的clas:正在设置的信息类型。
	1-正在设置文件新 	2-正在设置底层对象存储信息	3-正在设置安全信息	4-正在设置底层对象存储配额信息(不是很懂)
3、INFOLevel:不知道是什么
4、(Setinfo Size:)BufferLength(4 个字节):要设置的信息的长度,以字节为单位。
5、(Setinfo Offset)BufferOffset(2 个字节):从 SMB2 标头的开头到要设置的信息的偏移量,以字节为单位
6、Reserved2(2字节):该字段不得使用且必须保留。服务器应该将此设置为 0,并且客户端必须在收到时忽略它
7、AdditionalInformation(4 个字节):向服务器提供附加信息。
8、GUID handle File(16 字节):文件名对应的FILE ID:一个文件的标识符
9、SMB2_FILE_ENDOFFILE_INFO:这是附加信息?End Of File: 131072(文件大小)

2.2.4 SMB2 SET_INFO Response
在这里插入图片描述

SMB2 SET_INFO 响应数据包由服务器发送以响应SMB2 SET_INFO Resquest,以通知客户端其请求已成功处理。此响应SMB2标头组成,后跟此响应结构。
1、StructureSize(2字节):服务器必须将此字段设置为2,表示请求结构的大小,不包括头部。

2.2.5 Write Request
在这里插入图片描述

1、StructureSize(2字节):客户端必须将此字段设置为49(十六进制31),表示请求结构的大小,不包括标头.
2、DataOffset(2个字节):从SMB2头的开头到正在写入的数据的偏移量,以字节为单位。
3、Write Length(4字节):正在写入的数据的长度,以字节为单位。正在写入的数据长度可以是零字节。
4、File offset(8字节):在目标文件中写入数据的位置的偏移量(以字节为单位)。如果写入是在管道上执行的,则偏移量必须由客户端设置为 0,并且必须被服务器忽略。
5、FILE ID(16字节):执行写入的文件或管道的标识符。
6、channel(4字节):对于 SMB 2.0.2 和 2.1 方言,该字段不得使用且必须保留。客户端必须将此字段设置为 0,并且服务器忽略
7、RemainingBytes(4字节):对于SMB3.x,如果请求的Channel字段包含SMB2_CHANNEL_RDMA_V1、SMB2_CHANNEL_RDMA_V1_INVALIDATE 或SMB2_CHANNEL_RDMA_TRANSFORM,则此字段包含正在写入的数据的长度(以字节为单位)。
8、Write flags标志位(4字节):标志字段指示如何处理操作。该字段必须使用以下零个或多个值来构造:
	0-不做其他操作(自我理解的)	1-服务器对写操作执行文件直写。此值对SMB2.0.2无效。
	2-不执行文件缓冲。该位对SMB2.0.2、2.1和3.0方言无效
9、Write Offset (2 bytes):对于SMB3.x,如果请求的Channel字段包含SMB2_CHANNEL_RDMA_V1、SMB2_CHANNEL_RDMA_V1_INVALIDATE 或SMB2_CHANNEL_RDMA_TRANSFORM,它包含从 SMB2头开始到通道数据的偏移量,以字节为单位由请求的Channel字段指定。否则为0
10、Write Length(2 字节):对于SMB3.x,如果请求的Channel字段包含SMB2_CHANNEL_RDMA_V1、SMB2_CHANNEL_RDMA_V1_INVALIDATE 或SMB2_CHANNEL_RDMA_TRANSFORM,则它包含由Channel字段指定的通道数据的长度(以字节为单位)。
11、date:写入的数据以及长度大小

2.2.6 Write Response
在这里插入图片描述

1、StructureSize(2字节):服务器必须将此字段设置为17,响应结构的实际大小。
2、Reserved2(2字节):该字段不得使用且必须保留。服务器应该将此设置为 0,并且客户端必须在收到时忽略它
3、write count(4字节):写入的字节数
4、write Remaining(4字节):该字段不得使用且必须保留。服务器必须将此设置为 0,并且客户端必须在收到时忽略它。
5、WriteChannelInfoOffset(2个字节):该字段不得使用且必须保留。服务器必须将此设置为0,并且客户端必须在收到时忽略它。
6、WriteChannelInfoLength(2个字节):该字段不得使用且必须保留。服务器必须将此设置为0,并且客户端必须在收到时忽略它。

2.2.7 Close Request
在这里插入图片描述

1、StructureSize(2字节):服务器必须将此字段设置为34,响应结构的实际大小。
2、Close flags(2字节):标志字段指示如何处理操作。
	1-如果设置,服务器必须将响应中的属性字段设置为有效值
	0-如果未设置,客户端不得使用响应中返回的值。
3、Reserved2(2字节):该字段不得使用且必须保留。服务器应该将此设置为 0,并且客户端必须在收到时忽略它
4、GUID handle File(16 字节):文件名对应的FILE ID:一个文件的标识符

2.2.8 Close Response
在这里插入图片描述

1、StructureSize(2字节):服务器必须将此字段设置为60,响应结构的实际大小。
2、Close flags(2字节):标志字段指示如何处理操作。
3、Reserved2(2字节):该字段不得使用且必须保留。服务器应该将此设置为 0,并且客户端必须在收到时忽略它
4、CreationTime(8字节):文件创建的时间,如果设置了SMB2 CLOSE Request中的SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB标志,则该字段必须设置为属性查询返回的值。如果未设置标志,则该字段应设置为零,并且不得在收到时进行检查。
5、LastAccessTime(8字节):文件最后一次访问的时间,如果设置了SMB2 CLOSE Request中的SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB标志,则该字段必须设置为属性查询返回的值。如果未设置标志,则该字段必须设置为零。
6、LastWriteTime(8字节):数据最后一次写入文件的时间,如果设置了SMB2 CLOSE Request中的SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB 标志,则该字段必须设置为属性查询返回的值。如果未设置标志,则该字段必须设置为零。
7、ChangeTime(8字节):文件最后一次修改的时间,如果设置了SMB2 CLOSE Request中的 SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB标志,则该字段必须设置为属性查询返回的值。如果未设置标志,则该字段必须设置为零。
8、AllocationSize(8字节):分配给文件的数据的大小(以字节为单位)。如果设置了SMB2 CLOSE Request中的SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB标志,则该字段必须设置为属性查询返回的值。如果未设置标志,则该字段必须设置为零。
9、EndofFile(8 个字节):文件的大小,以字节为单位。如果设置了SMB2 CLOSE Request中的SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB标志,则该字段必须设置为属性查询返回的值。如果未设置标志,则该字段必须设置为零。
10、FileAttributes(4个字节):文件的属性。如果设置了SMB2 CLOSE Request中的SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB 标志,则该字段必须设置为属性查询返回的值。如果未设置标志,则该字段必须设置为零。有关有效标志的更多信息,

2.2.9 Query Info Request

1、StructureSize(2字节):服务器必须将此字段设置为41,响应结构的实际大小。
2、InfoType(1字节):查询的信息类型。该字段必须包含以下值之一:
	1-请求文件信息	2-请求底层对象存储信息	3-请求安全信息	4-请求底层对象存储配额信息
3、FileInfoClass(1字节):
	对于文件信息查询,此字段必须包含以下FILE_INFORMATION_CLASS 值之一:
		https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/4718fc40-e539-4014-8e33-b675af74e3e1
	对于底层对象存储信息查询,此字段必须包含以下 FS_INFORMATION_CLASS 值之一。
		https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/ee12042a-9352-46e3-9f67-c094b75fe6c3
	对于安全查询,此字段必须设置为 0。对于配额查询,此字段应该设置为 0。
4、OutputBufferLength(4字节):服务器可以在响应中发送的最大信息字节数。
5、InputBufferOffset(2个字节):
	从 SMB2 标头的开头到输入缓冲区的偏移量,以字节为单位。对于配额请求,输入缓冲区必须包含SMB2_QUERY_QUOTA_INFO。
	对于FileFullEaInformation 请求,输入缓冲区必须包含用户提供的EA列表,其中包含零个或多个 FILE_GET_EA_INFORMATION 结构
	对于其他信息查询,该字段应该设置为 0。
6、Reserved2(2字节):该字段不得使用且必须保留。服务器应该将此设置为 0,并且客户端必须在收到时忽略它
7、InputBufferLength(4个字节):
	输入缓冲区的长度。对于配额请求,这必须是嵌入在请求中的 SMB2_QUERY_QUOTA_INFO 的长度。
	对于 FileFullEaInformation 请求,必须将其设置为指定的用户提供的EA列表的长度。
	对于其他信息查询,该字段应该设置为 0 并且服务器必须在收到时忽略它。
8、AdditionalInformation(4个字节):向服务器提供附加信息。
	如果正在查询FileFullEaInformation并且应用程序没有提供要查询的 EA 列表,但已经提供了开始查询的对象的完整扩展属性信息数组
	的索引,则此字段必须包含该索引的ULONG表示。对于所有其他查询,该字段必须设置为 0,并且服务器必须忽略它。
9、Flags(4个字节):标志必须设置为 FileFullEaInformation 查询的零个或多个这些位值的组合。
	1-从头开始扫描EA	2-从响应缓冲区中返回单个EA条目	3-调用方已指定EA索引。
	对于所有其他查询,客户端必须将此字段设置为 0,并且服务器必须在收到时忽略它。
10、FileId(16字节):执行查询的文件或命名管道的SMB2_FILEID(文件)标识符,对底层对象存储或配额信息的查询将定向到文件所在的卷。
11、Buffer (variable):包含请求的输入缓冲区的可变长度缓冲区,当InputBufferLength设置为0时,Win客户端发送0的1字节缓冲区。

2.2.10 Query Info Response

1、StructureSize(2字节):服务器必须将此字段设置为9,响应结构的实际大小。
2、OutputBufferOffset(2字节):从SMB2标头的开头到返回的信息的偏移量,以字节为单位。
3、OutputBufferLength(4字节):返回信息的长度(以字节为单位)。
4、Buffer (variable):包含响应中返回的信息的可变长度缓冲区如OutputBufferOffset和OutputBufferLength字段所述。

2.2.11 Read Request
在这里插入图片描述

1、StructureSize(2字节):服务器必须将此字段设置为49,响应结构的实际大小。
2、Padding (1字节):请求的从SMB2标头开始的偏移量,以字节为单位,将读取的数据放置在SMB2读取响应中。提供此值是为了优化客户端上的数据放置,而不是绑定在服务器上。 
3、Flags(1字节):对于SMB2.0.2、2.1和3.0,该字段不得使用且必须保留。客户端必须将此字段设置为0,并且服务器必须在收到时忽略它。
	1-数据直接从底层存储中读取	2-请求服务器在响应请求时压缩读取响应。此标志对SMB2.0.2、2.1、3.0和3.0.2无效
4、Read长度(4字节):要从指定文件或管道读取的数据的长度(以字节为单位)。正在读取的数据的长度可以是零字节。
5、FILE偏移量(8字节):从中读取数据的文件的偏移量(以字节为单位)。如果读取是在管道上执行的,则偏移量必须由客户端设置为0。此值为0在此处代表文件开头。
6、FileId(16字节):文件的标识符
7、Min Count (4字节):为使该操作成功而读取的最小字节数。
8、channel(4字节):对于SMB 2.0.2和2.1,该字段不得使用且必须保留。客户端必须将此字段设置为0,并且服务器必须在收到时忽略它
	0-请求中不存在频道信息。Remaining字节、ReadChannelInfoOffset和ReadChannelInfoLength字段必须由客户端设置为0。等等
9、RemainingBytes(4字节):对于SMB3,如果请求的Channel字段包含 SMB2_CHANNEL_RDMA_V1或SMB2_CHANNEL_RDMA_V1_INVALIDATE,则该字段包含要读取的数据的长度,以字节为单位。
10、ReadChannelInfoOffset(2字节):对于SMB3,它包含从SMB2标头的开头到请求的Channel字段指定的通道数据的偏移量
11、ReadChannelInfoLength(2字节):对于SMB3,它包含请求的Channel字段指定的通道数据的长度(以字节为单位)。
12、缓冲区(变量):包含读取通道信息的可变长度缓冲区,如ReadChannelInfoOffset 和ReadChannelInfoLength 所述。

2.2.12 Read Respones
在这里插入图片描述

1、StructureSize(2字节):服务器必须将此字段设置为17,响应结构的实际大小。
2、DataOffset(1字节):从标头的开头到此响应中返回的数据读取的偏移量,以字节为单位。
3、Reserved2(2字节):该字段不得使用且必须保留。服务器应该将此设置为 0,并且客户端必须在收到时忽略它
4、(Blob)DataLength(4字节):此响应中返回的读取数据的长度(以字节为单位)。
5、Remaining(4字节):在请求中指定的Channel上发送的数据的长度(以字节为单位)。
6、Reserved2(2字节):该字段不得使用且必须保留。服务器应该将此设置为 0,并且客户端必须在收到时忽略它
7、缓冲区(变量):一个可变长度的缓冲区,其中包含为响应读取的数据,如DataOffset和DataLength所述。最小长度为1字节。如果从底层对象存储返回0字节,则服务器必须发送状态等于STATUS_END_OF_FILE的失败响应。

四、上传文件流程(向服务器写)
在这里插入图片描述
1、主要命令:CREAT SET_INFO WRITE CLOSE
过程:
1、从客户段读取数据:Create Request (0x05),读取的长度包括NETBIOS头的长度,也就是NETBISO头+NETBIOS数据体,抓包出来的值是数据长度。
2、处理Create Request数据包,提取文件名、MID、和方向。
3、服务器Create Response (0x05),回应中携带访问时间、文件大小、FID等信息.
4、客户端发送SetInfo Request (0x11),在消息中的FileInfoClass为特定值时,表明Request中包含文件大小,如果服务器不具备空闲空间,则在Response中提醒客户端。
5、服务器回应客户端SetInfo Response (0x11)请求成功
6、客户端发送Write Request (0x09),此命令包含写入的数据长度和在整个文件中的偏移值
7、服务器回应Write Response (0x09),回应不是对应resquest发的,根据偏移值进行回应
8、等文件发送完毕,客户端发送close resquest关闭此次传输,服务器close response回应客户端,关闭成功

五、下载文件(从服务器读)
在这里插入图片描述
下载文件的过程与注意事项与上传差不多,区别是过程中的命令不同,下载涉及到的命令是CREATE READ CLOSE。

六、断开共享并注销
在这里插入图片描述

  • 15
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值