-
Notifications
You must be signed in to change notification settings - Fork 1.8k
SCTP decoder and sticky buffers v6 #15534
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
Changes from all commits
3f65beb
16f7486
bbd906f
9bf615e
b1d2082
47160ee
0e71428
0823683
16f17fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,144 @@ | ||
| .. 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. | ||
|
|
||
| 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;) | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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, | ||
|
|
@@ -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_not_alone": { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't have a suggestion, but this doesn't sound great |
||
| "type": "integer", | ||
| "description": "SCTP 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" | ||
| } | ||
| } | ||
| }, | ||
|
|
@@ -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", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| # 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;) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is the packet still marked as sctp in this case? Is there a SV test?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the packet is still identified as SCTP. Adding a SV test. |
||
| 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 not alone"; decode-event:sctp.init_chunk_not_alone; 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;) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: we generally have a next sid comment at the bottom of these files |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should these also reference keyword sctp.chunk_type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering whether it makes sense to log these boolean fields. Thoughts?