Commit Graph

2435 Commits (fe939e8da7203bab461114e2258ad386e9346284)

Author SHA1 Message Date
Juliana Fajardini fe939e8da7 pgsql: better boundaries to row_description/data_row
parse_row_description and parse_consolidated_data_row read a field_count
from the message body and use that to iterate a slice, without checking
whether the count actually fits the body.

A backend-controlled attack could lead to fewer fields logged, or
stalling of the parser to-client direction for the duration of the flow.

A malformed_response event is set for pgsql, if either of those
message's inner parsers has a field_count that can't be reconciled with
the body slice.

A new pgsql.response log field is added to indicate this, too:
pgsql.response.row_description_malformed, a boolean. This wasn't added
to the consolidated data row message, per its summarization nature.

The row_description unit test buffer declared a length one byte longer
than its three fields occupy. The old code silently discarded that
surplus byte; the new one reports it, so the buffer was corrected.

Ticket: #8885
2 months ago
Philippe Antoine 72829dbaea http: warn once for chunk extension
Avoids pushing multiple log messages, when the consumer will
only set one app-layer event for the tx

Ticket: 8867
2 months ago
Philippe Antoine 4dd7ebf079 http: warn once for response 100-continue already seen
Avoids pushing multiple log messages, when the consumer will
only set one app-layer event for the tx
Also, this is a warning, not an error, as we continue parsing.

Ticket: 8867
2 months ago
Philippe Antoine fefe0a9b8b http1: use strict brotli, forbid large window
Ticket: 9008

Avoids over-allocation from a few bytes
2 months ago
Philippe Antoine 2a85539ef0 http1: use brotli with owned BrotliState wrapper
Ticket: 9008

Will allow to use strict brotli, and forbid large window
2 months ago
Philippe Antoine 2b4d7a1f3d http2: use strict brotli, forbid large window
Ticket: 9008

Avoids over-allocation from a few bytes
2 months ago
Philippe Antoine a07cd82dc6 http2: use brotli with owned BrotliState wrapper
Ticket: 9008

Will allow to use strict brotli, and forbid large window
2 months ago
Philippe Antoine b13c742a9c ike: remove recursivity in functions
Ticket: 8800

Thus avoiding unbounded recursion

Before that, parse_payload could call
parse_security_association_payload which could call back
parse_payload if a type in the list was SecurityAssociation

But a Security Association only accepts the type Proposal in its
payload, see RFC 2408: section 3.5

There was another recursive path with parse_payload calling
parse_proposal_payload which called back parse_payload

And a Proposal only accepts the type Transform in its payload, see
RFC 2408: section 3.6
2 months ago
Juliana Fajardini 7f4d44edc1 pgsql: fix regression in handling request gap
Fixes: 9aeeac53 ("pgsql: remove probe_ts function")

When the probe_ts function was removed in 9aeeac532, the request gap
handling got inverted, preventing re-sync of the app-proto from the
frontend side.

This could lead to detection evasion after a gap.

Ticket: #8822
2 months ago
Philippe Antoine 521deb07d6 http2: respect max-table-size in headers size update
Ticket: 8755

The config parameter was only taken into account from the
settings frame HEADER_TABLE_SIZE

Emits an event http2.header_table_overflow when we have the first
header that we cannot keep in Suricata's memory due to the
configured limit.
2 months ago
Philippe Antoine 1197bd175b http2: delay setting event during processing headers
So that if there is something weird with the first tx,
we set the event to it instead of discarding it
2 months ago
Philippe Antoine ec869b18c7 http2: delay setting event during processing frame
We need to find or create tx first.

So that if there is something weird with the first tx,
we set the event to it instead of discarding it
2 months ago
Giuseppe Longo 8c9bca92fb rdp: treat tpkt payload as complete input
parse_t123_tpkt runs the X.224 and X.223/MCS sub-parsers over the
length-bounded tpkt payload, but they use streaming nom parsers.
An inner length field overrunning the payload, such as an oversized
CS_CORE block, escaped as Err::Incomplete although the tpkt was fully
present.

This patch wraps the child parsers in complete() so Incomplete from within the
bounded payload becomes an Error.
The tpkt is then returned as an unrecognized Raw child, which the caller skips,
and parsing resumes at the next tpkt.

Ticket #8838
2 months ago
Giuseppe Longo f13021e022 ssh: fix record_left for oversized KEXINIT records
When an incomplete SSH_MSG_KEXINIT record has a body of at least
SSH_MAX_REASSEMBLED_RECORD_LEN bytes and hassh is enabled, record_left
was overwritten with the full body length even though the function
returns ok() and thus consumes the body bytes already present in the
input. The next call then over-skipped by that many bytes into the
following record, desynchronising the parser for that direction so
hassh was never computed and ssh.hassh keywords could not match.

This patch keeps the record_left computed from the bytes actually consumed in
the oversized path, and only use the full body length in the path that
returns incomplete, where the body bytes are delivered again.

