====================== 与Snort的差异 ====================== 本文档旨在重点介绍Suricata与Snort在规则及规则编写方面的主要区别。 若无特别说明,以下描述均针对Suricata。一般情况下,对Snort的引用特指2.9版本分支。 自动协议检测 ---------------------------- - Suricata自动检测以下应用层协议: - dcerpc - dnp3 - dns - http - imap(默认仅检测;不解析) - pop3(默认仅检测;不解析) - ftp - modbus(默认禁用;最小化探测解析器;可能导致误报) - smb - smb2(引擎内部默认禁用) - smtp - ssh - tls(支持SSLv2、SSLv3、TLSv1、TLSv1.1和TLSv1.2) - 在Suricata中,协议检测通常与端口无关(多数情况下)。而Snort需要通过配置端口才能使 ``http_inspect`` 等预处理器生效。 - Suricata的yaml配置中,某些应用层协议默认会指定特定目标端口(如DNS) - **可在任意端口检测流量,无需担心Snort中可能存在的性能影响** - 若流量被Suricata识别为HTTP,无论规则中指定何种端口,``http_*`` 缓冲区都会被填充并可用。 - 使用 ``http_*`` 缓冲区时不必显式检查HTTP协议(即 ``alert http ...``),但仍建议这样做。 - 若需检测合法(支持的)应用层协议流量且不限定特定端口,规则应写为 ``alert <协议> ...`` 并将端口设为 ``any``。例如检测HTTP流量且不限端口时: Snort规则示例:: alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS ... Suricata对应写法:: alert http $HOME_NET -> $EXTERNAL_NET any ... 或:: alert tcp $HOME_NET any -> $EXTERNAL_NET any (app-layer-protocol:http; ... ``urilen`` 关键字 ------------------ - ``urilen`` 的范围界定: - Snort为闭区间(包含边界值) - Suricata为开区间(不包含边界值) 示例:``urilen:2<>10`` - Snort解释:"URI长度≥2且≤10" - Suricata解释:"URI长度>2且<10" - 未来版本可能调整Suricata行为以兼容Snort—— `https://redmine.openinfosecfoundation.org/issues/1416 `_ - 当前暂未实施 - *Suricata* 默认作用于**标准化**缓冲区 - 使用 ``,raw`` 指定原始缓冲区 - 如:``urilen:>20,raw;`` - *Snort* 默认作用于**原始**缓冲区 - 使用 ``,norm`` 指定标准化缓冲区 - 如:``urilen:>20,norm;`` ``http_uri`` 缓冲区 ------------------- - Snort的 ``http_uri`` 会将 '+' 字符(0x2B)标准化为空格(0x20)。 - Suricata需在yaml文件的 ``libhtp`` 部分设置 ``query-plusspace-decode: yes`` 才能实现相同行为。 - 相关链接: - `https://redmine.openinfosecfoundation.org/issues/1035 `_ - `https://github.com/inliniac/suricata/pull/620 `_ ``http_header`` 缓冲区 ---------------------- - 结尾差异: - Snort的 ``http_header`` 包含分隔HTTP头与体的CRLF CRLF(0x0D 0x0A 0x0D 0x0A) - Suricata仅包含最后一个头的CRLF - 需匹配缓冲区末尾时,建议使用 ``http_raw_header``、相对 ``isdataat``(如 ``isdataat:!1,relative``)或PCRE(性能较差) - Suricata的 ``http_raw_header`` 会像Snort一样包含CRLF CRLF结尾 - 头部差异: - Snort在服务端响应的 ``http_header`` 中包含*前导*CRLF(客户端请求无此行为) - Suricata在请求/响应的 ``http_header`` 中均不包含前导CRLF - 标准化差异: - Suricata会规范化HTTP头行,确保冒号(':')后只保留一个空格(0x20) - Snort仅当冒号后存在空格(非制表符)时才进行规范化 - 重复头处理: - 标准化缓冲区(``http_header``)会按顺序用", "连接重复头的值 - 示例请求:: GET /test.html HTTP/1.1 Content-Length: 44 Accept: */* Content-Length: 55 - ``http_header`` 中的结果:: Content-Length: 44, 55 - Cookie头特殊处理: - ``http_header`` 不包含'Cookie'和'Set-Cookie'头(移至 ``http_cookie`` 缓冲区) - ``http_raw_header`` 仍包含这些头 - Snort启用 ``enable_cookie`` 时会保留头名称和CRLF - 其他HTTP专用缓冲区(如 ``http_user_agent``、``http_host``)不会被移除 - 服务端响应检测时,``http_*`` 缓冲区的匹配应置于 ``file_data`` 之前,除非使用 ``pkt_data`` 重置指针 ``http_cookie`` 缓冲区 ---------------------- - 不包含头名称、冒号及前导空格(如"Cookie: ") - 末尾不包含CRLF(需用相对 ``isdataat`` 或PCRE匹配结尾) - Suricata无 ``http_raw_cookie`` 缓冲区(使用 ``http_raw_header`` 替代) - 无需特殊配置即可使用(Snort需设置 ``enable_cookie``) - 多Cookie头处理差异: - Snort直接拼接值(无分隔符) - Suricata用", "连接值 示例请求:: GET /test.html HTTP/1.1 Cookie: monster Accept: */* Cookie: elmo Suricata结果:: monster, elmo Snort结果:: monsterelmo - PCRE修饰符:``C``(与Snort相同) 新增HTTP关键字 ----------------- Suricata支持Snort不具备的HTTP关键字,如 ``http_user_agent``、``http_host`` 和 ``http_content_type``。 完整列表见 :doc:`http-keywords`。 ``byte_extract`` 关键字 ------------------------ - Suricata支持从 ``http_*`` 缓冲区(含 ``http_header``)提取字节(Snort中可能异常) - 提取的变量必须在同一缓冲区使用,否则值为0(Snort允许跨缓冲区使用) - 建议对使用 ``byte_extract`` 和 ``byte_test`` 的规则进行正反测试 ``byte_jump`` 关键字 --------------------- - 允许使用 ``byte_extract`` 或 ``byte_math`` 的变量作为 ``nbytes`` 值 ``byte_math`` 关键字 --------------------- - 支持 ``dce`` 作为字节序值或独立关键字(等效于 ``endian dce``) - 拒绝单条规则中重复的关键字(如 ``byte_math: endian big, endian little``) - 接受 ``rvalue`` 值为0至uint32最大值(Snort拒绝0值) - 除数为0时永不匹配 ``byte_test`` 关键字 --------------------- - 允许使用 ``byte_extract`` 变量作为 ``nbytes`` 值 ``isdataat`` 关键字 -------------------- - ``rawbytes`` 语法支持但无效 - 绝对检查:偏移量小于检测缓冲区大小时成功(与Snort相同) - 相对检查差异: - Suricata:偏移量≤缓冲区大小时成功 - Snort:偏移量<缓冲区大小时成功 - 示例(匹配末尾无数据): - Snort:``isdataat:!0,relative;`` - Suricata:``isdataat:!1,relative;`` - 检测缓冲区范围: - Snort通常检查数据包/分段(某些预处理器例外) - Suricata绝对检查针对数据包/重组流 - Suricata相对检查基于前次内容匹配的缓冲区 - 示例规则(匹配URI末尾".exe"):: alert http $HOME_NET any -> $EXTERNAL_NET any (msg:".EXE File Download Request"; flow:established,to_server; content:"GET"; http_method; content:".exe"; http_uri; isdataat:!1,relative; priority:3; sid:18332111;) 相对PCRE ------------- - Suricata支持在标准化缓冲区中使用相对PCRE(如 ``content:".php?sign="; http_uri; pcre:"/^[a-zA-Z0-9]{8}$/UR";``) - Snort不允许将相对选项('R')与其他缓冲区选项(如'U')组合使用 ``tls*`` 关键字 ------------------ 除TLS协议识别外,Suricata还支持: - 证书磁盘存储 - 证书有效期验证 - SHA1指纹匹配 - 证书字段匹配(包括版本、Subject、Issuer、SNI等) 详见 :doc:`tls-keywords`。 ``dns_query`` 关键字 --------------------- - 设置检测指针至DNS查询(类似 ``file_data`` 的"粘性缓冲区") - 使用 ``pkt_data`` 重置指针 - 详见 :doc:`dns-keywords` IP信誉与 ``iprep`` 关键字 ----------------------------------- - Snort通过"reputation"预处理器实现IP黑白名单(生成GID 136警报) - Suricata扩展功能: - IP分类 - 信誉评分 - 方向/分类/值匹配 - 相关文档: - :doc:`../reputation/index` - :doc:`../reputation/ipreputation/ip-reputation-config` - :doc:`ip-reputation-rules` - :doc:`../reputation/ipreputation/ip-reputation-format` - `https://blog.inliniac.net/2012/11/21/ip-reputation-in-suricata/ `_ Flowbits -------- - Suricata完全支持同包/同流中设置和检查flowbits(含相同flowbit) - ``flowbits:isset`` 在快速模式匹配后检查(Snort按规则顺序检查) - 链式flowbits需注意规则顺序或 ``sid`` 影响 - 相关bug:`https://redmine.openinfosecfoundation.org/issues/1399 `_ - 详见 :doc:`flow-keywords` flowbits:noalert; ----------------- - Suricata中 ``noalert;`` 与 ``flowbits:noalert;`` 等效 否定内容匹配特例 ---------------------------------- - Snort中,当检测起始点超出缓冲区时,否定内容匹配永不返回真 - 示例HTTP请求:: POST /test.php HTTP/1.1 Content-Length: 9 user=suri - 此规则片段在Snort中永不匹配,Suricata正常匹配:: content:!"snort"; offset:10; http_client_body; 文件提取 --------------- - Suricata支持从FTP/HTTP/SMTP流中匹配并提取文件 - 支持的关键字包括: - ``filename`` - ``fileext`` - ``filemagic`` - 哈希值相关(md5/sha1/sha256) - 详见 :doc:`file-keywords` - ``filestore`` 触发文件存储 - 需注意流重组深度等配置 - 相关文档: - :doc:`../file-extraction/file-extraction` - `https://blog.inliniac.net/2011/11/29/file-extraction-in-suricata/ `_ - `https://blog.inliniac.net/2014/11/11/smtp-file-extraction-in-suricata/ `_ Lua脚本 ------------- - 通过 ``lua`` 关键字调用脚本访问数据包/负载/HTTP缓冲区等 - 提供Snort不具备的灵活能力 - 详见 :ref:`lua-detection` 快速模式 ------------ - 差异要点: - Suricata默认区分大小写(除非设置nocase) - Suricata不自动截断快速模式(Snort受 ``max-pattern-len`` 限制) - Suricata允许所有 ``http_*`` 缓冲区用于快速模式 - ``fast_pattern:only`` 语法支持但实际忽略 - Hyperscan算法可显著提升性能 - 详见 :doc:`fast-pattern-explained` 和 :ref:`rules-keyword-fast_pattern` 流检测限制 --------------------- - Suricata严格区分数据包级(如 ``dsize``、``flags``)和流级(如 ``http_*``)关键字 - 特殊协议值: - ``tcp-pkt``:仅检测TCP包 - ``tcp-stream``:仅检测重组流 - Snort对此限制较宽松 警报生成 ------ - Snort通过 ``event_queue`` 限制每包/流的警报数 - Suricata内置硬限制为15条警报(不可配置) 缓冲区参考表 ---------------------- (完整表格内容请参照原文格式,此处从略)