Zeek Login 插件事件全解析:Telnet/Rlogin/RSH 登录会话的启发式检测事件参考
网络安全网络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 仓库中base/bif/plugins/Zeek_Login.events.bif.zeek的 API 参考文档为核心骨架系统梳理Zeek::Login插件Telnet / Rlogin / Rsh 分析器对外暴露的全部 18 个事件涵盖登录成败判定、认证协商、Telnet 选项协商、环境变量透传与 RSH 命令记录。读者将掌握每个事件的确切签名、参数语义、触发时机、底层源码实现依据以及如何通过Analyzer::register_for_ports或 DPD 载荷签名手动激活这些事件并编写检测脚本。一、事件总览Login 分析器的对外接口Zeek::Login插件在 src/analyzer/protocol/login/Plugin.cc 中注册了七个分析器组件Telnet、Rsh、Rlogin、NVT、Login、Contents_Rsh、Contents_Rlogin插件描述为 Telnet/Rsh/Rlogin analyzers。其中NVTNetwork Virtual Terminal负责 Telnet 协议选项层的解析Login负责通用的登录对话框启发式跟踪Contents_Rsh/Contents_Rlogin负责按行切分会话数据。所有事件的定义位于 src/analyzer/protocol/login/events.bif命名空间为GLOBAL。下表给出 18 个事件的一览事件签名触发场景rsh_request(c: connection, client_user: string, server_user: string, line: string, new_session: bool)RSH 连接上客户端发送的命令rsh_reply(c: connection, client_user: string, server_user: string, line: string)RSH 连接上服务端返回的文本行login_failure(c: connection, user, client_user, password, line: string)Telnet/Rlogin 登录失败login_success(c: connection, user, client_user, password, line: string)Telnet/Rlogin 登录成功login_input_line(c: connection, line: string)Telnet/Rlogin 会话中的客户端输入行login_output_line(c: connection, line: string)Telnet/Rlogin 会话中的服务端输出行login_confused(c: connection, msg: string, line: string)登录跟踪启发式判定失败login_confused_text(c: connection, line: string)混淆后对后续用户输入的逐行报告login_terminal(c: connection, terminal: string)客户端通过 Telnet 选项发送 TERMlogin_display(c: connection, display: string)客户端通过 Telnet 选项发送 X11 DISPLAYlogin_prompt(c: connection, prompt: string)客户端通过 Telnet 选项发送 TTYPROMPTauthentication_accepted(name: string, c: connection)Telnet 认证选项协商成功authentication_rejected(name: string, c: connection)Telnet 认证选项协商失败authentication_skipped(c: connection)模式匹配表明未执行认证activating_encryption(c: connection)Telnet 加密选项协商成功启用inconsistent_option(c: connection)对端违反 Telnet 选项协商约定bad_option(c: connection)遇到格式错误或未识别的 Telnet 选项bad_option_termination(c: connection)Telnet 选项被错误地终止二、事件分类与触发机制2.1 登录成败事件login_success与login_failurelogin_success与login_failure是登录监控最核心的两个事件二者签名完全相同(c: connection, user: string, client_user: string, password: string, line: string)。user为尝试/成功的用户名password为尝试/成功的口令line是导致分析器得出成功或失败结论的那行文本。client_user在 Telnet 连接中恒为空字符串而在 Rlogin 连接中则是初始认证信息中携带的客户端用户名用于对照.rhosts检查。分析器提取这些信息的路径在 src/analyzer/protocol/login/Login.cc 的LoginEvent()中分析器用环形缓冲区user_text[]暂存客户端预输入type-ahead的用户文本在判定登录成功或失败时将缓冲区中用户名、密码与触发判定的行一起打包通过EnqueueConnEvent()抛出事件若缓冲区为空用户名与密码会被替换为none。Login_Analyzer的启发式判定在 Login.cc 的AuthenticationDialog()中实现内部状态机包含LOGIN_STATE_AUTHENTICATE、LOGIN_STATE_CONFUSED、LOGIN_STATE_SKIP、LOGIN_STATE_LOGGED_IN等状态。判定的关键分支包括看到登录提示符后若IsDirectLoginPrompt()命中直接登录提示符如免密登录直接触发login_success并进入LOGGED_IN状态看到超时或失败消息IsTimeout()或IsFailureMsg()命中时触发login_failure并对超时情况以timeout占位符记录用户文本看到成功消息IsSuccessMsg()命中或已超过login_prompt_line MAX_LOGIN_LOOKAHEAD num_user_text行仍无失败迹象时触发login_success跳过认证IsSkipAuthentication()命中时触发authentication_skipped并进入SKIP状态。此外EndpointEOF()见 Login.cc在连接结束且仍处于认证态、尚有预输入时会以EOF行触发一次login_success。注意文档明确指出login_success/login_failure是通过启发式观测会话数据得出的结论而authentication_accepted/authentication_rejected则是直接解析 Telnet 认证选项得到的确定性结论二者机制不同。2.2 会话行事件login_input_line与login_output_linelogin_input_line与login_output_line分别针对 Telnet/Rlogin 会话中客户端输入与服务端输出的每一行触发参数均为(c: connection, line: string)。文档特别说明行内容中已剔除控制字符如带内的 Telnet 选项字节因此可以直接用于关键词匹配或日志记录。在源码中这一行为由NewLine()实现Login.ccDeliverStream()先剥离流中的 NUL 字节并对 NUL 触发NUL_in_line的 weird再按方向调用LineEvent()抛出login_input_line/login_output_line。注意在LOGIN_STATE_SKIP或已LOGGED_IN状态下行事件仍会抛出但不会再进入认证对话框跟踪。2.3 混淆事件login_confused与login_confused_text由于 Login 分析器完全依赖启发式匹配遇到异常会话时可能失去方向。login_confused携带两个参数msg字符串描述启发式检测到的具体问题与line导致判定混淆的那行文本。文档给出示例msg为multiple_login_prompts表示分析器连续看到多个登录提示符却没有客户端侧应有的 type-ahead 输入来解释它们。源码中Confused()Login.cc在抛出的同时将状态置为LOGIN_STATE_CONFUSED以抑制后续重复消息并清空所有预输入缓冲区。已知的混淆消息还包括no_login_prompt认证阶段行数超过MAX_AUTHENTICATE_LINES仍未看到提示符、no_username/no_username2判定成功却缺少用户名、non_empty_multi_login、repeat_without_username、username_with_embedded_repeat、multiple_USERs、responder_environment、excessive_typeahead、possible_login_ploy等。login_confused_text在混淆发生后对用户输入的每一行逐一触发参数仅(c: connection, line: string)用于记录混淆之后用户继续输入的内容便于事后还原会话。2.4 环境变量事件login_terminal、login_display、login_prompt这三个事件均从 Telnet 选项携带的环境变量中提取信息login_terminal客户端发送的TERM值终端类型login_display客户端发送的 X11DISPLAY值login_prompt客户端发送的TTYPROMPT值。在 NVT.cc 的TelnetEnvironmentOption::RecvSubOption()中分析器解析 ENVIRON 子选项ENVIRON_IS/ENVIRON_INFO用ExtractEnv()逐个提取VAR/VAL键值对并回调Login_Analyzer::SetEnv()Login.cc变量名为USER时记录用户名重复 USER 会触发multiple_USERs混淆为TERM/DISPLAY/TTYPROMPT时分别抛出login_terminal/login_display/login_prompt。Rlogin 场景下终端类型也可由握手协议直接携带见Rlogin_Analyzer::TerminalType()Rlogin.cc。2.5 认证选项事件authentication_accepted/authentication_rejected/authentication_skippedTelnet 协议内置认证RFC 2941 系列选项的协商结果由前两个事件表达authentication_accepted客户端向服务端发送认证选项、服务端回复接受时触发name为通过认证的用户名authentication_rejected服务端回复拒绝时触发name为被拒绝的认证尝试用户名。两者均带(name: string, c: connection)签名。在 NVT.cc 的TelnetAuthenticateOption::RecvSubOption()中分析器处理AUTHENTICATION_STATUS子选项状态字节为AUTH_ACCEPT2时调用AuthenticationAccepted()为AUTH_REJECT1时调用AuthenticationRejected()二者NVT.cc最终抛出对应事件name取自对端的认证名PeerAuthName()缺失时为empty。authentication_skipped则完全不同当模式匹配表明会话根本没有执行认证时触发如某些免密服务参数仅(c: connection)。其触发路径在Login_Analyzer::AuthenticationDialog()中由IsSkipAuthentication()匹配skip_authentication正则集合命中后调用见 Login.cc。2.6 Telnet 选项协商事件activating_encryption、inconsistent_option、bad_option、bad_option_termination这四个事件反映 Telnet 选项协商层的健壮性与安全相关行为参数均为(c: connection)activating_encryptionTelnet 加密选项RFC 2946协商成功后触发。在 NVT.cc 中TelnetEncryptOption::RecvSubOption()处理ENCRYPT_REQUEST_START_TO_ENCRYPT/ENCRYPT_STARTING_TO_ENCRYPT子选项当对端已请求加密、双方已在加密或认证已被接受时SetEncrypting(1)会设置加密模式并触发该事件此后会话数据默认不再向下游传递SetSkipDeliveries。协议中的ENCRYPT_SET_ALGORITHM、ENCRYPT_SUPPORT_ALGORITHM、ENCRYPT_ENCRYPT_KEY、ENCRYPT_DECRYPT_KEY等子选项也在该文件顶部以枚举形式定义。inconsistent_option对端违反了选项协商的承诺。文档指出Telnet 选项协商是双方先声明支持/不支持再互相指示当前连接应启用/禁用哪些选项若某一方违背了对方的指示或自己此前的声明即触发该事件。对应实现TelnetOption::RecvOption()NVT.cc对WILL/WONT/DO/DONT四种指令做一致性校验例如收到WILL时若己方此前声明DONT、对端声明过WONT或选项已激活即判定不一致。bad_option遇到格式错误或无法识别的 Telnet 选项子选项长度非法、未知子选项码等时触发。bad_option_terminationTelnet 选项被错误终止如子选项未以SE240正确收尾时触发见NVT_Analyzer::BadOptionTermination()NVT.cc与ScanOption()中对last_was_IAC处理逻辑NVT.cc。2.7 RSH 事件rsh_request与rsh_reply这两个事件针对 RSHRFC 1258 的 Rlogin/Rsh 协议族连接文档注明出于历史原因这两个事件与login_系列事件分开理想情况下应统一处理rsh_request签名(c, client_user, server_user, line, new_session: bool)其中client_user/server_user是初始握手NUL 分隔的三元组中携带的客户端/服务端用户名line是请求中的命令行new_session为true表示这是该 Rsh 会话的第一条命令rsh_reply签名(c, client_user, server_user, line)表示服务端返回的文本行。触发路径在 RSH.ccContents_Rsh_Analyzer::DoDeliver()维护RSH_FIRST_NULL→RSH_CLIENT_USER_NAME→RSH_SERVER_USER_NAME→RSH_LINE_MODE的状态机跳过 stderr 端口号、解析两个用户名再按 CR/LF/NUL 切分行Rsh_Analyzer::DeliverStream()将行与用户名拼装后抛出事件new_session通过检查内容分析器是否刚从RSH_SERVER_USER_NAME状态离开即首条输入来判定。三、如何激活 Login 分析器与这些事件文档对绝大多数事件都附有同样的 todo 说明Zeek 当前默认配置并未激活生成这些事件的分析器对应的脚本尚未移植。要在自己的环境中启用需要二选一方式一按端口注册。在 Zeek 脚本中调用Analyzer::register_for_ports将Zeek::TELNET或Zeek::RSH、Zeek::RSH分析器绑定到目标端口。注册机制由 src/analyzer/Manager.cc 提供脚本层接口位于 scripts/base/frameworks/analyzer/main.zeekredef Analyzer::ports { [Analyzer::ANALYZER_TELNET] { 23/tcp }, }; event zeek_init() { Analyzer::register_for_ports(Analyzer::ANALYZER_TELNET, 23/tcp); }方式二DPD 载荷签名。为动态协议检测DPD添加针对 Telnet/Rlogin 会话特征的载荷签名使分析器在端口未注册时也能通过流量内容被识别并实例化。此外authentication_skipped、login_failure、login_success等事件还依赖一组脚本级模式变量。这组变量已在 scripts/base/init-bare.zeek 中声明均为set[string] redef当前注释仍为## TODO.未提供默认值变量作用skip_authentication命中即判定未执行认证触发authentication_skippeddirect_login_prompts直接登录提示符命中即判定登录成功login_prompts登录提示符模式如login:、Password:类文本login_non_failure_msgs排除误判的非失败消息IsFailureMsg要求失败消息命中且非失败消息不命中login_failure_msgs登录失败消息模式如Login incorrectlogin_success_msgs登录成功消息模式login_timeouts超时消息模式触发login_failure并以timeout占位这些集合在Login_Analyzer构造时被读取并编译为正则Login.cc因此修改后需要在新连接上生效。文档提醒由于该配置尚未移植login_failure/login_success/authentication_skipped等事件当前无法直接使用需自行以redef补齐模式集合才能驱动启发式判定。四、实战编写登录监控处理脚本在完成上述激活后可以像下面这样编写事件处理器覆盖登录成功、失败与异常场景event login_success(c: connection, user: string, client_user: string, password: string, line: string) { print fmt(LOGIN SUCCESS: %s - %s (user%s, line%s), c$id$orig_h, c$id$resp_h, user, line); } event login_failure(c: connection, user: string, client_user: string, password: string, line: string) { print fmt(LOGIN FAILURE: %s tried user %s on %s (line%s), c$id$orig_h, user, c$id$resp_h, line); } event login_confused(c: connection, msg: string, line: string) { print fmt(LOGIN CONFUSED: %s msg%s line%s, c$id$orig_h, msg, line); } event login_input_line(c: connection, line: string) { # 输入行已剔除控制字符可安全用于匹配 if ( /rm -rf|shutdown/ in line ) print fmt(SUSPICIOUS CMD on %s: %s, c$id$orig_h, line); } event rsh_request(c: connection, client_user: string, server_user: string, line: string, new_session: bool) { print fmt(RSH %s as %s - %s: %s%s, c$id$orig_h, client_user, server_user, line, new_session ? (new session) : ); } event activating_encryption(c: connection) { # 记录 Telnet 加密协商成功的连接 print fmt(TELNET ENCRYPTION ACTIVATED: %s, c$id$orig_h); } event authentication_rejected(name: string, c: connection) { print fmt(AUTH REJECTED for %s from %s, name, c$id$orig_h); }需要特别说明的取值口径密码字段可能为none缓冲区无预输入时不要假定其必然存在login_input_line/login_output_line与登录成败判定相互独立即使分析器处于SKIP/LOGGED_IN状态也持续抛出适合做全量会话行审计client_user仅在 Rlogin 场景非空Telnet 场景恒为空串login_confused触发后状态即锁定为CONFUSED后续输入改由login_confused_text逐行报告二者常配合使用以重建会话。五、相关资源事件完整定义与文档注释src/analyzer/protocol/login/events.bif插件组件注册src/analyzer/protocol/login/Plugin.cc登录启发式核心实现src/analyzer/protocol/login/Login.ccTelnet 选项/NVT 层实现src/analyzer/protocol/login/NVT.ccRlogin 行切分与握手解析src/analyzer/protocol/login/Rlogin.ccRSH 行切分与握手解析src/analyzer/protocol/login/RSH.cc脚本级模式变量声明scripts/base/init-bare.zeek赞分享网络安全网络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 BitTorrent 分析器事件接口全解从 Peer 消息到 Tracker 会话的 18 个事件参考Zeek BitTorrent 分析器事件接口全解从 Peer 消息到 Tracker 会话的 18 个事件参考 本文围绕 Zeek 内置 Zeek::Bit网络安全网络IDSTorchTitan graph_trainer Autoresearch用 LLM Agent 自主优化训练图 Pass 与 GPU 内核的闭环实验框架TorchTitan graph_trainer Autoresearch用 LLM Agent 自主优化训练图 Pass 与 GPU 内核的闭环实验框架 A网络安全网络IDSSplunk 中分析 Windows 事件日志的 API 参考与实践事件 ID、登录类型与 SPL 检测模式Anthropic-Cybersecurity-SkillsSplunk 中分析 Windows 事件日志的 API 参考与实践事件 ID、登录类型与 SPL 检测模式Anthropic Cybersecurity网络安全AI 技能/插件渗透测试红蓝对抗上一篇Vuex 4 API 参考全解从 Store 构造器到组合式函数的完整指南下一篇MediaPipe 手部追踪升级翻车实录Hand Landmarker 迁移必改的 3 处代码 1 个隐藏默认值创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考