Ticket #8837
2 months ago
Shivani Bhardwaj 9dfc132e33 mqtt: change the logging type of user properties
MQTT5 logs user properties wherein a user can send any metadata
over the wire in the form of key-value pairs.
MQTT logger used these key-value pairs directly to populate the common
"properties" field. But we do not want to use arbitrary json keys
(which may contain arbitrary characters)

1. A fixed new child object to the common "properties" called
   "user_properties" which carries a list of dicts.
2. Each key-value pair received as a part of the user properties is now
   saved as:

"properties": {
    ...
    "user_properties": [{"key": "mykey", "value": "myvalue"}]
    ...
}

instead of:

"properties": {
    ...
    "key": "value"
    ...
}

Ticket: 8785
2 months ago
Shivani Bhardwaj 07e83bff3d jsonbuilder: encode key strings when needed
Keys were not encoded as json UTF-8 strings.
This allowed json injection/corruption when an attacker
could control the key and put special JSON chars in it
such as double quote. Encode the keys when needed.

Ticket: 8999
2 months ago
Philippe Antoine 96c6ba6f76 http2/detect: avoids use-after-free with Http2ThreadMultiBuf
Ticket: 9003

When a single tx is getting inspected by rules having
http.response_header keyword both with a transform and without
a transform, the code went like this :

Http2ThreadMultiBuf structure contains a list (Vec) of buffers
(Vec<u8>) and owns these Vec<u8> (they are not owned by the tx).

For the first list_id, we computed each buffer for a http2 header
and put them in these Http2ThreadMultiBuf structure.

But for the second list_id, the code began by freeing the memory
of these http2 headers, and reallocated new buffers (Vec<u8>)
and recomputed each buffer.

After these rounds, which may happen in DetectRunPrefilterTx,
the buffers might need further checks, hence the use-after-free.

Now, the code does not free and allocate a new buffer, it just rewrites
the old one, as is done for HTTP1.
2 months ago
Jason Ish 03dac6d7fb ldap: recover parsing after a gap
While in gap state, if a parse attempt failed, the protocol return error
preventing future retries to get out of gap state.

Ticket: 8949
2 months ago
Jason Ish 42412fa5af ike: validate ISAKMP message length
Follow-up on the todo left in this section of code.

Ticket: 8961.
2 months ago
Jason Ish b7c4030201 ike: propagate version-specific parser result
Ticket: 8961.
2 months ago
Juliana Fajardini 8b5fb9b044 pgsql: bound Copy responses to their length field
CopyIn and CopyOut message parsers read the length field, but did not
use that information to parse the rest of the message, instead, parsing
as many columns as indicated in the columns field, without ever
checking against the informed length. This opened the door for
attackers to fabricate messages that were never sent by the server,
as well as to obfuscate following valid backend messages, in case the
columns value was bigger than the actual message (up to ~128KiB).

Those parsers also had a message length parsing check off-by-one, fixed
in this patch.

When a malformed CopyIn or CopyOut response is seen, it is logged as
previously, with a new field added to indicate whether it is malformed
or not.

Ticket: #8863
2 months ago
Juliana Fajardini 42098ede68 pgsql: use message type for transaction actions
parse_request and parse_response were using the parser state for
transaction bookkeeping.
Instead, use the message types themselves.

This change means that message types that ended up not being added to
the responses array, before (due to not advancing the parser state), now
are pushed and thus can be logged.

** Noticeable effect: AuthenticationSSPI, Notice and Notification
messages, previously missed due to falling into the None state progress
branch, could now get logged.
** To prevent affecting existing setups that don't expect these, since
they weren't logged before, we refrain from pushing them into the
responses queue, for now.

Leave state progress for state machine keeping.

Bug: #8886
2 months ago
Philippe Antoine c18f5e6f96 http1: fix gzip decompression with flags and multiple chunks
Ticket: 8850
2 months ago
Shivani Bhardwaj df0e9f106b mqtt: add too_many_properties event and limit
So far, the properties parsed across various different types of MQTT
messages was unbounded and could be exploited. Add a limit of 255 on the
maximum number of properties that any message type can store.
Additionally, raise an event for too many properties indicating an
anomaly in the network traffic.

Ticket: 8839
2 months ago
Shivani Bhardwaj ad9a9204e9 mqtt: do not store unknown property
UNKNOWN property carries 1 byte in the MQTTProperty enum variant. It is
neither logged nor matched on, so, don't store it.

Ticket: 8839
2 months ago
Shivani Bhardwaj 0e9d79abf9 x509: saturate SAN count returned by parser
Introduce a maximum SAN limit of 4k instead of returning a u16 casted
count of TLS X.509 SubjectAltNames, saturate the count to make sure it
stays within the 4k bounds without truncating the existing count value.

Ticket: 8864
2 months ago
Shivani Bhardwaj 88d3af4c2e enip: make sure to have enough data for parser
ENIP parser makes use of nom's complete macros which by design expect
full data to be passed along to them. In case there is incomplete data
sent to them, they result in an error. This disables the ENIP parser and
further detection and could happen with an incomplete/fragmented
request/response.

