Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[New Rule] Elastic Endpoint and External Alerts #42

Merged
merged 13 commits into from
Jul 9, 2020
23 changes: 23 additions & 0 deletions detection_rules/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
VERSION_PATTERN = r'\d+\.\d+\.\d+'
RULE_LEVELS = ['recommended', 'aggressive']
MATURITY_LEVELS = ['development', 'testing', 'staged', 'production', 'deprecated']
OPERATORS = ['equals']
spong marked this conversation as resolved.
Show resolved Hide resolved
OS_OPTIONS = ['windows', 'linux', 'macos', 'solaris'] # need to verify with ecs
INTERVAL_PATTERN = r'\d+[mshd]'
MITRE_URL_PATTERN = r'https://attack.mitre.org/{type}/T[A-Z0-9]+/'
Expand Down Expand Up @@ -81,6 +82,23 @@ class Filters(jsl.Document):
query = jsl.DocumentField(FilterQuery)


class RiskScoreMapping(jsl.Document):
"""Risk score mapping."""

field = jsl.StringField(required=True)
operator = jsl.StringField(required=False, enum=OPERATORS)
value = jsl.StringField(required=False)


class SeverityMapping(jsl.Document):
"""Severity mapping."""

field = jsl.StringField(required=True)
operator = jsl.StringField(required=False, enum=OPERATORS)
value = jsl.StringField(required=False)
severity = jsl.StringField(required=False)


class ThreatTactic(jsl.Document):
"""Threat tactics."""

Expand Down Expand Up @@ -110,6 +128,7 @@ class SiemRuleApiSchema(jsl.Document):

actions = jsl.ArrayField(required=False)
author = jsl.ArrayField(jsl.StringField(default="Elastic"), required=True, min_items=1)
building_block_type = jsl.StringField(required=False)
spong marked this conversation as resolved.
Show resolved Hide resolved
description = jsl.StringField(required=True)
# api defaults to false if blank
enabled = jsl.BooleanField(default=False, required=False)
Expand All @@ -127,13 +146,17 @@ class SiemRuleApiSchema(jsl.Document):
# output_index = jsl.StringField(required=False) # this is NOT allowed!
references = jsl.ArrayField(jsl.StringField(), required=False)
risk_score = jsl.IntField(minimum=0, maximum=100, required=True, default=21)
risk_score_mapping = jsl.ArrayField(jsl.DocumentField(RiskScoreMapping), required=False, min_items=1)
rule_id = jsl.StringField(pattern=UUID_PATTERN, required=True)
rule_name_override = jsl.StringField(required=False)
spong marked this conversation as resolved.
Show resolved Hide resolved
severity = jsl.StringField(enum=['low', 'medium', 'high', 'critical'], default='low', required=True)
severity_mapping = jsl.ArrayField(jsl.DocumentField(SeverityMapping), required=False, min_items=1)
# saved_id - type must be 'saved_query' to allow this or else it is forbidden
tags = jsl.ArrayField(jsl.StringField(), required=False)
throttle = jsl.StringField(required=False)
timeline_id = jsl.StringField(required=False)
timeline_title = jsl.StringField(required=False)
timestamp_override = jsl.StringField(required=False)
to = jsl.StringField(required=False, default='now')
# require this to be always validated with a role
# type = jsl.StringField(enum=[MACHINE_LEARNING, QUERY, SAVED_QUERY], required=True)
Expand Down
56 changes: 56 additions & 0 deletions rules/cross-platform/external_alerts.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
[metadata]
creation_date = "2020/07/08"
ecs_version = ["1.5.0"]
maturity = "production"
updated_date = "2020/07/08"

[rule]
author = ["Elastic"]
description = """
Generates a detection alert for each external alert written to the configured securitySolution:defaultIndex. Enabling
this rule allows you to immediately begin investigating external alerts in the app.
"""
language = "kuery"
license = "Elastic License"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add max_signals = unbounded (and support for unbounded 😉 )

name = "External Alerts"
spong marked this conversation as resolved.
Show resolved Hide resolved
risk_score = 47
rule_id = "eb079c62-4481-4d6e-9643-3ca499df7aaa"
rule_name_override = "message"
spong marked this conversation as resolved.
Show resolved Hide resolved
severity = "medium"
tags = ["Elastic"]
timestamp_override = "event.ingested"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want to override the timestamp here since event.ingested might not be filled in for most external alerts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when a timestamp override is defined and missing, does it default back to @timestamp?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, will need to add to signal metadata so the user knows this happened.

type = "query"

query = '''
event.kind:alert and not event.module:(endgame or endpoint)
'''


[[rule.risk_score_mapping]]
field = "event.risk_score"
operator = "equals"
value = ""

[[rule.severity_mapping]]
field = "event.severity"
operator = "equals"
value = "21"
severity = "low"

[[rule.severity_mapping]]
field = "event.severity"
operator = "equals"
value = "47"
severity = "medium"

[[rule.severity_mapping]]
field = "event.severity"
operator = "equals"
value = "73"
severity = "high"

[[rule.severity_mapping]]
field = "event.severity"
operator = "equals"
value = "99"
severity = "critical"
59 changes: 59 additions & 0 deletions rules/endpoint/elastic_endpoint.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
[metadata]
creation_date = "2020/07/08"
ecs_version = ["1.5.0"]
maturity = "production"
updated_date = "2020/07/08"

[rule]
author = ["Elastic"]
description = """
Generates a detection alert each time an Elastic Endpoint alert is received. Enabling this rule allows you to
immediately begin investigating your Elastic Endpoint alerts.
"""
enabled = true
from = "now-10m"
index = ["logs-*"]
spong marked this conversation as resolved.
Show resolved Hide resolved
language = "kuery"
license = "Elastic License"
name = "Elastic Endpoint"
risk_score = 47
rule_id = "9a1a2dae-0b5f-4c3d-8305-a268d404c306"
rule_name_override = "message"
severity = "medium"
tags = ["Elastic", "Endpoint"]
timestamp_override = "event.ingested"
type = "query"

query = '''
event.kind:alert and event.module:(endpoint and not endgame)
'''


[[rule.risk_score_mapping]]
field = "event.risk_score"
operator = "equals"
value = ""

[[rule.severity_mapping]]
field = "event.severity"
operator = "equals"
value = "21"
severity = "low"

[[rule.severity_mapping]]
field = "event.severity"
operator = "equals"
value = "47"
severity = "medium"

[[rule.severity_mapping]]
field = "event.severity"
operator = "equals"
value = "73"
severity = "high"

[[rule.severity_mapping]]
field = "event.severity"
operator = "equals"
value = "99"
severity = "critical"
spong marked this conversation as resolved.
Show resolved Hide resolved