You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
suricata/doc/userguide/rules/multi-buffer-matching.rst

185 lines
5.8 KiB
ReStructuredText

.. _rules-multi-buffer-matching:
Multiple Buffer Matching
========================
Suricata 7 and newer now supports matching contents in multiple
buffers within the same transaction.
For example a single DNS transaction that has two queries in it:
query 1: example.net
query 2: something.com
Example rule:
.. container:: example-rule
alert dns $HOME_NET any -> $EXTERNAL_NET any (msg:"DNS Multiple Question Example Rule"; dns.query; content:"example"; dns.query; content:".com"; classtype:misc-activity; sid:1; rev:1;)
Within the single DNS query transaction, there are two queries
and Suricata will set up two instances of a dns.query buffer.
The first ``dns.query`` buffer will look for content:"example";
The second ``dns.query`` buffer will look for content:".com";
The example rule will alert on the example query since all the
content matches are satisfied for the rule.
For matching multiple headers in HTTP2 traffic a rule using the
new functionality would look like:
.. container:: example-rule
alert http2 any any -> any any (msg:"HTTP2 Multiple Header Buffer Example"; flow:established,to_server; http.request_header; content:"method|3a 20|GET"; http.request_header; content:"authority|3a 20|example.com"; classtype:misc-activity; sid:1; rev:1;)
With HTTP2 there are multiple headers seen in the same flow record.
We now have a way to write a rule in a more efficient way using the
multiple buffer capability.
**Note** Existing behavior when using sticky buffers still applies:
Example rule:
.. container:: example-rule
alert dns $HOME_NET any -> $EXTERNAL_NET any (msg:"DNS Query Sticky Buffer Classic Example Rule"; dns.query; content:"example"; content:".net"; classtype:misc-activity; sid:1; rev:1;)
The above rule will alert on a single dns query containing
"example.net" or "example.domain.net" since the rule content
matches are within a single ``dns.query`` buffer and all
content match requirements of the rule are met.
**Note:** This is new behavior. In versions of Suricata prior to
version 7 multiple statements of the same sticky buffer did not
make a second instance of the buffer. For example:
dns.query; content:"example"; dns.query; content:".com";
would be equivalent to:
dns.query; content:"example"; content:".com";
Using our example from above, the first query is for example.net
which matches content:"example"; but does not match content:".com";
The second query is for something.com which would match on the
content:".com"; but not the content:"example";
So with the Suricata behavior prior to Suricata 7, the signature
would not fire in this case since both content conditions will
not be met.
Indexes for multi-buffers
-------------------------
As for :ref:`multi-integer <multi-integers>`, multi-buffers can precise
which index to match on.
The syntax is::
buffer: index; content: "toto";
.. table:: **Index values for multi-buffers keywords**
=============== ===========================================================
Value Description
=============== ===========================================================
[default] Match with any index
any Match with any index
any_or_absent Match with any index or matches on an empty list
all Match only if all and at least one indexes match
all_or_absent Match only if all indexes match or matches on an empty list
matches <value> Matches a number of times
index <value> Match specific index
oob_or <value> Match with specific index or index out of bounds
=============== ===========================================================
.. container:: example-rule
alert ip any any -> any 5353 (:example-rule-emphasis:`email.received: all;` content:"abc"; sid:1;)
.. container:: example-rule
alert ip any any -> any 5353 (:example-rule-emphasis:`email.received: matches >2;` content:"def"; sid:1;)
.. container:: example-rule
alert ip any any -> any 5353 (:example-rule-emphasis:`email.received: index 0;` content:"ghi"; sid:1;)
**Please note that:**
The index ``all`` will not match if there is no value.
The index ``all_or_absent`` will match if there is no value
and behaves like ``all`` if there is at least one value.
If needed, these keywords will wait for transaction completion to run,
to be sure to have the final number of elements.
The index ``matches`` accepts all comparison modes as integer keywords.
For example ``matches>3`` will match only if more than 3 integers in the
array match the value.
List of multi-buffers
---------------------
Multiple buffer matching is currently enabled for use with the
following keywords:
* ``dns.additionals.rrname``
* ``dns.answer.name``
* ``dns.answers.rrname``
* ``dns.authorities.rrname``
* ``dns.queries.rrname``
* ``dns.query``
* ``dns.query.name``
* ``email.received``
* ``email.url``
* ``file.data``
* ``file.magic``
* ``file.name``
* ``ftp.completion_code``
* ``ftp.reply``
* ``http.request_header``
* ``http.response_header``
* ``http2.header_name``
* ``ike.vendor``
* ``krb5.cname``
* ``krb5.sname``
* ``ldap.request.attribute_type``
* ``ldap.responses.attribute_type``
* ``ldap.responses.dn``
* ``ldap.responses.message``
* ``mdns.additionals.rrname``
* ``mdns.answers.rrname``
* ``mdns.authorities.rrname``
* ``mdns.queries.rrname``
* ``mqtt.subscribe.topic``
* ``mqtt.unsubscribe.topic``
* ``quic.cyu.hash``
* ``quic.cyu.string``
* ``sdp.attribute``
* ``sdp.bandwidth``
* ``sdp.media.connection_data``
* ``sdp.media.encryption_key``
* ``sdp.media.media``
* ``sdp.media.media_info``
* ``sdp.repeat_time``
* ``sdp.time``
* ``sip.content_length``
* ``sip.content_type``
* ``sip.from``
* ``sip.to``
* ``sip.user_agent``
* ``sip.via``
* ``smtp.rcpt_to``
* ``tls.alpn``
* ``tls.certs``
* ``tls.subjectaltname``
These can be found by command
``suricata --list-keywords=csv | grep "multi buffer" | cut -d';' -f1``