Use AppLayerResult API to ask for more data from the stream engine in
case the stream slice currently at hand does not match the length
parameters received from the header or is not long enough to parse the
header itself.

Ticket: 8809
2 months ago
Jason Ish b71178b667 lua/dns: handle OPT answers like TXT records
In "tx:answers()" don't attempt to push each OPT as its own string,
instead concatenate into one string like we do with TXT.

The previous method was broken and didn't work anyways, so we're not
breaking something that previously worked.

Ticket: 8843
2 months ago
Jason Ish bddf04d99b dns: fix TCP request gap resync
Ticket: #8842
2 months ago
Philippe Antoine 0c1ec09879 enip: avoid quadratic complexity with multiple service packet
Ticket: 8757
2 months ago
Jason Ish 491259842b psl: update to 2.1.228
Ticket: 8147
2 months ago
Philippe Antoine c608165c04 rfb: keep failure_reason as Vec<u8>
And log it with from_utf8_lossy

Since we may now cut a too big failure_reason breaking a valid
utf-8 string

Ticket: 8731
2 months ago
Philippe Antoine f9515dc71d rfb: limit strings length
Ticket: 8731

Adds a configurable limit to string lengths to avoid to retain
too much memory for too long, and avoid producing log events
that are too big
2 months ago
Philippe Antoine 0b0606b126 http2: log :authority header as hostname
Ticket: 8774
2 months ago
Philippe Antoine f5e44ced1e http2: use host header for http.host keyword
if :authority header is absent

Ticket: 8774
2 months ago
Victor Julien 9b491a131e nfs: fix SECINFO_NO_NAME parser handling
nfs4_res_secinfo_no_name() used a local var "i2" to walk through
the security-flavor array entries, but returned the pre-walk var "i"
in the Ok at the end. Every byte of the flavor array was therefore left
unconsumed in the input stream and re-interpreted by count next iteration
as a subsequent compound operation.

Addressed by returning i2 instead of i so all flavor bytes are consumed.

Ticket: #8860.
2 months ago
Philippe Antoine b0b353d0c0 http2: host normalization handles ipv6 address
And does not consider automatically a port after first colon

Ticket: 8778
2 months ago
Philippe Antoine 52c01543c9 http2: code cleanup for http2_normalize_host
Just separate the steps in parsing, and deduplicate code
2 months ago
Jeff Lucovsky 89d09c457c detect/bytemath: reject literal shift counts of 64
Fail rule load when byte_math pairs << or >> with a literal rvalue of
64 or more. rvalue was bounded only to u32::MAX, so a rule shifting by
100 loaded and then produced 0 for every packet it inspected, spending
detection work on a comparison whose outcome was settled before the
first packet arrived.

A variable rvalue still loads. Its value comes from a byte_extract on
the packet and is not known until the rule runs, so the guard in
DetectByteMathDoMatch() stays the only check covering that path.

DetectByteMathParse() reports every SCByteMathParse() failure as
"invalid bytemath values", so the rejected rule is named by the
"error parsing signature" line that follows rather than by the reason
the parser gave.

Issue: 8845
2 months ago
Philippe Antoine 7c669548cb nfs: optionally parse nfs3 read attr-follows
Ticket: 8750
2 months ago
Philippe Antoine 7c394b9774 datasets: add size checks for hashes read
Ticket: 8768
2 months ago
Jason Ish 99f7b1f437 dhcp: remove unused import in test
To address clippy warning.
2 months ago
Jason Ish 17bd53c29c rust/ffi: add flow accessors to flow wrapper
Ticket: #8599
2 months ago
Jason Ish d3d206faa5 rust/ffi: add safe flow storage wrapper
Add a typed FlowStorage<T> wrapper around the flow storage bindings.

Update example and docs.

Ticket: #8447
2 months ago
Jason Ish 8a5c729ac9 rust/ffi: add number setters to jsonbuilder wrapper 2 months ago
Jason Ish f3332694e3 rust/ffi: bindgen flow storage
Ticket: #8447
2 months ago
Jason Ish 8cf5d4d770 rust/ffi: use Flow wrapper in flow and eve callbacks
Pass the safe Flow wrapper to the flow init/update/finish callbacks and
the EVE callback instead of a raw sys::Flow pointer.

Ticket: #8599
2 months ago
Jason Ish b4043dc207 rust/ffi: add wrapper around Flow
Ticket: #8599
2 months ago
Jason Ish bedd65f766 flow: add accessors for flow addresses
Expose source and destination addresses as raw byte pointers, so FFI
callers do not need the internal FlowAddress layout.
2 months ago
Jason Ish c0de5bca46 flow: add accessor functions
Add accessor functions to allow NDPI and our plugin examples to access
flow fields in an opaque manner.

Provides accessors for:

- is ipv4
- is ipv6
- ip protocol
- to server packet count
- to destination packet count

Ticket: #8632
2 months ago