Let signature framework match HTTP body end

The HTTP analyzer never tells the signature framework when the body of a
request or a response ends, so any signature regex ending in a '$' used
in an 'http-request-body' or in an 'http-reply-body' condition will
never match.

This made it impossible to write a signature which could distinguish an
HTTP body consisting only of something from an HTTP body prefixed by
that same something.

- Fix:

The fix notifies the signature framework on EndOfData() that there will
be no further data to match for this body by giving it an empty buffer
of length 0 with the eol parameter set to true and all others set to
false. This lets it reach the '$' state in its DFA, and doesn't affect
other documented HTTP match behaviours.

- Limitation:

Since the signature framework doesn't appear to keep previously consumed
data on hand, any match of an http-*-body condition whose patterns ends
with a '$' will lead to an empty data parameter being passed to the
signature_match() event because the body data is no longer available
when EndOfData() happens.

Due to segmentation there is anyway no guarantee the data parameter
would have held the entire match even without the '$', since the data
parameter only receives the last chunk of data which completed the match
condition, as can be seen on prefix matches in the btest cases where the
matching data spans multiple segments (the event gives 'B' and not
'AB'), so this is only an extreme case of partial data being given to
that event.
This commit is contained in:
xb-anssi 2023-11-03 13:21:16 +01:00
parent c8103dd963
commit 9e61bfd010
No known key found for this signature in database
GPG key ID: 08AAE5775A62F923

View file

@ -69,6 +69,12 @@ void HTTP_Entity::EndOfData() {
encoding = IDENTITY;
}
zeek::detail::Rule::PatternType rule =
http_message->IsOrig() ? zeek::detail::Rule::HTTP_REQUEST_BODY : zeek::detail::Rule::HTTP_REPLY_BODY;
http_message->MyHTTP_Analyzer()->Conn()->Match(rule, reinterpret_cast<const u_char*>(""), 0,
http_message->IsOrig(), false, true, false);
if ( body_length )
http_message->MyHTTP_Analyzer()->ForwardEndOfData(http_message->IsOrig());