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

[Security Content] Introduce Investigate Plugin in Investigation Guides #3080

Merged
merged 13 commits into from
Dec 8, 2023
Merged
28 changes: 12 additions & 16 deletions detection_rules/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,34 +91,30 @@ class OsQuery:
ecs_mapping: Optional[Dict[str, Dict[Literal['field', 'value'], str]]]

@dataclass(frozen=True)
class Insight:
class Investigate:
@dataclass(frozen=True)
class Provider:
excluded: bool
field: str
queryType: definitions.InvestigateProviderQueryType
value: str
type: str
valueType: definitions.InvestigateProviderValueType

label: str
description: Optional[str]
providers: List[List[Provider]]
relativeFrom: Optional[str]
relativeTo: Optional[str]

# these must be lists in order to have more than one. Their index in the list is how they will be referenced in the
# note string templates
osquery: Optional[List[OsQuery]]
insight: Optional[List[Insight]]
investigate: Optional[List[Investigate]]

@validates_schema
def validate_transforms(self, value: dict, **kwargs):
"""Validate transform fields."""
# temporarily invalidate insights until schema stabilizes
insight = value.get('insight')
if insight is not None:
raise NotImplementedError('Insights are not stable yet.')
return

def render_insight_osquery_to_string(self) -> Dict[Literal['osquery', 'insight'], List[str]]:
def render_investigate_osquery_to_string(self) -> Dict[definitions.TransformTypes, List[str]]:
obj = self.to_dict()

rendered: Dict[Literal['osquery', 'insight'], List[str]] = {'osquery': [], 'insight': []}
rendered: Dict[definitions.TransformTypes, List[str]] = {'osquery': [], 'investigate': []}
for plugin, entries in obj.items():
for entry in entries:
rendered[plugin].append(f'!{{{plugin}{json.dumps(entry, sort_keys=True, separators=(",", ":"))}}}')
Expand Down Expand Up @@ -343,12 +339,12 @@ def process_transforms(cls, transform: RuleTransform, obj: dict) -> dict:
# only create functions that CAREFULLY mutate the obj dict

def process_note_plugins():
"""Format the note field with osquery and insight plugin strings."""
"""Format the note field with osquery and investigate plugin strings."""
note = obj.get('note')
if not note:
return

rendered = transform.render_insight_osquery_to_string()
rendered = transform.render_investigate_osquery_to_string()
rendered_patterns = {}
for plugin, entries in rendered.items():
rendered_patterns.update(**{f'{plugin}_{i}': e for i, e in enumerate(entries)})
Expand Down
3 changes: 3 additions & 0 deletions detection_rules/schemas/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@
Date = NewType('Date', str, validate=validate.Regexp(DATE_PATTERN))
FilterLanguages = Literal["kuery", "lucene", "eql", "esql"]
Interval = NewType('Interval', str, validate=validate.Regexp(INTERVAL_PATTERN))
InvestigateProviderQueryType = Literal["phrase", "range"]
InvestigateProviderValueType = Literal["string", "boolean"]
Markdown = NewType("MarkdownField", CodeString)
Maturity = Literal['development', 'experimental', 'beta', 'production', 'deprecated']
MaxSignals = NewType("MaxSignals", int, validate=validate.Range(min=1))
Expand All @@ -160,6 +162,7 @@
ThresholdValue = NewType("ThresholdValue", int, validate=validate.Range(min=1))
TimelineTemplateId = NewType('TimelineTemplateId', str, validate=validate.OneOf(list(TIMELINE_TEMPLATES)))
TimelineTemplateTitle = NewType('TimelineTemplateTitle', str, validate=validate.OneOf(TIMELINE_TEMPLATES.values()))
TransformTypes = Literal["osquery", "investigate"]
UUIDString = NewType('UUIDString', str, validate=validate.Regexp(UUID_PATTERN))
BuildingBlockType = Literal['default']

Expand Down
41 changes: 38 additions & 3 deletions rules/windows/command_and_control_common_webservices.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ integration = ["endpoint"]
maturity = "production"
min_stack_comments = "New fields added: required_fields, related_integrations, setup"
min_stack_version = "8.3.0"
updated_date = "2023/10/16"
updated_date = "2023/12/07"

