nldcsc-elastic-rules 0.0.8__py3-none-any.whl → 0.0.16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nldcsc_elastic_rules/__init__.py +1 -1
- nldcsc_elastic_rules/rules/{linux → cross-platform}/command_and_control_curl_wget_spawn_via_nodejs_parent.toml +32 -11
- nldcsc_elastic_rules/rules/cross-platform/command_and_control_genai_process_suspicious_tld_connection.toml +134 -0
- nldcsc_elastic_rules/rules/cross-platform/command_and_control_genai_process_unusual_domain.toml +128 -0
- nldcsc_elastic_rules/rules/cross-platform/credential_access_genai_process_sensitive_file_access.toml +154 -0
- nldcsc_elastic_rules/rules/cross-platform/credential_access_gitleaks_execution.toml +114 -0
- nldcsc_elastic_rules/rules/cross-platform/credential_access_multi_could_secrets_via_api.toml +198 -0
- nldcsc_elastic_rules/rules/cross-platform/credential_access_trufflehog_execution.toml +24 -5
- nldcsc_elastic_rules/rules/cross-platform/defense_evasion_genai_config_modification.toml +120 -0
- nldcsc_elastic_rules/rules/cross-platform/defense_evasion_genai_process_compiling_executables.toml +158 -0
- nldcsc_elastic_rules/rules/cross-platform/defense_evasion_genai_process_encoding_prior_to_network_activity.toml +172 -0
- nldcsc_elastic_rules/rules/cross-platform/defense_evasion_potential_http_downgrade_attack.toml +98 -0
- nldcsc_elastic_rules/rules/cross-platform/discovery_web_server_local_file_inclusion_activity.toml +172 -0
- nldcsc_elastic_rules/rules/cross-platform/discovery_web_server_remote_file_inclusion_activity.toml +133 -0
- nldcsc_elastic_rules/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml +250 -0
- nldcsc_elastic_rules/rules/{linux/persistence_nodejs_pre_or_post_install_script_execution.toml → cross-platform/execution_nodejs_pre_or_post_install_script_execution.toml} +40 -24
- nldcsc_elastic_rules/rules/cross-platform/execution_privileged_container_creation_with_host_reference.toml +146 -0
- nldcsc_elastic_rules/rules/cross-platform/execution_register_github_actions_runner.toml +126 -0
- nldcsc_elastic_rules/rules/cross-platform/execution_via_github_actions_runner.toml +130 -0
- nldcsc_elastic_rules/rules/cross-platform/execution_via_github_runner_with_runner_tracking_id_tampering_via_env_vars.toml +163 -0
- nldcsc_elastic_rules/rules/cross-platform/initial_access_execution_susp_react_serv_child.toml +130 -0
- nldcsc_elastic_rules/rules/cross-platform/initial_access_file_upload_followed_by_get_request.toml +145 -0
- nldcsc_elastic_rules/rules/cross-platform/multiple_alerts_elastic_defend_netsecurity_by_host.toml +4 -1
- nldcsc_elastic_rules/rules/cross-platform/persistence_credential_access_modify_auth_module_or_config.toml +3 -4
- nldcsc_elastic_rules/rules/cross-platform/persistence_web_server_potential_command_injection.toml +23 -25
- nldcsc_elastic_rules/rules/cross-platform/reconnaissance_web_server_discovery_or_fuzzing_activity.toml +13 -14
- nldcsc_elastic_rules/rules/cross-platform/reconnaissance_web_server_unusual_spike_in_error_logs.toml +8 -5
- nldcsc_elastic_rules/rules/cross-platform/reconnaissance_web_server_unusual_spike_in_error_response_codes.toml +12 -12
- nldcsc_elastic_rules/rules/cross-platform/reconnaissance_web_server_unusual_user_agents.toml +37 -43
- nldcsc_elastic_rules/rules/integrations/aws/defense_evasion_rds_instance_restored.toml +137 -45
- nldcsc_elastic_rules/rules/integrations/aws/discovery_iam_principal_enumeration_via_update_assume_role_policy.toml +152 -0
- nldcsc_elastic_rules/rules/integrations/aws/discovery_multiple_discovery_api_calls_via_cli.toml +242 -0
- nldcsc_elastic_rules/rules/integrations/aws/exfiltration_rds_snapshot_export.toml +141 -33
- nldcsc_elastic_rules/rules/integrations/aws/exfiltration_rds_snapshot_shared_with_another_account.toml +108 -30
- nldcsc_elastic_rules/rules/integrations/aws/exfiltration_s3_bucket_policy_added_for_external_account_access.toml +2 -1
- nldcsc_elastic_rules/rules/integrations/aws/exfiltration_s3_bucket_replicated_to_external_account.toml +114 -27
- nldcsc_elastic_rules/rules/integrations/aws/impact_efs_filesystem_deleted.toml +174 -0
- nldcsc_elastic_rules/rules/integrations/aws/impact_kms_cmk_disabled_or_scheduled_for_deletion.toml +111 -33
- nldcsc_elastic_rules/rules/integrations/aws/impact_rds_instance_cluster_deletion.toml +129 -43
- nldcsc_elastic_rules/rules/integrations/aws/impact_rds_instance_cluster_deletion_protection_disabled.toml +89 -27
- nldcsc_elastic_rules/rules/integrations/aws/impact_rds_snapshot_deleted.toml +127 -37
- nldcsc_elastic_rules/rules/integrations/aws/impact_s3_object_encryption_with_external_key.toml +160 -43
- nldcsc_elastic_rules/rules/integrations/aws/initial_access_iam_session_token_used_from_multiple_addresses.toml +20 -10
- nldcsc_elastic_rules/rules/integrations/aws/ml_cloudtrail_error_message_spike.toml +35 -1
- nldcsc_elastic_rules/rules/integrations/aws/ml_cloudtrail_rare_error_code.toml +59 -1
- nldcsc_elastic_rules/rules/integrations/aws/ml_cloudtrail_rare_method_by_city.toml +19 -1
- nldcsc_elastic_rules/rules/integrations/aws/ml_cloudtrail_rare_method_by_country.toml +19 -1
- nldcsc_elastic_rules/rules/integrations/aws/ml_cloudtrail_rare_method_by_user.toml +58 -1
- nldcsc_elastic_rules/rules/integrations/aws/persistence_rds_db_instance_password_modified.toml +109 -35
- nldcsc_elastic_rules/rules/integrations/aws/persistence_rds_instance_made_public.toml +103 -22
- nldcsc_elastic_rules/rules/integrations/aws/persistence_redshift_instance_creation.toml +3 -3
- nldcsc_elastic_rules/rules/integrations/aws/privilege_escalation_sts_assume_root_from_rare_user_and_member_account.toml +126 -69
- nldcsc_elastic_rules/rules/integrations/azure/credential_access_azure_entra_susp_device_code_signin.toml +134 -0
- nldcsc_elastic_rules/rules/integrations/azure/credential_access_entra_id_excessive_account_lockouts.toml +2 -2
- nldcsc_elastic_rules/rules/integrations/azure/ml_azure_event_failures.toml +124 -0
- nldcsc_elastic_rules/rules/integrations/azure/ml_azure_rare_event_failures.toml +148 -0
- nldcsc_elastic_rules/rules/integrations/azure/ml_azure_rare_method_by_city.toml +109 -0
- nldcsc_elastic_rules/rules/integrations/azure/ml_azure_rare_method_by_country.toml +108 -0
- nldcsc_elastic_rules/rules/integrations/azure/ml_azure_rare_method_by_user.toml +147 -0
- nldcsc_elastic_rules/rules/integrations/fim/persistence_suspicious_file_modifications.toml +9 -1
- nldcsc_elastic_rules/rules/integrations/gcp/ml_gcp_error_message_spike.toml +95 -0
- nldcsc_elastic_rules/rules/integrations/gcp/ml_gcp_rare_error_code.toml +118 -0
- nldcsc_elastic_rules/rules/integrations/gcp/ml_gcp_rare_method_by_city.toml +79 -0
- nldcsc_elastic_rules/rules/integrations/gcp/ml_gcp_rare_method_by_country.toml +79 -0
- nldcsc_elastic_rules/rules/integrations/gcp/ml_gcp_rare_method_by_user.toml +117 -0
- nldcsc_elastic_rules/rules/integrations/github/initial_access_github_register_self_hosted_runner.toml +92 -0
- nldcsc_elastic_rules/rules/integrations/o365/collection_onedrive_excessive_file_downloads.toml +24 -14
- nldcsc_elastic_rules/rules/linux/defense_evasion_file_deletion_via_shred.toml +12 -5
- nldcsc_elastic_rules/rules/linux/execution_suspicious_pod_or_container_creation_command_execution.toml +150 -0
- nldcsc_elastic_rules/rules/linux/persistence_at_job_creation.toml +4 -4
- nldcsc_elastic_rules/rules/linux/persistence_pluggable_authentication_module_creation.toml +12 -7
- nldcsc_elastic_rules/rules/linux/persistence_pth_file_creation.toml +6 -1
- nldcsc_elastic_rules/rules/linux/persistence_site_and_user_customize_file_creation.toml +6 -1
- nldcsc_elastic_rules/rules/linux/persistence_web_server_unusual_command_execution.toml +155 -0
- nldcsc_elastic_rules/rules/ml/ml_high_count_events_for_a_host_name.toml +58 -1
- nldcsc_elastic_rules/rules/ml/ml_high_count_network_denies.toml +71 -1
- nldcsc_elastic_rules/rules/ml/ml_high_count_network_events.toml +53 -1
- nldcsc_elastic_rules/rules/ml/ml_linux_anomalous_network_activity.toml +56 -1
- nldcsc_elastic_rules/rules/ml/ml_linux_anomalous_network_port_activity.toml +40 -1
- nldcsc_elastic_rules/rules/ml/ml_low_count_events_for_a_host_name.toml +27 -1
- nldcsc_elastic_rules/rules/ml/ml_packetbeat_rare_server_domain.toml +63 -1
- nldcsc_elastic_rules/rules/ml/ml_rare_destination_country.toml +68 -1
- nldcsc_elastic_rules/rules/ml/ml_spike_in_traffic_to_a_country.toml +53 -1
- nldcsc_elastic_rules/rules/ml/ml_windows_anomalous_network_activity.toml +56 -1
- nldcsc_elastic_rules/rules/network/initial_access_react_server_components_rce_attempt.toml +123 -0
- nldcsc_elastic_rules/rules/promotions/external_alerts.toml +2 -2
- nldcsc_elastic_rules/rules/windows/command_and_control_common_webservices.toml +4 -3
- nldcsc_elastic_rules/rules/windows/credential_access_rare_webdav_destination.toml +3 -4
- nldcsc_elastic_rules/rules/windows/defense_evasion_masquerading_as_svchost.toml +11 -8
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation.toml +25 -2
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_backtick.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_backtick_var.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_char_arrays.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_concat_dynamic.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_high_number_proportion.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_iex_env_vars_reconstruction.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_iex_string_reconstruction.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_index_reversal.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_reverse_keyword.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_string_concat.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_string_format.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_whitespace_special_proportion.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_wsl_filesystem.toml +13 -10
- nldcsc_elastic_rules/rules/windows/execution_posh_hacktool_functions.toml +3 -2
- nldcsc_elastic_rules/rules/windows/execution_suspicious_powershell_imgload.toml +7 -2
- nldcsc_elastic_rules/rules/windows/execution_windows_powershell_susp_args.toml +9 -2
- nldcsc_elastic_rules/rules/windows/impact_mod_critical_os_files.toml +16 -6
- nldcsc_elastic_rules/rules/windows/lateral_movement_credential_access_kerberos_correlation.toml +7 -2
- nldcsc_elastic_rules/rules/windows/lateral_movement_scheduled_task_target.toml +2 -2
- nldcsc_elastic_rules/rules/windows/persistence_browser_extension_install.toml +19 -2
- nldcsc_elastic_rules/rules/windows/persistence_msi_installer_task_startup.toml +50 -13
- nldcsc_elastic_rules/rules/windows/persistence_via_application_shimming.toml +12 -2
- nldcsc_elastic_rules/rules/windows/privilege_escalation_tokenmanip_sedebugpriv_enabled.toml +24 -18
- nldcsc_elastic_rules/rules/windows/privilege_escalation_unusual_printspooler_childprocess.toml +14 -2
- nldcsc_elastic_rules/rules/windows/privilege_escalation_via_ppid_spoofing.toml +3 -2
- {nldcsc_elastic_rules-0.0.8.dist-info → nldcsc_elastic_rules-0.0.16.dist-info}/METADATA +1 -1
- {nldcsc_elastic_rules-0.0.8.dist-info → nldcsc_elastic_rules-0.0.16.dist-info}/RECORD +119 -87
- nldcsc_elastic_rules/rules/integrations/aws/credential_access_aws_iam_assume_role_brute_force.toml +0 -105
- nldcsc_elastic_rules/rules/integrations/aws/discovery_ec2_multi_region_describe_instances.toml +0 -135
- nldcsc_elastic_rules/rules/integrations/aws/discovery_ec2_multiple_discovery_api_calls_via_cli.toml +0 -155
- nldcsc_elastic_rules/rules/integrations/aws/impact_efs_filesystem_or_mount_deleted.toml +0 -95
- {nldcsc_elastic_rules-0.0.8.dist-info → nldcsc_elastic_rules-0.0.16.dist-info}/WHEEL +0 -0
- {nldcsc_elastic_rules-0.0.8.dist-info → nldcsc_elastic_rules-0.0.16.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
[metadata]
|
|
2
|
+
creation_date = "2025/11/26"
|
|
3
|
+
integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike", "auditd_manager"]
|
|
4
|
+
maturity = "production"
|
|
5
|
+
updated_date = "2025/11/26"
|
|
6
|
+
|
|
7
|
+
[rule]
|
|
8
|
+
author = ["Elastic"]
|
|
9
|
+
description = """
|
|
10
|
+
This rule detects potentially dangerous commands spawned by the GitHub Actions Runner.Worker process on self-hosted runner
|
|
11
|
+
machines. Adversaries who gain the ability to modify or trigger workflows in a linked GitHub repository can execute
|
|
12
|
+
arbitrary commands on the runner host. This behavior may indicate malicious or unexpected workflow activity, including
|
|
13
|
+
code execution, file manipulation, or network exfiltration initiated through a compromised repository or unauthorized
|
|
14
|
+
workflow.
|
|
15
|
+
"""
|
|
16
|
+
false_positives = [
|
|
17
|
+
"Authorized GitHub actions runner with no malicious workflow actions.",
|
|
18
|
+
]
|
|
19
|
+
from = "now-9m"
|
|
20
|
+
index = [
|
|
21
|
+
"endgame-*",
|
|
22
|
+
"logs-crowdstrike.fdr*",
|
|
23
|
+
"logs-endpoint.events.process-*",
|
|
24
|
+
"logs-m365_defender.event-*",
|
|
25
|
+
"logs-sentinel_one_cloud_funnel.*",
|
|
26
|
+
"logs-system.security*",
|
|
27
|
+
"logs-windows.forwarded*",
|
|
28
|
+
"logs-windows.sysmon_operational-*",
|
|
29
|
+
"winlogbeat-*",
|
|
30
|
+
"auditbeat-*",
|
|
31
|
+
"logs-auditd_manager.auditd-*"
|
|
32
|
+
]
|
|
33
|
+
language = "eql"
|
|
34
|
+
license = "Elastic License v2"
|
|
35
|
+
name = "Execution via GitHub Actions Runner"
|
|
36
|
+
note = """## Triage and analysis
|
|
37
|
+
|
|
38
|
+
### Investigating Execution via GitHub Actions Runner
|
|
39
|
+
|
|
40
|
+
Adversaries who gain the ability to modify or trigger workflows in a linked GitHub repository can execute arbitrary commands on the runner host.
|
|
41
|
+
|
|
42
|
+
### Possible investigation steps
|
|
43
|
+
|
|
44
|
+
- Review the execution details like process.command_line and if it's expected or not.
|
|
45
|
+
- Examine associated network and file activities and if there is any ingress tool transfer activity.
|
|
46
|
+
- Verify if there is adjascent any sensitive file access or collection.
|
|
47
|
+
- Correlate with other alerts and investiguate if this activity is related to a supply chain attack.
|
|
48
|
+
|
|
49
|
+
### False positive analysis
|
|
50
|
+
|
|
51
|
+
- Authorized github workflow actions.
|
|
52
|
+
|
|
53
|
+
### Response and remediation
|
|
54
|
+
|
|
55
|
+
- Immediately isolate the affected system from the network to prevent further unauthorized command execution and potential lateral movement.
|
|
56
|
+
- Terminate any suspicious child processes that were initiated by the Github actions runner.
|
|
57
|
+
- Conduct a thorough review of the affected system's logs and configurations to identify any unauthorized changes or additional indicators of compromise.
|
|
58
|
+
- Restore the system from a known good backup if any unauthorized changes or malicious activities are confirmed.
|
|
59
|
+
- Implement application whitelisting to prevent unauthorized execution.
|
|
60
|
+
- 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."""
|
|
61
|
+
references = [
|
|
62
|
+
"https://www.elastic.co/blog/shai-hulud-worm-npm-supply-chain-compromise",
|
|
63
|
+
"https://socket.dev/blog/shai-hulud-strikes-again-v2",
|
|
64
|
+
]
|
|
65
|
+
risk_score = 47
|
|
66
|
+
rule_id = "a640ef5b-e1da-4b17-8391-468fdbd1b517"
|
|
67
|
+
severity = "medium"
|
|
68
|
+
tags = [
|
|
69
|
+
"Domain: Endpoint",
|
|
70
|
+
"OS: Linux",
|
|
71
|
+
"OS: Windows",
|
|
72
|
+
"OS: macOS",
|
|
73
|
+
"Use Case: Threat Detection",
|
|
74
|
+
"Tactic: Execution",
|
|
75
|
+
"Tactic: Initial Access",
|
|
76
|
+
"Data Source: Elastic Endgame",
|
|
77
|
+
"Data Source: Elastic Defend",
|
|
78
|
+
"Data Source: Windows Security Event Logs",
|
|
79
|
+
"Data Source: Microsoft Defender for Endpoint",
|
|
80
|
+
"Data Source: Sysmon",
|
|
81
|
+
"Data Source: SentinelOne",
|
|
82
|
+
"Data Source: Crowdstrike",
|
|
83
|
+
"Data Source: Auditd Manager",
|
|
84
|
+
"Resources: Investigation Guide",
|
|
85
|
+
]
|
|
86
|
+
timestamp_override = "event.ingested"
|
|
87
|
+
type = "eql"
|
|
88
|
+
|
|
89
|
+
query = '''
|
|
90
|
+
process where event.type == "start" and event.action in ("exec", "exec_event", "start", "ProcessRollup2", "executed", "process_started") and
|
|
91
|
+
process.parent.name in ("Runner.Worker", "Runner.Worker.exe") and
|
|
92
|
+
(
|
|
93
|
+
process.name like ("curl", "curl.exe", "wget", "wget.exe", "powershell.exe", "cmd.exe", "pwsh.exe", "certutil.exe", "rundll32.exe", "bash", "sh", "zsh", "tar", "rm",
|
|
94
|
+
"sed", "osascript", "chmod", "nohup", "setsid", "dash", "ash", "tcsh", "csh", "ksh", "fish", "python*", "perl*", "ruby*", "lua*", "php*", "node", "node.exe") or
|
|
95
|
+
process.executable : ("/tmp/*", "/private/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/*", "/var/run/*", "?:\\Users\\*")
|
|
96
|
+
)
|
|
97
|
+
'''
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
[[rule.threat]]
|
|
101
|
+
framework = "MITRE ATT&CK"
|
|
102
|
+
[[rule.threat.technique]]
|
|
103
|
+
id = "T1059"
|
|
104
|
+
name = "Command and Scripting Interpreter"
|
|
105
|
+
reference = "https://attack.mitre.org/techniques/T1059/"
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
[rule.threat.tactic]
|
|
110
|
+
id = "TA0002"
|
|
111
|
+
name = "Execution"
|
|
112
|
+
reference = "https://attack.mitre.org/tactics/TA0002/"
|
|
113
|
+
[[rule.threat]]
|
|
114
|
+
framework = "MITRE ATT&CK"
|
|
115
|
+
[[rule.threat.technique]]
|
|
116
|
+
id = "T1195"
|
|
117
|
+
name = "Supply Chain Compromise"
|
|
118
|
+
reference = "https://attack.mitre.org/techniques/T1195/"
|
|
119
|
+
[[rule.threat.technique.subtechnique]]
|
|
120
|
+
id = "T1195.002"
|
|
121
|
+
name = "Compromise Software Supply Chain"
|
|
122
|
+
reference = "https://attack.mitre.org/techniques/T1195/002/"
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
[rule.threat.tactic]
|
|
127
|
+
id = "TA0001"
|
|
128
|
+
name = "Initial Access"
|
|
129
|
+
reference = "https://attack.mitre.org/tactics/TA0001/"
|
|
130
|
+
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
[metadata]
|
|
2
|
+
creation_date = "2025/11/27"
|
|
3
|
+
integration = ["endpoint"]
|
|
4
|
+
maturity = "production"
|
|
5
|
+
updated_date = "2025/11/27"
|
|
6
|
+
|
|
7
|
+
[rule]
|
|
8
|
+
author = ["Elastic"]
|
|
9
|
+
description = """
|
|
10
|
+
This rule detects processes spawned by GitHub Actions runners where "RUNNER_TRACKING_ID" is overridden from its
|
|
11
|
+
default "github_*" value. Such tampering has been associated with attempts to evade runner tracking/cleanup on
|
|
12
|
+
self-hosted runners, including behavior observed in the Shai-Hulud 2.0 npm worm campaign.
|
|
13
|
+
"""
|
|
14
|
+
from = "now-9m"
|
|
15
|
+
index = ["logs-endpoint.events.process*"]
|
|
16
|
+
language = "eql"
|
|
17
|
+
license = "Elastic License v2"
|
|
18
|
+
name = "Tampering with RUNNER_TRACKING_ID in GitHub Actions Runners"
|
|
19
|
+
note = """## Triage and analysis
|
|
20
|
+
|
|
21
|
+
> **Disclaimer**:
|
|
22
|
+
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
|
|
23
|
+
|
|
24
|
+
### Investigating Tampering with RUNNER_TRACKING_ID in GitHub Actions Runners
|
|
25
|
+
|
|
26
|
+
This rule surfaces processes launched by GitHub Actions runners where RUNNER_TRACKING_ID is deliberately set to a non-default value. Attackers do this to break runner job tracking and cleanup on self-hosted runners, enabling long‑lived or hidden workloads. A common pattern is a workflow step that exports a custom RUNNER_TRACKING_ID and then spawns bash or node to fetch and execute a script via curl|bash or npm install scripts, keeping the process alive after the job finishes to run mining or exfil tasks.
|
|
27
|
+
|
|
28
|
+
### Possible investigation steps
|
|
29
|
+
|
|
30
|
+
- Correlate the event to its GitHub Actions run/job and workflow YAML, identify the repository and actor (commit/PR), and verify whether RUNNER_TRACKING_ID was explicitly set in the workflow or injected by a step script.
|
|
31
|
+
- On the runner host, determine if the spawned process persisted beyond job completion by checking for orphaning or reparenting to PID 1, sustained CPU/memory usage, and timestamps relative to the runner process exit.
|
|
32
|
+
- Review nearby telemetry for fetch-and-execute patterns (curl|bash, wget, node/npm lifecycle scripts), unexpected file writes under /tmp or actions-runner/_work, and outbound connections to non-GitHub endpoints.
|
|
33
|
+
- Enumerate persistence artifacts created during the run, including crontab entries, systemd unit files, pm2 or nohup sessions, and changes to authorized_keys or rc.local, and tie them back to the suspicious process.
|
|
34
|
+
- Assess blast radius by listing secrets and tokens available to the job, checking audit logs for their subsequent use from the runner IP or unusual repositories, and decide whether to revoke or rotate credentials.
|
|
35
|
+
|
|
36
|
+
### False positive analysis
|
|
37
|
+
|
|
38
|
+
- A self-hosted runner bootstrap script or base image intentionally sets a fixed RUNNER_TRACKING_ID for internal log correlation or debugging, causing all runner-spawned processes to inherit a non-github_* value.
|
|
39
|
+
- A composite action or reusable workflow accidentally overrides RUNNER_TRACKING_ID through env mapping or variable expansion (for example templating it from the run ID), resulting in benign non-default values during standard jobs.
|
|
40
|
+
|
|
41
|
+
### Response and remediation
|
|
42
|
+
|
|
43
|
+
- Quarantine the self-hosted runner by stopping Runner.Listener, removing the runner from the repository/organization, and terminating any Runner.Worker children or orphaned processes (PID 1) that carry a non-default RUNNER_TRACKING_ID.
|
|
44
|
+
- Purge persistence by removing artifacts created during the run, including systemd unit files under /etc/systemd/system, crontab entries in /var/spool/cron, pm2/nohup sessions, edits to ~/.ssh/authorized_keys or /etc/rc.local, and files under /tmp and actions-runner/_work linked to the tampered process.
|
|
45
|
+
- Revoke and rotate credentials exposed to the job (GITHUB_TOKEN, personal access tokens, cloud keys), delete leftover containers and caches in actions-runner/_work, invalidate the runner registration, and redeploy the runner from a clean, patched image.
|
|
46
|
+
- Escalate to incident response if you observe outbound connections to non-GitHub endpoints, processes persisting after job completion, modifications to ~/.ssh/authorized_keys or /etc/systemd/system, or repeated RUNNER_TRACKING_ID tampering across runners or repositories.
|
|
47
|
+
- Harden by restricting self-hosted runners to trusted repositories and actors, enforcing ephemeral per-job runners with egress allowlisting to github.com, setting strict job timeouts, and adding a workflow guard step that exits if RUNNER_TRACKING_ID does not start with github_."""
|
|
48
|
+
references = [
|
|
49
|
+
"https://www.elastic.co/blog/shai-hulud-worm-npm-supply-chain-compromise",
|
|
50
|
+
"https://socket.dev/blog/shai-hulud-strikes-again-v2",
|
|
51
|
+
"https://www.wiz.io/blog/shai-hulud-2-0-ongoing-supply-chain-attack",
|
|
52
|
+
"https://www.praetorian.com/blog/self-hosted-github-runners-are-backdoors/",
|
|
53
|
+
]
|
|
54
|
+
risk_score = 47
|
|
55
|
+
rule_id = "df0553c8-2296-45ef-b4dc-3b88c4c130a7"
|
|
56
|
+
setup = """## Setup
|
|
57
|
+
|
|
58
|
+
This rule requires data coming in from Elastic Defend.
|
|
59
|
+
|
|
60
|
+
### Elastic Defend Integration Setup
|
|
61
|
+
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
|
|
62
|
+
|
|
63
|
+
#### Prerequisite Requirements:
|
|
64
|
+
- Fleet is required for Elastic Defend.
|
|
65
|
+
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
|
|
66
|
+
|
|
67
|
+
#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
|
|
68
|
+
- Go to the Kibana home page and click "Add integrations".
|
|
69
|
+
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
|
|
70
|
+
- Click "Add Elastic Defend".
|
|
71
|
+
- Configure the integration name and optionally add a description.
|
|
72
|
+
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
|
|
73
|
+
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
|
|
74
|
+
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
|
|
75
|
+
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
|
|
76
|
+
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
|
|
77
|
+
- Click "Save and Continue".
|
|
78
|
+
- 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.
|
|
79
|
+
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
|
|
80
|
+
|
|
81
|
+
Elastic Defend integration does not collect environment variable logging by default.
|
|
82
|
+
In order to capture this behavior, this rule requires a specific configuration option set within the advanced settings of the Elastic Defend integration.
|
|
83
|
+
#### To set up environment variable capture for an Elastic Agent policy:
|
|
84
|
+
- Go to “Security → Manage → Policies”.
|
|
85
|
+
- Select an “Elastic Agent policy”.
|
|
86
|
+
- Click “Show advanced settings”.
|
|
87
|
+
- Scroll down or search for “linux.advanced.capture_env_vars”.
|
|
88
|
+
- Enter the names of environment variables you want to capture, separated by commas.
|
|
89
|
+
- For Linux, this rule requires the linux.advanced.capture_env_vars variable to be set to "RUNNER_TRACKING_ID".
|
|
90
|
+
- For macOS, this rule requires the macos.advanced.capture_env_vars variable to be set to "RUNNER_TRACKING_ID".
|
|
91
|
+
- Click “Save”.
|
|
92
|
+
After saving the integration change, the Elastic Agents running this policy will be updated and the rule will function properly.
|
|
93
|
+
For more information on capturing environment variables refer to the [helper guide](https://www.elastic.co/guide/en/security/current/environment-variable-capture.html).
|
|
94
|
+
"""
|
|
95
|
+
severity = "medium"
|
|
96
|
+
tags = [
|
|
97
|
+
"Domain: Endpoint",
|
|
98
|
+
"OS: Linux",
|
|
99
|
+
"OS: macOS",
|
|
100
|
+
"Use Case: Threat Detection",
|
|
101
|
+
"Tactic: Execution",
|
|
102
|
+
"Tactic: Initial Access",
|
|
103
|
+
"Tactic: Defense Evasion",
|
|
104
|
+
"Data Source: Elastic Defend",
|
|
105
|
+
"Resources: Investigation Guide",
|
|
106
|
+
]
|
|
107
|
+
timestamp_override = "event.ingested"
|
|
108
|
+
type = "eql"
|
|
109
|
+
query = '''
|
|
110
|
+
process where host.os.type in ("linux", "macos") and event.type == "start" and event.action == "exec" and
|
|
111
|
+
process.parent.name in ("Runner.Worker", "Runner.Listener") and process.env_vars like~ "RUNNER_TRACKING_ID*" and
|
|
112
|
+
not process.env_vars like~ "RUNNER_TRACKING_ID=github_*"
|
|
113
|
+
'''
|
|
114
|
+
|
|
115
|
+
[[rule.threat]]
|
|
116
|
+
framework = "MITRE ATT&CK"
|
|
117
|
+
|
|
118
|
+
[rule.threat.tactic]
|
|
119
|
+
name = "Execution"
|
|
120
|
+
id = "TA0002"
|
|
121
|
+
reference = "https://attack.mitre.org/tactics/TA0002/"
|
|
122
|
+
|
|
123
|
+
[[rule.threat.technique]]
|
|
124
|
+
id = "T1059"
|
|
125
|
+
name = "Command and Scripting Interpreter"
|
|
126
|
+
reference = "https://attack.mitre.org/techniques/T1059/"
|
|
127
|
+
|
|
128
|
+
[[rule.threat]]
|
|
129
|
+
framework = "MITRE ATT&CK"
|
|
130
|
+
|
|
131
|
+
[rule.threat.tactic]
|
|
132
|
+
name = "Initial Access"
|
|
133
|
+
id = "TA0001"
|
|
134
|
+
reference = "https://attack.mitre.org/tactics/TA0001/"
|
|
135
|
+
|
|
136
|
+
[[rule.threat.technique]]
|
|
137
|
+
name = "Supply Chain Compromise"
|
|
138
|
+
id = "T1195"
|
|
139
|
+
reference = "https://attack.mitre.org/techniques/T1195/"
|
|
140
|
+
|
|
141
|
+
[[rule.threat.technique.subtechnique]]
|
|
142
|
+
name = "Compromise Software Dependencies and Development Tools"
|
|
143
|
+
id = "T1195.001"
|
|
144
|
+
reference = "https://attack.mitre.org/techniques/T1195/001/"
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
[[rule.threat]]
|
|
148
|
+
framework = "MITRE ATT&CK"
|
|
149
|
+
|
|
150
|
+
[rule.threat.tactic]
|
|
151
|
+
name = "Defense Evasion"
|
|
152
|
+
id = "TA0005"
|
|
153
|
+
reference = "https://attack.mitre.org/tactics/TA0005/"
|
|
154
|
+
|
|
155
|
+
[[rule.threat.technique]]
|
|
156
|
+
name = "Impair Defenses"
|
|
157
|
+
id = "T1562"
|
|
158
|
+
reference = "https://attack.mitre.org/techniques/T1562/"
|
|
159
|
+
|
|
160
|
+
[[rule.threat.technique.subtechnique]]
|
|
161
|
+
name = "Disable or Modify Tools"
|
|
162
|
+
id = "T1562.001"
|
|
163
|
+
reference = "https://attack.mitre.org/techniques/T1562/001/"
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
[metadata]
|
|
2
|
+
creation_date = "2025/12/04"
|
|
3
|
+
integration = ["endpoint", "windows", "auditd_manager", "sentinel_one_cloud_funnel"]
|
|
4
|
+
maturity = "production"
|
|
5
|
+
updated_date = "2025/12/08"
|
|
6
|
+
|
|
7
|
+
[rule]
|
|
8
|
+
author = ["Elastic"]
|
|
9
|
+
description = """
|
|
10
|
+
This rule detects suspicious child process activity from a React server application. This could be related to successful
|
|
11
|
+
exploitation of CVE-2025-55182 or CVE-2025-66478. These vulnerabilities allow attackers to execute remote code due to
|
|
12
|
+
insecure deserialization of React Server Components (RSC) Flight payloads, leading to unauthenticated RCE on servers
|
|
13
|
+
running React 19.x or Next.js 14.3.0-canary+, 15.x, and 16.x with the App Router enabled
|
|
14
|
+
"""
|
|
15
|
+
from = "now-9m"
|
|
16
|
+
index = [
|
|
17
|
+
"auditbeat-*",
|
|
18
|
+
"logs-auditd_manager.auditd-*",
|
|
19
|
+
"logs-endpoint.events.process*",
|
|
20
|
+
"logs-sentinel_one_cloud_funnel.*",
|
|
21
|
+
"logs-windows.sysmon_operational-*"
|
|
22
|
+
]
|
|
23
|
+
language = "eql"
|
|
24
|
+
license = "Elastic License v2"
|
|
25
|
+
name = "Suspicious React Server Child Process"
|
|
26
|
+
note = """## Triage and analysis
|
|
27
|
+
|
|
28
|
+
> **Disclaimer**:
|
|
29
|
+
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
|
|
30
|
+
|
|
31
|
+
### Investigating Suspicious React Server Child Process
|
|
32
|
+
|
|
33
|
+
This rule flags suspicious shell or system utility processes spawned by a React or Next.js server application—clear evidence of CVE-2025-55182 or CVE-2025-66478 exploitation enabling arbitrary code execution. An attacker sends a specially crafted RSC Flight protocol payload to a vulnerable Next.js or React Server Components endpoint, causing the server to deserialize untrusted data and execute attacker-controlled JavaScript, which then spawns shell commands or system utilities to establish initial access and persistence.
|
|
34
|
+
|
|
35
|
+
### Possible investigation steps
|
|
36
|
+
|
|
37
|
+
- Extract the parent Node.js process command line and working directory to identify the React or Next.js application, then check package.json or package-lock.json for React version (19.0-19.2) and Next.js version (14.3.0-canary, 15.x, 16.x) to confirm vulnerability.
|
|
38
|
+
- Review web server access logs (Nginx, Apache, ALB) for suspicious POST requests to RSC endpoints (/_next/data/, /.next/, /api/) in the minutes before the shell spawn, focusing on requests with unusual Content-Type headers (text/x-component, application/rsc) or large payload sizes.
|
|
39
|
+
- Analyze the spawned child process command line, arguments, working directory, and any downloaded files or scripts to identify the payload type (reverse shell, data exfiltration, credential theft, persistence mechanism) and compute file hashes for threat intelligence correlation.
|
|
40
|
+
- Pivot on the source IP address from web logs across other hosts and applications to identify additional compromised servers, and check for lateral movement attempts or scanning activity from the compromised host to internal networks.
|
|
41
|
+
- Examine the host for post-exploitation artifacts including new cron jobs, modified .bashrc/.profile files, SSH authorized_keys additions, new user accounts, unusual network connections to external IPs, files in /tmp or /var/tmp directories, and container escape attempts (nsenter, docker socket access).
|
|
42
|
+
|
|
43
|
+
### False positive analysis
|
|
44
|
+
|
|
45
|
+
- Legitimate build or deployment scripts triggered by CI/CD pipelines may cause Next.js build workers (jest-worker/processChild.js) to spawn shell commands; filter these by excluding processes with --node-ipc flags or running in /builds/, /workspace/, or other CI directories.
|
|
46
|
+
- Development servers (next dev, expo start, react-scripts start) running on developer workstations may spawn legitimate shells for tooling; consider excluding NODE_ENV=development or processes running from user home directories if appropriate for your environment.
|
|
47
|
+
- Server-side rendering (SSR) frameworks may legitimately invoke system utilities for image processing, PDF generation, or other server-side tasks; maintain an allowlist of expected child processes and their arguments for known applications.
|
|
48
|
+
|
|
49
|
+
### Response and remediation
|
|
50
|
+
|
|
51
|
+
- Immediately isolate the affected host to prevent lateral movement, terminate the Node.js parent process and all child processes spawned from the React/Next.js server, and block the source IP address at the firewall and WAF level.
|
|
52
|
+
- Remove any persistence mechanisms installed by the attacker including cron jobs (check crontab -l for all users), modified shell initialization files (~/.bashrc, ~/.profile, /etc/profile.d/), SSH keys in ~/.ssh/authorized_keys, and systemd timers or service units.
|
|
53
|
+
- Rotate all credentials and secrets accessible to the compromised application including database passwords, API keys, cloud service credentials (AWS/Azure/GCP), and session tokens, assuming they may have been exfiltrated.
|
|
54
|
+
- Collect forensic artifacts including memory dumps of the Node.js process (if still running), packet captures of the malicious HTTP request, web server access and error logs, application logs from the React/Next.js server, and copies of any files created in /tmp, /var/tmp, or the application directory.
|
|
55
|
+
- Escalate to incident command if the attacker achieved container escape (nsenter usage detected), accessed sensitive data or credentials, established C2 communication to external infrastructure, or if multiple hosts show similar exploitation patterns from the same source.
|
|
56
|
+
- Patch immediately by upgrading React to version 19.0.1+, 19.1.2+, or 19.2.1+, and Next.js to versions 14.3.0-canary.88+, 15.0.5+, 15.1.9+, 15.2.6+, 15.3.6+, 15.4.8+, 15.5.7+, or 16.0.7+ depending on your major version, and deploy WAF rules to block malformed RSC payloads at the application edge.
|
|
57
|
+
"""
|
|
58
|
+
references = [
|
|
59
|
+
"https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182"
|
|
60
|
+
]
|
|
61
|
+
risk_score = 73
|
|
62
|
+
rule_id = "ae3e9625-89ad-4fc3-a7bf-fced5e64f01b"
|
|
63
|
+
severity = "high"
|
|
64
|
+
tags = [
|
|
65
|
+
"Domain: Endpoint",
|
|
66
|
+
"OS: Linux",
|
|
67
|
+
"OS: macOS",
|
|
68
|
+
"OS: Windows",
|
|
69
|
+
"Use Case: Threat Detection",
|
|
70
|
+
"Tactic: Initial Access",
|
|
71
|
+
"Data Source: Elastic Defend",
|
|
72
|
+
"Data Source: Auditd Manager",
|
|
73
|
+
"Data Source: SentinelOne",
|
|
74
|
+
"Data Source: Sysmon",
|
|
75
|
+
"Resources: Investigation Guide",
|
|
76
|
+
]
|
|
77
|
+
timestamp_override = "event.ingested"
|
|
78
|
+
type = "eql"
|
|
79
|
+
query = '''
|
|
80
|
+
process where event.type == "start" and event.action in ("exec", "executed", "start", "process_started") and (
|
|
81
|
+
process.name in (
|
|
82
|
+
"sh", "bash", "zsh", "curl", "wget", "id", "whoami", "uname", "cmd.exe", "cat", "powershell.exe", "java", "rundll32.exe", "wget.exe", "certutil.exe",
|
|
83
|
+
"nc", "ncat", "netcat", "nc.openbsd", "nc.traditional", "socat", "busybox", "mkfifo", "nohup", "setsid", "xterm"
|
|
84
|
+
) or
|
|
85
|
+
(process.name : "python*" and process.args : "-c" and process.args : (
|
|
86
|
+
"*import*pty*spawn*", "*import*subprocess*call*"
|
|
87
|
+
)) or
|
|
88
|
+
(process.name : "perl*" and process.args : "-e" and process.args : "*socket*" and process.args : (
|
|
89
|
+
"*exec*", "*system*"
|
|
90
|
+
)) or
|
|
91
|
+
(process.name : "ruby*" and process.args : ("-e", "-rsocket") and process.args : (
|
|
92
|
+
"*TCPSocket.new*", "*TCPSocket.open*"
|
|
93
|
+
)) or
|
|
94
|
+
(process.name : "lua*" and process.args : "-e" and process.args : "*socket.tcp*" and process.args : (
|
|
95
|
+
"*io.popen*", "*os.execute*"
|
|
96
|
+
)) or
|
|
97
|
+
(process.name : "php*" and process.args : "-r" and process.args : "*fsockopen*" and process.args : "*/bin/*sh*") or
|
|
98
|
+
(process.name == "node" and process.args == "-e" and process.args : "*spawn*sh*" and process.args : "*connect*") or
|
|
99
|
+
(process.name : ("awk", "gawk", "mawk", "nawk") and process.args : "*/inet/tcp/*") or
|
|
100
|
+
(process.name in ("rvim", "vim", "vimdiff", "rview", "view") and process.args == "-c" and process.args : "*socket*")
|
|
101
|
+
)
|
|
102
|
+
and (
|
|
103
|
+
?process.working_directory : (
|
|
104
|
+
"*react-dom*", "*.next*", "*node_modules/next*", "*react-server*", "*bin/next*", "*--experimental-https*", "*app/server*",
|
|
105
|
+
"*.pnpm/next*", "*/app/*", "*next/dist/server*", "*react-scripts*") or
|
|
106
|
+
(
|
|
107
|
+
process.parent.name in ("node", "bun", "node.exe", "bun.exe") and
|
|
108
|
+
process.parent.command_line : (
|
|
109
|
+
"*react-dom*", "*.next*", "*node_modules/next*", "*react-server*", "*next-server*", "*server.js*", "*bin/next*",
|
|
110
|
+
"*--experimental-https*", "*app/server*", "*.pnpm/next*", "*next start*", "*next dev*", "*react-scripts start*", "*next/dist/server*"
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
) and not (
|
|
114
|
+
?process.parent.executable in ("./runc", "/opt/google/chrome/chrome") or
|
|
115
|
+
process.command_line like "/bin/sh -c git config*"
|
|
116
|
+
)
|
|
117
|
+
'''
|
|
118
|
+
|
|
119
|
+
[[rule.threat]]
|
|
120
|
+
framework = "MITRE ATT&CK"
|
|
121
|
+
|
|
122
|
+
[[rule.threat.technique]]
|
|
123
|
+
id = "T1190"
|
|
124
|
+
name = "Exploit Public-Facing Application"
|
|
125
|
+
reference = "https://attack.mitre.org/techniques/T1190/"
|
|
126
|
+
|
|
127
|
+
[rule.threat.tactic]
|
|
128
|
+
id = "TA0001"
|
|
129
|
+
name = "Initial Access"
|
|
130
|
+
reference = "https://attack.mitre.org/tactics/TA0001/"
|
nldcsc_elastic_rules/rules/cross-platform/initial_access_file_upload_followed_by_get_request.toml
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
[metadata]
|
|
2
|
+
creation_date = "2025/11/27"
|
|
3
|
+
integration = ["endpoint", "network_traffic"]
|
|
4
|
+
maturity = "production"
|
|
5
|
+
updated_date = "2025/12/08"
|
|
6
|
+
|
|
7
|
+
[rule]
|
|
8
|
+
author = ["Elastic"]
|
|
9
|
+
description = """
|
|
10
|
+
This rule detects potential initial access activity where an adversary uploads a web shell or malicious script
|
|
11
|
+
to a web server via a file upload mechanism (e.g., through a web form using multipart/form-data), followed by
|
|
12
|
+
a GET or POST request to access the uploaded file. By checking the body content of HTTP requests for file upload
|
|
13
|
+
indicators such as "Content-Disposition: form-data" and "filename=", the rule identifies suspicious upload
|
|
14
|
+
activities. This sequence of actions is commonly used by attackers to gain and maintain access to compromised web
|
|
15
|
+
servers.
|
|
16
|
+
"""
|
|
17
|
+
from = "now-9m"
|
|
18
|
+
index = ["logs-endpoint.events.*", "logs-network_traffic.*"]
|
|
19
|
+
language = "eql"
|
|
20
|
+
license = "Elastic License v2"
|
|
21
|
+
name = "Initial Access via File Upload Followed by GET Request"
|
|
22
|
+
note = """## Triage and analysis
|
|
23
|
+
|
|
24
|
+
> **Disclaimer**:
|
|
25
|
+
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
|
|
26
|
+
|
|
27
|
+
### Investigating Initial Access via File Upload Followed by GET Request
|
|
28
|
+
|
|
29
|
+
This rule flags a common initial-access pattern: a multipart/form-data upload that drops a dynamic web script on a server, followed shortly by a request to execute that file and establish a foothold. Attackers exploit a permissive upload form to plant shell.php or shell.jsp in an uploads or temp directory, then immediately request it to spawn a web shell, enumerate files, and run commands—often leveraging redirects or 2xx/3xx responses that indicate successful placement and access.
|
|
30
|
+
|
|
31
|
+
### Possible investigation steps
|
|
32
|
+
|
|
33
|
+
- Correlate the upload transaction with the server-side file creation and the subsequent access to the same resource, matching timestamps, source IP, and path, and follow any redirects to the final executed file.
|
|
34
|
+
- Retrieve the uploaded artifact from disk, verify it sits in a web-accessible location, inspect content for web shell traits (eval/system/exec, obfuscation, password gates), and record hashes.
|
|
35
|
+
- Examine server process telemetry immediately after the access for interpreter or shell spawns and unexpected outbound connections originating from web server workers.
|
|
36
|
+
- Review application logs and access context to determine whether the upload was authenticated, which account or session performed it, and whether user-agent, referer, or headers deviate from normal clients.
|
|
37
|
+
- Broaden the timeline to identify related uploads, file renames, or repeated requests from the same actor, including parameterized calls that suggest command execution or directory enumeration.
|
|
38
|
+
|
|
39
|
+
### False positive analysis
|
|
40
|
+
|
|
41
|
+
- An authenticated administrator installs a legitimate plugin or module via the application’s upload form, which unpacks or renames .php or .jsp files and then auto-loads a setup page, producing the multipart upload, file creation/rename, and immediate GET pattern.
|
|
42
|
+
- Automated deployment or QA routines upload and deploy a .war or server-side script through a web-based admin interface and then perform health-check or warm-up requests, resulting in the same multipart upload, server-side file creation, and follow-up GET sequence.
|
|
43
|
+
|
|
44
|
+
### Response and remediation
|
|
45
|
+
|
|
46
|
+
- Immediately block access to the uploaded script that was invoked via GET/POST (e.g., /uploads/shell.php) and the source IPs that executed it, restrict the site to allowlisted IPs or maintenance mode, and temporarily disable the upload endpoint.
|
|
47
|
+
- Quarantine and remove the uploaded web shell and any additional executable scripts or WARs in web-accessible directories (uploads, webroot, temp), terminate interpreter or shell processes spawned by the web server account (www-data/nginx/w3wp/tomcat), and revert malicious .htaccess/web.config rewrites.
|
|
48
|
+
- Hunt for persistence and lateral-movement artifacts created after the upload, including recent .php/.jsp/.cgi file creations or renames in static asset folders, cron/systemd tasks, startup scripts, unauthorized admin users or plugins, and remove them.
|
|
49
|
+
- Restore altered application files from known-good backups or redeploy a clean container/VM, rotate database and API credentials stored in config files or environment variables, invalidate active sessions, and only re-enable uploads after confirming execution is blocked in upload directories.
|
|
50
|
+
- Escalate to incident command and privacy/legal if you observe command execution parameters on the uploaded page (?cmd=, ?exec=), shells spawning (/bin/sh, powershell.exe), database dumps, or outbound callbacks from web server processes to external hosts.
|
|
51
|
+
- Harden by storing uploads outside the webroot, denying execution in upload paths (disable PHP/CGI handlers and set noexec permissions), enforcing strict extension/MIME allowlists and AV/sandbox scanning for multipart/form-data, enabling file-integrity alerts on new .php/.jsp in served paths, and deploying WAF rules to block direct requests to uploaded executables.
|
|
52
|
+
"""
|
|
53
|
+
risk_score = 47
|
|
54
|
+
rule_id = "1d306bf0-7bcf-4acd-83fd-042f5711acc9"
|
|
55
|
+
setup = """## Setup
|
|
56
|
+
|
|
57
|
+
This rule requires data coming in from both Elastic Defend (for file events) and Network Packet Capture integrations (for HTTP traffic analysis).
|
|
58
|
+
|
|
59
|
+
### Network Packet Capture Integration Setup
|
|
60
|
+
|
|
61
|
+
**IMPORTANT**: This rule requires HTTP request body capture to be enabled in order to detect the multipart/form-data content containing WebKitFormBoundary indicators. The network traffic integration must be configured to capture HTTP request bodies for POST requests with `multipart/form-data` content type.
|
|
62
|
+
|
|
63
|
+
To enable HTTP request body capture, follow these steps:
|
|
64
|
+
1. Navigate to the Fleet policy leveraging the Network Packet Capture integration in Kibana.
|
|
65
|
+
2. Locate and select the "Network Packet Capture" integration, and edit the integration.
|
|
66
|
+
3. Locate "Change Default", and scroll down to the "HTTP" section.
|
|
67
|
+
4. Enable the "HTTP" toggle to capture HTTP traffic, add the correct ports for your web application, and click "advanced options".
|
|
68
|
+
5. Edit the integration settings to enable HTTP request body capture for POST requests with `multipart/form-data` content type.
|
|
69
|
+
6. Save the integration configuration and wait for the policy to deploy to the agents.
|
|
70
|
+
"""
|
|
71
|
+
severity = "medium"
|
|
72
|
+
tags = [
|
|
73
|
+
"Domain: Endpoint",
|
|
74
|
+
"Domain: Web",
|
|
75
|
+
"Domain: Network",
|
|
76
|
+
"OS: Linux",
|
|
77
|
+
"OS: Windows",
|
|
78
|
+
"OS: macOS",
|
|
79
|
+
"Use Case: Threat Detection",
|
|
80
|
+
"Tactic: Initial Access",
|
|
81
|
+
"Tactic: Persistence",
|
|
82
|
+
"Data Source: Elastic Defend",
|
|
83
|
+
"Data Source: Network Traffic",
|
|
84
|
+
"Resources: Investigation Guide",
|
|
85
|
+
]
|
|
86
|
+
type = "eql"
|
|
87
|
+
query = '''
|
|
88
|
+
sequence by agent.id with maxspan=5m
|
|
89
|
+
[network where
|
|
90
|
+
data_stream.dataset == "network_traffic.http" and
|
|
91
|
+
http.request.method in ("POST", "PUT") and
|
|
92
|
+
/* We can restrict to 200 in the future, but I prefer to broaden the scope and decrease it later if necessary */
|
|
93
|
+
http.response.status_code in (200, 201, 204, 301, 302, 303, 409) and
|
|
94
|
+
/* These should detect most common file upload activities, adhering to browser standards */
|
|
95
|
+
http.request.body.content like "*Content-Disposition: form-data*" and
|
|
96
|
+
http.request.body.content like "*filename=*"
|
|
97
|
+
/* May add a lower/upper boundary limit to reduce FPs in the future, e.g.
|
|
98
|
+
and http.request.body.bytes >= 500
|
|
99
|
+
*/
|
|
100
|
+
]
|
|
101
|
+
[file where
|
|
102
|
+
event.dataset == "endpoint.events.file" and
|
|
103
|
+
event.action in ("creation", "rename") and
|
|
104
|
+
file.extension in ("php", "phtml", "pht", "php5", "asp", "aspx", "jsp", "jspx", "war", "cgi")
|
|
105
|
+
/* We can add file.path values here in the future, if telemetry is noisy */
|
|
106
|
+
]
|
|
107
|
+
[network where
|
|
108
|
+
data_stream.dataset == "network_traffic.http" and
|
|
109
|
+
http.request.method in ("GET", "POST") and
|
|
110
|
+
/* we may restrict to 200, but keeping it broader right now */
|
|
111
|
+
http.response.status_code >= 200 and http.response.status_code < 600 and
|
|
112
|
+
url.extension in ("php", "phtml", "pht", "php5", "asp", "aspx", "jsp", "jspx", "war", "cgi")
|
|
113
|
+
]
|
|
114
|
+
'''
|
|
115
|
+
|
|
116
|
+
[[rule.threat]]
|
|
117
|
+
framework = "MITRE ATT&CK"
|
|
118
|
+
|
|
119
|
+
[[rule.threat.technique]]
|
|
120
|
+
id = "T1190"
|
|
121
|
+
name = "Exploit Public-Facing Application"
|
|
122
|
+
reference = "https://attack.mitre.org/techniques/T1190/"
|
|
123
|
+
|
|
124
|
+
[rule.threat.tactic]
|
|
125
|
+
id = "TA0001"
|
|
126
|
+
name = "Initial Access"
|
|
127
|
+
reference = "https://attack.mitre.org/tactics/TA0001/"
|
|
128
|
+
|
|
129
|
+
[[rule.threat]]
|
|
130
|
+
framework = "MITRE ATT&CK"
|
|
131
|
+
|
|
132
|
+
[[rule.threat.technique]]
|
|
133
|
+
id = "T1505"
|
|
134
|
+
name = "Server Software Component"
|
|
135
|
+
reference = "https://attack.mitre.org/techniques/T1505/"
|
|
136
|
+
|
|
137
|
+
[[rule.threat.technique.subtechnique]]
|
|
138
|
+
id = "T1505.003"
|
|
139
|
+
name = "Web Shell"
|
|
140
|
+
reference = "https://attack.mitre.org/techniques/T1505/003/"
|
|
141
|
+
|
|
142
|
+
[rule.threat.tactic]
|
|
143
|
+
id = "TA0003"
|
|
144
|
+
name = "Persistence"
|
|
145
|
+
reference = "https://attack.mitre.org/tactics/TA0003/"
|
nldcsc_elastic_rules/rules/cross-platform/multiple_alerts_elastic_defend_netsecurity_by_host.toml
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
creation_date = "2025/11/18"
|
|
3
3
|
integration = ["endpoint", "panw", "fortinet_fortigate", "suricata"]
|
|
4
4
|
maturity = "production"
|
|
5
|
-
updated_date = "2025/11/
|
|
5
|
+
updated_date = "2025/11/28"
|
|
6
6
|
|
|
7
7
|
[rule]
|
|
8
8
|
author = ["Elastic"]
|
|
@@ -65,6 +65,9 @@ FROM logs-* metadata _id
|
|
|
65
65
|
Esql.destination_ip_values = VALUES(destination.ip)
|
|
66
66
|
by Esql.source_ip
|
|
67
67
|
| where Esql.event_module_distinct_count >= 2
|
|
68
|
+
| eval concat_module_values = MV_CONCAT(Esql.event_module_values, ",")
|
|
69
|
+
// Make sure an endpoint alert is present along one of the network ones
|
|
70
|
+
| where concat_module_values like "*endpoint*"
|
|
68
71
|
| keep Esql.alerts_count, Esql.source_ip, Esql.destination_ip_values, Esql.host_id_values, Esql.user_name_values, Esql.event_module_values, Esql.message_values, Esql.process_executable_values
|
|
69
72
|
'''
|
|
70
73
|
note = """## Triage and analysis
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
creation_date = "2020/12/21"
|
|
3
3
|
integration = ["endpoint"]
|
|
4
4
|
maturity = "production"
|
|
5
|
-
updated_date = "2025/
|
|
5
|
+
updated_date = "2025/12/08"
|
|
6
6
|
|
|
7
7
|
[rule]
|
|
8
8
|
author = ["Elastic"]
|
|
@@ -17,7 +17,7 @@ from = "now-9m"
|
|
|
17
17
|
index = ["auditbeat-*", "logs-endpoint.events.*"]
|
|
18
18
|
language = "kuery"
|
|
19
19
|
license = "Elastic License v2"
|
|
20
|
-
name = "Modification of Standard Authentication Module or Configuration"
|
|
20
|
+
name = "Deprecated - Modification of Standard Authentication Module or Configuration"
|
|
21
21
|
references = [
|
|
22
22
|
"https://github.com/zephrax/linux-pam-backdoor",
|
|
23
23
|
"https://github.com/eurialo/pambd",
|
|
@@ -39,7 +39,6 @@ tags = [
|
|
|
39
39
|
]
|
|
40
40
|
timestamp_override = "event.ingested"
|
|
41
41
|
type = "new_terms"
|
|
42
|
-
|
|
43
42
|
query = '''
|
|
44
43
|
event.category:file and event.type:change and
|
|
45
44
|
(file.name:pam_*.so or file.path:(/etc/pam.d/* or /private/etc/pam.d/* or /usr/lib64/security/*)) and
|
|
@@ -74,7 +73,7 @@ note = """## Triage and analysis
|
|
|
74
73
|
> **Disclaimer**:
|
|
75
74
|
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
|
|
76
75
|
|
|
77
|
-
### Investigating Modification of Standard Authentication Module or Configuration
|
|
76
|
+
### Investigating Deprecated - Modification of Standard Authentication Module or Configuration
|
|
78
77
|
|
|
79
78
|
Authentication modules, such as PAM (Pluggable Authentication Modules), are crucial for managing user authentication in Linux and macOS environments. Adversaries may exploit these by altering module files or configurations to gain unauthorized access or escalate privileges. The detection rule identifies suspicious changes to these modules, excluding legitimate processes and paths, to flag potential unauthorized modifications.
|
|
80
79
|
|