news 2026/10/6 2:20:39

Zeek 中 SMB1 transaction_secondary 请求事件 `smb1_transaction_secondary_request` 解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Zeek 中 SMB1 transaction_secondary 请求事件 `smb1_transaction_secondary_request` 解析
  • 网络安全
  • 网络
  • 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/CIFS 版本 1 协议暴露的事件smb1_transaction_secondary_request展开,说明其事件签名、SMB1::Trans_Sec_Args参数结构、与 SMB Transaction 子协议(Transaction Subprotocol)的关系,并结合仓库中对应的 BIF 声明与 binpac 语法解析实现,梳理该事件从报文解析到 Zeek 脚本层投递的完整链路。读完本文,你将能够在 Zeek 脚本中正确挂接该事件,读懂parameters/data载荷的语义,并理解它与smb1_transaction_request如何协同还原大事务的完整数据。

事件概览:签名、命名空间与触发条件

smb1_transaction_secondary_request是 Zeek 的 SMB 分析器(位于src/analyzer/protocol/smb/)在解析 SMB/CIFS 版本 1 的transaction_secondary类型请求时生成的脚本层事件,定义在 GLOBAL 命名空间中。其完整签名如下:

event smb1_transaction_secondary_request(c: connection, hdr: SMB1::Header, args: SMB1::Trans_Sec_Args, parameters: string, data: string)

依据官方生成的接口文档(Zeek_SMB.smb1_com_transaction_secondary.bif.zeek.rst),该事件:

  • 为 SMB(Server Message Block)/ CIFS(Common Internet File System)版本 1的transaction_secondary类型请求而生成;
  • 充当Transaction Subprotocol Commands(由 transaction 请求承载)的附加请求数据容器,即用于续传主transaction请求未能一次携带完的参数与数据;
  • 对应的协议规范参考为 MS-CIFS 2.2.4.34(即SMB_COM_TRANSACTION_SECONDARY请求结构)。

事件声明位于 smb1_com_transaction_secondary.bif,其中除了事件本身外,还声明了配套的记录类型type SMB1::Trans_Sec_Args: record;,作为args参数的承载类型。

背景:SMB1 Transaction 子协议为什么需要 secondary 请求

SMB1 的 Transaction 子协议允许客户端发起一个“事务”(如命名管道 I/O、邮件槽广播、RAP 远程管理调用等),其语义由请求中的 Setup/Parameters/Data 三部分描述。由于单个 SMB 报文存在长度上限,较大的事务数据无法一次装下。MS-CIFS 定义了两种续传机制:

  • SMB_COM_TRANSACTION_SECONDARY:本事件对应的报文,用于在主transaction请求之后继续追加 Parameters 与 Data 片段;
  • 与之对应的还有SMB_COM_TRANSACTION2_SECONDARY(Zeek 中以smb1_com_transaction2_secondary事件族呈现,见 src/analyzer/protocol/smb 目录下同名.bif与.pac文件),面向 Transaction2 子协议。

因此smb1_transaction_secondary_request本身不携带事务的“发起信息”(如事务名称、子命令号),这些信息由先行到达的smb1_transaction_request提供;secondary 请求只负责把剩余的参数与数据“接力”送达,这也是文档中称其为“additional request data container(附加请求数据容器)”的原因。

事件参数详解

该事件的五个参数语义如下(依据官方文档与 smb1_com_transaction_secondary.bif 中的注释):

参数类型含义
cconnection产生该请求的连接对象
hdrSMB1::Header该 SMB 版本 1 报文的解析后头部
argsSMB1::Trans_Sec_Args记录类型,携带本次续传的字节计数与位移等结构化信息(详见下文)
parametersstringSMB_Data.Trans_Parameters字段内容,即续传的参数块
datastringSMB_Data.Trans_Data字段内容,即续传的数据块

args:SMB1::Trans_Sec_Args 的结构字段

Trans_Sec_Args的具体字段由 binpac 解析器在投递事件时逐项填充,字段顺序与赋值索引可从 smb1-com-transaction-secondary.pac 的proc_smb1_transaction_secondary_request函数中确认:

索引字段说明
0total_param_count整个事务的参数总字节数(跨多个报文累计)
1total_data_count整个事务的数据总字节数
2param_count本报文中参数块的字节数
3param_offset本报文参数块相对 SMB 头的偏移
4param_displacement本报文参数块在事务总参数序列中的起始位移
5data_count本报文中数据块的字节数
6data_offset本报文数据块相对 SMB 头的偏移
7data_displacement本报文数据块在事务总数据序列中的起始位移

从字段可以看出,secondary 报文的关键信息是*_displacement(位移):分析器或脚本可以据此把各续传片段按位移拼接,还原完整的事务参数与数据序列。这也是smb1_transaction_secondary_request事件最有价值的字段组。

源码级实现:从报文到事件投递

1. binpac 语法定义报文字段布局

smb1-com-transaction-secondary.pac 用 binpac 语法定义了SMB1_transaction_secondary_request记录的完整报文布局:

type SMB1_transaction_secondary_request(header: SMB_Header) = record { word_count : uint8; total_param_count : uint16; total_data_count : uint16; param_count : uint16; param_offset : uint16; param_displacement : uint16; data_count : uint16; data_offset : uint16; data_displacement : uint16; byte_count : uint16; pad1 : padding to param_offset - SMB_Header_length; parameters : bytestring &length = param_count; pad2 : padding to data_offset - SMB_Header_length; data : SMB1_transaction_data(header, true, data_count, 0, SMB_UNKNOWN, false); } &let { proc : bool = $context.connection.proc_smb1_transaction_secondary_request(header, this); };

