Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

decode/ethertype: Event on unknown ethertype #11546

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 91 additions & 75 deletions doc/userguide/rules/thresholding.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. role:: example-rule-emphasis

Thresholding Keywords
=====================

Expand All @@ -7,98 +9,122 @@ Thresholding can be configured per rule and also globally, see
Thresholds are tracked in a hash table that is sized according to configuration, see:
:ref:`suricata-yaml-thresholds`.

*Note: mixing rule and global thresholds is not supported in 1.3 and
before. See bug #425.* For the state of the support in 1.4 see
:ref:`global-thresholds-vs-rule-thresholds`
**IMPORTANT** for both ``threshold`` and ``detection_filter`` keywords

.. note::

Rules that contain ``flowbits``, ``flowints``, etc will still have those actions performed when the rule
contains one of the ``threshold`` keywords. Those actions are not subject to the threshold limits.

Rule actions ``drop`` (IPS mode) and ``reject`` are applied to each packet
(not only the one that meets the limit condition).

threshold
---------

The threshold keyword can be used to control the rule's alert
frequency. It has 3 modes: threshold, limit and both.
The ``threshold`` keyword can be used to control the rule's alert
frequency. There are four threshold modes:

#. threshold
#. limit
#. both
#. backoff

Syntax::

threshold: type <threshold|limit|both|backoff>, track <by_src|by_dst|by_rule|by_both|by_flow>, count <N>, <seconds <T>|multiplier <M>>

Specify ``seconds`` to control the number of alerts per time period.

type "threshold"
~~~~~~~~~~~~~~~~

This type can be used to set a minimum threshold for a rule before it
generates alerts. A threshold setting of N means on the Nth time the
rule matches an alert is generated.
This type sets a minimum threshold for a rule before it generates alerts.

Example::
A threshold setting with a ``count`` value of ``C`` will generate an alert
the ``Cth`` time the alert matches. If ``seconds`` is specified, an
alert is generated when ``count`` matches have occurred within ``N`` seconds.

alert tcp !$HOME_NET any -> $HOME_NET 25 (msg:"ET POLICY Inbound Frequent Emails - Possible Spambot Inbound"; \
flow:established; content:"mail from|3a|"; nocase; \
threshold: type threshold, track by_src, count 10, seconds 60; \
reference:url,doc.emergingthreats.net/2002087; classtype:misc-activity; sid:2002087; rev:10;)
Syntax::

threshold: type threshold, track by_flow, count <C>, seconds <N>;

This signature only generates an alert if we get 10 inbound emails or
more from the same server in a time period of one minute.
Example:

If a signature sets a flowbit, flowint, etc. those actions are still
performed for each of the matches.
.. container:: example-rule

*Rule actions drop (IPS mode) and reject are applied to each packet
(not only the one that meets the threshold condition).*
alert tcp !$HOME_NET any -> $HOME_NET 25 (msg:"ET POLICY Inbound Frequent Emails - Possible Spambot Inbound";
flow:established; content:"mail from|3a|"; nocase;
:example-rule-emphasis:`threshold: type threshold, track by_src, count 10, seconds 60;`
reference:url,doc.emergingthreats.net/2002087; classtype:misc-activity; sid:2002087; rev:10;)

This signature generates an alert if there are 10 or more inbound emails from the same server within
one minute.

type "limit"
~~~~~~~~~~~~

This type can be used to make sure you're not getting flooded with
alerts. If set to limit N, it alerts at most N times.
The ``limit`` type prevents a flood of alerts by limiting the number of alerts.
A limit with a count of ``N`` won't generate more than ``N`` alerts.

Limit the number of alerts per time period by specifying ``seconds`` with
``count.``

Syntax::

Example::
threshold: type limit, track by_dst, count <C>, seconds <N>;

