SMB的全称为Server Message Block,主要是作为Microsoft网络的通讯协议,现在已经更新到了SMBv3,由于其保持了很好的向后兼容性,所以包括了大量的老旧函数等内容,但是其核心功能还是向打印机发送数据、远程读写文件、执行远程管理和访问远程机器上的服务等。但是由于协议版本不同,具体的SMB头结构也不太相同,可以通过这一点来对版本进行识别。下面简单说明下在smb协议中,如何进行身份验证。
SMBv1中,早期直接使用明文传输口令,后来出现了"LAN Manager Challenge/Response"验证机制,简称LM,但是由于其加密安全性较差,微软在1993年的Windows NT 3.1中推出了“NT LAN Manager”机制作为替代,但是考虑到兼容性的问题,直到Windows Vista,Microsoft才彻底将LM认证方式从支持的列表中去除。并在后续又加入了NTLM的升级版NTLMv2以及更为安全的Kerberos等认证方式。Kerberos最早是在Windows 2000中加入的一种认证方式,不但弥补了NTLM的不支持双向认证等一系列缺点,还具有更高的安全性。但是由于需要一个TGS来运行,所以针对没有域控的Windows环境,依旧保留了对NTLM的支持。值得一提的是,虽然最新的Windows已经默认取消了对SMBv1的支持,但是却依旧保留了对NTLMv2的支持。
由于LAN Manager Challenge/Response太过久远,就以一个NTLM认证的例子来说明整个流程,如图:
主要分为两个部分,上面的是双方在协商认证方式,下面则是NTLM认证。在双方进行TCP的握手连接之后,客户端和服务端会启动SMB连接,在这里客户端会先向服务端发送一个SMB_COM_NEGOTIATE类型的消息,具体结构如图:
如果选择了NTLM进行身份验证,客户端还需要判断Capabilities字段中CAP_EXTENDED_SECURITY的值,如果置为0,则需要按照以下格式构建SMB_COM_SESSION_SETUP_ANDX请求。
如果置为1,则会按照以下格式进行构建:
这里红色箭头指向的就是NTLM的头部分,蓝色箭头指向的就是当前认证所进行的阶段。
2. 服务端回复NTLMSSP_CHALLENGE消息,其中包含一段随机数(挑战码)。