Skip to content
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
1 change: 1 addition & 0 deletions doc/userguide/rules/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Suricata Rules
base64-keywords
sip-keywords
sdp-keywords
sctp-keywords
rfb-keywords
mqtt-keywords
ike-keywords
Expand Down
150 changes: 150 additions & 0 deletions doc/userguide/rules/sctp-keywords.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
.. role:: example-rule-emphasis

SCTP Keywords
=============

Suricata supports sticky buffers and keywords for matching on SCTP
packet headers, chunks, and metadata.

Sticky buffers are expected to be followed by one or more
:doc:`payload-keywords`.

sctp.hdr
--------

Sticky buffer to match on the raw SCTP header and all chunks.

Example rule:

.. container:: example-rule

alert sctp any any -> any any (msg:"SCTP header match"; :example-rule-emphasis:`sctp.hdr; content:"|01|"; offset:8; depth:1;` sid:1; rev:1;)

``sctp.hdr`` is a 'sticky buffer'.

``sctp.hdr`` can be used as ``fast_pattern``.

sctp.chunk_data
---------------

Sticky buffer to match on any SCTP DATA chunk user payload.

When a packet contains DATA chunks, the packet payload (``p->payload``)
is set to the user data of the first DATA chunk. A bare ``content``
match (without a sticky buffer) therefore inspects the first DATA
chunk's payload. Use ``sctp.chunk_data`` to inspect all DATA chunks
independently.

Example rule:

.. container:: example-rule

alert sctp any any -> any any (msg:"SCTP DATA payload match"; :example-rule-emphasis:`sctp.chunk_data; content:"test";` sid:2; rev:1;)

``sctp.chunk_data`` is a 'sticky buffer'.

``sctp.chunk_data`` can be used as ``fast_pattern``.

sctp.vtag
---------

Match on the SCTP verification tag field in the common header.

sctp.vtag uses an :ref:`unsigned 32-bit integer <rules-integer-keywords>`.

Syntax::

sctp.vtag:[op]<number>

The verification tag can be matched exactly, or compared using the _op_ setting::

sctp.vtag:12345 # exactly 12345
sctp.vtag:>0 # greater than 0
sctp.vtag:100-200 # range 100 to 200

Example rule:

.. container:: example-rule

alert sctp any any -> any any (msg:"SCTP vtag match"; :example-rule-emphasis:`sctp.vtag:0;` sid:3; rev:1;)

sctp.chunk_type
---------------

Match on the type of any SCTP chunk in the packet.

sctp.chunk_type uses an :ref:`unsigned 8-bit integer <rules-integer-keywords>`.

Syntax::

sctp.chunk_type:[!]<value>
sctp.chunk_type:[op]<number>

Values can be specified by name or by numeric value. The following
named chunk types are supported:

================= =====
Name Value
================= =====
data 0
init 1
init_ack 2
sack 3
heartbeat 4
hb_ack 5
abort 6
shutdown 7
shutdown_ack 8
error 9
cookie_echo 10
cookie_ack 11
ecne 12
cwr 13
shutdown_complete 14
forward_tsn 192
================= =====

Named values are case-insensitive and can be negated with ``!``::

sctp.chunk_type:init # INIT chunk
sctp.chunk_type:init_ack # INIT ACK chunk
sctp.chunk_type:!data # any chunk that is not DATA

Numeric values support comparison operators and ranges::

sctp.chunk_type:1 # INIT chunk (type 1)
sctp.chunk_type:0-4 # range 0 to 4

Example rules:

.. container:: example-rule

alert sctp any any -> any any (msg:"SCTP INIT chunk detected"; :example-rule-emphasis:`sctp.chunk_type:init;` sid:4; rev:1;)

.. container:: example-rule

alert sctp any any -> any any (msg:"SCTP INIT chunk detected"; :example-rule-emphasis:`sctp.chunk_type:1;` sid:5; rev:1;)

sctp.chunk_cnt
--------------

Match on the number of SCTP chunks in the packet.

sctp.chunk_cnt uses an :ref:`unsigned 8-bit integer <rules-integer-keywords>`.

Syntax::

sctp.chunk_cnt:[op]<number>

The chunk count can be matched exactly, or compared using the _op_ setting::

sctp.chunk_cnt:1 # exactly 1 chunk
sctp.chunk_cnt:>3 # more than 3 chunks
sctp.chunk_cnt:2-5 # range 2 to 5

Example rule:

.. container:: example-rule

alert sctp any any -> any any (msg:"SCTP packet with multiple chunks"; :example-rule-emphasis:`sctp.chunk_cnt:>1;` sid:5; rev:1;)

