From fe9cac58706d05c8b0dd4a27e0df400da18ffceb Mon Sep 17 00:00:00 2001 From: Martin Natano Date: Fri, 11 Aug 2017 18:11:09 +0200 Subject: [PATCH] eve/alert: include rule text in alert output For SIEM analysis it is often useful to refer to the actual rules to find out why a specific alert has been triggered when the signature message does not convey enough information. Turn on the new rule flag to include the rule text in eve alert output. The feature is turned off by default. With a rule like this: alert dns $HOME_NET any -> 8.8.8.8 any (msg:"Google DNS server contacted"; sid:42;) The eve alert output might look something like this (pretty-printed for readability): { "timestamp": "2017-08-14T12:35:05.830812+0200", "flow_id": 1919856770919772, "in_iface": "eth0", "event_type": "alert", "src_ip": "10.20.30.40", "src_port": 50968, "dest_ip": "8.8.8.8", "dest_port": 53, "proto": "UDP", "alert": { "action": "allowed", "gid": 1, "signature_id": 42, "rev": 0, "signature": "Google DNS server contacted", "category": "", "severity": 3, "rule": "alert dns $HOME_NET any -> 8.8.8.8 any (msg:\"Google DNS server contacted\"; sid:43;)" }, "app_proto": "dns", "flow": { "pkts_toserver": 1, "pkts_toclient": 0, "bytes_toserver": 81, "bytes_toclient": 0, "start": "2017-08-14T12:35:05.830812+0200" } } Feature #2020 --- doc/userguide/output/eve/eve-json-output.rst | 1 + doc/userguide/partials/eve-log.yaml | 2 ++ src/detect-parse.c | 10 +++++++--- src/detect.h | 4 +--- src/output-json-alert.c | 9 +++++++++ suricata.yaml.in | 3 +++ 6 files changed, 23 insertions(+), 6 deletions(-) diff --git a/doc/userguide/output/eve/eve-json-output.rst b/doc/userguide/output/eve/eve-json-output.rst index 936027ee8e..ca5e96dc62 100644 --- a/doc/userguide/output/eve/eve-json-output.rst +++ b/doc/userguide/output/eve/eve-json-output.rst @@ -59,6 +59,7 @@ Metadata:: # packet: yes # enable dumping of packet (without stream segments) # http-body: yes # enable dumping of http body in Base64 # http-body-printable: yes # enable dumping of http body in printable format + # rule: yes # enable dumping of signature definition metadata: yes # add L7/applayer fields, flowbit and other vars to the alert Alternatively to the `metadata` key it is also possible to select the application diff --git a/doc/userguide/partials/eve-log.yaml b/doc/userguide/partials/eve-log.yaml index 98e4e8bf8b..b50620f972 100644 --- a/doc/userguide/partials/eve-log.yaml +++ b/doc/userguide/partials/eve-log.yaml @@ -38,6 +38,8 @@ outputs: # http-body: yes # enable dumping of http body in Base64 # http-body-printable: yes # enable dumping of http body in printable format + # rule: yes # enable dumping of signature definition + # Include extra data in alert records like the app-layer # information and flow records. Default: yes. #metadata: yes diff --git a/src/detect-parse.c b/src/detect-parse.c index b7e2ac4add..c300867f31 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -1110,7 +1110,10 @@ int SigParse(DetectEngineCtx *de_ctx, Signature *s, const char *sigstr, uint8_t SignatureParser parser; memset(&parser, 0x00, sizeof(parser)); - s->sig_str = sigstr; + s->sig_str = SCStrdup(sigstr); + if (unlikely(s->sig_str == NULL)) { + SCReturnInt(-1); + } int ret = SigParseBasics(de_ctx, s, sigstr, &parser, addrs_direction); if (ret < 0) { @@ -1139,8 +1142,6 @@ int SigParse(DetectEngineCtx *de_ctx, Signature *s, const char *sigstr, uint8_t } while (ret == 1); } - s->sig_str = NULL; - DetectIPProtoRemoveAllSMs(s); SCReturnInt(ret); @@ -1322,6 +1323,9 @@ void SigFree(Signature *s) if (s->addr_dst_match6 != NULL) { SCFree(s->addr_dst_match6); } + if (s->sig_str != NULL) { + SCFree(s->sig_str); + } SigRefFree(s); SigMetadataFree(s); diff --git a/src/detect.h b/src/detect.h index b58be1910e..e5e1f7c268 100644 --- a/src/detect.h +++ b/src/detect.h @@ -461,9 +461,7 @@ typedef struct Signature_ { /** Metadata */ DetectMetadata *metadata; - /* Be careful, this pointer is only valid while parsing the sig, - * to warn the user about any possible problem */ - const char *sig_str; + char *sig_str; SignatureInitData *init_data; diff --git a/src/output-json-alert.c b/src/output-json-alert.c index 030091c752..60127ffc55 100644 --- a/src/output-json-alert.c +++ b/src/output-json-alert.c @@ -87,6 +87,7 @@ #define LOG_JSON_HTTP_BODY BIT_U16(6) #define LOG_JSON_HTTP_BODY_BASE64 BIT_U16(7) #define LOG_JSON_RULE_METADATA BIT_U16(8) +#define LOG_JSON_RULE BIT_U16(9) #define LOG_JSON_METADATA (LOG_JSON_APP_LAYER | LOG_JSON_FLOW) @@ -541,6 +542,13 @@ static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p) AlertJsonPacket(p, js); } + /* signature text */ + if (json_output_ctx->flags & LOG_JSON_RULE) { + hjs = json_object_get(js, "alert"); + if (json_is_object(hjs)) + json_object_set_new(hjs, "rule", json_string(pa->s->sig_str)); + } + HttpXFFCfg *xff_cfg = json_output_ctx->xff_cfg; /* xff header */ @@ -814,6 +822,7 @@ static void XffSetup(AlertJsonOutputCtx *json_output_ctx, ConfNode *conf) SetFlag(conf, "payload-printable", LOG_JSON_PAYLOAD, &flags); SetFlag(conf, "http-body-printable", LOG_JSON_HTTP_BODY, &flags); SetFlag(conf, "http-body", LOG_JSON_HTTP_BODY_BASE64, &flags); + SetFlag(conf, "rule", LOG_JSON_RULE, &flags); ConfNode *rmetadata = ConfNodeLookupChild(conf, "rule-metadata"); if (rmetadata != NULL) { diff --git a/suricata.yaml.in b/suricata.yaml.in index 2b52fa3592..f49a13cfeb 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -175,9 +175,12 @@ outputs: # packet: yes # enable dumping of packet (without stream segments) # http-body: yes # enable dumping of http body in Base64 # http-body-printable: yes # enable dumping of http body in printable format + rule-metadata: # dumping of key/value pairs defined by metadata keyword of rule enabled: no # set to yes to enable + # rule: yes # enable dumping of signature definition + # Enable the logging of tagged packets for rules using the # "tag" keyword. tagged-packets: yes