10.14. HTTP 关键词

使用 HTTP 特定的粘性缓冲区(参见 修饰关键字)可以高效检查 HTTP 协议通信的特定字段。在规则中指定粘性缓冲区后,应跟随一个或多个 有效载荷关键词 或使用 pcre

10.14.1. HTTP 基础

HTTP 被视为客户端-服务器或请求-响应协议。客户端向服务器请求资源,服务器响应请求。

在 HTTP 2.0 之前的版本中,客户端请求可能如下所示:

HTTP 请求示例:

GET /index.html HTTP/1.1
User-Agent: Mozilla/5.0
Host: suricata.io

针对上述请求的告警签名示例:

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP 请求示例"; flow:established,to_server; 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

针对上述响应的告警签名示例:

alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP 状态码示例"; flow:established,to_client; http.stat_code; content:"200"; bsize:8; http.content_type; content:"text/html"; bsize:9; classtype:bad-unknown; sid:30; rev:1;)

请求关键词:
响应关键词:
  • http.location

  • http.response_body

  • http.response_header

  • http.response_line

  • http.server

  • http.stat_code

  • http.stat_msg

请求或响应关键词:
  • file.data

  • http.connection

  • http.content_len

  • http.content_type

  • http.cookie

  • http.header

  • http.header.raw

  • http.header_names

  • http.protocol

  • http.start

10.14.2. 规范化

有时 Suricata 会对观察到的流量执行格式化/规范化更改。

10.14.2.1. 重复的头部名称

如果同一头部名称有多个值,它们会以逗号和空格(", ")连接。更多信息可参考 RFC 2616 https://www.rfc-editor.org/rfc/rfc2616.html#section-4.2

在下面的示例中,注意无论字母大小写如何,User-Agent 头部都被视为相同的头部。规范化头部评估会导致如上述 RFC 所述的连接头部值。

重复 HTTP 头部示例:

GET / HTTP/1.1
Host: suricata.io
User-Agent: Mozilla/5.0
User-agent: Chrome/121.0.0

alert http $HOME_NET -> $EXTERNAL_NET (msg:"重复头部示例"; flow:established,to_server; http.user_agent; content:"Mozilla/5.0, Chrome/121.0.0"; classtype:bad-unknown; sid:103; rev:1;)

10.14.3. file.name

file.name 关键词可用于 HTTP 请求。

可以与 file.name 关键词一起使用任何 有效载荷关键词

HTTP 请求示例:

GET /picture.jpg HTTP/1.1
User-Agent: Mozilla/5.0
Host: suricata.io

alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP file.name 示例"; flow:established,to_client; file.name; content:"picture.jpg"; classtype:bad-unknown; sid:129; rev:1;)

Note

更多信息可参考 文件关键词

10.14.4. http.accept

http.accept 关键词用于匹配 HTTP 请求头部中可能存在的 Accept 字段。

可以与 http.accept 关键词一起使用任何 有效载荷关键词

HTTP 请求示例:

GET /index.html HTTP/1.1
User-Agent: Mozilla/5.0
Accept: */*
Host: suricata.io

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Accept 示例"; flow:established,to_server; http.accept; content:"*/*"; bsize:3; classtype:bad-unknown; sid:91; rev:1;)

Note

http.accept 不包含前导空格或尾部 \r\n

Note

http.accept 可能会对缓冲区内容应用额外的格式化/规范化,更多细节请参考 规范化

10.14.5. http.accept_enc

http.accept_enc 关键词用于匹配 HTTP 请求头部中可能存在的 Accept-Encoding 字段。

可以与 http.accept_enc 关键词一起使用任何 有效载荷关键词

HTTP 请求示例:

GET /index.html HTTP/1.1
User-Agent: Mozilla/5.0
Accept-Encoding: gzip, deflate
Host: suricata.io

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Accept-Encoding 示例"; flow:established,to_server; 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 可能会对缓冲区内容应用额外的格式化/规范化,更多细节请参考 规范化

10.14.6. http.accept_lang

http.accept_lang 关键词用于匹配 HTTP 请求头部中可能存在的 Accept-Language 字段。

可以与 http.accept_lang 关键词一起使用任何 有效载荷关键词

HTTP 请求示例:

GET /index.html HTTP/1.1
User-Agent: Mozilla/5.0
Accept-Language: en-US
Host: suricata.io

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Accept-Language 示例"; flow:established,to_server; 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 可能会对缓冲区内容应用额外的格式化/规范化,更多细节请参考 规范化

10.14.7. http.host

在 Suricata 中,匹配 HTTP 主机名有两个选项:http.hosthttp.host.raw 粘性缓冲区。

可以与这两个 http.host 关键词一起使用任何 有效载荷关键词

Note

http.host 关键词会规范化主机头部内容。如果主机名包含大写字符,这些字符会被转换为小写。

规范化示例:

GET /index.html HTTP/1.1
User-Agent: Mozilla/5.0
Host: SuRiCaTa.Io

在上面的示例中,主机缓冲区将包含 suricata.io

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP 主机示例"; flow:established,to_server; http.host; content:"suricata.io"; bsize:11; classtype:bad-unknown; sid:123; rev:1;)