alert http $HOME_NET any -> any $HTTP_PORTS (msg:"ET USER_AGENTS Internet Explorer 6 in use - Significant Security Risk"; \
flow:to_server,established; content:"|0d 0a|User-Agent|3a| Mozilla/4.0 (compatible|3b| MSIE 6.0|3b|"; \
threshold: type limit, track by_src, seconds 180, count 1; \
reference:url,doc.emergingthreats.net/2010706; classtype:policy-violation; sid:2010706; rev:7;)
Example:

In this example at most 1 alert is generated per host within a period
of 3 minutes if MSIE 6.0 is detected.
.. container:: example-rule

If a signature sets a flowbit, flowint, etc. those actions are still
performed for each of the matches.
alert http $HOME_NET any -> any any (msg:"ET INFO Internet Explorer 6 in use - Significant Security Risk";
flow:established,to_server; http.user_agent; content:"Mozilla/4.0 (compatible|3b| MSIE 6.0|3b|";
:example-rule-emphasis:`threshold: type limit, track by_src, seconds 180, count 1;`
classtype:policy-violation; sid:2010706; rev:10; metadata:created_at 2010_07_30, updated_at 2024_03_16;)

*Rule actions drop (IPS mode) and reject are applied to each packet
(not only the one that meets the limit condition).*
In this example, at most 1 alert is generated per host within a period
of 3 minutes if "MSIE 6.0" is detected.

type "both"
~~~~~~~~~~~

This type is a combination of the "threshold" and "limit" types. It
applies both thresholding and limiting.
This type combines ``threshold`` and ``limit`` to control when alerts
are generated.

Example::
Syntax::

alert tcp $HOME_NET 5060 -> $EXTERNAL_NET any (msg:"ET VOIP Multiple Unauthorized SIP Responses TCP"; \
flow:established,from_server; content:"SIP/2.0 401 Unauthorized"; depth:24; \
threshold: type both, track by_src, count 5, seconds 360; \
reference:url,doc.emergingthreats.net/2003194; classtype:attempted-dos; sid:2003194; rev:6;)
threshold: type both, track by_flow, count <C>, multiplier <M>;

Example:

.. container:: example-rule

This alert will only generate an alert if within 6 minutes there have
been 5 or more "SIP/2.0 401 Unauthorized" responses, and it will alert
only once in that 6 minutes.
alert tcp $HOME_NET 5060 -> $EXTERNAL_NET any (msg:"ET VOIP Multiple Unauthorized SIP Responses TCP";
flow:established,from_server; content:"SIP/2.0 401 Unauthorized"; depth:24;
:example-rule-emphasis:`threshold: type both, track by_src, count 5, seconds 360;`
reference:url,doc.emergingthreats.net/2003194; classtype:attempted-dos; sid:2003194; rev:6;)

If a signature sets a flowbit, flowint, etc. those actions are still
performed for each of the matches.
This rule will generate at most one alert every 6 minutes if there have been 5 or more occurrences
of "SIP2.0 401 Unauthorized" responses.

*Rule actions drop (IPS mode) and reject are applied to each packet.*
The ``type backoff`` section describes the ``multiplier`` keyword.

type "backoff"
~~~~~~~~~~~~~~

Allow limiting of alert output by using a backoff algorithm.
This type limits the alert output by using a backoff algorithm between alerts.

.. note::

``backoff`` can only be used with ``track by_flow``

Syntax::

threshold: type backoff, track by_flow, count <C>, multiplier <M>;

``track``: backoff is only supported for ``by_flow``
``count``: number of alerts before the first match is logged
``count``: number of alerts before the first match generates an alert.
``multiplier``: value to multiply ``count`` with each time the next value is reached

A count of 1 with a multiplier of 10 would generate alerts for matching packets::
Expand All @@ -117,14 +143,9 @@ In the following example, the ``pkt_invalid_ack`` would only lead to alerts the

.. container:: example-rule

alert tcp any any -> any any (stream-event:pkt_invalid_ack; \
:example-rule-options:`threshold:type backoff, track by_flow, count 1, multiplier 10;`
sid:2210045; rev:2;)

If a signature sets a flowbit, flowint, etc. those actions are still
performed for each of the matches.

