Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
075d25c
[New/Tuning] NPM Shai-Hulud coverage
Samirbous Nov 26, 2025
4def7ab
Update command_and_control_curl_wget_spawn_via_nodejs_parent.toml
Samirbous Nov 26, 2025
3decbd4
Update command_and_control_curl_wget_spawn_via_nodejs_parent.toml
Samirbous Nov 26, 2025
af51eb8
Update command_and_control_curl_wget_spawn_via_nodejs_parent.toml
Samirbous Nov 26, 2025
84b00b5
Update credential_access_trufflehog_execution.toml
Samirbous Nov 26, 2025
136e385
Update credential_access_trufflehog_execution.toml
Samirbous Nov 26, 2025
0c2422a
Update credential_access_trufflehog_execution.toml
Samirbous Nov 26, 2025
dce060c
Update rules/cross-platform/command_and_control_curl_wget_spawn_via_n…
Samirbous Nov 27, 2025
20e438d
Update rules/cross-platform/command_and_control_curl_wget_spawn_via_n…
Samirbous Nov 27, 2025
6e1e918
Update rules/cross-platform/command_and_control_curl_wget_spawn_via_n…
Samirbous Nov 27, 2025
91f09be
Update rules/cross-platform/execution_register_github_actions_runner.…
Samirbous Nov 27, 2025
3fc61fa
Update rules/cross-platform/execution_via_github_actions_runner.toml
Samirbous Nov 27, 2025
f060176
Create initial_access_github_register_self_hosted_runner.toml
Samirbous Nov 28, 2025
a56f011
Merge branch 'shaih-cov' of https://github.com/elastic/detection-rule…
Samirbous Nov 28, 2025
d7aac6d
Update initial_access_github_register_self_hosted_runner.toml
Samirbous Nov 28, 2025
a6779f9
Update initial_access_github_register_self_hosted_runner.toml
Samirbous Nov 28, 2025
a32358e
Update initial_access_github_register_self_hosted_runner.toml
Samirbous Nov 28, 2025
3622a8a
Merge branch 'main' into shaih-cov
w0rk3r Dec 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[metadata]
creation_date = "2025/09/18"
integration = ["endpoint", "crowdstrike"]
integration = ["endpoint", "windows", "system", "sentinel_one_cloud_funnel", "crowdstrike", "auditd_manager"]
maturity = "production"
updated_date = "2025/10/17"
updated_date = "2025/11/26"

[rule]
author = ["Elastic"]
Expand All @@ -12,7 +12,18 @@ command and control behavior. Adversaries may use Node.js to download additional
the system.
"""
from = "now-9m"
index = ["logs-endpoint.events.process*", "logs-crowdstrike.fdr*"]
index = [
"endgame-*",
"logs-crowdstrike.fdr*",
"logs-endpoint.events.process-*",
"logs-sentinel_one_cloud_funnel.*",
"logs-system.security*",
"logs-windows.forwarded*",
"logs-windows.sysmon_operational-*",
"winlogbeat-*",
"auditbeat-*",
"logs-auditd_manager.auditd-*"
]
language = "eql"
license = "Elastic License v2"
name = "Curl or Wget Spawned via Node.js"
Expand Down Expand Up @@ -46,7 +57,7 @@ This rule flags Node.js launching curl or wget, directly or via a shell, a commo
- Rebuild and redeploy the workload from a known-good image, remove the malicious child_process code path from the Node.js application, restore validated configs/data, rotate any keys or tokens used by that service, and verify no further curl/wget spawns occur post-recovery.
- Harden by removing curl/wget from runtime images where not required, enforcing egress allowlists for the service, constraining execution with AppArmor/SELinux/seccomp and least-privilege service accounts, and adding CI/CD checks to block package.json postinstall scripts or code that shells out to downloaders.
"""
risk_score = 21
risk_score = 47
rule_id = "d9af2479-ad13-4471-a312-f586517f1243"
setup = """## Setup

Expand All @@ -73,28 +84,38 @@ For more details on Elastic Agent configuration settings, refer to the [helper g
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "low"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Linux",
"OS: Windows",
"OS: macOS",
"Use Case: Threat Detection",
"Tactic: Command and Control",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
"Data Source: Elastic Defend",
"Data Source: Elastic Endgame",
"Data Source: Windows Security Event Logs",
"Data Source: Sysmon",
"Data Source: SentinelOne",
"Data Source: Crowdstrike",
"Data Source: Auditd Manager",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "ProcessRollup2") and process.parent.name == "node" and (
process where event.type == "start" and
event.action in ("exec", "exec_event", "start", "ProcessRollup2", "executed", "process_started") and
Copy link
Contributor

@w0rk3r w0rk3r Dec 1, 2025

Choose a reason for hiding this comment

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

Unsure if these are going to work with MacOS (when using 3rd party EDRs), but it is worth a shot

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🤞

process.parent.name in ("node", "bun", "node.exe", "bun.exe") and (
(
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and
process.args == "-c" and process.command_line like~ ("*curl*", "*wget*")
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "cmd.exe", "bash.exe", "powershell.exe") and
process.command_line like~ ("*curl*http*", "*wget*http*")
) or
(
process.name in ("curl", "wget")
process.name in ("curl", "wget", "curl.exe", "wget.exe")
)
)
) and
not process.command_line like ("*127.0.0.1*", "*localhost*")
'''

[[rule.threat]]
Expand Down
29 changes: 24 additions & 5 deletions rules/cross-platform/credential_access_trufflehog_execution.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[metadata]
creation_date = "2025/09/18"
integration = ["endpoint"]
integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike", "auditd_manager"]
maturity = "production"
updated_date = "2025/11/25"
updated_date = "2025/11/26"

[rule]
author = ["Elastic"]
Expand All @@ -19,7 +19,19 @@ false_positives = [
""",
]
from = "now-9m"
index = ["logs-endpoint.events.process-*"]
index = [
"endgame-*",
"logs-crowdstrike.fdr*",
"logs-endpoint.events.process-*",
"logs-m365_defender.event-*",
"logs-sentinel_one_cloud_funnel.*",
"logs-system.security*",
"logs-windows.forwarded*",
"logs-windows.sysmon_operational-*",
"winlogbeat-*",
"auditbeat-*",
"logs-auditd_manager.auditd-*"
]
language = "eql"
license = "Elastic License v2"
name = "Credential Access via TruffleHog Execution"
Expand Down Expand Up @@ -58,17 +70,24 @@ references = [
"https://www.elastic.co/blog/shai-hulud-worm-npm-supply-chain-compromise",
"https://socket.dev/blog/shai-hulud-strikes-again-v2",
]
risk_score = 21
risk_score = 47
rule_id = "47595dea-452b-4d37-b82d-6dd691325139"
severity = "low"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Linux",
"OS: Windows",
"OS: macOS",
"Use Case: Threat Detection",
"Tactic: Credential Access",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Data Source: Windows Security Event Logs",
"Data Source: Microsoft Defender for Endpoint",
"Data Source: Sysmon",
"Data Source: SentinelOne",
"Data Source: Crowdstrike",
"Data Source: Auditd Manager",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
Expand Down
126 changes: 126 additions & 0 deletions rules/cross-platform/execution_register_github_actions_runner.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
[metadata]
creation_date = "2025/11/26"
integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike", "auditd_manager"]
maturity = "production"
updated_date = "2025/11/26"

