HTTP 关键词 ============= .. role:: example-rule-action .. role:: example-rule-header .. role:: example-rule-options .. role:: example-rule-emphasis 使用 HTTP 特定的粘性缓冲区(参见 :ref:`rules-modifiers`)可以高效检查 HTTP 协议通信的特定字段。在规则中指定粘性缓冲区后,应跟随一个或多个 :doc:`payload-keywords` 或使用 :ref:`pcre`。 HTTP 基础 ----------- HTTP 被视为客户端-服务器或请求-响应协议。客户端向服务器请求资源,服务器响应请求。 在 HTTP 2.0 之前的版本中,客户端请求可能如下所示: HTTP 请求示例:: GET /index.html HTTP/1.1 User-Agent: Mozilla/5.0 Host: suricata.io 针对上述请求的告警签名示例: .. container:: example-rule alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP 请求示例"; \ flow:established,to_server; :example-rule-options:`http.method; \ content:"GET"; http.uri; content:"/index.html"; bsize:11; http.protocol; \ content:"HTTP/1.1"; bsize:8; http.user_agent; content:"Mozilla/5.0"; bsize:11; \ http.host; content:"suricata.io"; bsize:11;` classtype:bad-unknown; sid:25; rev:1;) 在 HTTP 2.0 之前的版本中,服务器响应可能如下所示: HTTP 响应示例:: HTTP/1.1 200 OK Content-Type: text/html Content-Length: 258 Date: Thu, 14 Dec 2023 20:22:41 GMT Server: nginx/0.8.54 Connection: Close 针对上述响应的告警签名示例: .. container:: example-rule alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP 状态码示例"; \ flow:established,to_client; :example-rule-options:`http.stat_code; \ content:"200"; bsize:8; http.content_type; content:"text/html"; bsize:9;` \ classtype:bad-unknown; sid:30; rev:1;) 请求关键词: * :ref:`file.name` * :ref:`http.accept` * :ref:`http.accept_enc` * :ref:`http.accept_lang` * :ref:`http.host` * :ref:`http.host.raw` * :ref:`http.method` * :ref:`http.referer` * :ref:`http.request_body` * :ref:`http.request_header` * :ref:`http.request_line` * :ref:`http.uri` * :ref:`http.uri.raw` * :ref:`http.user_agent` * :ref:`urilen` 响应关键词: * :ref:`http.location` * :ref:`http.response_body` * :ref:`http.response_header` * :ref:`http.response_line` * :ref:`http.server` * :ref:`http.stat_code` * :ref:`http.stat_msg` 请求或响应关键词: * :ref:`file.data` * :ref:`http.connection` * :ref:`http.content_len` * :ref:`http.content_type` * :ref:`http.cookie` * :ref:`http.header` * :ref:`http.header.raw` * :ref:`http.header_names` * :ref:`http.protocol` * :ref:`http.start` .. _http.normalization: 规范化 ------------- 有时 Suricata 会对观察到的流量执行格式化/规范化更改。 重复的头部名称 ~~~~~~~~~~~~~~~~~~~~~~ 如果同一头部名称有多个值,它们会以逗号和空格(", ")连接。更多信息可参考 RFC 2616 ``_ 在下面的示例中,注意无论字母大小写如何,User-Agent 头部都被视为相同的头部。规范化头部评估会导致如上述 RFC 所述的连接头部值。 重复 HTTP 头部示例:: GET / HTTP/1.1 Host: suricata.io User-Agent: Mozilla/5.0 User-agent: Chrome/121.0.0 .. container:: example-rule alert http $HOME_NET -> $EXTERNAL_NET (msg:"重复头部示例"; \ flow:established,to_server; :example-rule-options:`http.user_agent; \ content:"Mozilla/5.0, Chrome/121.0.0";` classtype:bad-unknown; sid:103; \ rev:1;) .. _file.name: file.name --------- ``file.name`` 关键词可用于 HTTP 请求。 可以与 ``file.name`` 关键词一起使用任何 :doc:`payload-keywords`。 HTTP 请求示例:: GET /picture.jpg HTTP/1.1 User-Agent: Mozilla/5.0 Host: suricata.io .. container:: example-rule alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP file.name 示例"; \ flow:established,to_client; :example-rule-options:`file.name; \ content:"picture.jpg";` classtype:bad-unknown; sid:129; rev:1;) .. note:: 更多信息可参考 :doc:`file-keywords` .. _http.accept: http.accept ----------- ``http.accept`` 关键词用于匹配 HTTP 请求头部中可能存在的 Accept 字段。 可以与 ``http.accept`` 关键词一起使用任何 :doc:`payload-keywords`。 HTTP 请求示例:: GET /index.html HTTP/1.1 User-Agent: Mozilla/5.0 Accept: */* Host: suricata.io .. container:: example-rule alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Accept 示例"; \ flow:established,to_server; :example-rule-options:`http.accept; \ content:"*/*";` bsize:3; classtype:bad-unknown; sid:91; rev:1;) .. note:: ``http.accept`` 不包含前导空格或尾部 \\r\\n .. note:: ``http.accept`` 可能会对缓冲区内容应用额外的格式化/规范化,更多细节请参考 :ref:`http.normalization`。 .. _http.accept_enc: http.accept_enc --------------- ``http.accept_enc`` 关键词用于匹配 HTTP 请求头部中可能存在的 Accept-Encoding 字段。 可以与 ``http.accept_enc`` 关键词一起使用任何 :doc:`payload-keywords`。 HTTP 请求示例:: GET /index.html HTTP/1.1 User-Agent: Mozilla/5.0 Accept-Encoding: gzip, deflate Host: suricata.io .. container:: example-rule alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Accept-Encoding 示例"; \ flow:established,to_server; :example-rule-options:`http.accept_enc; \ content:"gzip, deflate";` bsize:13; classtype:bad-unknown; sid:92; rev:1;) .. note:: ``http.accept_enc`` 不包含前导空格或尾部 \\r\\n .. note:: ``http.accept_enc`` 可能会对缓冲区内容应用额外的格式化/规范化,更多细节请参考 :ref:`http.normalization`。 .. _http.accept_lang: http.accept_lang ---------------- ``http.accept_lang`` 关键词用于匹配 HTTP 请求头部中可能存在的 Accept-Language 字段。 可以与 ``http.accept_lang`` 关键词一起使用任何 :doc:`payload-keywords`。 HTTP 请求示例:: GET /index.html HTTP/1.1 User-Agent: Mozilla/5.0 Accept-Language: en-US Host: suricata.io .. container:: example-rule alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Accept-Language 示例"; \ flow:established,to_server; :example-rule-options:`http.accept_lang; \ content:"en-US";` bsize:5; classtype:bad-unknown; sid:93; rev:1;) .. note:: ``http.accept_lang`` 不包含前导空格或尾部 \\r\\n .. note:: ``http.accept_lang`` 可能会对缓冲区内容应用额外的格式化/规范化,更多细节请参考 :ref:`http.normalization`。 .. _http.host: http.host --------- 在 Suricata 中,匹配 HTTP 主机名有两个选项:``http.host`` 和 ``http.host.raw`` 粘性缓冲区。 可以与这两个 ``http.host`` 关键词一起使用任何 :doc:`payload-keywords`。 .. note:: ``http.host`` 关键词会规范化主机头部内容。如果主机名包含大写字符,这些字符会被转换为小写。 规范化示例:: GET /index.html HTTP/1.1 User-Agent: Mozilla/5.0 Host: SuRiCaTa.Io 在上面的示例中,主机缓冲区将包含 `suricata.io`。 .. container:: example-rule alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP 主机示例"; \ flow:established,to_server; :example-rule-options:`http.host; \ content:"suricata.io";` bsize:11; classtype:bad-unknown; sid:123; rev:1;) .. note:: 不再允许使用 ``nocase`` 关键词,因为主机名已被规范化为仅包含小写字母。 .. note:: ``http.host`` 不包含与主机关联的端口(例如 suricata.io:1234)。要匹配主机和端口或排除主机和端口,请使用 :ref:`http.host.raw`。 .. note:: ``http.host`` 不包含前导空格或尾部 \\r\\n .. note:: ``http.host`` 和 ``http.host.raw`` 缓冲区从 URI(如果请求中包含完整 URI,如代理请求)或 HTTP Host 头部填充。如果两者都存在,则使用 URI。 .. note:: ``http.host`` 可能会对缓冲区内容应用额外的格式化/规范化,更多细节请参考 :ref:`http.normalization`。 .. _http.host.raw: http.host.raw ------------- ``http.host.raw`` 缓冲区匹配 HTTP 主机内容,但不对缓冲区内容执行任何规范化(参见 :ref:`http.host`) HTTP 请求示例:: GET /index.html HTTP/1.1 User-Agent: Mozilla/5.0 Host: SuRiCaTa.Io:8445 .. container:: example-rule alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP 主机原始示例"; \ flow:established,to_server; :example-rule-options:`http.host.raw; \ content:"SuRiCaTa.Io|3a|8445";` bsize:16; classtype:bad-unknown; sid:124; rev:1;) .. note:: ``http.host.raw`` 不包含前导空格或尾部 \\r\\n .. note:: ``http.host`` 和 ``http.host.raw`` 缓冲区从 URI(如果请求中包含完整 URI,如代理请求)或 HTTP Host 头部填充。如果两者都存在,则使用 URI。 .. note:: ``http.host.raw`` 可能会对缓冲区内容应用额外的格式化/规范化,更多细节请参考 :ref:`http.normalization`。 .. _http.method: http.method ----------- ``http.method`` 关键词用于匹配 HTTP 请求中使用的方法/动词。HTTP 请求方法可以是以下任意一种: * GET * POST * HEAD * OPTIONS * PUT * DELETE * TRACE * CONNECT * PATCH 可以与 ``http.method`` 关键词一起使用任何 :doc:`payload-keywords`。 HTTP 请求示例:: GET /index.html HTTP/1.1 User-Agent: Mozilla/5.0 Host: suricata.io .. container:: example-rule alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP 请求示例"; \ flow:established,to_server; :example-rule-options:`http.method; \ content:"GET";` classtype:bad-unknown; sid:2; rev:1;) .. _http.referer: http.referer ------------ ``http.referer`` 关键词用于匹配 HTTP 请求头部中可能存在的 Referer 字段。 可以与 ``http.referer`` 关键词一起使用任何 :doc:`payload-keywords`。 HTTP 请求示例:: GET / HTTP/1.1 Host: suricata.io Referer: https://suricata.io .. container:: example-rule alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Referer 示例"; \ flow:established,to_server; :example-rule-options:`http.referer; \ content:"http|3a 2f 2f|suricata.io";` bsize:19; classtype:bad-unknown; \ sid:200; rev:1;) .. note:: ``http.referer`` 不包含前导空格或尾部 \\r\\n .. note:: ``http.referer`` 可能会对缓冲区内容应用额外的格式化/规范化,更多细节请参考 :ref:`http.normalization`。 .. _http.request_body: http.request_body ----------------- ``http.request_body`` 关键词用于匹配 HTTP 请求中可能存在的请求体。 可以与 ``http.request_body`` 关键词一起使用任何 :doc:`payload-keywords`。 HTTP 请求示例:: POST /suricata.php HTTP/1.1 Content-Type: application/x-www-form-urlencoded Host: suricata.io Content-Length: 23 Connection: Keep-Alive Suricata 请求体 .. container:: example-rule alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP 请求体示例"; \ flow:established,to_server; :example-rule-options:`http.request_body; \ content:"Suricata 请求体";` classtype:bad-unknown; sid:115; rev:1;) .. note:: 检查多少请求/客户端体由 :ref:`libhtp 配置部分 ` 中的 ``request-body-limit`` 设置控制。 .. note:: ``http.request_body`` 替换了之前的关键词名称 ``http_client_body``。仍可使用 ``http_client_body``,但建议将规则转换为使用 ``http.request_body``。 .. _http.request_header: http.request_header ------------------- ``http.request_header`` 关键词用于匹配 HTTP/1 或 HTTP/2 请求的头部名称和值。 可以与 ``http.request_header`` 关键词一起使用任何 :doc:`payload-keywords`。 对于 HTTP/2,头部名称和值通过 ": "(冒号和空格)连接。冒号和空格在签名中通常以十六进制格式 `|3a 20|` 表示。 要检测 HTTP/2 头部名称是否包含 ":"(冒号),可以使用关键词 :ref:`http2.header_name`。 HTTP/1 请求示例:: GET /index.html HTTP/1.1 User-Agent: Mozilla/5.0 Host: suricata.io .. container:: example-rule alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP 请求示例"; \ flow:established,to_server; :example-rule-options:`http.request_header; \ content:"Host|3a 20|suricata.io";` classtype:bad-unknown; sid:126; rev:1;) .. note:: ``http.request_header`` 不包含尾部 \\r\\n .. _http.request_line: http.request_line ----------------- ``http.request_line`` 关键词用于匹配 HTTP 请求行的全部内容。 HTTP 请求示例:: GET /index.html HTTP/1.1 User-Agent: Mozilla/5.0 Host: suricata.io .. container:: example-rule alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP 请求示例"; \ flow:established,to_server; :example-rule-options:`http.request_line; \ content:"GET /index.html HTTP/1.1";` bsize:24; classtype:bad-unknown; \ sid:60; rev:1;) .. note:: ``http.request_line`` 不包含尾部 \\r\\n .. _rules-http-uri-normalization: .. _http.uri: http.uri -------- 在 Suricata 中,匹配 HTTP URI 缓冲区有两个选项:``http.uri`` 和 ``http.uri.raw`` 粘性缓冲区。 可以与这两个 ``http.uri`` 关键词一起使用任何 :doc:`payload-keywords`。 ``http.uri`` 关键词规范化 URI 缓冲区。例如,如果 URI 有两个前导 ``//``,Suricata 会将 URI 规范化为单个前导 ``/``。 规范化示例:: GET //index.html HTTP/1.1 User-Agent: Mozilla/5.0 Host: suricata.io 在这种情况下,:example-rule-emphasis:`//index.html` 将被规范化为 :example-rule-emphasis:`/index.html`。 规范化 HTTP 请求示例:: GET /index.html HTTP/1.1 User-Agent: Mozilla/5.0 Host: suricata.io .. container:: example-rule alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP URI 示例"; \ flow:established,to_server; :example-rule-options:`http.uri; \ content:"/index.html";` bsize:11; classtype:bad-unknown; sid:3; rev:1;