*Rule actions drop (IPS mode) and reject are applied to each matching packet.*
alert tcp any any -> any any (stream-event:pkt_invalid_ack;
:example-rule-emphasis:`threshold:type backoff, track by_flow, count 1, multiplier 10;`
sid:2210045; rev:2;)


track
Expand All @@ -150,31 +171,26 @@ track
detection_filter
----------------

The detection_filter keyword can be used to alert on every match after
a threshold has been reached. It differs from the threshold with type
threshold in that it generates an alert for each rule match after the
initial threshold has been reached, where the latter will reset it's
internal counter and alert again when the threshold has been reached
again.
The ``detection_filter`` keyword can be used to alert on every match after
an initial threshold has been reached. It differs from ``threshold`` with type
``threshold`` in that it generates an alert for each rule match after the
initial threshold has been reached, where the latter will reset its
internal counter and alert each time the threshold has been reached.

Syntax::

detection_filter: track <by_src|by_dst|by_rule|by_both|by_flow>, count <N>, seconds <T>

Example::

alert http $EXTERNAL_NET any -> $HOME_NET any \
(msg:"ET WEB_SERVER WebResource.axd access without t (time) parameter - possible ASP padding-oracle exploit"; \
flow:established,to_server; content:"GET"; http_method; content:"WebResource.axd"; http_uri; nocase; \
content:!"&t="; http_uri; nocase; content:!"&amp|3b|t="; http_uri; nocase; \
detection_filter:track by_src,count 15,seconds 2; \
reference:url,netifera.com/research/; reference:url,www.microsoft.com/technet/security/advisory/2416728.mspx; \
classtype:web-application-attack; sid:2011807; rev:5;)
Example:

Alerts each time after 15 or more matches have occurred within 2 seconds.
.. container:: example-rule

If a signature sets a flowbit, flowint, etc. those actions are still
performed for each of the matches.
alert http $EXTERNAL_NET any -> $HOME_NET any
(msg:"ET WEB_SERVER WebResource.axd access without t (time) parameter - possible ASP padding-oracle exploit";
flow:established,to_server; content:"GET"; http_method; content:"WebResource.axd"; http_uri; nocase;
content:!"&t="; http_uri; nocase; content:!"&amp|3b|t="; http_uri; nocase;
:example-rule-emphasis:`detection_filter:track by_src,count 15,seconds 2;`
reference:url,netifera.com/research/; reference:url,www.microsoft.com/technet/security/advisory/2416728.mspx;
classtype:web-application-attack; sid:2011807; rev:5;)

