TLS parsers use x509-parser crate which parses X.509 certificates that
use ASN.1 DER encoding that can allow arbitrary byte sequences. An
attacker could inject null byte in a certificate anywhere to stump the
common language parsers terminating the string at a null byte leading to
a bypass of a possibly malicious certificate.
So far, the rust TLS parser for "issuerdn" used a pattern that involved:
-> Get ASN.1 DER encoded raw data from the x509-parser crate
-> Convert this raw data to a decoded string (Rust)
-> Convert the Rust string to CString
-- The problem lies here. CString only accepts proper strings/byte
buffers and converts it into an owned C-compatible, null-terminated
string. However, if any null byte occurs in the string passed to the
CString then it panics.
In the rust TLS parser, this panic is handled by returning NULL.
This means that the parser will error out during the decoding of the
certificate. However, Suricata must be able to detect the null byte
injection attack being an IDS/IPS.
Hence, replace all such string patterns w.r.t. TLS IssuerDN with a byte
array.
Bug 7887
(cherry picked from commit f025e07191)
TLS parsers use x509-parser crate which parses X.509 certificates that
use ASN.1 DER encoding that can allow arbitrary byte sequences. An
attacker could inject null byte in a certificate anywhere to stump the
common language parsers terminating the string at a null byte leading to
a bypass of a possibly malicious certificate.
So far, the rust TLS parser for "Subject" used a pattern that involved:
-> Get ASN.1 DER encoded raw data from the x509-parser crate
-> Convert this raw data to a decoded string (Rust)
-> Convert the Rust string to CString
-- The problem lies here. CString only accepts proper strings/byte
buffers and converts it into an owned C-compatible, null-terminated
string. However, if any null byte occurs in the string passed to the
CString then it panics.
In the rust TLS parser, this panic is handled by returning NULL.
This means that the parser will error out during the decoding of the
certificate. However, Suricata must be able to detect the null byte
injection attack being an IDS/IPS.
Hence, replace all such string patterns w.r.t. TLS Subject with a byte
array.
Bug 7887
(cherry picked from commit 77c21b05d2)
16384 is used as the max, but a configuration parameter has been
provided. The reason for setting an upper bound is that bit flags can
create a memory amplification as we parse them into individual data
structures.
Ticket: #8181
(cherry picked from commit 3a32bb5743)
Lower the number of unreplied requests from 500 to 32 to consider a
flood. At the very least this is an anomaly given the DNP3 spec mentions
that DNP3 should only have one outstanding request at a time, with an
exception for unsolicited responses, so in practice no more than 2
should be seen.
Additionally make this value configurable by introducing the max-tx
parameter.
Ticket: #8181
(cherry picked from commit a16f087b93)
Complete is a flag used to tell if the message was completely parsed,
as not all messages may be completely parsed if we don't know all
their objects. However, they are still "done".
In the alstate-progress callback, check the done flag, not the
complete flag.
Ticket: #8181
(cherry picked from commit d61eef9a8a)
DCERPC parsers had no upper bounds when it came to extending the stub
data buffer. Traffic can be crafted to bypass some internal parser
conditions to create an indefinite buffering in the stub_data array that
can make Suricata crash.
Add a default limit of 1MiB and make it configurable for the user.
Security 8182
Co-authored-by: Philippe Antoine <pantoine@oisf.net>
(cherry picked from commit e412215af9)
Ticket: 8201
Limits the quadratic complexity if each packet, restarting the
header parsing, just adds a new folded line.
This was previously bounded by the configurable max header length
(cherry picked from commit fa5a4a994a)
So far, the alert queue was expanded by doubling in size w/o any
boundary checks in place. This led to situations where doubling
the alert_queue_capacity meant overflow of the very same value
stored in det_ctx.
This led to heap-use-after-free in some conditions where
det_ctx->alert_queue_capacity overflowed.
Fix this by capping the max of alert_queue_capacity by checking if its
expansion could result in an overflow.
Security 8190
(cherry picked from commit ac1eb39418)
Ticket: 8156
In case of non-tx alerts, we try to loop over all the txs to find
the xff header. Do not start from tx_id 0, but from min_id
as AppLayerParserTransactionsCleanup to skip txs that were freed
(cherry picked from commit 3b1a6c1711)
When FlowSwap() reverses the direction of a flow, the MAC address sets
stored in the flow also need to be swapped to maintain consistency with
the new direction. Previously, MAC addresses were not swapped along with
other flow properties like packet/byte counters.
Ticket #8172
(cherry picked from commit f1b9669ed5)
Make sure the script can use all bytes configured. So exclude setup like
input buffers that are put on the lua state before script is executed.
Bug #8173.
(cherry picked from commit d7866495c2)
Detection and logging skip a lot of work if PKT_STREAM_EST is not set. When
a TFO packet with data comes in the TCP state is not yet established, but
the data still needs to be considered.
So for this case set the PKT_STREAM_EST flag.
Bug #6744.
(cherry picked from commit cc2287beb4)
As we want the last tx
Ticket: 8156
The generic function AppLayerParserGetTxCnt calls for HTTP1
Transactions.size()
This function has some specific code, as we may have pre-created
a tx that we do not want to count.
This used to get the last tx by iterating over all the transactions
waiting to find the one with max index.
So, instead of using the Transactions.get function, we get the last
tx out of the VecDeque and check its index.
(cherry picked from commit af246ae7ab)
In corner cases, we assume that a midstream exception policy could be
triggered by a prior exception policy in effect. Explain this in the
docs.
Task #5830
(cherry picked from commit 0ca874b678)
While debug_validate_bug_on is still used, it does not need to be
imported directly, as that macro is marked with `macro_export`, making
it globally available to the crate.
(cherry picked from commit 50224f2ee5)
Ticket: 3220
DetectSslVersionMatch did not handle properly negation.
It could never match on a signatrue with ssl_version: !tls1.3
That is because, if we had such a signature and network traffic
with tls1.1, we were looking into DetectSslVersionData field
for tls1.1, which was not set, instead of looking at field
for tls1.3 which was set with negated flag.
Previous DetectSslVersionData was holding redundant information.
It did not need to have it for each ssl version, but just globally.
Also, it did not need to hold the version as a value in the array,
as it was redundant with the index of the array.
(cherry picked from commit c93e69830a)