【译者注】 MS17-010的硝烟已经过去两个月了,每个关注它的安全爱好者都学到了不同的东西。这篇翻译是原作者结合NSA泄露的武器库,通过补丁对比从MS17-010中发现的九个漏洞。作者从微软对SMB协议的实现缺陷方面向我们讲述了MS17-010涉及的方方面面,堪称鞭辟入里之作。可以毫不夸张地说,只有理解这篇文章,才算真正了解MS17-010。看过之后,越来越觉得不敢独享,故将其细细翻译并作了标注,希望能对寻找相关资料的童鞋有所帮助。
0×00 SMB Transaction概述 1、消息格式为了能更好地理解后面的漏洞,有必要先了解一下SMB Transaction的相关知识,大多数MS17-010中的漏洞都与transaction有关。当然,我尽可能简短地介绍。
[译者注] SMB协议是一个通过网络在共享文件、打印设备、命名管道、邮槽之间操作数据的协议。利用该协议,客户端就可以去访问服务器上的共享文件和目录(增删改查)、打印队列和进程间通信服务等,还可以实现客户端和服务器之间的远程过程子协议的认证传输。这些功能落实到实现上,就变成了符合下述SMB消息格式的数据包。
SMB消息格式分为三部分:
格式长度SMB_header a fixed 32-bytes
SMB_Parameters a variable length parameter block
SMB_Data a variable length data block
根据微软官方文档,SMB消息根据功能可大致分为如下类别:
* Session management * Transaction subprotocol * File/directory access methods * Read/write/lock methods * Query directory information * Query/set attributes methods * Printing methods * Other * Obsolete * Reserved but not implemented目前SMB协议共包含75种命令,不同命令通过SMB_Header中1字节大小的Command字段来区别定义。其中SMB Transaction子协议包括以下6种命令:
SMB_COM_TRANSACTION SMB_COM_TRANSACTION_SECONDARY SMB_COM_TRANSACTION2 SMB_COM_TRANSACTION2_SECONDARY SMB_COM_NT_TRANSACT SMB_COM_NT_TRANSACT_SECONDARY[译者注] 其中SMB_COM_TRANSACTION命令用于和邮槽、命名管道进行通信。SMB_COM_TRANSACTION2命令用于打开或创建一个共享文件或文件夹,设置它们的扩展属性。SMB_COM_NT_TRANSACT命令用于打开或创建一个文件或文件夹,并应用扩展属性EA或安全描述符SD。
SMB_COM_*TRANSACT*_SECONDARY的作用就是,当一个需要发送的transaction消息的实际长度超过SMB_Parameters中MaxBufferSize字段能够定义的最大长度时,客户端必须通过一个或多个SMB_COM_*TRANSACT*_SECONDARY命令来发送剩余的消息内容。SMB_COM_*TRANSACT*_SECONDARY必须保证和SMB_COM_*TRANSACT*命令具有相同的TID、UID、PID和MID。
微软官方文档列举了上述SMB Transaction命令相关的三组子命令码(SMB_COM_*TRANSACT*_SECONDARY只是被用来发送对应较大size的transaction消息),部分摘录如下:
SMB_COM_TRANSACTION TRANS_MAILSLOT_WRITE 0x0001 TRANS_SET_NMPIPE_STATE 0x0001 TRANS_RAW_READ_NMPIPE 0x0036 SMB_COM_TRANSACTION2 TRANS2_OPEN2 0x0000 TRANS2_FIND_NEXT2 0x0002 TRANS2_QUERY_FILE_INFORMATION 0x0007 SMB_COM_NT_TRANSACT NT_TRANSACT_CREATE 0x0001 NT_TRANSACT_SET_SECURITY_DESC 0x0003[译者注] 这些子命令码分别通过2字节的SMB_Parameters.Words.Setup.Subcommand、SMB_Parameters.Words.Setup、SMB_Parameters.Words.Function字段来区分定义。比较有趣的是,SMB_COM_TRANSACTION中的TRANS_MAILSLOT_WRITE、TRANS_SET_NMPIPE_STATE子命令码完全一致,不知在处理流程上有什么相似的地方,后续可以着重研究一番。
2、 实现细节[译者注] 前面已经介绍过,一个完整的SMB消息包含SMB_Header、SMB_Parameters和SMB_Data三部分。
SMB_Header主要定义了各种SMB命令的命令码、TID、PID、UID、MID等字段:
SMB_Header { UCHAR Protocol[4]; UCHAR Command; //命令码 SMB_ERROR Status; UCHAR Flags; USHORT Flags2; USHORT PIDHigh; UCHAR SecurityFeatures[8]; USHORT Reserved; USHORT TID; USHORT PIDLow; USHORT UID; USHORT MID; }同一Transaction消息序列中的SMB数据包的TID、PID、UID、MID必须保持一致。