布局要点:

  • 头部是固定的计数/位移字段组(total_*为总量,param_*/data_*为本次片段的计数、偏移与位移);
  • parameters按param_count精确截取;
  • data字段复用SMB1_transaction_data联合类型(定义于 smb1-com-transaction.pac),其case分支会按传输类型(如SMB_PIPE、SMB_UNKNOWN等)解析出对应的字节内容;
  • 记录末尾通过&let的proc钩子调用连接对象上的处理函数proc_smb1_transaction_secondary_request,把解析结果投递为 Zeek 事件。

2. C++ 侧:填充 args、构造字符串并投递事件

同一文件中的proc_smb1_transaction_secondary_request函数(C++ 代码块)完成事件投递前的全部准备工作:

  1. 快速失败检查:若脚本层未注册smb1_transaction_secondary_request事件处理器,函数直接返回false,避免无谓开销;
  2. 构造Trans_Sec_Args记录:通过zeek::make_intrusive<zeek::RecordVal>(zeek::BifType::Record::SMB1::Trans_Sec_Args)创建记录,并依次将total_param_count、total_data_count、param_count、param_offset、param_displacement、data_count、data_offset、data_displacement八个字段赋值到索引 0–7;
  3. 构造参数串:把parameters字节序列转为zeek::StringVal;
  4. 构造数据串:当data_count > 0时,调用transaction_data_to_val()(定义于 smb1-com-transaction.pac,按传输类型返回管道数据或未知数据);当data_count == 0时,直接使用空字符串zeek::val_mgr->EmptyString();
  5. 投递事件:调用zeek::BifEvent::enqueue_smb1_transaction_secondary_request(...),把连接、SMB 头、args、parameters、data 一并入队,最终由事件调度器回调 Zeek 脚本层。

3. 与 transaction 请求的协作:子命令信息的来源

由于 secondary 报文本身不携带事务名称与子命令号,相关上下文来自主请求。仓库中的脚本 smb1-main.zeek 给出了smb1_transaction_request事件的官方处理示例:

event smb1_transaction_request(c: connection, hdr: SMB1::Header, name: string, sub_cmd: count, parameters: string, data: string) { c$smb_state$current_cmd$sub_command = SMB1::trans_sub_commands[sub_cmd]; }

也就是说,事务的“身份”(如name指向的管道/邮件槽名称、sub_cmd对应的子命令)在smb1_transaction_request中即可确定,而后续到达的多个smb1_transaction_secondary_request事件则持续补充分片数据——脚本层若需要拼装完整事务,可依据args$param_displacement/args$data_displacement将多个片段的parameters与data按序归位。

Zeek 脚本使用示例

在 Zeek 脚本中挂接该事件与挂接其他 SMB1 事件一致,例如:

event smb1_transaction_secondary_request(c: connection, hdr: SMB1::Header, args: SMB1::Trans_Sec_Args, parameters: string, data: string) { if ( args$data_count > 0 ) print fmt("%s transaction_secondary data fragment: %d bytes at displacement %d", c$id, args$data_count, args$data_displacement); }

实践要点:

  • 事件仅在transaction_secondary类型请求到达时触发,无需额外注册即可生效(前提是 SMB 分析器已加载,scripts/base/protocols/smb/下的脚本随默认策略加载);
  • 若要完整还原事务内容,应与smb1_transaction_request事件联合使用,以connection为纽带聚合多个续传片段;
  • data为空串是正常情况(data_count == 0时解析器显式投递空字符串),判断时应以args$data_count为准而非字符串是否为空。

相关文件索引

以下仓库文件可供进一步深入研究:

  • 事件接口文档:doc/scripts/base/bif/plugins/Zeek_SMB.smb1_com_transaction_secondary.bif.zeek.rst
  • BIF 事件与类型声明:src/analyzer/protocol/smb/smb1_com_transaction_secondary.bif
  • binpac 报文解析与 C++ 投递实现:src/analyzer/protocol/smb/smb1-com-transaction-secondary.pac
  • 事务数据联合类型与transaction_data_to_val:src/analyzer/protocol/smb/smb1-com-transaction.pac
  • 脚本层状态维护示例(smb1_transaction_request处理器):scripts/base/protocols/smb/smb1-main.zeek
  • SMB 分析器目录(含 transaction2-secondary 等相关事件族):src/analyzer/protocol/smb

本文所述协议字段布局与事件语义均可在上述源码与文档中逐项对照验证;SMB1::Trans_Sec_Args的字段顺序则从smb1-com-transaction-secondary.pac的赋值代码推断得出,可作为编写依赖该记录结构脚本时的依据。

  • 网络安全
  • 网络
  • 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
点击查看免费下载
上一篇:LinkSwift:九大网盘直链下载终极解决方案,轻松突破下载限制
下一篇:Operit 计算器限定 API 修复实践:Math 与 stats 命名空间在解析器与求值器中的对齐实现

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/6 2:19:19

uBlock Origin:免费开源的轻量广告拦截插件

uBlock Origin&#xff1a;免费开源的轻量广告拦截插件 【免费下载链接】uBlock uBlock Origin - An efficient blocker for Chromium and Firefox. Fast and lean. 项目地址: https://gitcode.com/GitHub_Trending/ub/uBlock 点开一个新闻页&#xff0c;标题还没读完&a…

作者头像 李华
网站建设 2026/10/6 2:15:32

AI Agent 面试题 166:如何设计Agent的上下文优先级排序机制?

&#x1f525; AI Agent 面试题 166&#xff1a;如何设计Agent的上下文优先级排序机制&#xff1f;摘要&#xff1a;本文深入解析了「如何设计Agent的上下文优先级排序机制&#xff1f;」这一 AI Agent 领域的核心面试题。文章从 上下文窗口管理 的基本概念出发&#xff0c;系统…

作者头像 李华