Zeek SMB 分析器实战:`smb1_nt_cancel_request` 事件与 SMB1 NT_CANCEL 命令的解析原理 网络安全网络IDS【免费下载链接】zeekZeek 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 内置的 SMBServer 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.bifbif 文件是 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_count1 字节和byte_count2 字节两个字段是 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_CANCELmidMultiplex 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() priority5 { Log::create_stream(LOG, [$columnsInfo, $pathsmb1_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_responsesmb1_com_negotiate.bifsmb1_nt_create_andx_request/smb1_nt_create_andx_responsesmb1_com_nt_create_andx.bifsmb1_transaction_request、smb1_transaction2_requestsmb1_com_transaction.bif、smb1_com_transaction2.bifsmb1_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【免费下载链接】zeekZeek is a powerful network analysis framework that is much different from the typical IDS you may know.项目地址https://gitcode.com/gh_mirrors/ze/zeek点击查看免费下载相关推荐用 GetQzonehistory 导出全部 QQ 空间历史说说一次扫码拿到 6 张 Excel 和一个网页相册用 GetQzonehistory 导出全部 QQ 空间历史说说一次扫码拿到 6 张 Excel 和一个网页相册 GetQzonehistory 是一个在本网络安全网络IDS语音AI智能体落地实战从三十秒Demo到7×24语音客服系统的避坑指南语音AI智能体落地实战从三十秒Demo到7×24语音客服系统的避坑指南 你搭的语音AI智能体——语音客服系统、博物馆导览都算——多半卡在同一处本地演示挺顺网络安全网络IDSZeek 文件传输事件 file_transferred 深度解析原理、参数与脚本实战Zeek 文件传输事件 file_transferred 深度解析原理、参数与脚本实战 导读 file_transferred 是 Zeek 网络分析框架中用网络安全网络IDS上一篇CANN ops-nn 仓库 MseLoss 算子深度解析从 aclnn 两段式调用到 Ascend C 实现原理下一篇彻底解决Pydantic-AI中Gemini模型响应验证失败的5个关键方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考