[transform]
[[transform.osquery]]
Expand All @@ -31,6 +31,38 @@ services.path FROM services JOIN authenticode ON services.path = authenticode.pa
authenticode.path JOIN hash ON services.path = hash.path WHERE authenticode.result != 'trusted'
"""

[[transform.investigate]]
label = "Alerts associated with the user in the last 48h"
relativeFrom = "now-48h/h"
relativeTo = "now"
providers = [
[
{field = "event.kind", excluded = false, queryType = "phrase", value = "signal", valueType = "string"},
{field = "user.id", excluded = false, queryType = "phrase", value = "{{user.id}}", valueType = "string"}
]
]


[[transform.investigate]]
label = "Alerts associated with the host in the last 48h"
relativeFrom = "now-48h/h"
relativeTo = "now"
providers = [
[
{field = "event.kind", excluded = false, queryType = "phrase", value = "signal", valueType = "string"},
{field = "host.name", excluded = false, queryType = "phrase", value = "{{host.name}}", valueType = "string"}
]
]

[[transform.investigate]]
label = "Investigate the Subject Process Network Events"
providers = [
[
{field = "process.entity_id", excluded = false, queryType = "phrase", value = "{{process.entity_id}}", valueType = "string"},
{field = "event.category", excluded = false, queryType = "phrase", value = "network", valueType = "string"}
]
]


[rule]
author = ["Elastic"]
Expand All @@ -55,18 +87,22 @@ This rule looks for processes outside known legitimate program locations communi

> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/master/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
> This investigation guide uses the [Investigate Markdown Plugin](https://www.elastic.co/guide/en/security/master/interactive-investigation-guides.html) introduced in Elastic Stack version 8.8.0. Older Elastic Stack versions will display unrendered Markdown in this guide.

#### Possible investigation steps

- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
- Investigate other alerts associated with the user/host during the past 48 hours.
- $investigate_0
- $investigate_1
- Verify whether the digital signature exists in the executable.
- Identify the operation type (upload, download, tunneling, etc.).
- Examine the host for derived artifacts that indicate suspicious activities:
- Analyze the process executable using a private sandboxed analysis system.
- Observe and collect information about the following activities in both the sandbox and the alert subject host:
- Attempts to contact external domains and addresses.
- Use the Elastic Defend network events to determine domains and addresses contacted by the subject process by filtering by the process' `process.entity_id`.
- $investigate_2
- Examine the DNS cache for suspicious or anomalous entries.
- $osquery_0
- Use the Elastic Defend registry events to examine registry keys accessed, modified, or created by the related processes in the process tree.
Expand All @@ -75,7 +111,6 @@ This rule looks for processes outside known legitimate program locations communi
- $osquery_2
- $osquery_3
- Retrieve the files' SHA-256 hash values using the PowerShell `Get-FileHash` cmdlet and search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.
- Investigate potentially compromised accounts. Analysts can do this by searching for login events (for example, 4624) to the target host after the registry modification.

### False positive analysis

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
creation_date = "2020/09/03"
integration = ["endpoint", "windows"]
maturity = "production"
updated_date = "2023/10/23"
updated_date = "2023/12/07"
min_stack_comments = "New fields added: required_fields, related_integrations, setup"
min_stack_version = "8.3.0"

Expand Down Expand Up @@ -31,6 +31,37 @@ services.path FROM services JOIN authenticode ON services.path = authenticode.pa
authenticode.path JOIN hash ON services.path = hash.path WHERE authenticode.result != 'trusted'
"""

[[transform.investigate]]
label = "Alerts associated with the user in the last 48h"
relativeFrom = "now-48h/h"
relativeTo = "now"
providers = [
[
{field = "event.kind", excluded = false, queryType = "phrase", value = "signal", valueType = "string"},
{field = "user.id", excluded = false, queryType = "phrase", value = "{{user.id}}", valueType = "string"}
]
]

