☰
Zeek SMB 分析器实战:`smb1_nt_cancel_request` 事件与 SMB1 NT_CANCEL 命令的解析原理
2026/10/6 1:53:19 网站建设 项目流程
  • 网络安全
  • 网络
  • IDS

【免费下载链接】zeek

Zeek is a powerful network analysis framework that is much different from the typical IDS you may know.

项目地址:https://gitcode.com/gh_mirrors/ze/zeek
点击查看免费下载

Zeek 内置的 SMB(Server Message Block)协议分析器针对 SMB/CIFS 版本 1 的每一条命令,都会在脚本层暴露对应的事件接口。本文聚焦其中的 NT Cancel 命令:它由客户端在会话中主动发送,用于取消一个尚未完成(仍处于 pending 状态)的 SMB 请求。全文以官方事件文档(doc/scripts/base/bif/plugins/Zeek_SMB.smb1_com_nt_cancel.bif.zeek.rst)为骨架,结合分析器源码与脚本层状态机实现,讲清楚该事件的事件签名、触发时机、底层解析流程,以及如何用它在 Zeek 脚本中编写取消请求的检测与追踪逻辑。

事件总览:smb1_nt_cancel_request

在 Zeek 的脚本接口中,该事件定义于全局命名空间(GLOBAL),完整签名如下:

event smb1_nt_cancel_request(c: connection, hdr: SMB1::Header)
参数类型含义
cconnection承载该 SMB 消息的连接对象
hdrSMB1::Header该 SMB 版本 1 消息的已解析头部

事件触发语义(来自官方文档):每当客户端发送类型为nt cancel的 SMB/CIFS 版本 1 请求时生成。NT Cancel 请求的作用是让客户端请求服务器取消某个当前正处于 pending 状态(已提交但尚未完成)的请求。协议细节可参考 MS-CIFS 规范 2.2.4.65。

事件声明本体位于 src/analyzer/protocol/smb/smb1_com_nt_cancel.bif(bif 文件是 Zeek 桥接 C++ 解析器与脚本层的声明源),文档中与该事件建立互见(zeek:see)关系的是smb1_message事件,后者在每条 SMB1 消息被解析时统一触发,是观察所有 SMB1 命令总览的最佳切入点。

NT_CANCEL 在 SMB1 命令空间中的位置

SMB 版本 1 的消息体由一个单字节的 Command 字段标识。在脚本层,命令号到命令名的映射表定义于 scripts/base/protocols/smb/consts.zeek:

[0xA4] = "NT_CANCEL",

即 NT Cancel 的命令码为0xA4(十进制 164)。它隶属于 NT 系列命令家族(0xA0~0xA5),同族还包括 NT_TRANSACT、NT_TRANSACT_SECONDARY、NT_CREATE_ANDX、NT_RENAME 等。分析器侧的 C++ 分发逻辑位于 src/analyzer/protocol/smb/smb1-protocol.pac,请求方向被完整支持:

SMB_COM_NT_CANCEL -> nt_cancel : SMB1_nt_cancel_request(header);

值得注意的是,响应方向(SMB_COM_NT_CANCEL -> nt_cancel : SMB1_nt_cancel_response)在源码中是被注释掉的(同文件第 284 行),这是因为 NT Cancel 在协议语义上本身没有对应的响应消息——它只是单向的“取消”指令。这也解释了为什么 Zeek 只为该命令暴露了*_request事件、而没有*_response事件。

解析器底层:请求结构体与事件入队

smb1_nt_cancel_request事件的触发源头位于 src/analyzer/protocol/smb/smb1-com-nt-cancel.pac。该文件用 binpac 语言定义了解析逻辑,核心结构如下:

type SMB1_nt_cancel_request(header: SMB_Header) = record { word_count : uint8; byte_count : uint16; } &let { proc : bool = $context.connection.proc_smb1_nt_cancel_request(header, this); };

解析要点:

  • 字段布局:NT Cancel 请求体仅包含word_count(1 字节)和byte_count(2 字节)两个字段,是 SMB1 命令族中载荷最轻的命令之一。协议头由调用方通过header: SMB_Header参数传入。
  • 事件派发:&let块中的proc字段在解析完成后立即调用连接对象上的处理函数,其内部实现为:
function proc_smb1_nt_cancel_request(header: SMB_Header, val: SMB1_nt_cancel_request): bool %{ if ( smb1_nt_cancel_request ) zeek::BifEvent::enqueue_smb1_nt_cancel_request(zeek_analyzer(), zeek_analyzer()->Conn(), SMBHeaderVal(header)); return true; %}

即:当脚本层注册了smb1_nt_cancel_request事件处理器时,分析器会把当前连接与解析出的 SMB 头(经由SMBHeaderVal转换为脚本层的SMB1::Header记录值)入队触发该事件。若脚本未注册该事件,则整个请求体解析后不产生任何脚本层开销——这是 Zeek 分析器"按需派发"的一贯设计。

SMB1::Header结构与头部字段说明

事件参数中的hdr类型为SMB1::Header,其记录定义位于 scripts/base/init-bare.zeek,与 SMB 版本 1 协议头的标准字段一一对应:

type SMB1::Header : record { command : count; ##< The command number status : count; ##< The status code flags : count; ##< Flag set 1 flags2 : count; ##< Flag set 2 tid : count; ##< Tree ID pid : count; ##< Process ID uid : count; ##< User ID mid : count; ##< Multiplex ID };

在 NT Cancel 场景中,最重要的两个字段是:

  • command:恒为0xA4,可用SMB1::commands[hdr$command]反查得到字符串"NT_CANCEL";
  • mid(Multiplex ID):客户端用它标识被取消的目标请求——取消命令正是通过匹配服务器端 pending 请求的 MID 来定位目标。因此,在脚本层把hdr$mid与先前观察到的请求 MID 关联起来,是追踪"哪个请求被取消"的核心手段。

实战:编写 NT Cancel 检测脚本

下面给出一个可直接运行的 Zeek 脚本示例,演示如何订阅该事件、过滤无关噪声、并借助SMB::CmdInfo状态与smb1_message事件还原被取消的请求上下文:

@load base/protocols/smb export { redef enum Log::ID += { LOG }; } event zeek_init() &priority=5 { Log::create_stream(LOG, [$columns=Info, $path="smb1_nt_cancel"]); } event smb1_nt_cancel_request(c: connection, hdr: SMB1::Header) { # 仅记录命令码确实为 NT_CANCEL 的消息,作为防御性校验。 if ( SMB1::commands[hdr$command] != "NT_CANCEL" ) return; local rec: Info; rec$ts = network_time(); rec$uid = c$uid; rec$id = c$id; rec$mid = hdr$mid; rec$pid = hdr$pid; rec$command = SMB1::commands[hdr$command]; rec$orig = T; # 若此前已记录过该 MID 的请求,则补充其命令名以标识被取消的目标。 if ( c?$smb_state && hdr$mid in c$smb_state$pending_cmds ) rec$canceled_cmd = c$smb_state$pending_cmds[hdr$mid]$command; Log::write(LOG, rec); }

配套的日志类型定义(Info)可按需包含ts / uid / id / mid / pid / command / canceled_cmd / orig等字段。实际部署时建议将脚本放入站点目录(如 scripts/site/local.zeek 同级或@load引用)后,用zeek -i eth0 local.zeek或zeek -r trace.pcap local.zeek加载。

结合状态机理解 MID 的语义

smb1_nt_cancel_request并非孤立事件——Zeek 的 SMB 脚本层通过smb_state$pending_cmds表维护"已发送、未完成"的请求集合,其维护逻辑在 scripts/base/protocols/smb/smb1-main.zeek:

  • 每个新 MID 的请求到达时,smb1_message(优先级 +5)会为该 MID 创建SMB::CmdInfo记录并放入pending_cmds;
  • 收到对应响应后,优先级 -5 的smb1_message处理器会执行delete c$smb_state$pending_cmds[hdr$mid],将已完成请求移出集合(同文件第 61-67 行)。

由此可以推断:当smb1_nt_cancel_request触发时,若目标 MID 仍存在于pending_cmds中,说明该请求确实处于未完成状态,取消操作语义上有效;若 MID 已被移除,则说明请求在取消到达前已得到响应,属于"迟到取消"或重复取消。把这一判定写进检测脚本,可有效降低误报,也为异常取消行为(如取消不存在的请求)的检测提供了依据。

与其他 SMB1 事件的关系

smb1_nt_cancel_request是 SMB1 分析器对外暴露的众多命令级事件之一,与它相邻的同族事件包括(均在 src/analyzer/protocol/smb/ 下,各自对应一个.bif声明文件与一个解析文件):

  • smb1_negotiate_request/smb1_negotiate_response(smb1_com_negotiate.bif)
  • smb1_nt_create_andx_request/smb1_nt_create_andx_response(smb1_com_nt_create_andx.bif)
  • smb1_transaction_request、smb1_transaction2_request(smb1_com_transaction.bif、smb1_com_transaction2.bif)
  • smb1_read_andx_request、smb1_write_andx_request、smb1_close_request等

所有命令级事件都遵循同一模式:bif 文件声明签名 →.pac文件定义解析结构 → 解析完成后按需派发事件。与smb1_message的区别在于粒度:smb1_message在每条 SMB1 消息上都会触发(适合全局会话重建与统计),而smb1_nt_cancel_request只在特定命令上触发(适合针对性检测,且未被订阅时几乎零开销)。

小结

  • smb1_nt_cancel_request是 Zeek 针对 SMB1SMB_COM_NT_CANCEL(命令码0xA4)暴露的请求级事件,签名固定为(c: connection, hdr: SMB1::Header),规范依据为 MS-CIFS 2.2.4.65。
  • 该命令无响应消息,因此 Zeek 侧也没有对应的*_response事件;请求体仅含word_count与byte_count两个字段。
  • 事件中的hdr$mid是关联"取消目标请求"的关键线索,配合pending_cmds状态表(scripts/base/protocols/smb/smb1-main.zeek)可判断取消是否针对真正处于 pending 状态的请求。
  • 检测脚本只需订阅事件并记录SMB1::Header关键字段,即可产出独立日志流,用于异常取消行为分析与 SMB 会话审计。
  • 网络安全
  • 网络
  • IDS

【免费下载链接】zeek

Zeek is a powerful network analysis framework that is much different from the typical IDS you may know.

项目地址:https://gitcode.com/gh_mirrors/ze/zeek
点击查看免费下载

相关推荐

上一篇:CANN ops-nn 仓库 MseLoss 算子深度解析:从 aclnn 两段式调用到 Ascend C 实现原理
下一篇:彻底解决!Pydantic-AI中Gemini模型响应验证失败的5个关键方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询