*Rule actions drop (IPS mode) and reject are applied to each packet
that generate an alert*
This rule will generate alerts are 15 or more matches have occurred within 2 seconds.
3 changes: 3 additions & 0 deletions etc/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -5364,6 +5364,9 @@
"properties": {
"pkt_too_small": {
"type": "integer"
},
"unknown_ethertype": {
"type": "integer"
}
},
"additionalProperties": false
Expand Down
3 changes: 2 additions & 1 deletion rules/decoder-events.rules
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ alert pkthdr any any -> any any (msg:"SURICATA UDP header length too small"; dec
alert pkthdr any any -> any any (msg:"SURICATA UDP invalid length field in the header"; decode-event:udp.len_invalid; classtype:protocol-command-decode; sid:2200120; rev:2;)
alert pkthdr any any -> any any (msg:"SURICATA SLL packet too small"; decode-event:sll.pkt_too_small; classtype:protocol-command-decode; sid:2200041; rev:2;)
alert pkthdr any any -> any any (msg:"SURICATA Ethernet packet too small"; decode-event:ethernet.pkt_too_small; classtype:protocol-command-decode; sid:2200042; rev:2;)
alert pkthdr any any -> any any (msg:"SURICATA Ethertype unknown"; decode-event:ethernet.unknown_ethertype; threshold: type limit, track by_rule, seconds 60, count 1; classtype:protocol-command-decode; sid:2200121; rev:1;)
alert pkthdr any any -> any any (msg:"SURICATA PPP packet too small"; decode-event:ppp.pkt_too_small; classtype:protocol-command-decode; sid:2200043; rev:2;)
alert pkthdr any any -> any any (msg:"SURICATA PPP VJU packet too small"; decode-event:ppp.vju_pkt_too_small; classtype:protocol-command-decode; sid:2200044; rev:2;)
alert pkthdr any any -> any any (msg:"SURICATA PPP IPv4 packet too small"; decode-event:ppp.ip4_pkt_too_small; classtype:protocol-command-decode; sid:2200045; rev:2;)
Expand Down Expand Up @@ -151,5 +152,5 @@ alert pkthdr any any -> any any (msg:"SURICATA CHDLC packet too small"; decode-e

alert pkthdr any any -> any any (msg:"SURICATA packet with too many layers"; decode-event:too_many_layers; classtype:protocol-command-decode; sid:2200116; rev:1;)

# next sid is 2200121
# next sid is 2200122

4 changes: 4 additions & 0 deletions src/decode-events.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,10 @@ const struct DecodeEvents_ DEvents[] = {
"decoder.ethernet.pkt_too_small",
ETHERNET_PKT_TOO_SMALL,
},
{
"decoder.ethernet.unknown_ethertype",
ETHERNET_UNKNOWN_ETHERTYPE,
},

/* PPP EVENTS */
{
Expand Down
3 changes: 2 additions & 1 deletion src/decode-events.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ enum {
SLL_PKT_TOO_SMALL, /**< sll packet smaller than minimum size */

/* ETHERNET EVENTS */
ETHERNET_PKT_TOO_SMALL, /**< ethernet packet smaller than minimum size */
ETHERNET_PKT_TOO_SMALL, /**< ethernet packet smaller than minimum size */
ETHERNET_UNKNOWN_ETHERTYPE, /**< ethertype unknown/unhandled*/

/* PPP EVENTS */
PPP_PKT_TOO_SMALL, /**< ppp packet smaller than minimum size */
Expand Down
3 changes: 3 additions & 0 deletions src/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ void PacketDecodeFinalize(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
if (p->flags & PKT_IS_INVALID) {
StatsIncr(tv, dtv->counter_invalid);
}
if (p->flags & PKT_IS_UNKNOWN) {
StatsIncr(tv, dtv->counter_ethertype_unknown);
}
}

void PacketUpdateEngineEventCounters(ThreadVars *tv,
Expand Down
9 changes: 8 additions & 1 deletion src/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,10 @@ void DecodeUnregisterCounters(void);
ENGINE_SET_EVENT(p, e); \
} while(0)

#define ENGINE_SET_UNKNOWN_EVENT(p, e) do { \
p->flags |= PKT_IS_UNKNOWN; \
ENGINE_SET_EVENT(p, e); \
} while(0)


#define ENGINE_ISSET_EVENT(p, e) ({ \
Expand Down Expand Up @@ -1322,6 +1326,9 @@ void DecodeUnregisterCounters(void);
#define PKT_FIRST_ALERTS BIT_U32(29)
#define PKT_FIRST_TAG BIT_U32(30)

/** Unknown/unsupported */
#define PKT_IS_UNKNOWN BIT_U32(31)

/** \brief return 1 if the packet is a pseudo packet */
#define PKT_IS_PSEUDOPKT(p) \
((p)->flags & (PKT_PSEUDO_STREAM_END|PKT_PSEUDO_DETECTLOG_FLUSH))
Expand Down Expand Up @@ -1508,7 +1515,7 @@ static inline bool DecodeNetworkLayer(ThreadVars *tv, DecodeThreadVars *dtv,
break;
default:
SCLogDebug("unknown ether type: %" PRIx16 "", proto);
StatsIncr(tv, dtv->counter_ethertype_unknown);
ENGINE_SET_UNKNOWN_EVENT(p, ETHERNET_UNKNOWN_ETHERTYPE);
return false;
}
return true;
Expand Down
Loading