Skip to content
Wireshark Wiki 中文翻译整理专题首页原始页面

SMB/未解问题

关于 SMB 协议仍有许多未知内容。以下是这些未解问题的部分列表。

QFS Info Levels

在 trans2 QFS(子命令 3)中,我们知道如何解码 Windows 服务器支持的全部 11 个 info level,以及 Samba 支持的两个扩展 unix info level。我们不知道的是,为什么有些 Windows 服务器支持 level 1008(OBJECTID_INFORMATION),而有些不支持。具体 level 包括:

  • 我们不知道 OBJECTID_INFORMATION level 返回的 64 字节中最后 48 字节的含义。它似乎总是为零,因此也许是为将来扩展预留的空间,但也可能不是。

Ronnie:参见 http://wiki.wireshark.org/SMB2/Ioctl/FILE_OBJECTID_BUFFER

  • 我们不知道 QUOTA_INFORMATION level(level 1006)返回的 48 字节中前 24 字节的含义。dave 说:这可能在 Nebbett 中有文档说明(参见我下面的评论)。

QPATHINFO/QFILEINFO Info Levels

在 QPATHINFO(子命令 5)和 QFILEINFO(子命令 7)trans2 调用中,我们知道 Windows 服务器支持 27 个 information level(QFILEINFO 为 26 个)。其中若干 level 包含我们不能正确理解的字段。具体而言:

  • 在 ALL_EAS level(level 4)中,每个返回的 EA 上 8 位 flag 字段中的各个位是什么意思?
  • 在 BASIC_INFORMATION level(level 0x101 及其 level 1004 别名)中,为什么有些 Windows 服务器返回 40 字节响应,而有些返回 36 字节响应?这是否意味着添加了一个新字段,或者 file attribute 字段已经扩展为 64 位?如果它已扩展为 64 位,那么 file attribute 的高 32 位是什么意思?
  • 在 COMPRESSION_INFORMATION level(level 0x10b 及其 level 1028 别名)中,各个字段是什么意思?我们知道前 8 字节是压缩后的大小,但另外 8 字节不太清楚。
  • 在 MODE_INFORMATION level(level 1016)中,返回的 64 位 mode 是什么?它似乎只有 3 个取值(0、1 或 2),并且我们知道客户端可以使用 SETFILEINFO level 1016 调用设置这些值,但我们不知道这些值是什么意思。
  • QFILEINFO level 1017 返回的 64 位 ALIGNMENT_INFORMATION 字段是什么意思?它对文件 I/O 有什么影响?dave 说:参见 Nebbett 了解编码。我认为这只是在说,如果你要执行未缓存、无缓冲的本地磁盘 IO(从用户内存到磁盘的 DMA),那么需要确保缓冲区至少按该值对齐。我看不出它在 cifs 相关场景中有什么含义,但我只是在猜测。
  • 在 ATTRIBUTE_TAG_INFORMATION level(level 1035)中,第 2 个 32 位字段是什么意思?我们认为它是 reparse_tag,但不知道该字段如何使用。
  • 出现在若干 level 中的 64 位 file_id 字段(例如 INTERNAL_INFORMATION level 1006 中)的生命周期是多久?这显然是一个唯一的文件 ID,但它是保证在文件生命周期内唯一,还是只在此连接生命周期内唯一?dave 说:cifs 对此没有意见;这是文件系统的事情。对于 NTFS,这是文件的持久索引号(可理解为 inode number

SETFILEINFO/SETPATHINFO level

有相当多 SETFILEINFO/SETPATHINFO trans2 level 是我们不了解的。Windows 服务器支持 19 个 level,而我们只能解码其中 13 个。我们不了解的 level 包括:

  • level 1023,它似乎接受一个 8 字节值。filemon 称其为 FilePipeInformation

  • level 1025,它似乎接受一个 16 字节值。filemon 称其为 FilePipeRemoteInformation

  • level 1029,它似乎接受一个 72 字节值。filemon 称其为 CopyOnWriteInformation

  • level 1032,它似乎接受一个 56 字节值。filemon 称其为 OleClassInformation

  • level 1039,它似乎接受一个 8 字节值。filemon 称其为 InheritContentIndexInfo

  • level 1040,它似乎接受一个 8 字节值。filemon 称其为 OleInformation

dave 说:level > 1000 是 nt passthrough,我认为这意味着 CIFS 只是传输 NT 系统调用所使用的相同数据格式。Gary Nebbett 的《Windows NT/2000 Native API Reference》一书是其中许多材料的绝佳参考,尽管它有点过时。pipe level 在那里有文档说明。注意 C 编译器引入的对齐填充。

错误码

在整个协议中,我们不知道对于特定操作哪些错误码被认为是有效的。我们也尚未完全弄清楚,在协商了 NTSTATUS 代码的情况下,什么时候某个操作仍会使用强制 DOS 错误码。

例如,我们知道,当 SMBntcreatex 和 SMBntcancel 调用中给出无效 vuid 时,Windows 服务器会返回旧式 DOS 错误码 ERRSRV:ERRbaduid,但对于其他带有无效 vuid 字段的 SMB 命令,则使用 NT_STATUS_INVALID_HANDLE NTSTATUS 代码。我们不知道在其他哪些情况下会发生这种情况。

字符串格式

关于 SMB 协议的现有公开文档在字符串格式方面非常不清楚,但我们发现 Windows 客户端对精确的格式约定极其挑剔。特别是,协议中的一些字符串即使在协商 ASCII 字符串时也必须始终采用 UTF16 unicode 格式,而有些字符串即使协商了 UTF16,也必须始终采用 ASCII。

此外,一些字符串必须以 NULL 终止,而一些字符串不得以 NULL 终止,但在许多情况下所需的终止方式并不清楚。这一点之所以关键,是因为我们知道某些 Windows 应用程序会查找返回字符串的特定长度;因此,例如,如果在 SMBfindfirst 搜索中返回的文件名带有 null 终止,而客户端期望该字符串不被终止,那么客户端将无法识别该文件名,这可能导致数据损坏。

理想情况下,我们会扩展 Wireshark 解析器,使其对不符合已知“正确”格式和终止规则的字符串显示错误,这样我们就可以快速发现实现中的这些错误。

这类问题的一个好例子是,trans2 findfirst 中的 STANDARD info level(level 1)需要返回一个 null 终止的字符串,但同一返回数据中偏移 22 处的 8 位长度字段在长度计算中不得包含终止符。在 Samba 中,我们将此字符串标记为 STR_LEN8BIT|STR_TERMINATE|STR_LEN_NOTERM。

类似地,大多数 UTF16 格式的字符串都相对于 SMB 数据包的开头在 16 位边界上对齐,但此规则也有例外。例如,EA_LIST SMB trans2 findfirst level(level 3)中返回的 filename 没有 16 位对齐。

导入自 https://wiki.wireshark.org/SMB/OpenQuestions,时间为 2020-08-11 23:24:50 UTC

相关 Wireshark Wiki 页面

网络分析技术档案