Note

不再允许使用 nocase 关键词,因为主机名已被规范化为仅包含小写字母。

Note

http.host 不包含与主机关联的端口(例如 suricata.io:1234)。要匹配主机和端口或排除主机和端口,请使用 http.host.raw

Note

http.host 不包含前导空格或尾部 \r\n

Note

http.hosthttp.host.raw 缓冲区从 URI(如果请求中包含完整 URI,如代理请求)或 HTTP Host 头部填充。如果两者都存在,则使用 URI。

Note

http.host 可能会对缓冲区内容应用额外的格式化/规范化,更多细节请参考 规范化

10.14.8. http.host.raw

http.host.raw 缓冲区匹配 HTTP 主机内容,但不对缓冲区内容执行任何规范化(参见 http.host

HTTP 请求示例:

GET /index.html HTTP/1.1
User-Agent: Mozilla/5.0
Host: SuRiCaTa.Io:8445

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP 主机原始示例"; flow:established,to_server; 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.hosthttp.host.raw 缓冲区从 URI(如果请求中包含完整 URI,如代理请求)或 HTTP Host 头部填充。如果两者都存在,则使用 URI。

Note

http.host.raw 可能会对缓冲区内容应用额外的格式化/规范化,更多细节请参考 规范化

10.14.9. http.method

http.method 关键词用于匹配 HTTP 请求中使用的方法/动词。HTTP 请求方法可以是以下任意一种:

  • GET

  • POST

  • HEAD

  • OPTIONS

  • PUT

  • DELETE

  • TRACE

  • CONNECT

  • PATCH

可以与 http.method 关键词一起使用任何 有效载荷关键词

HTTP 请求示例:

GET /index.html HTTP/1.1
User-Agent: Mozilla/5.0
Host: suricata.io

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP 请求示例"; flow:established,to_server; http.method; content:"GET"; classtype:bad-unknown; sid:2; rev:1;)

10.14.10. http.referer

http.referer 关键词用于匹配 HTTP 请求头部中可能存在的 Referer 字段。

可以与 http.referer 关键词一起使用任何 有效载荷关键词

HTTP 请求示例:

GET / HTTP/1.1
Host: suricata.io
Referer: https://suricata.io

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Referer 示例"; flow:established,to_server; 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 可能会对缓冲区内容应用额外的格式化/规范化,更多细节请参考 规范化

10.14.11. http.request_body

http.request_body 关键词用于匹配 HTTP 请求中可能存在的请求体。

可以与 http.request_body 关键词一起使用任何 有效载荷关键词

HTTP 请求示例:

POST /suricata.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: suricata.io
Content-Length: 23
Connection: Keep-Alive

Suricata 请求体

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP 请求体示例"; flow:established,to_server; http.request_body; content:"Suricata 请求体"; classtype:bad-unknown; sid:115; rev:1;)

Note

检查多少请求/客户端体由 libhtp 配置部分 中的 request-body-limit 设置控制。

Note

http.request_body 替换了之前的关键词名称 http_client_body。仍可使用 http_client_body,但建议将规则转换为使用 http.request_body

10.14.12. http.request_header

http.request_header 关键词用于匹配 HTTP/1 或 HTTP/2 请求的头部名称和值。

可以与 http.request_header 关键词一起使用任何 有效载荷关键词

对于 HTTP/2,头部名称和值通过 ": "(冒号和空格)连接。冒号和空格在签名中通常以十六进制格式 |3a 20| 表示。

要检测 HTTP/2 头部名称是否包含 ":"(冒号),可以使用关键词 http2.header_name

HTTP/1 请求示例:

GET /index.html HTTP/1.1
User-Agent: Mozilla/5.0
Host: suricata.io

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP 请求示例"; flow:established,to_server; http.request_header; content:"Host|3a 20|suricata.io"; classtype:bad-unknown; sid:126; rev:1;)

Note

http.request_header 不包含尾部 \r\n

10.14.13. http.request_line

http.request_line 关键词用于匹配 HTTP 请求行的全部内容。

HTTP 请求示例:

GET /index.html HTTP/1.1
User-Agent: Mozilla/5.0
Host: suricata.io

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP 请求示例"; flow:established,to_server; 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

10.14.14. http.uri

在 Suricata 中,匹配 HTTP URI 缓冲区有两个选项:http.urihttp.uri.raw 粘性缓冲区。

可以与这两个 http.uri 关键词一起使用任何 有效载荷关键词

http.uri 关键词规范化 URI 缓冲区。例如,如果 URI 有两个前导 //,Suricata 会将 URI 规范化为单个前导 /

规范化示例:

GET //index.html HTTP/1.1
User-Agent: Mozilla/5.0
Host: suricata.io

在这种情况下,//index.html 将被规范化为 /index.html

规范化 HTTP 请求示例:

GET /index.html HTTP/1.1
User-Agent: Mozilla/5.0
Host: suricata.io

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP URI 示例"; flow:established,to_server; http.uri; content:"/index.html"; bsize:11; classtype:bad-unknown; sid:3; rev:1;