[rule]
author = ["Elastic"]
description = """
This rule detects the configuration of a GitHub Actions self-hosted runner using the Runner.Listener binary.
When a machine is registered to a remote repository, its owner gains the ability to execute arbitrary workflow commands on that host.
Unexpected or unauthorized runner registration may indicate adversarial activity aimed at establishing remote code execution
via malicious GitHub workflows.
"""
false_positives = [
"Authorized github repository with no malicious workflow actions.",
]
from = "now-9m"
index = [
"endgame-*",
"logs-crowdstrike.fdr*",
"logs-endpoint.events.process-*",
"logs-m365_defender.event-*",
"logs-sentinel_one_cloud_funnel.*",
"logs-system.security*",
"logs-windows.forwarded*",
"logs-windows.sysmon_operational-*",
"winlogbeat-*",
"auditbeat-*",
"logs-auditd_manager.auditd-*"
]
language = "eql"
license = "Elastic License v2"
name = "Remote GitHub Actions Runner Registration"
note = """## Triage and analysis
### Investigating Remote GitHub Actions Runner Registration
Unexpected or unauthorized Github actions runner registration may indicate adversarial activity aimed at establishing remote code execution via malicious GitHub workflows.
### Possible investigation steps
- Review the remote repository details and reputation.
- Examine the remote repository for any suspicious workflows run commands in the `.github/workflows` folder.
- Examine the execution context like process tree, associated network and file activities.
- Verify if there is adjascent any sensitive file access or collection.
- Correlate with other alerts and investiguate if this activity is related to a supply chain attack.
### False positive analysis
- Authorized configuration changes.
### Response and remediation
- Immediately isolate the affected system from the network to prevent further unauthorized command execution and potential lateral movement.
- Terminate any suspicious child processes that were initiated by the registered Github actions runner.
- Conduct a thorough review of the affected system's logs and configurations to identify any unauthorized changes or additional indicators of compromise.
- Restore the system from a known good backup if any unauthorized changes or malicious activities are confirmed.
- Implement application whitelisting to prevent unauthorized execution.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to assess the potential impact on the broader network."""
references = [
"https://www.elastic.co/blog/shai-hulud-worm-npm-supply-chain-compromise",
"https://socket.dev/blog/shai-hulud-strikes-again-v2",
]
risk_score = 47
rule_id = "57e118c1-19eb-4c20-93a6-8a6c30a5b48b"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Linux",
"OS: Windows",
"OS: macOS",
"Use Case: Threat Detection",
"Tactic: Execution",
"Tactic: Initial Access",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Data Source: Windows Security Event Logs",
"Data Source: Microsoft Defender for Endpoint",
"Data Source: Sysmon",
"Data Source: SentinelOne",
"Data Source: Crowdstrike",
"Data Source: Auditd Manager",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where event.type == "start" and event.action in ("exec", "exec_event", "start", "ProcessRollup2", "executed", "process_started") and
process.name in ("Runner.Listener", "Runner.Listener.exe") and
process.args == "configure" and process.args == "--url" and process.args == "--token"
Comment on lines +91 to +92
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Consider using case insensitive operators to make these more resilient on windows

Copy link
Contributor Author

Choose a reason for hiding this comment

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

they use the default stuff and mostly on Linux/macOS

'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"



[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1195"
name = "Supply Chain Compromise"
reference = "https://attack.mitre.org/techniques/T1195/"
[[rule.threat.technique.subtechnique]]
id = "T1195.002"
name = "Compromise Software Supply Chain"
reference = "https://attack.mitre.org/techniques/T1195/002/"



[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"

Loading