The format of initial packet for quic ietf, ie quic v1,
is described in rfc 9000, section 17.2.2
Parse more frames and logs interesting extensions from crypto frame
Do not try to parse encrypted data, ie after we have seen
a crypto frame in each direction.
Use sni from crypto frame with tls for detection already implemented
Ticket: #4967
Bug introduced by https://github.com/OISF/suricata/pull/7111
Nom's count begins by allocating a Vector, which leads to arbitrary
allocation due to flavors_cnt coming from network, and not even
being checked against i.len()
Ticket: #5237
Move it away from http2 to generic core crate.
And use it for DCERPC (and SMB)
And remove the C version.
Main change in API is the free function is not free itself, but
a rust wrapper around unbox.
Ticket: #4112
Without dangerous snprintf pattern identified by CodeQL
even if this pattern is not a problem in those precise cases,
it may easily get copy pasted in a dangerous place, so better
get rid of it and make CodeQL happy
Adds a PDU frame to the DNS parser. For UDP this is the DNS payload
portion of the DNS packet, for TCP this is the payload minus the leading
legth field.
Ticket: 4984
Wrap the calls behind frames to C code if a `cfg!(not(test))` so they
don't get compiled when running Rust unit tests. Linkage to C functions
is not yet available for Rust unit tests, and this will keep the check
out of individual parsers.
Ticket: 4984
Instead of a method that is required to return a slice of transactions,
use 2 methods, one to return the number of transactions in the
collection, and another to get a transaction by its index in the
collection.
This allows for the transaction collection to not be a contiguous array
and instead can be a VecDeque, or possibly another collection type that
supports retrieval by index.
Ticket #5278
Fuzzers found a possible integer overflow bug when parsing response
messages. To fix that, removed the case where we incremented the parsed
field length and created a new message type for situations where Suri
parsers an Unknown message. This is good because there may happen that
an unknown message to Suri is valid, and in this case, we would still be
able to log it.
Philippe Antoine found the bug while fuzzing with rust debug assertions.
Bug #5016
To recognize a protocol, Suricata first looks for
patterns, which can be confirmed by a probing parser.
If this does not work, Suricata can try to run
some probing parsers on some ports.
This is the case for SMB.
This commit makes handling the confirming and the probing
paser differently even if they share much code.
The confirmation parser knows that a pattern has been found.
So, it must not do the midstream case of looking for this
pattern in the whole buffer, but only check it at the beginning.
But it must reverse direction if needed.
The DNS name parser will error out with an error even if the
error is incomplete. Instead of manually generating errors,
use '?' to let the nom error ripple up the error handling chain.
The reason this wasn't done in the first place is this code
predates the ? operator, or we were not aware of it at the time.
This prevents the case where probing fails when there is enough data to
parse the header, but not enough to complete name parser. In such a case
a parse error is returned (instead of incomplete) resulting in the
payload not being detected as DNS.
Ticket #5034
If there is more data than a header, but not enough for a complete DNS
message, the hostname parser could return an error causing the probe to
fail on valid DNS messages.
So only parse the complete message if we have enough input data. This is
reliable for TCP as DNS messages are prefixed, but for UDP its just
going to be the size of the input buffer presented to the parser, so
incomplete could still happen.
Ticket #5034
Allow limiting in-flight out or order data chunks per size or count.
Implemented for read and writes separately:
app-layer.protocols.smb.max-write-queue-size
app-layer.protocols.smb.max-write-queue-cnt
app-layer.protocols.smb.max-read-queue-size
app-layer.protocols.smb.max-read-queue-cnt
This addresses Redmine bug #5018 by ensuring that the parser
never requests additional data via the Incomplete error, but to
raise an actual parse error, since it is supposed to have all
the data as specified by the message length in the header already.
Instead of closing files in both direction when receiving a close request,
close only toserver files for the request and close toclient on receiving
a response.
If an SMB record is seen in the wrong direction, set an event on the PDU
frame and don't process the record in the state.
No error is returned, so the next record will be processed.
The bits were being parsed in the order they're displayed in Wireshark,
rather than the order they were being seen on the wire, resulting in
direction and async being 0 more often than they should be.
Instead of bits, take the 4 bytes as an le_u32 and just use bit masks to
extract what we need into a struct, I think its easier to reason about
this way when comparing to the Microsoft documentation.
There should be no remaining data after parsing the partial
RPC record, so don't handle it but instead add a debug validation
bug on.
Successful processing for NFSv3 read/write records returns
AppLayerResult::ok() directly as all data is consumed.
With these, the portion of code within the tags should be included
in the related code-snippets (for frame support documentation) w/o
errors, even if the code within changes. The tags can also work as
a reminder that the existing code is being shown elsewhere, so folks
know documentation might need updates, in case of major changes.
Our current rust code isn't always documentation friendly when it
comes to using code snippets. Used rustfmt to apply rust default
formatting on functions that we wanted to show in our documentation
for Frame support
When we want to share our code in our documentation pages, the current
rust formatting isn't so nice to read. Formatted just the portion of
the code that will be shown, for now.
cargo vendor has been part of the core cargo command since Rust 1.37,
and are minimum Rust version is not 1.41, so remove the check. Its
always available now.
Frames:
- sip.pdu
- sip.request_line
- sip.response_line
- sip.request_headers
- sip.response_headers
- sip.request_body
- sip.response_body
The `sip.pdu` frame is always created, the rest only if the record
parser succeeded.
Ticket: #5036.
max-streams and max-table-size
Allows users to find balance between completeness of decoding
and increases resource consumption, which can DOS suricata.
http2_parse_var_uint can overflow the variable-length
integer it is decoding. In this case, it now returns an error
of kind LengthValue.
The new function http2_parse_headers_blocks, which factorizes
the code loop for headers, push promise, and continuation, will
check for this specific error, and instead of erroring itself,
will return the list of so far parsed headers, plus another one
with HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeIntegerOverflow
This status is then checked by process_headers to create an
app-layer event.
The smb dce_iface keyword must match for all those dcerpc requests
and responses sent in the context of the given interface. They are
not matching as the current bind interfaces are deleted by any
non bind message.
Ticket: 4767
The smb dce_iface keyword must match for all those dcerpc requests and
responses sent in the context of the given interface. They are not
matching because in rs_smb_tx_get_dce_iface, x.req_cmd is erroneously
compared with 1. Fix this by comparing with DCERPC_TYPE_REQUEST instead.
Ticket: 4767
The smb dce_opnum matches all the opnums that are higher that the
indicated opnum. This is due the range comparison if was put in the
exact comparison context, and in case the opnum doesn't match exactly,
then the range comparison is triggered (the upper limit is always true).
Move the erroneus if to the outer context, as else option of the block
checks if comparison should be exact or range.
Ticket: 4767
The smb dce_opnum keyword doesn't match the dcerpc requests/responses.
This occurs because in the rs_smb_tx_match_dce_opnum function, the
x.req_cmd is matched against the erroneous code 1. Fix this by using
DCERPC_TYPE_REQUEST for the comparison instead.
Ticket: 4767
The bug:
The dcerpc dce_iface keyword just match the packet following the bind. Only the
next request after the rpc is sent will match. However the expected behaviour it
that all the rpc requests/responses sent under the context of the given
interface would match.
In the Open Group c706 the following is indicated:
In 2.2.1 Binding-related Operations, indicates that one category of binding
operations are those that "operations that establish internal call routing
information for the server." (The other are to establish the protocol which is
not relevant here). And the following statement can be found:
Operations in the second category establish a set of mappings that the server
can use to route calls internally to the appropriate manager routine. This
routing is based on the interface and version, operation and any object
requested by the call.
It indicates that server routes (to call methods) are based on the operation,
interface and object.
- Operation: To indicate the method to call, and operation number is
specified as indicated in the second step of 2.3.3.2 (Client
Binding Steps).
- Interface: An interface is a set of remotely callable operations offered by a
server and invokable by clients. (2.1.1.1)
- Object: Is the manager that implements the interface, as stated in section
Interface and Manager Selection of 2.3.3.3. It is not mandatory, can
be nil.
To call a method, a client must send a request message as defined in 2.6.4.9,
that contains these identifiers:
- opnum: The opnum field identifies the operation being invoked within the
interface.
- p_cont_id (Context ID in Wireshark): The p_cont_id field holds a presentation
context identifier that identifies the
data representation and interface, as
defined in 12.6.3.4 (Context Identifiers).
- object: The object field is contained if the PFC_OBJECT_UUID is set. (Could be
interesting to create a keyword dce_object for matching this UUID)
Therefore, to get the correct method to invoke, the server must map the context
to the correct interface. This is negotiated by the bind request
Interfaces are first negotiated using the bind message (12.6.4.3), contained in
the p_context_elem array. Then they are accepted or rejected using the bind_ack
message (12.6.4.4).
Once these contexts are established, both client and server can use the context
id, which is the index of the p_context_elem array, to refer the interface they
are using.
Moreover, in the middle of the connection, the context can be changed with the
alter_context message.
This is way suricata shouldn't delete the bindack attribute, that contains
the contexts, used by match_backuuid. This is the only way to know the interface
a request message is referring to.
ticket: 4769
https://redmine.openinfosecfoundation.org/issues/4769
Pgsql was using bitwise operations to assign password output config to
its context flags, but mixing that with logic negation of the default
value, resulting in the expressions having a constant value as result.
Bug: #5007
- add nom parsers for decoding most messages from StartupPhase and
SimpleQuery subprotocols
- add unittests
- tests/fuzz: add pgsql to confyaml
Feature: #4241
SMB1 record parsing code simplification.
Frames:
nbss.pdu
nbss.hdr
nbss.data
smb1.pdu
smb1.hdr
smb1.data
smb2.pdu
smb2.hdr
smb2.data
smb3.pdu
smb3.hdr
smb3.data
The smb* frames are created for valid SMB records.