mirror of
https://github.com/OISF/suricata.git
synced 2026-10-12 02:07:10 +00:00
detect: log the hook for sub-state firewall rules
Alerts and drops for firewall rules hooked at a sub-state (http2 stream/global) had no firewall.hook field: the logger resolved the state name without the sub-state, so the lookup found nothing. Keep the rule's sub-state on the Signature next to app_progress_hook, set it from the hook and for the default policy signatures, resolve the name in the sub-state table, and fall back to the plain state name when that lookup fails. Ticket: #8944.
This commit is contained in:
@@ -122,6 +122,11 @@ alert
|
||||
action in firewall rules. The effect will be the creation of an alert event when the
|
||||
firewall rule matches.
|
||||
|
||||
For application layer transactions the alert event carries a ``firewall`` object with
|
||||
the resolved ``policy`` and, when the protocol registers a state name callback, the
|
||||
``hook`` the rule was registered at. Protocols without such a callback (``quic``,
|
||||
``modbus``, ``rdp``) omit the ``hook`` key; the policy is still reported.
|
||||
|
||||
config
|
||||
~~~~~~
|
||||
|
||||
|
||||
@@ -1575,6 +1575,8 @@ static int SigParseProtoHookApp(
|
||||
s->init_data->hook.t.app.app_progress);
|
||||
|
||||
s->app_progress_hook = s->init_data->hook.t.app.app_progress;
|
||||
/* the hook parser only accepts known sub states of the protocol */
|
||||
s->sub_state = s->init_data->hook.t.app.sub_state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4187,6 +4189,7 @@ static int AddAppPolicySignature(struct DetectFirewallAppPolicy *pol)
|
||||
return -1;
|
||||
}
|
||||
s->app_progress_hook = pol->progress;
|
||||
s->sub_state = pol->sub_state;
|
||||
s->action = pol->policy.action;
|
||||
s->action_scope = pol->policy.action_scope;
|
||||
s->alproto = pol->alproto;
|
||||
|
||||
@@ -727,6 +727,10 @@ typedef struct Signature_ {
|
||||
|
||||
/** firewall: progress value for this signature */
|
||||
uint8_t app_progress_hook;
|
||||
/** firewall: sub state (transaction type) of the hook on protocols with sub
|
||||
* states (http2 stream/global, DoH2); 0 when the hook has no sub state.
|
||||
* Signatures are zero initialized, so unused stays 0. */
|
||||
uint8_t sub_state;
|
||||
|
||||
DetectMatchAddressIPv4 *addr_dst_match4;
|
||||
DetectMatchAddressIPv4 *addr_src_match4;
|
||||
|
||||
+26
-11
@@ -662,20 +662,35 @@ static void AlertJsonAddFirewall(SCJsonBuilder *jb, const Signature *s)
|
||||
const char *hook = NULL;
|
||||
char hook_string[256];
|
||||
switch (s->detect_table) {
|
||||
case DETECT_TABLE_APP_FILTER:
|
||||
if (s->flags & SIG_FLAG_TOSERVER) {
|
||||
hook = AppLayerParserGetStateNameById(
|
||||
IPPROTO_TCP, s->alproto, s->app_progress_hook, STREAM_TOSERVER);
|
||||
} else {
|
||||
hook = AppLayerParserGetStateNameById(
|
||||
IPPROTO_TCP, s->alproto, s->app_progress_hook, STREAM_TOCLIENT);
|
||||
case DETECT_TABLE_APP_FILTER: {
|
||||
const uint8_t dir_flag =
|
||||
(s->flags & SIG_FLAG_TOSERVER) ? STREAM_TOSERVER : STREAM_TOCLIENT;
|
||||
if (s->sub_state != 0 && AppLayerParserSupportsSubStates(s->alproto)) {
|
||||
/* sub state rules (http2 stream/global): resolve the state in
|
||||
* the sub state table and keep the sub state in the name */
|
||||
const char *state = AppLayerParserGetSubStateProgressName(
|
||||
s->alproto, s->sub_state, s->app_progress_hook, dir_flag);
|
||||
const char *sub_state_name =
|
||||
AppLayerParserGetSubStateName(s->alproto, s->sub_state);
|
||||
if (state != NULL && sub_state_name != NULL) {
|
||||
snprintf(hook_string, sizeof(hook_string), "%s:%s:%s",
|
||||
AppProtoToString(s->alproto), sub_state_name, state);
|
||||
hook = hook_string;
|
||||
}
|
||||
}
|
||||
if (hook) {
|
||||
snprintf(hook_string, sizeof(hook_string), "%s:%s", AppProtoToString(s->alproto),
|
||||
hook);
|
||||
hook = hook_string;
|
||||
if (hook == NULL) {
|
||||
/* no sub state, or the sub state lookup failed: fall back to
|
||||
* the plain per-protocol state name */
|
||||
hook = AppLayerParserGetStateNameById(
|
||||
IPPROTO_TCP, s->alproto, s->app_progress_hook, dir_flag);
|
||||
if (hook != NULL) {
|
||||
snprintf(hook_string, sizeof(hook_string), "%s:%s",
|
||||
AppProtoToString(s->alproto), hook);
|
||||
hook = hook_string;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DETECT_TABLE_PACKET_FILTER:
|
||||
hook = "packet:filter";
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user