[[transform.investigate]]
label = "Alerts associated with the host in the last 48h"
relativeFrom = "now-48h/h"
relativeTo = "now"
providers = [
[
{field = "event.kind", excluded = false, queryType = "phrase", value = "signal", valueType = "string"},
{field = "host.name", excluded = false, queryType = "phrase", value = "{{host.name}}", valueType = "string"},
]
]

[[transform.investigate]]
label = "Investigate the Subject Process Network Events"
providers = [
[
{field = "process.entity_id", excluded = false, queryType = "phrase", value = "{{process.entity_id}}", valueType = "string"},
{field = "event.category", excluded = false, queryType = "phrase", value = "network", valueType = "string"}
]
]


[rule]
author = ["Elastic"]
Expand All @@ -53,20 +84,24 @@ The `Desktopimgdownldr.exe` utility is used to to configure lockscreen/desktop i

> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/master/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
> This investigation guide uses the [Investigate Markdown Plugin](https://www.elastic.co/guide/en/security/master/interactive-investigation-guides.html) introduced in Elastic Stack version 8.8.0. Older Elastic Stack versions will display unrendered Markdown in this guide.

#### Possible investigation steps

- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
- Identify the user account that performed the action and whether it should perform this kind of action.
- Contact the account owner and confirm whether they are aware of this activity.
- Investigate other alerts associated with the user/host during the past 48 hours.
- $investigate_0
- $investigate_1
- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.
- Check the reputation of the domain or IP address used to host the downloaded file or if the user downloaded the file from an internal system.
- Examine the host for derived artifacts that indicate suspicious activities:
- Analyze the file using a private sandboxed analysis system.
- Observe and collect information about the following activities in both the sandbox and the alert subject host:
- Attempts to contact external domains and addresses.
- Use the Elastic Defend network events to determine domains and addresses contacted by the subject process by filtering by the process' `process.entity_id`.
- $investigate_2
- Examine the DNS cache for suspicious or anomalous entries.
- $osquery_0
- Use the Elastic Defend registry events to examine registry keys accessed, modified, or created by the related processes in the process tree.
Expand Down
37 changes: 36 additions & 1 deletion rules/windows/command_and_control_remote_file_copy_mpcmdrun.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
creation_date = "2020/09/03"
integration = ["endpoint", "windows"]
maturity = "production"
updated_date = "2023/10/23"
updated_date = "2023/12/07"
min_stack_comments = "New fields added: required_fields, related_integrations, setup"
min_stack_version = "8.3.0"

Expand Down Expand Up @@ -31,6 +31,37 @@ services.path FROM services JOIN authenticode ON services.path = authenticode.pa
authenticode.path JOIN hash ON services.path = hash.path WHERE authenticode.result != 'trusted'
"""

[[transform.investigate]]
label = "Alerts associated with the user in the last 48h"
relativeFrom = "now-48h/h"
relativeTo = "now"
providers = [
[
{field = "event.kind", excluded = false, queryType = "phrase", value = "signal", valueType = "string"},
{field = "user.id", excluded = false, queryType = "phrase", value = "{{user.id}}", valueType = "string"}
]
]

[[transform.investigate]]
label = "Alerts associated with the host in the last 48h"
relativeFrom = "now-48h/h"
relativeTo = "now"
providers = [
[
{field = "event.kind", excluded = false, queryType = "phrase", value = "signal", valueType = "string"},
{field = "host.name", excluded = false, queryType = "phrase", value = "{{host.name}}", valueType = "string"}
]
]

[[transform.investigate]]
label = "Investigate the Subject Process Network Events"
providers = [
[
{field = "process.entity_id", excluded = false, queryType = "phrase", value = "{{process.entity_id}}", valueType = "string"},
{field = "event.category", excluded = false, queryType = "phrase", value = "network", valueType = "string"}
]
]


[rule]
author = ["Elastic"]
Expand All @@ -50,19 +81,23 @@ The `MpCmdRun.exe` is a command-line tool part of Windows Defender and is used t

> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/master/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
> This investigation guide uses the [Investigate Markdown Plugin](https://www.elastic.co/guide/en/security/master/interactive-investigation-guides.html) introduced in Elastic Stack version 8.8.0. Older Elastic Stack versions will display unrendered Markdown in this guide.

#### Possible investigation steps

- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
- Identify the user account that performed the action and whether it should perform this kind of action.
- Contact the account owner and confirm whether they are aware of this activity.
- Investigate other alerts associated with the user/host during the past 48 hours.
- $investigate_0
- $investigate_1
- Check the reputation of the domain or IP address used to host the downloaded file.
- Examine the host for derived artifacts that indicate suspicious activities:
- Analyze the file using a private sandboxed analysis system.
- Observe and collect information about the following activities in both the sandbox and the alert subject host:
- Attempts to contact external domains and addresses.
- Use the Elastic Defend network events to determine domains and addresses contacted by the subject process by filtering by the process' `process.entity_id`.
- $investigate_2
- Examine the DNS cache for suspicious or anomalous entries.
- $osquery_0
- Use the Elastic Defend registry events to examine registry keys accessed, modified, or created by the related processes in the process tree.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
creation_date = "2020/11/30"
integration = ["endpoint"]
maturity = "production"
updated_date = "2023/10/22"
updated_date = "2023/12/07"
min_stack_comments = "New fields added: required_fields, related_integrations, setup"
min_stack_version = "8.3.0"

Expand Down Expand Up @@ -31,6 +31,37 @@ services.path FROM services JOIN authenticode ON services.path = authenticode.pa
authenticode.path JOIN hash ON services.path = hash.path WHERE authenticode.result != 'trusted'
"""

[[transform.investigate]]
label = "Alerts associated with the user in the last 48h"
relativeFrom = "now-48h/h"
relativeTo = "now"
providers = [
[
{field = "event.kind", excluded = false, queryType = "phrase", value = "signal", valueType = "string"},
{field = "user.id", excluded = false, queryType = "phrase", value = "{{user.id}}", valueType = "string"}
]
]

[[transform.investigate]]
label = "Alerts associated with the host in the last 48h"
relativeFrom = "now-48h/h"
relativeTo = "now"
providers = [
[
{field = "event.kind", excluded = false, queryType = "phrase", value = "signal", valueType = "string"},
{field = "host.name", excluded = false, queryType = "phrase", value = "{{host.name}}", valueType = "string"}
]
]

[[transform.investigate]]
label = "Investigate the Subject Process Network Events"
providers = [
[
{field = "process.entity_id", excluded = false, queryType = "phrase", value = "{{process.entity_id}}", valueType = "string"},
{field = "event.category", excluded = false, queryType = "phrase", value = "network", valueType = "string"}
]
]


[rule]
author = ["Elastic"]
Expand All @@ -50,19 +81,23 @@ PowerShell is one of system administrators' main tools for automation, report ro

> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/master/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
> This investigation guide uses the [Investigate Markdown Plugin](https://www.elastic.co/guide/en/security/master/interactive-investigation-guides.html) introduced in Elastic Stack version 8.8.0. Older Elastic Stack versions will display unrendered Markdown in this guide.

#### Possible investigation steps

- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
- Identify the user account that performed the action and whether it should perform this kind of action.
- Evaluate whether the user needs to use PowerShell to complete tasks.
- Investigate other alerts associated with the user/host during the past 48 hours.
- $investigate_0
- $investigate_1
- Check the reputation of the domain or IP address used to host the downloaded file.
- Examine the host for derived artifacts that indicate suspicious activities:
- Analyze the file using a private sandboxed analysis system.
- Observe and collect information about the following activities in both the sandbox and the alert subject host:
- Attempts to contact external domains and addresses.
- Use the Elastic Defend network events to determine domains and addresses contacted by the subject process by filtering by the process' `process.entity_id`.
- $investigate_2
- Examine the DNS cache for suspicious or anomalous entries.
- $osquery_0
- Use the Elastic Defend registry events to examine registry keys accessed, modified, or created by the related processes in the process tree.
Expand Down
Loading