111 changes: 110 additions & 1 deletion etc/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -5641,6 +5641,59 @@
}
}
},
"sctp": {
"type": "object",
"description": "SCTP protocol information",
"additionalProperties": false,
"properties": {
"chunk_cnt": {
"type": "integer",
"description": "Number of SCTP chunks in the packet",
"suricata": {
"keywords": [
"sctp.chunk_cnt"
]
}
},
"chunk_types": {
"type": "array",
"description": "Array of SCTP chunk type names present in the packet",
"items": {
"type": "string"
},
"suricata": {
"keywords": [
"sctp.chunk_type"
]
}
},
"has_abort": {
"type": "boolean",
"description": "Whether the packet contains an ABORT chunk"
},
"has_data": {
"type": "boolean",
"description": "Whether the packet contains a DATA chunk"
},
"has_init": {
"type": "boolean",
"description": "Whether the packet contains an INIT chunk"
},
"has_init_ack": {
"type": "boolean",
"description": "Whether the packet contains an INIT_ACK chunk"
},
"vtag": {
"type": "integer",
"description": "SCTP verification tag",
"suricata": {
"keywords": [
"sctp.vtag"
]
}
}
}
},
"sip": {
"type": "object",
"additionalProperties": false,
Expand Down Expand Up @@ -7459,8 +7512,37 @@
"type": "object",
"additionalProperties": false,
"properties": {
"chunk_len_invalid": {
"type": "integer",
"description": "SCTP chunk length < 4 or exceeds remaining packet"
},
"chunk_too_small": {
"type": "integer",
"description": "Remaining data too small for SCTP chunk header"
},
"data_with_zero_vtag": {
"type": "integer",
"description": "SCTP DATA chunk with verification tag == 0"
},
"init_chunk_bundled": {
"type": "integer",
"description": "RFC 4960 sec 6.10 violation: INIT/INIT_ACK bundled with other chunks"
},
"init_with_non_zero_vtag": {
"type": "integer",
"description": "SCTP INIT with verification tag != 0"
},
"pkt_too_small": {
"type": "integer"
"type": "integer",
"description": "SCTP packet smaller than minimum size"
},
"too_many_chunks": {
"type": "integer",
"description": "More chunks than SCTP_MAX_TRACKED_CHUNKS"
},
"too_many_data_chunks": {
"type": "integer",
"description": "More DATA chunks than SCTP_MAX_DATA_CHUNKS"
}
}
},
Expand Down Expand Up @@ -8547,6 +8629,33 @@
}
}
},
"sctp": {
"type": "object",
"description": "Statistics on SCTP chunk types",
"additionalProperties": false,
"properties": {
"abort": {
"type": "integer",
"description": "Number of SCTP packets with ABORT chunk"
},
"data": {
"type": "integer",
"description": "Number of SCTP packets with DATA chunk"
},
"init": {
"type": "integer",
"description": "Number of SCTP packets with INIT chunk"
},
"init_ack": {
"type": "integer",
"description": "Number of SCTP packets with INIT_ACK chunk"
},
"shutdown": {
"type": "integer",
"description": "Number of SCTP packets with SHUTDOWN chunk"
}
}
},
"stream": {
"type": "object",
"description": "Observational statistics on TCP stream events",
Expand Down
1 change: 1 addition & 0 deletions rules/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pgsql-events.rules \
pop3-events.rules \
quic-events.rules \
rfb-events.rules \
sctp-events.rules \
smb-events.rules \
smtp-events.rules \
snmp-events.rules \
Expand Down
1 change: 1 addition & 0 deletions rules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ signature IDs.
| POP3 | 2236000 | 2236999 |
| LDAP | 2237000 | 2237999 |
| SNMP | 2238000 | 2238999 |
| SCTP | 2239000 | 2239999 |
| DNS | 2240000 | 2240999 |
| PGSQL | 2241000 | 2241999 |
| mDNS | 2242000 | 2242999 |
Expand Down
13 changes: 13 additions & 0 deletions rules/sctp-events.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# SCTP decoder event rules.
# SID's fall in the 2239000+ range. See rules/README.md

alert sctp any any -> any any (msg:"SURICATA SCTP packet too small"; decode-event:sctp.pkt_too_small; classtype:protocol-command-decode; sid:2239001; rev:1;)
alert sctp any any -> any any (msg:"SURICATA SCTP chunk too small"; decode-event:sctp.chunk_too_small; classtype:protocol-command-decode; sid:2239002; rev:1;)
alert sctp any any -> any any (msg:"SURICATA SCTP chunk length invalid"; decode-event:sctp.chunk_len_invalid; classtype:protocol-command-decode; sid:2239003; rev:1;)
alert sctp any any -> any any (msg:"SURICATA SCTP INIT chunk bundled"; decode-event:sctp.init_chunk_bundled; classtype:protocol-command-decode; sid:2239004; rev:1;)
alert sctp any any -> any any (msg:"SURICATA SCTP INIT with non-zero vtag"; decode-event:sctp.init_with_non_zero_vtag; classtype:protocol-command-decode; sid:2239005; rev:1;)
alert sctp any any -> any any (msg:"SURICATA SCTP DATA with zero vtag"; decode-event:sctp.data_with_zero_vtag; classtype:protocol-command-decode; sid:2239006; rev:1;)
alert sctp any any -> any any (msg:"SURICATA SCTP too many chunks"; decode-event:sctp.too_many_chunks; classtype:protocol-command-decode; sid:2239007; rev:1;)
alert sctp any any -> any any (msg:"SURICATA SCTP too many data chunks"; decode-event:sctp.too_many_data_chunks; classtype:protocol-command-decode; sid:2239008; rev:1;)

#next sid is 2239009
1 change: 1 addition & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ pub mod lzma;
pub mod util;
pub mod ffi;
pub mod feature;
pub mod sctp;
pub mod sdp;
pub mod ldap;
pub mod flow;
Expand Down
Loading
Loading