Skip to content

Commit

Permalink
output/eve: add verdict field w final packet action
Browse files Browse the repository at this point in the history
The eve logs have a field alert.action that may say something like
'allowed' even if a packet gets blocked by some other rules. To make
this more clear, add a field with the final verdict of what the engine
did to a given packet in the packet event_type with the action applied
to the packet, no based on a single alert/rule.

Bug OISF#5464
  • Loading branch information
jufajardini committed Dec 23, 2022
1 parent 4c7ca2c commit 0da6074
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 4 deletions.
20 changes: 18 additions & 2 deletions doc/userguide/output/eve/eve-json-format.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Event type: Alert
Field action
~~~~~~~~~~~~

Possible values: "allowed" and "blocked"
Possible values: "allowed" and "blocked".

Example:

Expand All @@ -101,7 +101,7 @@ Example:

"action":"allowed"

Action is set to "allowed" unless a rule used the "drop" action and Suricata is in IPS mode, or when the rule used the "reject" action.
Action is set to "allowed" unless a rule used the "drop" action and Suricata is in IPS mode, or when the rule used the "reject" action. It is important to note that this does not necessarily indicate the final verdict for a given packet or flow, since one packet may match on several rules.

It can also contain information about Source and Target of the attack in the alert.source and alert.target field if target keyword is used in
the signature.
Expand Down Expand Up @@ -147,6 +147,22 @@ the signature.
}
},

Verdict Field
~~~~~~~~~~~~~

Possible values are "accept", "drop" or "reject".

Example:

::


"verdict":"drop"

Verdict is the final action that will be applied to a given packet, based on all
the signatures triggered by it. In IPS mode, all values are possible. In IDS
mode, verdict is only present if its value is "reject".

Pcap Field
~~~~~~~~~~

Expand Down
3 changes: 3 additions & 0 deletions etc/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d+[+\\-]\\d+$",
"optional": false
},
"verdict": {
"type": "string"
},
"direction": {
"type": "string",
"optional": true
Expand Down
18 changes: 18 additions & 0 deletions src/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,24 @@ const char *PacketDropReasonToString(enum PacketDropReason r)
return NULL;
}

/** \brief Decide Packet's final verdict based on packet action, return it as a string */
const char *PacketActionVerdictToString(const Packet *p)
{
/* Reject is valid in both IDS and IPS */
if (PacketCheckAction(p, ACTION_REJECT_ANY)) {
return "reject";
} else if (EngineModeIsIPS()) {
/* Verdicts will be reject, drop, or accept */
if (PacketCheckAction(p, ACTION_DROP)) {
return "drop";
}
return "accept";
}

/* If we're in IDS mode and action isn't reject, we won't log verdict */
return NULL;
}

/* TODO drop reason stats! */
void CaptureStatsUpdate(ThreadVars *tv, CaptureStats *s, const Packet *p)
{
Expand Down
1 change: 1 addition & 0 deletions src/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,7 @@ void DecodeThreadVarsFree(ThreadVars *, DecodeThreadVars *);
void DecodeUpdatePacketCounters(ThreadVars *tv,
const DecodeThreadVars *dtv, const Packet *p);
const char *PacketDropReasonToString(enum PacketDropReason r);
const char *PacketActionVerdictToString(const Packet *p);

/* decoder functions */
int DecodeEthernet(ThreadVars *, DecodeThreadVars *, Packet *, const uint8_t *, uint32_t);
Expand Down
8 changes: 6 additions & 2 deletions src/output-json-alert.c
Original file line number Diff line number Diff line change
Expand Up @@ -826,12 +826,16 @@ static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p)
jb_set_string(jb, "capture_file", pcap_filename);
}

if (PacketActionVerdictToString(p) != NULL) {
const char *verdict = PacketActionVerdictToString(p);
jb_set_string(jb, "verdict", verdict);
}

OutputJsonBuilderBuffer(jb, aft->ctx);
jb_free(jb);
}

if ((p->flags & PKT_HAS_TAG) && (json_output_ctx->flags &
LOG_JSON_TAGGED_PACKETS)) {
if ((p->flags & PKT_HAS_TAG) && (json_output_ctx->flags & LOG_JSON_TAGGED_PACKETS)) {
JsonBuilder *packetjs =
CreateEveHeader(p, LOG_DIR_PACKET, "packet", NULL, json_output_ctx->eve_ctx);
if (unlikely(packetjs != NULL)) {
Expand Down
3 changes: 3 additions & 0 deletions src/output-json-drop.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ static int DropLogJSON (JsonDropLogThread *aft, const Packet *p)
/* Close drop. */
jb_close(js);

const char *verdict = PacketActionVerdictToString(p);
jb_set_string(js, "verdict", verdict);

if (aft->drop_ctx->flags & LOG_DROP_ALERTS) {
int logged = 0;
int i;
Expand Down
3 changes: 3 additions & 0 deletions src/output-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
#include "output.h"
#include "output-json.h"

#include "packet.h"
#include "action-globals.h"

#include "util-byte.h"
#include "util-privs.h"
#include "util-print.h"
Expand Down
3 changes: 3 additions & 0 deletions suricata.yaml.in
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ outputs:
# Enable the logging of tagged packets for rules using the
# "tag" keyword.
tagged-packets: yes
# Enable logging the final verdict on a packet (e.g. "blocked",
# "allowed", "rejected")
verdict: yes
# app layer frames
- frame:
# disabled by default as this is very verbose.
Expand Down

0 comments on commit 0da6074

Please sign in to comment.