From 4067ed06f84625f0a4d90291738cbf9013f1074e Mon Sep 17 00:00:00 2001 From: tradebot-elastic <178941316+tradebot-elastic@users.noreply.github.com> Date: Wed, 6 Aug 2025 07:09:56 +0000 Subject: [PATCH 1/2] Update latest docs --- ...oken-used-from-multiple-addresses.asciidoc | 205 +++++++++++++ ...se-denied-models-by-a-single-user.asciidoc | 135 +++++++++ ...exception-errors-by-a-single-user.asciidoc | 139 +++++++++ ...s-within-a-single-blocked-request.asciidoc | 144 +++++++++ ...s-by-a-single-user-over-a-session.asciidoc | 138 +++++++++ ...d-by-a-single-user-over-a-session.asciidoc | 135 +++++++++ ...ls-via-cli-from-a-single-resource.asciidoc | 171 +++++++++++ ...s-ec2-ebs-snapshot-access-removed.asciidoc | 142 +++++++++ ...bs-snapshot-shared-or-made-public.asciidoc | 141 +++++++++ ...egion-describeinstances-api-calls.asciidoc | 144 +++++++++ ...oraccess-policy-attached-to-group.asciidoc | 168 +++++++++++ ...toraccess-policy-attached-to-role.asciidoc | 168 +++++++++++ ...toraccess-policy-attached-to-user.asciidoc | 175 +++++++++++ ...-iam-login-profile-added-for-root.asciidoc | 214 ++++++++++++++ ...bucket-enumeration-or-brute-force.asciidoc | 165 +++++++++++ ...encryption-using-external-kms-key.asciidoc | 147 ++++++++++ ...tic-site-javascript-file-uploaded.asciidoc | 151 ++++++++++ ...i-region-getservicequota-requests.asciidoc | 147 ++++++++++ ...console-login-with-federated-user.asciidoc | 136 +++++++++ ...e-openai-insecure-output-handling.asciidoc | 125 ++++++++ ...truction-via-method-string-access.asciidoc | 180 ++++++++++++ ...-elastic-security-external-alerts.asciidoc | 118 ++++++++ ...ey-retrieval-from-azure-key-vault.asciidoc | 208 +++++++++++++ ...nnections-from-unusual-executable.asciidoc | 190 ++++++++++++ ...kies-generated-for-authentication.asciidoc | 164 +++++++++++ ...e-file-downloads-with-oauth-token.asciidoc | 142 +++++++++ ...brute-force-via-entra-id-sign-ins.asciidoc | 275 ++++++++++++++++++ ...gn-ins-with-suspicious-properties.asciidoc | 168 +++++++++++ ...cessive-account-lockouts-detected.asciidoc | 222 ++++++++++++++ ...-id-mfa-totp-brute-force-attempts.asciidoc | 199 +++++++++++++ ...euse-with-suspicious-graph-access.asciidoc | 200 +++++++++++++ ...a-id-sign-in-brute-force-activity.asciidoc | 265 +++++++++++++++++ ...en-hashes-for-single-okta-session.asciidoc | 148 ++++++++++ ...unt-lockouts-in-short-time-window.asciidoc | 162 +++++++++++ ...cation-events-with-client-address.asciidoc | 162 +++++++++++ ...vents-with-same-device-token-hash.asciidoc | 160 ++++++++++ ...discovery-url-changed-in-entra-id.asciidoc | 127 ++++++++ ...arted-from-different-geolocations.asciidoc | 146 ++++++++++ ...en-count-and-large-response-sizes.asciidoc | 145 +++++++++ ...3-bucket-ransomware-note-uploaded.asciidoc | 153 ++++++++++ ...otential-azure-openai-model-theft.asciidoc | 132 +++++++++ ...denial-of-azure-openai-ml-service.asciidoc | 129 ++++++++ ...ruction-via-environment-variables.asciidoc | 180 ++++++++++++ ...rshell-based-on-alert-correlation.asciidoc | 151 ++++++++++ ...re-driven-ssh-brute-force-attempt.asciidoc | 191 ++++++++++++ ...soft-365-user-account-brute-force.asciidoc | 195 +++++++++++++ ...ng-activity-from-compromised-host.asciidoc | 170 +++++++++++ ...cktick-escaped-variable-expansion.asciidoc | 178 ++++++++++++ ...ia-character-array-reconstruction.asciidoc | 178 ++++++++++++ ...enated-dynamic-command-invocation.asciidoc | 175 +++++++++++ ...high-numeric-character-proportion.asciidoc | 183 ++++++++++++ ...tion-via-invalid-escape-sequences.asciidoc | 184 ++++++++++++ ...-obfuscation-via-reverse-keywords.asciidoc | 177 +++++++++++ ...ion-via-special-character-overuse.asciidoc | 187 ++++++++++++ ...uscation-via-string-concatenation.asciidoc | 181 ++++++++++++ ...obfuscation-via-string-reordering.asciidoc | 195 +++++++++++++ ...ng-activity-from-compromised-host.asciidoc | 160 ++++++++++ ...e-infection-across-multiple-hosts.asciidoc | 117 ++++++++ ...ia-negative-index-string-reversal.asciidoc | 184 ++++++++++++ ...-rare-connection-to-webdav-target.asciidoc | 122 ++++++++ ...t-365-userloggedin-via-oauth-code.asciidoc | 163 +++++++++++ ...oauth-flow-via-auth-broker-to-drs.asciidoc | 227 +++++++++++++++ ...base64-encoding-decoding-activity.asciidoc | 228 +++++++++++++++ ...-execution-from-web-server-parent.asciidoc | 228 +++++++++++++++ ...al-file-transfer-utility-launched.asciidoc | 162 +++++++++++ ...ce-content-filter-blocks-detected.asciidoc | 150 ++++++++++ ...nformation-policy-blocks-detected.asciidoc | 137 +++++++++ ...high-denied-topic-blocks-detected.asciidoc | 137 +++++++++ ...-high-word-policy-blocks-detected.asciidoc | 137 +++++++++ ...ss-spawned-from-web-server-parent.asciidoc | 219 ++++++++++++++ .../prebuilt-rules-8-19-4-appendix.asciidoc | 77 +++++ .../prebuilt-rules-8-19-4-summary.asciidoc | 154 ++++++++++ ...ebuilt-rules-downloadable-updates.asciidoc | 5 + .../prebuilt-rules-reference.asciidoc | 146 +++++----- .../prebuilt-rules/rule-desc-index.asciidoc | 1 - ...oken-used-from-multiple-addresses.asciidoc | 172 ++++++----- ...se-denied-models-by-a-single-user.asciidoc | 29 +- ...exception-errors-by-a-single-user.asciidoc | 32 +- ...s-within-a-single-blocked-request.asciidoc | 35 ++- ...s-by-a-single-user-over-a-session.asciidoc | 28 +- ...d-by-a-single-user-over-a-session.asciidoc | 33 ++- ...ls-via-cli-from-a-single-resource.asciidoc | 30 +- ...s-ec2-ebs-snapshot-access-removed.asciidoc | 41 ++- ...bs-snapshot-shared-or-made-public.asciidoc | 31 +- ...egion-describeinstances-api-calls.asciidoc | 23 +- ...oraccess-policy-attached-to-group.asciidoc | 27 +- ...toraccess-policy-attached-to-role.asciidoc | 27 +- ...toraccess-policy-attached-to-user.asciidoc | 23 +- ...-iam-login-profile-added-for-root.asciidoc | 6 +- ...bucket-enumeration-or-brute-force.asciidoc | 32 +- ...encryption-using-external-kms-key.asciidoc | 41 ++- ...tic-site-javascript-file-uploaded.asciidoc | 41 +-- ...i-region-getservicequota-requests.asciidoc | 45 ++- ...console-login-with-federated-user.asciidoc | 22 +- ...e-openai-insecure-output-handling.asciidoc | 24 +- ...truction-via-method-string-access.asciidoc | 49 +++- .../elastic-security-external-alerts.asciidoc | 2 +- ...ey-retrieval-from-azure-key-vault.asciidoc | 114 ++++---- ...nnections-from-unusual-executable.asciidoc | 70 +++-- ...kies-generated-for-authentication.asciidoc | 38 ++- ...e-file-downloads-with-oauth-token.asciidoc | 41 +-- ...brute-force-via-entra-id-sign-ins.asciidoc | 207 +++++++------ ...gn-ins-with-suspicious-properties.asciidoc | 77 ++++- ...cessive-account-lockouts-detected.asciidoc | 168 ++++++----- ...-id-mfa-totp-brute-force-attempts.asciidoc | 56 ++-- ...euse-with-suspicious-graph-access.asciidoc | 96 +++--- ...a-id-sign-in-brute-force-activity.asciidoc | 186 ++++++------ ...en-hashes-for-single-okta-session.asciidoc | 45 +-- ...unt-lockouts-in-short-time-window.asciidoc | 102 ++++--- ...cation-events-with-client-address.asciidoc | 35 ++- ...vents-with-same-device-token-hash.asciidoc | 37 ++- ...discovery-url-changed-in-entra-id.asciidoc | 24 +- ...arted-from-different-geolocations.asciidoc | 35 ++- ...en-count-and-large-response-sizes.asciidoc | 44 ++- ...3-bucket-ransomware-note-uploaded.asciidoc | 52 ++-- ...otential-azure-openai-model-theft.asciidoc | 28 +- ...denial-of-azure-openai-ml-service.asciidoc | 25 +- ...ruction-via-environment-variables.asciidoc | 49 +++- ...rshell-based-on-alert-correlation.asciidoc | 27 +- ...re-driven-ssh-brute-force-attempt.asciidoc | 39 ++- ...soft-365-user-account-brute-force.asciidoc | 129 ++++---- ...ng-activity-from-compromised-host.asciidoc | 34 ++- ...cktick-escaped-variable-expansion.asciidoc | 46 ++- ...ia-character-array-reconstruction.asciidoc | 44 ++- ...enated-dynamic-command-invocation.asciidoc | 42 ++- ...high-numeric-character-proportion.asciidoc | 59 ++-- ...high-special-character-proportion.asciidoc | 52 ++-- ...tion-via-invalid-escape-sequences.asciidoc | 52 ++-- ...-obfuscation-via-reverse-keywords.asciidoc | 45 ++- ...ion-via-special-character-overuse.asciidoc | 60 ++-- ...uscation-via-string-concatenation.asciidoc | 49 +++- ...obfuscation-via-string-reordering.asciidoc | 66 +++-- ...ng-activity-from-compromised-host.asciidoc | 23 +- ...e-infection-across-multiple-hosts.asciidoc | 6 +- ...ia-negative-index-string-reversal.asciidoc | 51 +++- .../rare-connection-to-webdav-target.asciidoc | 35 ++- ...t-365-userloggedin-via-oauth-code.asciidoc | 80 ++--- ...oauth-flow-via-auth-broker-to-drs.asciidoc | 184 ++++++------ ...base64-encoding-decoding-activity.asciidoc | 74 ++++- ...-execution-from-web-server-parent.asciidoc | 83 ++++-- ...usual-file-creation-by-web-server.asciidoc | 65 +++-- ...al-file-transfer-utility-launched.asciidoc | 24 +- ...ce-content-filter-blocks-detected.asciidoc | 49 +++- ...nformation-policy-blocks-detected.asciidoc | 29 +- ...high-denied-topic-blocks-detected.asciidoc | 29 +- ...-high-word-policy-blocks-detected.asciidoc | 29 +- ...ss-spawned-from-web-server-parent.asciidoc | 77 +++-- docs/index.asciidoc | 2 + 148 files changed, 14557 insertions(+), 1513 deletions(-) create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-access-token-used-from-multiple-addresses.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-detected-multiple-attempts-to-use-denied-models-by-a-single-user.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-detected-multiple-validation-exception-errors-by-a-single-user.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-guardrails-detected-multiple-policy-violations-within-a-single-blocked-request.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-guardrails-detected-multiple-violations-by-a-single-user-over-a-session.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-invocations-without-guardrails-detected-by-a-single-user-over-a-session.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-discovery-api-calls-via-cli-from-a-single-resource.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-ec2-ebs-snapshot-access-removed.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-ec2-ebs-snapshot-shared-or-made-public.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-ec2-multi-region-describeinstances-api-calls.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-group.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-role.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-user.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-iam-login-profile-added-for-root.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-s3-bucket-enumeration-or-brute-force.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-s3-object-encryption-using-external-kms-key.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-s3-static-site-javascript-file-uploaded.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-service-quotas-multi-region-getservicequota-requests.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-signin-single-factor-console-login-with-federated-user.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-azure-openai-insecure-output-handling.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-dynamic-iex-reconstruction-via-method-string-access.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-elastic-security-external-alerts.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-excessive-secret-or-key-retrieval-from-azure-key-vault.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-high-number-of-egress-network-connections-from-unusual-executable.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-high-number-of-okta-device-token-cookies-generated-for-authentication.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-m365-onedrive-excessive-file-downloads-with-oauth-token.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-365-brute-force-via-entra-id-sign-ins.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-concurrent-sign-ins-with-suspicious-properties.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-exccessive-account-lockouts-detected.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-mfa-totp-brute-force-attempts.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-session-reuse-with-suspicious-graph-access.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-sign-in-brute-force-activity.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-multiple-device-token-hashes-for-single-okta-session.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-multiple-microsoft-365-user-account-lockouts-in-short-time-window.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-multiple-okta-user-authentication-events-with-client-address.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-multiple-okta-user-authentication-events-with-same-device-token-hash.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-oidc-discovery-url-changed-in-entra-id.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-okta-user-sessions-started-from-different-geolocations.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-abuse-of-resources-by-high-token-count-and-large-response-sizes.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-aws-s3-bucket-ransomware-note-uploaded.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-azure-openai-model-theft.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-denial-of-azure-openai-ml-service.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-dynamic-iex-reconstruction-via-environment-variables.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-malicious-powershell-based-on-alert-correlation.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-malware-driven-ssh-brute-force-attempt.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-microsoft-365-user-account-brute-force.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-port-scanning-activity-from-compromised-host.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-backtick-escaped-variable-expansion.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-character-array-reconstruction.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-concatenated-dynamic-command-invocation.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-high-numeric-character-proportion.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-invalid-escape-sequences.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-reverse-keywords.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-special-character-overuse.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-string-concatenation.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-string-reordering.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-subnet-scanning-activity-from-compromised-host.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-widespread-malware-infection-across-multiple-hosts.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-powershell-obfuscation-via-negative-index-string-reversal.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-rare-connection-to-webdav-target.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-suspicious-microsoft-365-userloggedin-via-oauth-code.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-suspicious-microsoft-oauth-flow-via-auth-broker-to-drs.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-base64-encoding-decoding-activity.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-command-execution-from-web-server-parent.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-file-transfer-utility-launched.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-high-confidence-content-filter-blocks-detected.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-high-denied-sensitive-information-policy-blocks-detected.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-high-denied-topic-blocks-detected.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-high-word-policy-blocks-detected.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-process-spawned-from-web-server-parent.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-appendix.asciidoc create mode 100644 docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-summary.asciidoc diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-access-token-used-from-multiple-addresses.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-access-token-used-from-multiple-addresses.asciidoc new file mode 100644 index 0000000000..bb6c83ec2a --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-access-token-used-from-multiple-addresses.asciidoc @@ -0,0 +1,205 @@ +[[prebuilt-rule-8-19-4-aws-access-token-used-from-multiple-addresses]] +=== AWS Access Token Used from Multiple Addresses + +This rule identifies potentially suspicious activity by detecting instances where a single IAM user's temporary session token is accessed from multiple IP addresses within a short time frame. Such behavior may suggest that an adversary has compromised temporary credentials and is utilizing them from various locations. To enhance detection accuracy and minimize false positives, the rule incorporates criteria that evaluate unique IP addresses, user agents, cities, and networks. These additional checks help distinguish between legitimate distributed access patterns and potential credential misuse. Detected activities are classified into different types based on the combination of unique indicators, with each classification assigned a fidelity score reflecting the likelihood of malicious behavior. High fidelity scores are given to patterns most indicative of threats, such as multiple unique IPs, networks, cities, and user agents. Medium and low fidelity scores correspond to less severe patterns, enabling security teams to effectively prioritize alerts. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 5m + +*Searches indices from*: now-32m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://www.sygnia.co/blog/sygnia-investigation-bybit-hack/ + +*Tags*: + +* Domain: Cloud +* Data Source: AWS +* Data Source: Amazon Web Services +* Data Source: AWS IAM +* Data Source: AWS CloudTrail +* Tactic: Initial Access +* Use Case: Identity and Access Audit +* Resources: Investigation Guide + +*Version*: 102 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and Analysis* + + + +*Investigating AWS Access Token Used from Multiple Addresses* + + +Access tokens are bound to a single user. Usage from multiple IP addresses may indicate the token was stolen and used elsewhere. By correlating this with additional detection criteria like multiple user agents, different cities, and different networks, we can improve the fidelity of the rule and help to eliminate false positives associated with expected behavior, like dual-stack IPV4/IPV6 usage. + + +*Possible Investigation Steps* + + +- **Identify the IAM User**: Examine the `aws.cloudtrail.user_identity.arn` stored in `user_id` and correlate with the `source.ips` stored in `ip_list` and `unique_ips` count to determine how widely the token was used. +- **Correlate Additional Detection Context**: Examine `activity_type` and `fidelity_score` to determine additional cities, networks or user agents associated with the token usage. +- **Determine Access Key Type**: Examine the `access_key_id` to determine whether the token is short-term (beginning with ASIA) or long-term (beginning with AKIA). +- **Check Recent MFA Events**: Determine whether the user recently enabled MFA, registered devices, or assumed a role using this token. +- **Review Workload Context**: Confirm whether the user was expected to be active across multiple cities, networks or user agent environments. +- **Trace Adversary Movement**: Pivot to related actions (e.g., `s3:ListBuckets`, `iam:ListUsers`, `sts:GetCallerIdentity`) to track further enumeration. + + +*False Positive Analysis* + + +- Automation frameworks that rotate through multiple IPs or cloud functions with dynamic egress IPs may cause this alert to fire. +- Confirm geolocation and workload context before escalating. + + +*Response and Remediation* + + +- **Revoke the Token**: Disable or rotate the IAM credentials and invalidate the temporary session token. +- **Audit the Environment**: Look for signs of lateral movement or data access during the token's validity. +- **Strengthen Controls**: Require MFA for high-privilege actions, restrict access via policy conditions (e.g., IP range or device). + + +*References* + + +- https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html[IAM Long-Term Credentials] +- https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html[STS Temporary Credentials] +- https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html[Using MFA with Temporary Credentials] +- https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-standards-fsbp-controls.html[AWS Threat Detection Use Cases] + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws.cloudtrail* metadata _id, _version, _index +| where @timestamp > now() - 30 minutes + and event.dataset == "aws.cloudtrail" + and aws.cloudtrail.user_identity.arn is not null + and aws.cloudtrail.user_identity.type == "IAMUser" + and source.ip is not null + and not ( + user_agent.original like "%Terraform%" or + user_agent.original like "%Ansible%" or + user_agent.original like "%Pulumni%" + ) + and `source.as.organization.name` != "AMAZON-AES" + and event.provider not in ( + "health.amazonaws.com", "monitoring.amazonaws.com", "notifications.amazonaws.com", + "ce.amazonaws.com", "cost-optimization-hub.amazonaws.com", + "servicecatalog-appregistry.amazonaws.com", "securityhub.amazonaws.com" + ) + +| eval + Esql.time_window_date_trunc = date_trunc(30 minutes, @timestamp), + Esql.aws_cloudtrail_user_identity_arn = aws.cloudtrail.user_identity.arn, + Esql.aws_cloudtrail_user_identity_access_key_id = aws.cloudtrail.user_identity.access_key_id, + Esql.source_ip = source.ip, + Esql.user_agent_original = user_agent.original, + Esql.source_ip_string = to_string(source.ip), + Esql.source_ip_user_agent_pair = concat(Esql.source_ip_string, " - ", user_agent.original), + Esql.source_ip_city_pair = concat(Esql.source_ip_string, " - ", source.geo.city_name), + Esql.source_geo_city_name = source.geo.city_name, + Esql.event_timestamp = @timestamp, + Esql.source_network_org_name = `source.as.organization.name` + +| stats + Esql.event_action_values = values(event.action), + Esql.event_provider_values = values(event.provider), + Esql.aws_cloudtrail_user_identity_access_key_id_values = values(Esql.aws_cloudtrail_user_identity_access_key_id), + Esql.aws_cloudtrail_user_identity_arn_values = values(Esql.aws_cloudtrail_user_identity_arn), + Esql.source_ip_values = values(Esql.source_ip), + Esql.user_agent_original_values = values(Esql.user_agent_original), + Esql.source_ip_user_agent_pair_values = values(Esql.source_ip_user_agent_pair), + Esql.source_geo_city_name_values = values(Esql.source_geo_city_name), + Esql.source_ip_city_pair_values = values(Esql.source_ip_city_pair), + Esql.source_network_org_name_values = values(Esql.source_network_org_name), + Esql.source_ip_count_distinct = count_distinct(Esql.source_ip), + Esql.user_agent_original_count_distinct = count_distinct(Esql.user_agent_original), + Esql.source_geo_city_name_count_distinct = count_distinct(Esql.source_geo_city_name), + Esql.source_network_org_name_count_distinct = count_distinct(Esql.source_network_org_name), + Esql.timestamp_first_seen = min(Esql.event_timestamp), + Esql.timestamp_last_seen = max(Esql.event_timestamp), + Esql.event_count = count() + by Esql.time_window_date_trunc, Esql.aws_cloudtrail_user_identity_access_key_id + +| eval + Esql.activity_type = case( + Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2 and Esql.user_agent_original_count_distinct >= 2, "multiple_ip_network_city_user_agent", + Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2, "multiple_ip_network_city", + Esql.source_ip_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2, "multiple_ip_and_city", + Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2, "multiple_ip_and_network", + Esql.source_ip_count_distinct >= 2 and Esql.user_agent_original_count_distinct >= 2, "multiple_ip_and_user_agent", + "normal_activity" + ), + Esql.activity_fidelity_score = case( + Esql.activity_type == "multiple_ip_network_city_user_agent", "high", + Esql.activity_type == "multiple_ip_network_city", "high", + Esql.activity_type == "multiple_ip_and_city", "medium", + Esql.activity_type == "multiple_ip_and_network", "medium", + Esql.activity_type == "multiple_ip_and_user_agent", "low" + ) + +| keep + Esql.time_window_date_trunc, + Esql.activity_type, + Esql.activity_fidelity_score, + Esql.event_count, + Esql.timestamp_first_seen, + Esql.timestamp_last_seen, + Esql.aws_cloudtrail_user_identity_arn_values, + Esql.aws_cloudtrail_user_identity_access_key_id_values, + Esql.event_action_values, + Esql.event_provider_values, + Esql.source_ip_values, + Esql.user_agent_original_values, + Esql.source_ip_user_agent_pair_values, + Esql.source_geo_city_name_values, + Esql.source_ip_city_pair_values, + Esql.source_network_org_name_values, + Esql.source_ip_count_distinct, + Esql.user_agent_original_count_distinct, + Esql.source_geo_city_name_count_distinct, + Esql.source_network_org_name_count_distinct + +| where Esql.activity_type != "normal_activity" + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Initial Access +** ID: TA0001 +** Reference URL: https://attack.mitre.org/tactics/TA0001/ +* Technique: +** Name: Valid Accounts +** ID: T1078 +** Reference URL: https://attack.mitre.org/techniques/T1078/ +* Sub-technique: +** Name: Cloud Accounts +** ID: T1078.004 +** Reference URL: https://attack.mitre.org/techniques/T1078/004/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-detected-multiple-attempts-to-use-denied-models-by-a-single-user.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-detected-multiple-attempts-to-use-denied-models-by-a-single-user.asciidoc new file mode 100644 index 0000000000..167ddab740 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-detected-multiple-attempts-to-use-denied-models-by-a-single-user.asciidoc @@ -0,0 +1,135 @@ +[[prebuilt-rule-8-19-4-aws-bedrock-detected-multiple-attempts-to-use-denied-models-by-a-single-user]] +=== AWS Bedrock Detected Multiple Attempts to use Denied Models by a Single User + +Identifies multiple successive failed attempts to use denied model resources within AWS Bedrock. This could indicated attempts to bypass limitations of other approved models, or to force an impact on the environment by incurring exhorbitant costs. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: high + +*Risk score*: 73 + +*Runs every*: 10m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-components.html +* https://atlas.mitre.org/techniques/AML.T0015 +* https://atlas.mitre.org/techniques/AML.T0034 +* https://www.elastic.co/security-labs/elastic-advances-llm-security + +*Tags*: + +* Domain: LLM +* Data Source: AWS Bedrock +* Data Source: AWS S3 +* Resources: Investigation Guide +* Use Case: Policy Violation +* Mitre Atlas: T0015 +* Mitre Atlas: T0034 + +*Version*: 5 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating AWS Bedrock Detected Multiple Attempts to use Denied Models by a Single User* + + +Amazon Bedrock is AWS’s managed service that enables developers to build and scale generative AI applications using large foundation models (FMs) from top providers. + +Bedrock offers a variety of pretrained models from Amazon (such as the Titan series), as well as models from providers like Anthropic, Meta, Cohere, and AI21 Labs. + + +*Possible investigation steps* + + +- Identify the user account that attempted to use denied models. +- Investigate other alerts associated with the user account during the past 48 hours. +- Consider the time of day. If the user is a human (not a program or script), did the activity take place during a normal time of day? +- Examine the account's attempts to access Amazon Bedrock models in the last 24 hours. +- If you suspect the account has been compromised, scope potentially compromised assets by tracking Amazon Bedrock model access, prompts generated, and responses to the prompts by the account in the last 24 hours. + + +*False positive analysis* + + +- Verify the user account that attempted to use denied models, is a legitimate misunderstanding by users or overly strict policies. + + +*Response and remediation* + + +- Initiate the incident response process based on the outcome of the triage. +- Disable or limit the account during the investigation and response. +- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context: + - Identify the account role in the cloud environment. + - Identify if the attacker is moving laterally and compromising other Amazon Bedrock Services. + - Identify any regulatory or legal ramifications related to this activity. +- Review the permissions assigned to the implicated user group or role behind these requests to ensure they are authorized and expected to access bedrock and ensure that the least privilege principle is being followed. +- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector. +- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR). + + +==== Setup + + + +*Setup* + + +This rule requires that guardrails are configured in AWS Bedrock. For more information, see the AWS Bedrock documentation: + +https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws_bedrock.invocation-* + +// Filter for access denied errors from GenAI responses +| where gen_ai.response.error_code == "AccessDeniedException" + +// keep ECS and response fields +| keep + user.id, + gen_ai.request.model.id, + cloud.account.id, + gen_ai.response.error_code + +// count total denials per user/model/account +| stats + Esql.ml_response_access_denied_count = count(*) + by + user.id, + gen_ai.request.model.id, + cloud.account.id + +// Filter for users with repeated denials +| where Esql.ml_response_access_denied_count > 3 + +// sort by volume of denials +| sort Esql.ml_response_access_denied_count desc + +---------------------------------- diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-detected-multiple-validation-exception-errors-by-a-single-user.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-detected-multiple-validation-exception-errors-by-a-single-user.asciidoc new file mode 100644 index 0000000000..f4e6aa6c0e --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-detected-multiple-validation-exception-errors-by-a-single-user.asciidoc @@ -0,0 +1,139 @@ +[[prebuilt-rule-8-19-4-aws-bedrock-detected-multiple-validation-exception-errors-by-a-single-user]] +=== AWS Bedrock Detected Multiple Validation Exception Errors by a Single User + +Identifies multiple validation exeception errors within AWS Bedrock. Validation errors occur when you run the InvokeModel or InvokeModelWithResponseStream APIs on a foundation model that uses an incorrect inference parameter or corresponding value. These errors also occur when you use an inference parameter for one model with a model that doesn't have the same API parameter. This could indicate attempts to bypass limitations of other approved models, or to force an impact on the environment by incurring exhorbitant costs. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: high + +*Risk score*: 73 + +*Runs every*: 10m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://atlas.mitre.org/techniques/AML.T0015 +* https://atlas.mitre.org/techniques/AML.T0034 +* https://atlas.mitre.org/techniques/AML.T0046 +* https://www.elastic.co/security-labs/elastic-advances-llm-security + +*Tags*: + +* Domain: LLM +* Data Source: AWS +* Data Source: AWS Bedrock +* Data Source: AWS S3 +* Use Case: Policy Violation +* Mitre Atlas: T0015 +* Mitre Atlas: T0034 +* Mitre Atlas: T0046 +* Resources: Investigation Guide + +*Version*: 5 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating AWS Bedrock Detected Multiple Validation Exception Errors by a Single User* + + +Amazon Bedrock is AWS’s managed service that enables developers to build and scale generative AI applications using large foundation models (FMs) from top providers. + +Bedrock offers a variety of pretrained models from Amazon (such as the Titan series), as well as models from providers like Anthropic, Meta, Cohere, and AI21 Labs. + + +*Possible investigation steps* + + +- Identify the user account that caused validation errors in accessing the Amazon Bedrock models. +- Investigate other alerts associated with the user account during the past 48 hours. +- Consider the time of day. If the user is a human (not a program or script), did the activity take place during a normal time of day? +- Examine the account's attempts to access Amazon Bedrock models in the last 24 hours. +- If you suspect the account has been compromised, scope potentially compromised assets by tracking Amazon Bedrock model access, prompts generated, and responses to the prompts by the account in the last 24 hours. + + +*False positive analysis* + + +- Verify the user account that that caused validation errors is a legitimate misunderstanding by users on accessing the bedrock models. + + +*Response and remediation* + + +- Initiate the incident response process based on the outcome of the triage. +- Disable or limit the account during the investigation and response. +- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context: + - Identify the account role in the cloud environment. + - Identify if the attacker is moving laterally and compromising other Amazon Bedrock Services. + - Identify any regulatory or legal ramifications related to this activity. + - Identify if any implication to resource billing. +- Review the permissions assigned to the implicated user group or role behind these requests to ensure they are authorized and expected to access bedrock and ensure that the least privilege principle is being followed. +- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector. +- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR). + + +==== Setup + + + +*Setup* + + +This rule requires that AWS Bedrock Integration be configured. For more information, see the AWS Bedrock integration documentation: + +https://www.elastic.co/docs/current/integrations/aws_bedrock + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws_bedrock.invocation-* + +// Truncate timestamp to 1-minute window +| eval Esql.time_window_date_trunc = date_trunc(1 minutes, @timestamp) + +// Filter for validation exceptions in responses +| where gen_ai.response.error_code == "ValidationException" + +// keep relevant ECS and derived fields +| keep + user.id, + gen_ai.request.model.id, + cloud.account.id, + gen_ai.response.error_code, + Esql.time_window_date_trunc + +// count number of denials by user/account/time window +| stats + Esql.ml_response_validation_error_count = count(*) + by + Esql.time_window_date_trunc, + user.id, + cloud.account.id + +// Filter for excessive errors +| where Esql.ml_response_validation_error_count > 3 + +---------------------------------- diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-guardrails-detected-multiple-policy-violations-within-a-single-blocked-request.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-guardrails-detected-multiple-policy-violations-within-a-single-blocked-request.asciidoc new file mode 100644 index 0000000000..683822b116 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-guardrails-detected-multiple-policy-violations-within-a-single-blocked-request.asciidoc @@ -0,0 +1,144 @@ +[[prebuilt-rule-8-19-4-aws-bedrock-guardrails-detected-multiple-policy-violations-within-a-single-blocked-request]] +=== AWS Bedrock Guardrails Detected Multiple Policy Violations Within a Single Blocked Request + +Identifies multiple violations of AWS Bedrock guardrails within a single request, resulting in a block action, increasing the likelihood of malicious intent. Multiple violations implies that a user may be intentionally attempting to cirvumvent security controls, access sensitive information, or possibly exploit a vulnerability in the system. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 10m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-components.html +* https://atlas.mitre.org/techniques/AML.T0051 +* https://atlas.mitre.org/techniques/AML.T0054 +* https://www.elastic.co/security-labs/elastic-advances-llm-security + +*Tags*: + +* Domain: LLM +* Data Source: AWS Bedrock +* Data Source: AWS S3 +* Resources: Investigation Guide +* Use Case: Policy Violation +* Mitre Atlas: T0051 +* Mitre Atlas: T0054 + +*Version*: 5 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating AWS Bedrock Guardrails Detected Multiple Policy Violations Within a Single Blocked Request* + + +Amazon Bedrock Guardrail is a set of features within Amazon Bedrock designed to help businesses apply robust safety and privacy controls to their generative AI applications. + +It enables users to set guidelines and filters that manage content quality, relevancy, and adherence to responsible AI practices. + +Through Guardrail, organizations can define "denied topics" to prevent the model from generating content on specific, undesired subjects, +and they can establish thresholds for harmful content categories, including hate speech, violence, or offensive language. + + +*Possible investigation steps* + + +- Identify the user account and the user request that caused multiple policy violations and whether it should perform this kind of action. +- Investigate the user activity that might indicate a potential brute force attack. +- Investigate other alerts associated with the user account during the past 48 hours. +- Consider the time of day. If the user is a human (not a program or script), did the activity take place during a normal time of day? +- Examine the account's prompts and responses in the last 24 hours. +- If you suspect the account has been compromised, scope potentially compromised assets by tracking Amazon Bedrock model access, prompts generated, and responses to the prompts by the account in the last 24 hours. + + +*False positive analysis* + + +- Verify the user account that caused multiple policy violations, is not testing any new model deployments or updated compliance policies in Amazon Bedrock guardrails. + + +*Response and remediation* + + +- Initiate the incident response process based on the outcome of the triage. +- Disable or limit the account during the investigation and response. +- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context: + - Identify the account role in the cloud environment. + - Identify if the attacker is moving laterally and compromising other Amazon Bedrock Services. + - Identify any regulatory or legal ramifications related to this activity. +- Review the permissions assigned to the implicated user group or role behind these requests to ensure they are authorized and expected to access bedrock and ensure that the least privilege principle is being followed. +- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector. +- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR). + + +==== Setup + + + +*Setup* + + +This rule requires that guardrails are configured in AWS Bedrock. For more information, see the AWS Bedrock documentation: + +https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws_bedrock.invocation-* + +// Filter for policy-blocked requests +| where gen_ai.policy.action == "BLOCKED" + +// count number of policy matches per request (multi-valued) +| eval Esql.ml_policy_violations_mv_count = mv_count(gen_ai.policy.name) + +// Filter for requests with more than one policy match +| where Esql.ml_policy_violations_mv_count > 1 + +// keep relevant fields +| keep + gen_ai.policy.action, + Esql.ml_policy_violations_mv_count, + user.id, + gen_ai.request.model.id, + cloud.account.id + +// Aggregate requests with multiple violations +| stats + Esql.ml_policy_violations_total_unique_requests_count = count(*) + by + Esql.ml_policy_violations_mv_count, + user.id, + gen_ai.request.model.id, + cloud.account.id + +// sort by number of unique requests +| sort Esql.ml_policy_violations_total_unique_requests_count desc + +---------------------------------- diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-guardrails-detected-multiple-violations-by-a-single-user-over-a-session.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-guardrails-detected-multiple-violations-by-a-single-user-over-a-session.asciidoc new file mode 100644 index 0000000000..d77a4aff10 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-guardrails-detected-multiple-violations-by-a-single-user-over-a-session.asciidoc @@ -0,0 +1,138 @@ +[[prebuilt-rule-8-19-4-aws-bedrock-guardrails-detected-multiple-violations-by-a-single-user-over-a-session]] +=== AWS Bedrock Guardrails Detected Multiple Violations by a Single User Over a Session + +Identifies multiple violations of AWS Bedrock guardrails by the same user in the same account over a session. Multiple violations implies that a user may be intentionally attempting to cirvumvent security controls, access sensitive information, or possibly exploit a vulnerability in the system. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 10m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-components.html +* https://atlas.mitre.org/techniques/AML.T0051 +* https://atlas.mitre.org/techniques/AML.T0054 +* https://www.elastic.co/security-labs/elastic-advances-llm-security + +*Tags*: + +* Domain: LLM +* Data Source: AWS Bedrock +* Data Source: AWS S3 +* Resources: Investigation Guide +* Use Case: Policy Violation +* Mitre Atlas: T0051 +* Mitre Atlas: T0054 + +*Version*: 6 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating AWS Bedrock Guardrails Detected Multiple Violations by a Single User Over a Session* + + +Amazon Bedrock Guardrail is a set of features within Amazon Bedrock designed to help businesses apply robust safety and privacy controls to their generative AI applications. + +It enables users to set guidelines and filters that manage content quality, relevancy, and adherence to responsible AI practices. + +Through Guardrail, organizations can define "denied topics" to prevent the model from generating content on specific, undesired subjects, +and they can establish thresholds for harmful content categories, including hate speech, violence, or offensive language. + + +*Possible investigation steps* + + +- Identify the user account that caused multiple policy violations over a session and whether it should perform this kind of action. +- Investigate the user activity that might indicate a potential brute force attack. +- Investigate other alerts associated with the user account during the past 48 hours. +- Consider the time of day. If the user is a human (not a program or script), did the activity take place during a normal time of day? +- Examine the account's prompts and responses in the last 24 hours. +- If you suspect the account has been compromised, scope potentially compromised assets by tracking Amazon Bedrock model access, prompts generated, and responses to the prompts by the account in the last 24 hours. + + +*False positive analysis* + + +- Verify the user account that caused multiple policy violations by a single user over session, is not testing any new model deployments or updated compliance policies in Amazon Bedrock guardrails. + + +*Response and remediation* + + +- Initiate the incident response process based on the outcome of the triage. +- Disable or limit the account during the investigation and response. +- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context: + - Identify the account role in the cloud environment. + - Identify if the attacker is moving laterally and compromising other Amazon Bedrock Services. + - Identify any regulatory or legal ramifications related to this activity. +- Review the permissions assigned to the implicated user group or role behind these requests to ensure they are authorized and expected to access bedrock and ensure that the least privilege principle is being followed. +- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector. +- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR). + + +==== Setup + + + +*Setup* + + +This rule requires that guardrails are configured in AWS Bedrock. For more information, see the AWS Bedrock documentation: + +https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws_bedrock.invocation-* + +// Filter for compliance violations detected +| where gen_ai.compliance.violation_detected + +// keep relevant ECS + model fields +| keep + user.id, + gen_ai.request.model.id, + cloud.account.id + +// count violations by user, model, and account +| stats + Esql.ml_violations_count = count(*) + by + user.id, + gen_ai.request.model.id, + cloud.account.id + +// Filter for repeated violations +| where Esql.ml_violations_count > 1 + +// sort descending by violation volume +| sort Esql.ml_violations_count desc + +---------------------------------- diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-invocations-without-guardrails-detected-by-a-single-user-over-a-session.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-invocations-without-guardrails-detected-by-a-single-user-over-a-session.asciidoc new file mode 100644 index 0000000000..5a6a134c43 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-bedrock-invocations-without-guardrails-detected-by-a-single-user-over-a-session.asciidoc @@ -0,0 +1,135 @@ +[[prebuilt-rule-8-19-4-aws-bedrock-invocations-without-guardrails-detected-by-a-single-user-over-a-session]] +=== AWS Bedrock Invocations without Guardrails Detected by a Single User Over a Session + +Identifies multiple AWS Bedrock executions in a one minute time window without guardrails by the same user in the same account over a session. Multiple consecutive executions implies that a user may be intentionally attempting to bypass security controls, by not routing the requests with the desired guardrail configuration in order to access sensitive information, or possibly exploit a vulnerability in the system. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 10m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-components.html +* https://atlas.mitre.org/techniques/AML.T0051 +* https://atlas.mitre.org/techniques/AML.T0054 +* https://www.elastic.co/security-labs/elastic-advances-llm-security + +*Tags*: + +* Domain: LLM +* Data Source: AWS Bedrock +* Data Source: AWS S3 +* Resources: Investigation Guide +* Use Case: Policy Violation +* Mitre Atlas: T0051 +* Mitre Atlas: T0054 + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating AWS Bedrock Invocations without Guardrails Detected by a Single User Over a Session* + + +Using Amazon Bedrock Guardrails during model invocation is critical for ensuring the safe, reliable, and ethical use of AI models. +Guardrails help manage risks associated with AI usage and ensure the output aligns with desired policies and standards. + + +*Possible investigation steps* + + +- Identify the user account that caused multiple model violations over a session without desired guardrail configuration and whether it should perform this kind of action. +- Investigate the user activity that might indicate a potential brute force attack. +- Investigate other alerts associated with the user account during the past 48 hours. +- Consider the time of day. If the user is a human (not a program or script), did the activity take place during a normal time of day? +- Examine the account's prompts and responses in the last 24 hours. +- If you suspect the account has been compromised, scope potentially compromised assets by tracking Amazon Bedrock model access, prompts generated, and responses to the prompts by the account in the last 24 hours. + + +*False positive analysis* + + +- Verify the user account that caused multiple policy violations by a single user over session, is not testing any new model deployments or updated compliance policies in Amazon Bedrock guardrails. + + +*Response and remediation* + + +- Initiate the incident response process based on the outcome of the triage. +- Disable or limit the account during the investigation and response. +- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context: + - Identify the account role in the cloud environment. + - Identify if the attacker is moving laterally and compromising other Amazon Bedrock Services. + - Identify any regulatory or legal ramifications related to this activity. +- Review the permissions assigned to the implicated user group or role behind these requests to ensure they are authorized and expected to access bedrock and ensure that the least privilege principle is being followed. +- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector. +- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR). + + +==== Setup + + + +*Setup* + + +This rule requires that guardrails are configured in AWS Bedrock. For more information, see the AWS Bedrock documentation: + +https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws_bedrock.invocation-* + +// Create 1-minute time buckets +| eval Esql.time_window_date_trunc = date_trunc(1 minute, @timestamp) + +// Filter for invocations without guardrails +| where gen_ai.guardrail_id is null and user.id is not null + +// keep only relevant fields +| keep + @timestamp, + Esql.time_window_date_trunc, + gen_ai.guardrail_id, + user.id + +// count number of unsafe invocations per user +| stats + Esql.ml_invocations_no_guardrails_count = count() + by user.id + +// Filter for suspicious volume +| where Esql.ml_invocations_no_guardrails_count > 5 + +// sort descending +| sort Esql.ml_invocations_no_guardrails_count desc + +---------------------------------- diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-discovery-api-calls-via-cli-from-a-single-resource.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-discovery-api-calls-via-cli-from-a-single-resource.asciidoc new file mode 100644 index 0000000000..316d5e8f11 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-discovery-api-calls-via-cli-from-a-single-resource.asciidoc @@ -0,0 +1,171 @@ +[[prebuilt-rule-8-19-4-aws-discovery-api-calls-via-cli-from-a-single-resource]] +=== AWS Discovery API Calls via CLI from a Single Resource + +Detects when a single AWS resource is running multiple `Describe` and `List` API calls in a 10-second window. This behavior could indicate an actor attempting to discover the AWS infrastructure using compromised credentials or a compromised instance. Adversaries may use this information to identify potential targets for further exploitation or to gain a better understanding of the target's infrastructure. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://stratus-red-team.cloud/attack-techniques/AWS/aws.discovery.ec2-enumerate-from-instance/ + +*Tags*: + +* Domain: Cloud +* Data Source: AWS +* Data Source: AWS EC2 +* Data Source: AWS IAM +* Data Source: AWS S3 +* Use Case: Threat Detection +* Tactic: Discovery +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating AWS Discovery API Calls via CLI from a Single Resource* + + +This rule detects multiple discovery-related API calls (`Describe`, `List`, or `Get` actions) within a short time window (30 seconds) from a single AWS resource. High volumes of such calls may indicate attempts to enumerate AWS infrastructure for reconnaissance purposes, which is often a tactic used by adversaries with compromised credentials or unauthorized access. + + +*Possible Investigation Steps* + + +- **Identify the Actor and Resource**: + - **User Identity and Resource**: Examine `aws.cloudtrail.user_identity.arn` to identify the actor making the discovery requests. Verify the user or resource associated with these actions to ensure they are recognized and expected. + - **User Agent and Tooling**: Check `user_agent.name` to confirm whether the `aws-cli` tool was used for these requests. Use of the CLI in an atypical context might indicate unauthorized or automated access. + +- **Evaluate the Context and Scope of API Calls**: + - **API Action Types**: Look into the specific actions under `event.action` for API calls like `Describe*`, `List*`, or `Get*`. Note if these calls are targeting sensitive services, such as `EC2`, `IAM`, or `S3`, which may suggest an attempt to identify high-value assets. + - **Time Pattern Analysis**: Review the `time_window` and `unique_api_count` to assess whether the frequency of these calls is consistent with normal patterns for this resource or user. + +- **Analyze Potential Compromise Indicators**: + - **Identity Type**: Review `aws.cloudtrail.user_identity.type` to determine if the calls originated from an assumed role, a root user, or a service role. Unusual identity types for discovery operations may suggest misuse or compromise. + - **Source IP and Geographic Location**: Examine the `source.ip` and `source.geo` fields to identify any unusual IP addresses or locations associated with the activity, which may help confirm or rule out external access. + +- **Examine Related CloudTrail Events**: + - **Pivot for Related Events**: Identify any additional IAM or CloudTrail events tied to the same actor ARN. Activities such as `AssumeRole`, `GetSessionToken`, or `CreateAccessKey` in proximity to these discovery calls may signal an attempt to escalate privileges. + - **Look for Anomalous Patterns**: Determine if this actor or resource has performed similar discovery actions previously, or if these actions coincide with other alerts related to credential use or privilege escalation. + + +*False Positive Analysis* + + +- **Expected Discovery Activity**: Regular discovery or enumeration API calls may be conducted by security, automation, or monitoring scripts to maintain an inventory of resources. Validate if this activity aligns with known automation or inventory tasks. +- **Routine Admin or Automated Access**: If specific roles or resources, such as automation tools or monitoring services, regularly trigger this rule, consider adding exceptions for these known, benign users to reduce false positives. + + +*Response and Remediation* + + +- **Confirm Authorized Access**: If the discovery activity appears unauthorized, consider immediate steps to restrict the user or resource’s permissions. +- **Review and Remove Unauthorized API Calls**: If the actor is not authorized to perform discovery actions, investigate and potentially disable their permissions or access keys to prevent further misuse. +- **Enhance Monitoring for Discovery Patterns**: Consider additional logging or alerting for high-frequency discovery API calls, especially if triggered from new or unrecognized resources. +- **Policy Review and Updates**: Review IAM policies associated with the actor, ensuring restrictive permissions and MFA enforcement where possible to prevent unauthorized discovery. + + +*Additional Information* + + +For further guidance on AWS infrastructure discovery and best practices, refer to https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference.html[AWS CloudTrail documentation] and MITRE ATT&CK’s https://attack.mitre.org/techniques/T1580/[Cloud Infrastructure Discovery]. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws.cloudtrail* + +// create time window buckets of 10 seconds +| eval Esql.time_window_date_trunc = date_trunc(10 seconds, @timestamp) +| where + event.dataset == "aws.cloudtrail" + + // filter on CloudTrail audit logs for IAM, EC2, S3, etc. + and event.provider in ( + "iam.amazonaws.com", + "ec2.amazonaws.com", + "s3.amazonaws.com", + "rds.amazonaws.com", + "lambda.amazonaws.com", + "dynamodb.amazonaws.com", + "kms.amazonaws.com", + "cloudfront.amazonaws.com", + "elasticloadbalancing.amazonaws.com" + ) + + // ignore AWS service actions + and aws.cloudtrail.user_identity.type != "AWSService" + + // filter for aws-cli specifically + and user_agent.name == "aws-cli" + + // exclude DescribeCapacityReservations events related to AWS Config + and not event.action in ("DescribeCapacityReservations") + +// filter for Describe, Get, List, and Generate API calls +| where true in ( + starts_with(event.action, "Describe"), + starts_with(event.action, "Get"), + starts_with(event.action, "List"), + starts_with(event.action, "Generate") +) + +// extract owner, identity type, and actor from the ARN +| dissect aws.cloudtrail.user_identity.arn "%{}::%{Esql_priv.aws_cloudtrail_user_identity_arn_owner}:%{Esql.aws_cloudtrail_user_identity_arn_type}/%{Esql.aws_cloudtrail_user_identity_arn_roles}" +| where starts_with(Esql.aws_cloudtrail_user_identity_arn_roles, "AWSServiceRoleForConfig") != true + +// keep relevant fields (preserving ECS fields and computed time window) +| keep @timestamp, Esql.time_window_date_trunc, event.action, aws.cloudtrail.user_identity.arn + +// count the number of unique API calls per time window and actor +| stats + Esql.event_action_count_distinct = count_distinct(event.action) + by Esql.time_window_date_trunc, aws.cloudtrail.user_identity.arn + +// filter for more than 5 unique API calls per 10s window +| where Esql.event_action_count_distinct > 5 + +// sort the results by the number of unique API calls in descending order +| sort Esql.event_action_count_distinct desc + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Discovery +** ID: TA0007 +** Reference URL: https://attack.mitre.org/tactics/TA0007/ +* Technique: +** Name: Cloud Infrastructure Discovery +** ID: T1580 +** Reference URL: https://attack.mitre.org/techniques/T1580/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-ec2-ebs-snapshot-access-removed.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-ec2-ebs-snapshot-access-removed.asciidoc new file mode 100644 index 0000000000..dbff7db238 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-ec2-ebs-snapshot-access-removed.asciidoc @@ -0,0 +1,142 @@ +[[prebuilt-rule-8-19-4-aws-ec2-ebs-snapshot-access-removed]] +=== AWS EC2 EBS Snapshot Access Removed + +Identifies the removal of access permissions from a shared AWS EC2 EBS snapshot. EBS snapshots are essential for data retention and disaster recovery. Adversaries may revoke or modify snapshot permissions to prevent legitimate users from accessing backups, thereby obstructing recovery efforts after data loss or destructive actions. This tactic can also be used to evade detection or maintain exclusive access to critical backups, ultimately increasing the impact of an attack and complicating incident response. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-6m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://docs.aws.amazon.com/ebs/latest/userguide/ebs-modifying-snapshot-permissions.html +* https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_ModifySnapshotAttribute.html + +*Tags*: + +* Domain: Cloud +* Data Source: AWS +* Data Source: Amazon Web Services +* Data Source: AWS EC2 +* Use Case: Threat Detection +* Tactic: Impact +* Resources: Investigation Guide + +*Version*: 2 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating AWS EC2 EBS Snapshot Access Removed* + + +This rule detects when access is removed for an AWS EC2 EBS snapshot. EBS virtual disks can be copied into snapshots, which can then be used as backups for recovery and data retention efforts. Adversaries may attempt to remove access to snapshots in order to prevent legitimate users or automated processes from accessing or restoring from snapshots following data loss, ransomware, or destructive actions. This can significantly delay or even prevent recovery, increasing the impact of the attack. +Restricting snapshot access may help adversaries cover their tracks by making it harder for defenders to analyze or recover deleted or altered data. Attackers may remove permissions for all users except their own compromised account, allowing them to maintain exclusive access to backups for future use or leverage. Understanding the context and legitimacy of such changes is crucial to determine if the action is benign or malicious. + + +*Possible Investigation Steps:* + + +- **Identify the Actor**: Review the `aws.cloudtrail.user_identity.arn` and `aws.cloudtrail.user_identity.access_key_id` fields to identify who made the change. Verify if this actor typically performs such actions and if they should have the necessary permissions. +- **Review the Request Details**: Examine the `aws.cloudtrail.request_parameters` to understand the specific changes made to the snapshot permissions. Look for any unusual parameters that could suggest unauthorized or malicious modifications. +- **Analyze the Source of the Request**: Investigate the `source.ip` and `source.geo` fields to determine the geographical origin of the request. An external or unexpected location might indicate compromised credentials or unauthorized access. +- **Contextualize with Timestamp**: Use the `@timestamp` field to check when the change occurred. Modifications during non-business hours or outside regular maintenance windows might require further scrutiny. +- **Correlate with Other Activities**: Search for related CloudTrail events before and after this change to see if the same actor or IP address engaged in other potentially suspicious activities. In particular, use the `snapshotId` to see if this snapshot was shared with an unauthorized account. +- **Review UserID**: Check the `userId` field to identify which user's permissions were removed. Verify if this account should be authorized to access the data or if the access removal is expected. + + +*False Positive Analysis:* + + +- **Legitimate Administrative Actions**: Confirm if the snapshot sharing aligns with scheduled updates, development activities, or legitimate administrative tasks documented in change management systems. +- **Consistency Check**: Compare the action against historical data of similar actions performed by the user or within the organization. If the action is consistent with past legitimate activities, it might indicate a false alarm. + + +*Response and Remediation:* + + +- **Immediate Review and Reversal if Necessary**: If the change was unauthorized, update the snapshot permissions to restore it to its previous state. +- **Enhance Monitoring and Alerts**: Adjust monitoring systems to alert on similar actions, especially those involving sensitive data or permissions. +- **Educate and Train**: Provide additional training to users with administrative rights on the importance of security best practices concerning snapshot management and sharing permissions. +- **Audit Snapshots and Policies**: Conduct a comprehensive audit of all snapshots and associated policies to ensure they adhere to the principle of least privilege. +- **Incident Response**: If there's an indication of malicious intent or a security breach, initiate the incident response protocol to mitigate any damage and prevent future occurrences. + + +*Additional Information:* + + +For further guidance on managing EBS snapshots and securing AWS environments, refer to the https://docs.aws.amazon.com/ebs/latest/userguide/ebs-modifying-snapshot-permissions.html[AWS EBS documentation] and AWS best practices for security. Additionally, consult the following resources for specific details on EBS snapshot security: +- https://docs.aws.amazon.com/ebs/latest/userguide/ebs-modifying-snapshot-permissions.html[AWS EBS Snapshot Permissions] +- https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_ModifySnapshotAttribute.html[AWS API ModifySnapshotAttribute] + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws.cloudtrail-* metadata _id, _version, _index + +// Filter for successful snapshot modifications +| where + event.provider == "ec2.amazonaws.com" + and event.action == "ModifySnapshotAttribute" + and event.outcome == "success" + +// dissect parameters to extract key fields +| dissect aws.cloudtrail.request_parameters + "{%{?snapshotId}=%{Esql.aws_cloudtrail_request_parameters_snapshot_id},%{?attributeType}=%{Esql.aws_cloudtrail_request_parameters_attribute_type},%{?createVolumePermission}={%{Esql.aws_cloudtrail_request_parameters_operation_type}={%{?items}=[{%{?userId}=%{Esql_priv.aws_cloudtrail_request_parameters_user_id}}]}}}" + +// Match on snapshot permission **removal** +| where Esql.aws_cloudtrail_request_parameters_operation_type == "remove" + +// keep ECS and derived fields +| keep + @timestamp, + aws.cloudtrail.user_identity.arn, + cloud.account.id, + event.action, + Esql.aws_cloudtrail_request_parameters_snapshot_id, + Esql.aws_cloudtrail_request_parameters_attribute_type, + Esql.aws_cloudtrail_request_parameters_operation_type, + Esql_priv.aws_cloudtrail_request_parameters_user_id, + source.address + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Impact +** ID: TA0040 +** Reference URL: https://attack.mitre.org/tactics/TA0040/ +* Technique: +** Name: Data Destruction +** ID: T1485 +** Reference URL: https://attack.mitre.org/techniques/T1485/ +* Technique: +** Name: Inhibit System Recovery +** ID: T1490 +** Reference URL: https://attack.mitre.org/techniques/T1490/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-ec2-ebs-snapshot-shared-or-made-public.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-ec2-ebs-snapshot-shared-or-made-public.asciidoc new file mode 100644 index 0000000000..44d6d406fb --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-ec2-ebs-snapshot-shared-or-made-public.asciidoc @@ -0,0 +1,141 @@ +[[prebuilt-rule-8-19-4-aws-ec2-ebs-snapshot-shared-or-made-public]] +=== AWS EC2 EBS Snapshot Shared or Made Public + +Identifies AWS EC2 EBS snaphots being shared with another AWS account or made public. EBS virtual disks can be copied into snapshots, which can then be shared with an external AWS account or made public. Adversaries may attempt this in order to copy the snapshot into an environment they control, to access the data. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-6m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://docs.aws.amazon.com/ebs/latest/userguide/ebs-modifying-snapshot-permissions.html +* https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_ModifySnapshotAttribute.html +* https://cloud.hacktricks.xyz/pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ebs-snapshot-dump +* https://hackingthe.cloud/aws/exploitation/Misconfigured_Resource-Based_Policies/exploting_public_resources_attack_playbook/ + +*Tags*: + +* Domain: Cloud +* Data Source: AWS +* Data Source: Amazon Web Services +* Data Source: AWS EC2 +* Use Case: Threat Detection +* Tactic: Exfiltration +* Resources: Investigation Guide + +*Version*: 7 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating AWS EC2 EBS Snapshot Shared or Made Public* + + +This rule detects when an AWS EC2 EBS snapshot is shared with another AWS account or made public. EBS virtual disks can be copied into snapshots, which can then be shared with an external AWS account or made public. Adversaries may attempt this to copy the snapshot into an environment they control to access the data. Understanding the context and legitimacy of such changes is crucial to determine if the action is benign or malicious. + + +*Possible Investigation Steps:* + + +- **Identify the Actor**: Review the `aws.cloudtrail.user_identity.arn` and `aws.cloudtrail.user_identity.access_key_id` fields to identify who made the change. Verify if this actor typically performs such actions and if they have the necessary permissions. +- **Review the Request Details**: Examine the `aws.cloudtrail.request_parameters` to understand the specific changes made to the snapshot permissions. Look for any unusual parameters that could suggest unauthorized or malicious modifications. +- **Analyze the Source of the Request**: Investigate the `source.ip` and `source.geo` fields to determine the geographical origin of the request. An external or unexpected location might indicate compromised credentials or unauthorized access. +- **Contextualize with Timestamp**: Use the `@timestamp` field to check when the change occurred. Modifications during non-business hours or outside regular maintenance windows might require further scrutiny. +- **Correlate with Other Activities**: Search for related CloudTrail events before and after this change to see if the same actor or IP address engaged in other potentially suspicious activities. +- **Review UserID**: Check the `userId` field to identify the AWS account with which the snapshot was shared. Verify if this account is authorized to access the data or if it belongs to a known third party. If this value is `all`, the snapshot is made public. + + +*False Positive Analysis:* + + +- **Legitimate Administrative Actions**: Confirm if the snapshot sharing aligns with scheduled updates, development activities, or legitimate administrative tasks documented in change management systems. +- **Consistency Check**: Compare the action against historical data of similar actions performed by the user or within the organization. If the action is consistent with past legitimate activities, it might indicate a false alarm. +- **Verify through Outcomes**: Check the `aws.cloudtrail.response_elements` and the `event.outcome` to confirm if the change was successful and intended according to policy. + + +*Response and Remediation:* + + +- **Immediate Review and Reversal if Necessary**: If the change was unauthorized, update the snapshot permissions to remove any unauthorized accounts and restore it to its previous state. +- **Enhance Monitoring and Alerts**: Adjust monitoring systems to alert on similar actions, especially those involving sensitive data or permissions. +- **Educate and Train**: Provide additional training to users with administrative rights on the importance of security best practices concerning snapshot management and sharing permissions. +- **Audit Snapshots and Policies**: Conduct a comprehensive audit of all snapshots and associated policies to ensure they adhere to the principle of least privilege. +- **Incident Response**: If there's an indication of malicious intent or a security breach, initiate the incident response protocol to mitigate any damage and prevent future occurrences. + + +*Additional Information:* + + +For further guidance on managing EBS snapshots and securing AWS environments, refer to the https://docs.aws.amazon.com/ebs/latest/userguide/ebs-modifying-snapshot-permissions.html[AWS EBS documentation] and AWS best practices for security. Additionally, consult the following resources for specific details on EBS snapshot security: +- https://docs.aws.amazon.com/ebs/latest/userguide/ebs-modifying-snapshot-permissions.html[AWS EBS Snapshot Permissions] +- https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_ModifySnapshotAttribute.html[AWS API ModifySnapshotAttribute] +- https://cloud.hacktricks.xyz/pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ebs-snapshot-dump[AWS EBS Snapshot Dump] + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws.cloudtrail-* metadata _id, _version, _index +| where + event.provider == "ec2.amazonaws.com" + and event.action == "ModifySnapshotAttribute" + and event.outcome == "success" + +// Extract snapshotId, attribute type, operation type, and userId +| dissect aws.cloudtrail.request_parameters + "{%{?snapshotId}=%{Esql.aws_cloudtrail_request_parameters_snapshot_id},%{?attributeType}=%{Esql.aws_cloudtrail_request_parameters_attribute_type},%{?createVolumePermission}={%{Esql.aws_cloudtrail_request_parameters_operation_type}={%{?items}=[{%{?userId}=%{Esql_priv.aws_cloudtrail_request_parameters_user_id}}]}}}" + +// Check for snapshot permission added for another AWS account +| where + Esql.aws_cloudtrail_request_parameters_operation_type == "add" + and cloud.account.id != Esql_priv.aws_cloudtrail_request_parameters_user_id + +// keep ECS and derived fields +| keep + @timestamp, + aws.cloudtrail.user_identity.arn, + cloud.account.id, + event.action, + Esql.aws_cloudtrail_request_parameters_snapshot_id, + Esql.aws_cloudtrail_request_parameters_attribute_type, + Esql.aws_cloudtrail_request_parameters_operation_type, + Esql_priv.aws_cloudtrail_request_parameters_user_id, + source.ip + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Exfiltration +** ID: TA0010 +** Reference URL: https://attack.mitre.org/tactics/TA0010/ +* Technique: +** Name: Transfer Data to Cloud Account +** ID: T1537 +** Reference URL: https://attack.mitre.org/techniques/T1537/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-ec2-multi-region-describeinstances-api-calls.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-ec2-multi-region-describeinstances-api-calls.asciidoc new file mode 100644 index 0000000000..23323ae319 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-ec2-multi-region-describeinstances-api-calls.asciidoc @@ -0,0 +1,144 @@ +[[prebuilt-rule-8-19-4-aws-ec2-multi-region-describeinstances-api-calls]] +=== AWS EC2 Multi-Region DescribeInstances API Calls + +Identifies when a single AWS resource is making `DescribeInstances` API calls in more than 10 regions within a 30-second window. This could indicate a potential threat actor attempting to discover the AWS infrastructure across multiple regions using compromised credentials or a compromised instance. Adversaries may use this information to identify potential targets for further exploitation or to gain a better understanding of the target's infrastructure. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://www.sentinelone.com/labs/exploring-fbot-python-based-malware-targeting-cloud-and-payment-services/ +* https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html + +*Tags*: + +* Domain: Cloud +* Data Source: AWS +* Data Source: AWS EC2 +* Resources: Investigation Guide +* Use Case: Threat Detection +* Tactic: Discovery + +*Version*: 5 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating AWS EC2 Multi-Region DescribeInstances API Calls* + + +This rule detects instances where a single AWS resource makes `DescribeInstances` API calls in over 10 regions within a 30-second window. This could indicate an adversary using compromised credentials or an exploited resource to enumerate AWS infrastructure across multiple regions. Attackers often leverage multi-region enumeration to assess the overall cloud environment and find potential targets for further exploitation. + + +*Possible Investigation Steps* + + +- **Identify the Resource and Actor**: + - **Actor ARN**: Check `aws.cloudtrail.user_identity.arn` to determine the exact identity performing the enumeration. Validate if the user is expected to perform region-wide `DescribeInstances` actions across multiple regions or if it seems unusual. + - **Account and Role Details**: Examine `cloud.account.id` and `aws.cloudtrail.user_identity.session_context.session_issuer` for information about the AWS account and specific role associated with the action. + +- **Analyze API Call Patterns**: + - **Frequency and Scope**: Review `cloud.region` field and confirm if this specific resource commonly performs `DescribeInstances` calls across multiple regions. + - **Time Window Context**: Compare the timing of the API calls within the `target_time_window` to determine if this burst pattern aligns with expected system usage or is potentially malicious. + +- **Check User Agent and Tooling**: + - **Source and User Agent**: Verify `user_agent.original` to determine if the request was made through expected tooling (e.g., AWS CLI or SDK) or a third-party tool that might indicate non-standard access. + - **Source IP Address**: Look into `source.address` to identify the origin of the calls. Unusual IP addresses, especially those outside expected ranges, may indicate compromised access. + +- **Evaluate for Potential Reconnaissance Behavior**: + - **Account and Region Enumeration**: Adversaries may use region-wide `DescribeInstances` requests to discover resources within an account across different regions. Confirm if this access aligns with operational practices or represents excessive access. + - **Permissions and Roles**: Investigate the permissions associated with the user role. Excessive permissions on a compromised role may allow broader enumeration, which should be restricted. + +- **Review Related CloudTrail Events**: + - **Additional Describe or List Actions**: Identify any associated `Describe` or `List` API calls that may indicate further enumeration of other AWS services within the same timeframe. + - **Potential Preceding Events**: Look for preceding login or access events from the same actor, as these may indicate potential credential compromise or unauthorized escalation of privileges. + + +*False Positive Analysis* + + +- **Expected Enumeration**: Certain administrative or automation scripts may conduct broad `DescribeInstances` API calls for inventory purposes. Review usage patterns or consult relevant teams to validate the purpose. +- **Automated Cloud Management**: Some automated services may perform regional checks for compliance or backup operations. If this rule is triggered repeatedly by a known service, consider whitelisting or tuning accordingly. + + +*Response and Remediation* + + +- **Review IAM Policies and Role Permissions**: Limit the permissions of roles associated with this resource, restricting unnecessary multi-region enumeration access. +- **Enforce Least Privilege Access**: Ensure that permissions for DescribeInstances are tightly controlled and restricted to specific roles or accounts that require multi-region access. +- **Increase Monitoring and Alerts**: Set up additional monitoring on this role or account for further signs of unauthorized activity or lateral movement attempts. +- **Access Review**: Conduct a review of users and entities with `DescribeInstances` permissions, especially for multi-region capabilities, and ensure these permissions are necessary for their functions. + + +*Additional Information* + + +For further information on AWS `DescribeInstances` permissions and best practices, refer to the https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html[AWS DescribeInstances API documentation]. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws.cloudtrail-* + +// filter for DescribeInstances API calls +| where event.dataset == "aws.cloudtrail" + and event.provider == "ec2.amazonaws.com" + and event.action == "DescribeInstances" + +// truncate the timestamp to a 30-second window +| eval Esql.time_window_date_trunc = date_trunc(30 seconds, @timestamp) + +// keep only the relevant raw fields +| keep Esql.time_window_date_trunc, aws.cloudtrail.user_identity.arn, cloud.region + +// count the number of unique regions and total API calls within the 30-second window +| stats + Esql.cloud_region_count_distinct = count_distinct(cloud.region), + Esql.event_count = count(*) + by Esql.time_window_date_trunc, aws.cloudtrail.user_identity.arn + +// filter for resources making DescribeInstances API calls in more than 10 regions within the 30-second window +| where Esql.cloud_region_count_distinct >= 10 and Esql.event_count >= 10 + +// sort the results by time window in descending order +| sort Esql.time_window_date_trunc desc + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Discovery +** ID: TA0007 +** Reference URL: https://attack.mitre.org/tactics/TA0007/ +* Technique: +** Name: Cloud Infrastructure Discovery +** ID: T1580 +** Reference URL: https://attack.mitre.org/techniques/T1580/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-group.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-group.asciidoc new file mode 100644 index 0000000000..96197839a7 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-group.asciidoc @@ -0,0 +1,168 @@ +[[prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-group]] +=== AWS IAM AdministratorAccess Policy Attached to Group + +An adversary with access to a set of compromised credentials may attempt to persist or escalate privileges by attaching additional permissions to user groups the compromised user account belongs to. This rule looks for use of the IAM `AttachGroupPolicy` API operation to attach the highly permissive `AdministratorAccess` AWS managed policy to an existing IAM user group. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 5m + +*Searches indices from*: now-6m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://docs.aws.amazon.com/IAM/latest/APIReference/API_AttachGroupPolicy.html +* https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AdministratorAccess.html +* https://hackingthe.cloud/aws/exploitation/iam_privilege_escalation/ + +*Tags*: + +* Domain: Cloud +* Data Source: AWS +* Data Source: Amazon Web Services +* Data Source: AWS IAM +* Use Case: Identity and Access Audit +* Tactic: Privilege Escalation +* Tactic: Persistence +* Resources: Investigation Guide + +*Version*: 6 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating AWS IAM AdministratorAccess Policy Attached to Group* + + +The AWS IAM `AdministratorAccess` managed policy provides full access to all AWS services and resources. +With access to the `iam:AttachGroupPolicy` permission, a set of compromised credentials could be used to attach +this policy to the current user's groups for privilege escalation or as a means of persistence. This rule uses https://www.elastic.co/guide/en/security/current/rules-ui-create.html#create-esql-rule[ESQL] +to look for use of the `AttachGroupPolicy` operation along with request_parameters where the policyName is `AdministratorAccess`. + + + +*Possible investigation steps* + + +- Identify the account and its role in the environment. +- Review IAM permission policies for the user identity. +- Identify the applications or users that should use this account. +- Investigate other alerts associated with the account during the past 48 hours. +- Investigate abnormal values in the `user_agent.original` field by comparing them with the intended and authorized usage and historical data. Suspicious user agent values include non-SDK, AWS CLI, custom user agents, etc. +- Contact the account owner and confirm whether they are aware of this activity. +- Considering the source IP address and geolocation of the user who issued the command: + - Do they look normal for the calling user? + - If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts or is the source IP from an EC2 instance that's not under your control? + - If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance? +- If you suspect the account has been compromised, scope potentially compromised assets by tracking servers, services, and data accessed by the account in the last 24 hours. + - Determine what other API calls were made by the user. + - Assess whether this behavior is prevalent in the environment by looking for similar occurrences involving other users. + + +*False positive analysis* + + +- False positives may occur due to the intended usage of the IAM `AdministratorAccess` managed policy. Verify the `aws.cloudtrail.user_identity.arn` should have the `iam:AttachUserPolicy` permission and that the `target.userName` should be given full administrative access. + + +*Response and remediation* + + +- Initiate the incident response process based on the outcome of the triage. +- Disable or limit the account during the investigation and response. + - Rotate user credentials + - Remove the `AdministratorAccess` policy from the affected group(s) +- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context: + - Identify the account role in the cloud environment. + - Assess the criticality of affected services and servers. + - Work with your IT team to identify and minimize the impact on users. + - Identify if the attacker is moving laterally and compromising other accounts, servers, or services. + - Identify any regulatory or legal ramifications related to this activity. +- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. + - Rotate secrets or delete API keys as needed to revoke the attacker's access to the environment. + - Work with your IT teams to minimize the impact on business operations during these actions. +- Check if unauthorized new users were created, remove unauthorized new accounts, and request password resets for other IAM users. +- Consider enabling multi-factor authentication for users. +- Review the permissions assigned to the implicated user to ensure that the least privilege principle is being followed. +- Implement security best practices https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/[outlined] by AWS. +- Take the actions needed to return affected systems, data, or services to their normal operational levels. +- Identify the initial vector abused by the attacker and take action to prevent reinfection via the same vector. +- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR). + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws.cloudtrail-* metadata _id, _version, _index + +| where + event.provider == "iam.amazonaws.com" + and event.action == "AttachGroupPolicy" + and event.outcome == "success" + +// Extract policy and group details from request parameters +| dissect aws.cloudtrail.request_parameters + "{%{?policyArn}=%{?arn}:%{?aws}:%{?iam}::%{?aws}:%{?policy}/%{Esql.aws_cloudtrail_request_parameters_policy_name},%{?groupName}=%{Esql.aws_cloudtrail_request_parameters_group_name}}" + +// Filter for attachment of AdministratorAccess policy +| where Esql.aws_cloudtrail_request_parameters_policy_name == "AdministratorAccess" + +// keep ECS and derived fields +| keep + @timestamp, + event.provider, + event.action, + event.outcome, + Esql.aws_cloudtrail_request_parameters_policy_name, + Esql.aws_cloudtrail_request_parameters_group_name + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Privilege Escalation +** ID: TA0004 +** Reference URL: https://attack.mitre.org/tactics/TA0004/ +* Technique: +** Name: Account Manipulation +** ID: T1098 +** Reference URL: https://attack.mitre.org/techniques/T1098/ +* Sub-technique: +** Name: Additional Cloud Roles +** ID: T1098.003 +** Reference URL: https://attack.mitre.org/techniques/T1098/003/ +* Tactic: +** Name: Persistence +** ID: TA0003 +** Reference URL: https://attack.mitre.org/tactics/TA0003/ +* Technique: +** Name: Account Manipulation +** ID: T1098 +** Reference URL: https://attack.mitre.org/techniques/T1098/ +* Sub-technique: +** Name: Additional Cloud Roles +** ID: T1098.003 +** Reference URL: https://attack.mitre.org/techniques/T1098/003/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-role.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-role.asciidoc new file mode 100644 index 0000000000..cc0c218711 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-role.asciidoc @@ -0,0 +1,168 @@ +[[prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-role]] +=== AWS IAM AdministratorAccess Policy Attached to Role + +An adversary with access to a set of compromised credentials may attempt to persist or escalate privileges by attaching additional permissions to compromised IAM roles. This rule looks for use of the IAM `AttachRolePolicy` API operation to attach the highly permissive `AdministratorAccess` AWS managed policy to an existing IAM role. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 5m + +*Searches indices from*: now-6m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://docs.aws.amazon.com/IAM/latest/APIReference/API_AttachRolePolicy.html +* https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AdministratorAccess.html +* https://hackingthe.cloud/aws/exploitation/iam_privilege_escalation/ + +*Tags*: + +* Domain: Cloud +* Data Source: AWS +* Data Source: Amazon Web Services +* Data Source: AWS IAM +* Use Case: Identity and Access Audit +* Tactic: Privilege Escalation +* Tactic: Persistence +* Resources: Investigation Guide + +*Version*: 6 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating AWS IAM AdministratorAccess Policy Attached to Role* + + +The AWS IAM `AdministratorAccess` managed policy provides full access to all AWS services and resources. +With access to the `iam:AttachRolePolicy` permission, a set of compromised credentials could be used to attach +this policy to a compromised role for privilege escalation or as a means of persistence. This rule uses https://www.elastic.co/guide/en/security/current/rules-ui-create.html#create-esql-rule[ESQL] +to look for use of the `AttachRolePolicy` operation along with request_parameters where the policyName is `AdministratorAccess`. + + + +*Possible investigation steps* + + +- Identify the account and its role in the environment. +- Review IAM permission policies for the user identity. +- Identify the applications or users that should use this account. +- Investigate other alerts associated with the account during the past 48 hours. +- Investigate abnormal values in the `user_agent.original` field by comparing them with the intended and authorized usage and historical data. Suspicious user agent values include non-SDK, AWS CLI, custom user agents, etc. +- Contact the account owner and confirm whether they are aware of this activity. +- Considering the source IP address and geolocation of the user who issued the command: + - Do they look normal for the calling user? + - If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts or is the source IP from an EC2 instance that's not under your control? + - If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance? +- If you suspect the account has been compromised, scope potentially compromised assets by tracking servers, services, and data accessed by the account in the last 24 hours. + - Determine what other API calls were made by the user. + - Assess whether this behavior is prevalent in the environment by looking for similar occurrences involving other users. + + +*False positive analysis* + + +- False positives may occur due to the intended usage of the IAM `AdministratorAccess` managed policy. Verify the `aws.cloudtrail.user_identity.arn` should have the `iam:AttachRolePolicy` permission and that the `role.name` should be given full administrative access. + + +*Response and remediation* + + +- Initiate the incident response process based on the outcome of the triage. +- Disable or limit the account during the investigation and response. + - Rotate user credentials + - Remove the `AdministratorAccess` policy from the affected role(s) +- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context: + - Identify the account role in the cloud environment. + - Assess the criticality of affected services and servers. + - Work with your IT team to identify and minimize the impact on users. + - Identify if the attacker is moving laterally and compromising other accounts, servers, or services. + - Identify any regulatory or legal ramifications related to this activity. +- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. + - Rotate secrets or delete API keys as needed to revoke the attacker's access to the environment. + - Work with your IT teams to minimize the impact on business operations during these actions. +- Check if unauthorized new users were created, remove unauthorized new accounts, and request password resets for other IAM users. +- Consider enabling multi-factor authentication for users. +- Review the permissions assigned to the implicated user to ensure that the least privilege principle is being followed. +- Implement security best practices https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/[outlined] by AWS. +- Take the actions needed to return affected systems, data, or services to their normal operational levels. +- Identify the initial vector abused by the attacker and take action to prevent reinfection via the same vector. +- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR). + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws.cloudtrail-* metadata _id, _version, _index + +| where + event.provider == "iam.amazonaws.com" + and event.action == "AttachRolePolicy" + and event.outcome == "success" + +// Extract policy name and role name from request parameters +| dissect aws.cloudtrail.request_parameters + "{%{?policyArn}=%{?arn}:%{?aws}:%{?iam}::%{?aws}:%{?policy}/%{Esql.aws_cloudtrail_request_parameters_policy_name},%{?roleName}=%{Esql.aws_cloudtrail_request_parameters_role_name}}" + +// Filter for AdministratorAccess policy attachment +| where Esql.aws_cloudtrail_request_parameters_policy_name == "AdministratorAccess" + +// keep relevant ECS and dynamic fields +| keep + @timestamp, + event.provider, + event.action, + event.outcome, + Esql.aws_cloudtrail_request_parameters_policy_name, + Esql.aws_cloudtrail_request_parameters_role_name + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Privilege Escalation +** ID: TA0004 +** Reference URL: https://attack.mitre.org/tactics/TA0004/ +* Technique: +** Name: Account Manipulation +** ID: T1098 +** Reference URL: https://attack.mitre.org/techniques/T1098/ +* Sub-technique: +** Name: Additional Cloud Roles +** ID: T1098.003 +** Reference URL: https://attack.mitre.org/techniques/T1098/003/ +* Tactic: +** Name: Persistence +** ID: TA0003 +** Reference URL: https://attack.mitre.org/tactics/TA0003/ +* Technique: +** Name: Account Manipulation +** ID: T1098 +** Reference URL: https://attack.mitre.org/techniques/T1098/ +* Sub-technique: +** Name: Additional Cloud Roles +** ID: T1098.003 +** Reference URL: https://attack.mitre.org/techniques/T1098/003/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-user.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-user.asciidoc new file mode 100644 index 0000000000..740fbd3bdc --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-user.asciidoc @@ -0,0 +1,175 @@ +[[prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-user]] +=== AWS IAM AdministratorAccess Policy Attached to User + +An adversary with access to a set of compromised credentials may attempt to persist or escalate privileges by attaching additional permissions to compromised user accounts. This rule looks for use of the IAM `AttachUserPolicy` API operation to attach the highly permissive `AdministratorAccess` AWS managed policy to an existing IAM user. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 5m + +*Searches indices from*: now-6m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://docs.aws.amazon.com/IAM/latest/APIReference/API_AttachUserPolicy.html +* https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AdministratorAccess.html +* https://hackingthe.cloud/aws/exploitation/iam_privilege_escalation/ + +*Tags*: + +* Domain: Cloud +* Data Source: AWS +* Data Source: Amazon Web Services +* Data Source: AWS IAM +* Use Case: Identity and Access Audit +* Tactic: Privilege Escalation +* Tactic: Persistence +* Resources: Investigation Guide + +*Version*: 7 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating AWS IAM AdministratorAccess Policy Attached to User* + + +The AWS IAM `AdministratorAccess` managed policy provides full access to all AWS services and resources. +With access to the `iam:AttachUserPolicy` permission, a set of compromised credentials could be used to attach +this policy to the current user for privilege escalation or another user as a means of persistence. This rule uses https://www.elastic.co/guide/en/security/current/rules-ui-create.html#create-esql-rule[ESQL] +to look for use of the `AttachUserPolicy` operation along with request_parameters where the policyName is `AdministratorAccess`. + + + +*Possible investigation steps* + + +- Identify the account and its role in the environment. +- Review IAM permission policies for the user identity. +- Identify the applications or users that should use this account. +- Investigate other alerts associated with the account during the past 48 hours. +- Investigate abnormal values in the `user_agent.original` field by comparing them with the intended and authorized usage and historical data. Suspicious user agent values include non-SDK, AWS CLI, custom user agents, etc. +- Contact the account owner and confirm whether they are aware of this activity. +- Considering the source IP address and geolocation of the user who issued the command: + - Do they look normal for the calling user? + - If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts or is the source IP from an EC2 instance that's not under your control? + - If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance? +- If you suspect the account has been compromised, scope potentially compromised assets by tracking servers, services, and data accessed by the account in the last 24 hours. + - Determine what other API calls were made by the user. + - Assess whether this behavior is prevalent in the environment by looking for similar occurrences involving other users. + + +*False positive analysis* + + +- False positives may occur due to the intended usage of the IAM `AdministratorAccess` managed policy. Verify the `aws.cloudtrail.user_identity.arn` should have the `iam:AttachUserPolicy` permission and that the `target.userName` should be given full administrative access. + + +*Response and remediation* + + +- Initiate the incident response process based on the outcome of the triage. +- Disable or limit the account during the investigation and response. + - Rotate user credentials + - Remove the `AdministratorAccess` policy from the affected user(s) +- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context: + - Identify the account role in the cloud environment. + - Assess the criticality of affected services and servers. + - Work with your IT team to identify and minimize the impact on users. + - Identify if the attacker is moving laterally and compromising other accounts, servers, or services. + - Identify any regulatory or legal ramifications related to this activity. +- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. + - Rotate secrets or delete API keys as needed to revoke the attacker's access to the environment. + - Work with your IT teams to minimize the impact on business operations during these actions. +- Check if unauthorized new users were created, remove unauthorized new accounts, and request password resets for other IAM users. +- Consider enabling multi-factor authentication for users. +- Review the permissions assigned to the implicated user to ensure that the least privilege principle is being followed. +- Implement security best practices https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/[outlined] by AWS. +- Take the actions needed to return affected systems, data, or services to their normal operational levels. +- Identify the initial vector abused by the attacker and take action to prevent reinfection via the same vector. +- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR). + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws.cloudtrail-* metadata _id, _version, _index + +| where + event.provider == "iam.amazonaws.com" + and event.action == "AttachUserPolicy" + and event.outcome == "success" + +// Extract policy name and user name from request parameters +| dissect aws.cloudtrail.request_parameters + "{%{?policyArn}=%{?arn}:%{?aws}:%{?iam}::%{?aws}:%{?policy}/%{Esql.aws_cloudtrail_request_parameters_policy_name},%{?userName}=%{Esql_priv.aws_cloudtrail_request_parameters_target_user_name}}" + +// Filter for AdministratorAccess policy +| where Esql.aws_cloudtrail_request_parameters_policy_name == "AdministratorAccess" + +// keep ECS and parsed fields +| keep + @timestamp, + cloud.region, + event.provider, + event.action, + event.outcome, + Esql.aws_cloudtrail_request_parameters_policy_name, + Esql_priv.aws_cloudtrail_request_parameters_target_user_name, + aws.cloudtrail.request_parameters, + aws.cloudtrail.user_identity.arn, + related.user, + user_agent.original, + user.name, + source.address + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Privilege Escalation +** ID: TA0004 +** Reference URL: https://attack.mitre.org/tactics/TA0004/ +* Technique: +** Name: Account Manipulation +** ID: T1098 +** Reference URL: https://attack.mitre.org/techniques/T1098/ +* Sub-technique: +** Name: Additional Cloud Roles +** ID: T1098.003 +** Reference URL: https://attack.mitre.org/techniques/T1098/003/ +* Tactic: +** Name: Persistence +** ID: TA0003 +** Reference URL: https://attack.mitre.org/tactics/TA0003/ +* Technique: +** Name: Account Manipulation +** ID: T1098 +** Reference URL: https://attack.mitre.org/techniques/T1098/ +* Sub-technique: +** Name: Additional Cloud Roles +** ID: T1098.003 +** Reference URL: https://attack.mitre.org/techniques/T1098/003/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-iam-login-profile-added-for-root.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-iam-login-profile-added-for-root.asciidoc new file mode 100644 index 0000000000..ba12984f4e --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-iam-login-profile-added-for-root.asciidoc @@ -0,0 +1,214 @@ +[[prebuilt-rule-8-19-4-aws-iam-login-profile-added-for-root]] +=== AWS IAM Login Profile Added for Root + +Detects when an AWS IAM login profile is added to a root user account and is self-assigned. Adversaries, with temporary access to the root account, may add a login profile to the root user account to maintain access even if the original access key is rotated or disabled. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: high + +*Risk score*: 73 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Cloud +* Data Source: AWS +* Data Source: Amazon Web Services +* Data Source: AWS IAM +* Use Case: Identity and Access Audit +* Tactic: Persistence +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + +> **Disclaimer**: +> 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. + + +*Investigating AWS IAM Login Profile Added for Root* + + +AWS IAM allows management of user access and permissions within AWS environments. A login profile enables console access using a password. Adversaries may exploit temporary root access to create a login profile, ensuring persistent access even if keys are rotated. The detection rule identifies such actions by monitoring specific API calls and conditions, flagging unauthorized profile additions to root accounts. + + +*Possible investigation steps* + + +- Review the @timestamp field to determine when the CreateLoginProfile action occurred and correlate it with any other suspicious activities around the same time. +- Examine the aws.cloudtrail.user_identity.arn and aws.cloudtrail.user_identity.access_key_id fields to identify the specific root account and access key involved in the action. +- Investigate the source.address field to trace the IP address from which the CreateLoginProfile request originated, checking for any unusual or unauthorized locations. +- Analyze the aws.cloudtrail.request_parameters and aws.cloudtrail.response_elements fields to understand the specifics of the login profile creation and verify if any unexpected parameters were used. +- Check the cloud.account.id to confirm which AWS account was affected and assess if there are any other security incidents or alerts associated with this account. +- Review the event.action field to ensure that no other unauthorized actions were performed by the root account around the same time. + + +*False positive analysis* + + +- Administrative actions by trusted personnel may trigger the rule if they are performing legitimate maintenance or security tasks. To manage this, create exceptions for known administrative accounts by filtering their access key IDs. +- Automated scripts or tools used for account management might inadvertently match the rule's conditions. Identify these scripts and exclude their specific access key IDs or user agents from the detection criteria. +- Testing environments where root access is used for simulation or development purposes can cause false positives. Implement a tagging system for test environments and exclude logs with these tags from triggering the rule. +- Third-party integrations that require root access for initial setup or configuration might be flagged. Document these integrations and adjust the rule to recognize and exclude their specific access patterns. + + +*Response and remediation* + + +- Immediately revoke any active sessions and access keys associated with the root account to prevent further unauthorized access. +- Reset the root account password and ensure that multi-factor authentication (MFA) is enabled for the root user to enhance security. +- Review AWS CloudTrail logs to identify any other suspicious activities or changes made by the root account during the time of the incident. +- Conduct a thorough audit of IAM policies and permissions to ensure that no other unauthorized changes have been made and that least privilege principles are enforced. +- Notify the security operations team and relevant stakeholders about the incident for further investigation and to ensure awareness across the organization. +- Implement additional monitoring and alerting for root account activities to detect any future unauthorized access attempts promptly. +- Consider engaging AWS Support or a third-party security expert if the incident's scope is beyond internal capabilities or if further forensic analysis is required. + + +*Investigating AWS IAM Login Profile Added for Root* + + +This rule detects when a login profile is added to the AWS root account. Adding a login profile to the root account, especially if self-assigned, is highly suspicious as it might indicate an adversary trying to establish persistence in the environment. + + +*Possible Investigation Steps* + + +- **Identify the Source and Context of the Action**: + - Examine the `source.address` field to identify the IP address from which the request originated. + - Check the geographic location (`source.address`) to determine if the access is from an expected or unexpected region. + - Look at the `user_agent.original` field to identify the tool or browser used for this action. + - For example, a user agent like `Mozilla/5.0` might indicate interactive access, whereas `aws-cli` or SDKs suggest scripted activity. + +- **Confirm Root User and Request Details**: + - Validate the root user's identity through `aws.cloudtrail.user_identity.arn` and ensure this activity aligns with legitimate administrative actions. + - Review `aws.cloudtrail.user_identity.access_key_id` to identify if the action was performed using temporary or permanent credentials. This access key could be used to pivot into other actions. + +- **Analyze the Login Profile Creation**: + - Review the `aws.cloudtrail.request_parameters` and `aws.cloudtrail.response_elements` fields for details of the created login profile. + - For example, confirm the `userName` of the profile and whether `passwordResetRequired` is set to `true`. + - Compare the `@timestamp` of this event with other recent actions by the root account to identify potential privilege escalation or abuse. + +- **Correlate with Other Events**: + - Investigate for related IAM activities, such as: + - `CreateAccessKey` or `AttachUserPolicy` events targeting the root account. + - Unusual data access, privilege escalation, or management console logins. + - Check for any anomalies involving the same `source.address` or `aws.cloudtrail.user_identity.access_key_id` in the environment. + +- **Evaluate Policy and Permissions**: + - Verify the current security policies for the root account: + - Ensure password policies enforce complexity and rotation requirements. + - Check if MFA is enforced on the root account. + - Assess the broader IAM configuration for deviations from least privilege principles. + + +*False Positive Analysis* + + +- **Routine Administrative Tasks**: Adding a login profile might be a legitimate action during certain administrative processes. Verify with the relevant AWS administrators if this event aligns with routine account maintenance or emergency recovery scenarios. + +- **Automation**: If the action is part of an approved automation process (e.g., account recovery workflows), consider excluding these activities from alerting using specific user agents, IP addresses, or session attributes. + + +*Response and Remediation* + + +- **Immediate Access Review**: + - Disable the newly created login profile (`aws iam delete-login-profile`) if it is determined to be unauthorized. + - Rotate or disable the credentials associated with the root account to prevent further abuse. + +- **Enhance Monitoring and Alerts**: + - Enable real-time monitoring and alerting for IAM actions involving the root account. + - Increase the logging verbosity for root account activities. + +- **Review and Update Security Policies**: + - Enforce MFA for all administrative actions, including root account usage. + - Restrict programmatic access to the root account by disabling access keys unless absolutely necessary. + +- **Conduct Post-Incident Analysis**: + - Investigate how the credentials for the root account were compromised or misused. + - Strengthen the security posture by implementing account-specific guardrails and continuous monitoring. + + +*Additional Resources* + + +- AWS documentation on https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateLoginProfile.html[Login Profile Management]. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws.cloudtrail* metadata _id, _version, _index +| where + // filter for CloudTrail logs from IAM + event.dataset == "aws.cloudtrail" + and event.provider == "iam.amazonaws.com" + + // filter for successful CreateLoginProfile API call + and event.action == "CreateLoginProfile" + and event.outcome == "success" + + // filter for Root member account + and aws.cloudtrail.user_identity.type == "Root" + + // filter for an access key existing which sources from AssumeRoot + and aws.cloudtrail.user_identity.access_key_id is not null + + // filter on the request parameters not including UserName which assumes self-assignment + and not to_lower(aws.cloudtrail.request_parameters) like "*username*" +| keep + @timestamp, + aws.cloudtrail.request_parameters, + aws.cloudtrail.response_elements, + aws.cloudtrail.user_identity.type, + aws.cloudtrail.user_identity.arn, + aws.cloudtrail.user_identity.access_key_id, + cloud.account.id, + event.action, + source.address + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Persistence +** ID: TA0003 +** Reference URL: https://attack.mitre.org/tactics/TA0003/ +* Technique: +** Name: Valid Accounts +** ID: T1078 +** Reference URL: https://attack.mitre.org/techniques/T1078/ +* Sub-technique: +** Name: Cloud Accounts +** ID: T1078.004 +** Reference URL: https://attack.mitre.org/techniques/T1078/004/ +* Technique: +** Name: Account Manipulation +** ID: T1098 +** Reference URL: https://attack.mitre.org/techniques/T1098/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-s3-bucket-enumeration-or-brute-force.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-s3-bucket-enumeration-or-brute-force.asciidoc new file mode 100644 index 0000000000..c7cc282e04 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-s3-bucket-enumeration-or-brute-force.asciidoc @@ -0,0 +1,165 @@ +[[prebuilt-rule-8-19-4-aws-s3-bucket-enumeration-or-brute-force]] +=== AWS S3 Bucket Enumeration or Brute Force + +Identifies a high number of failed S3 operations from a single source and account (or anonymous account) within a short timeframe. This activity can be indicative of attempting to cause an increase in billing to an account for excessive random operations, cause resource exhaustion, or enumerating bucket names for discovery. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-6m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://medium.com/@maciej.pocwierz/how-an-empty-s3-bucket-can-make-your-aws-bill-explode-934a383cb8b1 +* https://docs.aws.amazon.com/cli/latest/reference/s3api/ + +*Tags*: + +* Domain: Cloud +* Data Source: AWS +* Data Source: Amazon Web Services +* Data Source: AWS S3 +* Resources: Investigation Guide +* Use Case: Log Auditing +* Tactic: Impact + +*Version*: 5 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating AWS S3 Bucket Enumeration or Brute Force* + + +AWS S3 buckets can be be brute forced to cause financial impact against the resource owner. What makes this even riskier is that even private, locked down buckets can still trigger a potential cost, even with an "Access Denied", while also being accessible from unauthenticated, anonymous accounts. This also appears to work on several or all https://docs.aws.amazon.com/cli/latest/reference/s3api/[operations] (GET, PUT, list-objects, etc.). Additionally, buckets are trivially discoverable by default as long as the bucket name is known, making it vulnerable to enumeration for discovery. + +Attackers may attempt to enumerate names until a valid bucket is discovered and then pivot to cause financial impact, enumerate for more information, or brute force in other ways to attempt to exfil data. + + +*Possible investigation steps* + + +- Examine the history of the operation requests from the same `source.address` and `cloud.account.id` to determine if there is other suspicious activity. +- Review similar requests and look at the `user.agent` info to ascertain the source of the requests (though do not overly rely on this since it is controlled by the requestor). +- Review other requests to the same `aws.s3.object.key` as well as other `aws.s3.object.key` accessed by the same `cloud.account.id` or `source.address`. +- Investigate other alerts associated with the user account during the past 48 hours. +- Validate the activity is not related to planned patches, updates, or network administrator activity. +- Examine the request parameters. These may indicate the source of the program or the nature of the task being performed when the error occurred. + - Check whether the error is related to unsuccessful attempts to enumerate or access objects, data, or secrets. +- Considering the source IP address and geolocation of the user who issued the command: + - Do they look normal for the calling user? + - If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts or is the source IP from an EC2 instance that's not under your control? + - If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance? +- Consider the time of day. If the user is a human (not a program or script), did the activity take place during a normal time of day? +- Contact the account owner and confirm whether they are aware of this activity if suspicious. +- If you suspect the account has been compromised, scope potentially compromised assets by tracking servers, services, and data accessed by the account in the last 24 hours. + + +*False positive analysis* + + +- Verify the `source.address` and `cloud.account.id` - there are some valid operations from within AWS directly that can cause failures and false positives. Additionally, failed automation can also caeuse false positives, but should be identifiable by reviewing the `source.address` and `cloud.account.id`. + + +*Response and remediation* + + +- Initiate the incident response process based on the outcome of the triage. +- Disable or limit the account during the investigation and response. +- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context: + - Identify the account role in the cloud environment. + - Assess the criticality of affected services and servers. + - Work with your IT team to identify and minimize the impact on users. + - Identify if the attacker is moving laterally and compromising other accounts, servers, or services. + - Identify any regulatory or legal ramifications related to this activity. +- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords or delete API keys as needed to revoke the attacker's access to the environment. Work with your IT teams to minimize the impact on business operations during these actions. +- Check if unauthorized new users were created, remove unauthorized new accounts, and request password resets for other IAM users. +- Consider enabling multi-factor authentication for users. +- Review the permissions assigned to the implicated user to ensure that the least privilege principle is being followed. +- Implement security best practices https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/[outlined] by AWS. +- Take the actions needed to return affected systems, data, or services to their normal operational levels. +- Identify the initial vector abused by the attacker and take action to prevent reinfection via the same vector. +- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR). +- Check for PutBucketPolicy event actions as well to see if they have been tampered with. While we monitor for denied, a single successful action to add a backdoor into the bucket via policy updates (however they got permissions) may be critical to identify during TDIR. + + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws.cloudtrail* + +| where + event.provider == "s3.amazonaws.com" + and aws.cloudtrail.error_code == "AccessDenied" + and tls.client.server_name is not null + and cloud.account.id is not null + +// keep only relevant ECS fields +| keep + tls.client.server_name, + source.address, + cloud.account.id + +// count access denied requests per server_name, source, and account +| stats + Esql.event_count = count(*) + by + tls.client.server_name, + source.address, + cloud.account.id + +// Threshold: more than 40 denied requests +| where Esql.event_count > 40 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Impact +** ID: TA0040 +** Reference URL: https://attack.mitre.org/tactics/TA0040/ +* Technique: +** Name: Financial Theft +** ID: T1657 +** Reference URL: https://attack.mitre.org/techniques/T1657/ +* Tactic: +** Name: Discovery +** ID: TA0007 +** Reference URL: https://attack.mitre.org/tactics/TA0007/ +* Technique: +** Name: Cloud Infrastructure Discovery +** ID: T1580 +** Reference URL: https://attack.mitre.org/techniques/T1580/ +* Tactic: +** Name: Collection +** ID: TA0009 +** Reference URL: https://attack.mitre.org/tactics/TA0009/ +* Technique: +** Name: Data from Cloud Storage +** ID: T1530 +** Reference URL: https://attack.mitre.org/techniques/T1530/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-s3-object-encryption-using-external-kms-key.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-s3-object-encryption-using-external-kms-key.asciidoc new file mode 100644 index 0000000000..46c1b31ab7 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-s3-object-encryption-using-external-kms-key.asciidoc @@ -0,0 +1,147 @@ +[[prebuilt-rule-8-19-4-aws-s3-object-encryption-using-external-kms-key]] +=== AWS S3 Object Encryption Using External KMS Key + +Identifies `CopyObject` events within an S3 bucket using an AWS KMS key from an external account for encryption. Adversaries with access to a misconfigured S3 bucket and the proper permissions may encrypt objects with an external KMS key to deny their victims access to their own data. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html/ +* https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html/ +* https://www.gem.security/post/cloud-ransomware-a-new-take-on-an-old-attack-pattern/ +* https://rhinosecuritylabs.com/aws/s3-ransomware-part-1-attack-vector/ + +*Tags*: + +* Domain: Cloud +* Data Source: AWS +* Data Source: Amazon Web Services +* Data Source: AWS S3 +* Data Source: AWS KMS +* Use Case: Threat Detection +* Tactic: Impact +* Resources: Investigation Guide + +*Version*: 6 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating AWS S3 Object Encryption Using External KMS Key* + + +This rule detects the use of an external AWS KMS key to encrypt objects within an S3 bucket. Adversaries with access to a misconfigured S3 bucket may use an external key to copy objects within a bucket and deny victims the ability to access their own data. +This rule uses https://www.elastic.co/guide/en/security/current/rules-ui-create.html#create-esql-rule[ESQL] to look for use of the `CopyObject` operation where the target bucket's `cloud.account.id` is different from the `key.account.id` dissected from the AWS KMS key used for encryption. + + +*Possible Investigation Steps:* + + +- **Identify the Actor**: Review the `aws.cloudtrail.user_identity.arn` and `aws.cloudtrail.user_identity.access_key_id` fields to identify who performed the action. Verify if this actor typically performs such actions and if they have the necessary permissions. +- **Review the Request Details**: Examine the `aws.cloudtrail.request_parameters` to understand the specific details of the `CopyObject` action. Look for any unusual parameters that could suggest unauthorized or malicious modifications or usage of an unknown KMS keyId. +- **Analyze the Source of the Request**: Investigate the `source.ip` and `source.geo` fields to determine the geographical origin of the request. An external or unexpected location might indicate compromised credentials or unauthorized access. +- **Contextualize with Timestamp**: Use the `@timestamp` field to check when the object was copied. Changes during non-business hours or outside regular maintenance windows might require further scrutiny. +- **Correlate with Other Activities**: Search for related CloudTrail events before and after this action to see if the same actor or IP address engaged in other potentially suspicious activities. +- **Check for Object Deletion or Access**: Look for `DeleteObject`, `DeleteObjects`, or `GetObject` API calls to the same S3 bucket that may indicate the adversary accessing and destroying objects including older object versions. +- **Interview Relevant Personnel**: If the copy event was initiated by a user, verify the intent and authorization for this action with the person or team responsible for managing S3 buckets. + + +*False Positive Analysis:* + + +- **Legitimate Administrative Actions**: Confirm if the `CopyObject` action aligns with scheduled updates, maintenance activities, or legitimate administrative tasks documented in change management systems. +- **Consistency Check**: Compare the action against historical data of similar activities performed by the user or within the organization. If the action is consistent with past legitimate activities, it might indicate a false alarm. + + +*Response and Remediation:* + + +- **Immediate Review**: If the activity was unauthorized, search for potential ransom note placed in S3 bucket and review the bucket's access logs for any suspicious activity. +- **Enhance Monitoring and Alerts**: Adjust monitoring systems to alert on similar `CopyObject` actions, especially those involving sensitive data or unusual file extensions. +- **Educate and Train**: Provide additional training to users with administrative rights on the importance of security best practices concerning S3 bucket management and the risks of ransomware. +- **Audit S3 Bucket Policies and Permissions**: Conduct a comprehensive audit of all S3 bucket policies and associated permissions to ensure they adhere to the principle of least privilege. +- **Incident Response**: If there's an indication of malicious intent or a security breach, initiate the incident response protocol to mitigate any damage and prevent future occurrences. + + +*Additional Information:* + + +For further guidance on managing S3 bucket security and protecting against ransomware, refer to the https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html[AWS S3 documentation] and AWS best practices for security. Additionally, consult the following resources for specific details on S3 ransomware protection: +- https://s3.amazonaws.com/bizzabo.file.upload/PtZzA0eFQwV2RA5ysNeo_ERMETIC%20REPORT%20-%20AWS%20S3%20Ransomware%20Exposure%20in%20the%20Wild.pdf[ERMETIC REPORT - AWS S3 Ransomware Exposure in the Wild] +- https://rhinosecuritylabs.com/aws/s3-ransomware-part-1-attack-vector/[S3 Ransomware Part 1: Attack Vector] + + +==== Setup + + +AWS S3 data event types need to be enabled in the CloudTrail trail configuration. + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws.cloudtrail-* metadata _id, _version, _index + +// any successful S3 copy event +| where + event.dataset == "aws.cloudtrail" + and event.provider == "s3.amazonaws.com" + and event.action == "CopyObject" + and event.outcome == "success" + +// dissect request parameters to extract KMS key info and target object info +| dissect aws.cloudtrail.request_parameters + "{%{?bucketName}=%{Esql.aws_cloudtrail_request_parameters_target_bucket_name},%{?x-amz-server-side-encryption-aws-kms-key-id}=%{?arn}:%{?aws}:%{?kms}:%{?region}:%{Esql.aws_cloudtrail_request_parameters_kms_key_account_id}:%{?key}/%{Esql.aws_cloudtrail_request_parameters_kms_key_id},%{?Host}=%{?tls.client.server.name},%{?x-amz-server-side-encryption}=%{?server_side_encryption},%{?x-amz-copy-source}=%{?bucket.object.name},%{?key}=%{Esql.aws_cloudtrail_request_parameters_target_object_key}}" + +// detect cross-account key usage +| where cloud.account.id != Esql.aws_cloudtrail_request_parameters_kms_key_account_id + +// keep ECS and dissected fields +| keep + @timestamp, + aws.cloudtrail.user_identity.arn, + cloud.account.id, + event.action, + Esql.aws_cloudtrail_request_parameters_target_bucket_name, + Esql.aws_cloudtrail_request_parameters_kms_key_account_id, + Esql.aws_cloudtrail_request_parameters_kms_key_id, + Esql.aws_cloudtrail_request_parameters_target_object_key + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Impact +** ID: TA0040 +** Reference URL: https://attack.mitre.org/tactics/TA0040/ +* Technique: +** Name: Data Encrypted for Impact +** ID: T1486 +** Reference URL: https://attack.mitre.org/techniques/T1486/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-s3-static-site-javascript-file-uploaded.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-s3-static-site-javascript-file-uploaded.asciidoc new file mode 100644 index 0000000000..c8425954b4 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-s3-static-site-javascript-file-uploaded.asciidoc @@ -0,0 +1,151 @@ +[[prebuilt-rule-8-19-4-aws-s3-static-site-javascript-file-uploaded]] +=== AWS S3 Static Site JavaScript File Uploaded + +This rule detects when a JavaScript file is uploaded or accessed in an S3 static site directory (`static/js/`) by an IAM user or assumed role. This can indicate suspicious modification of web content hosted on S3, such as injecting malicious scripts into a static website frontend. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://www.sygnia.co/blog/sygnia-investigation-bybit-hack/ +* https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteHosting.html +* https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + +*Tags*: + +* Domain: Cloud +* Data Source: AWS +* Data Source: Amazon Web Services +* Data Source: AWS S3 +* Tactic: Impact +* Use Case: Web Application Compromise +* Use Case: Cloud Threat Detection +* Resources: Investigation Guide + +*Version*: 2 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and Analysis* + + + +*Investigating AWS S3 Static Site JavaScript File Uploaded* + + +An S3 `PutObject` action that targets a path like `static/js/` and uploads a `.js` file is a potential signal for web content modification. If done by an unexpected IAM user or outside of CI/CD workflows, it may indicate a compromise. + + +*Possible Investigation Steps* + + +- **Identify the Source User**: Check `aws.cloudtrail.user_identity.arn`, access key ID, and session type (`IAMUser`, `AssumedRole`, etc). +- **Review File Content**: Use the S3 `GetObject` or CloudTrail `requestParameters` to inspect the uploaded file for signs of obfuscation or injection. +- **Correlate to Other Events**: Review events from the same IAM user before and after the upload (e.g., `ListBuckets`, `GetCallerIdentity`, IAM activity). +- **Look for Multiple Uploads**: Attackers may attempt to upload several files or modify multiple directories. + + +*False Positive Analysis* + + +- This behavior may be expected during app deployments. Look at: + - The `user_agent.original` to detect legitimate CI tools (like Terraform or GitHub Actions). + - Timing patternsβ€”does this match a regular release window? + - The origin IP and device identity. + + +*Response and Remediation* + + +- **Revert Malicious Code**: Replace the uploaded JS file with a clean version and invalidate CloudFront cache if applicable. +- **Revoke Access**: If compromise is confirmed, revoke the IAM credentials and disable the user. +- **Audit IAM Policies**: Ensure that only deployment users can modify static site buckets. +- **Enable Bucket Versioning**: This can allow for quick rollback and historical review. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws.cloudtrail* metadata _id, _version, _index + +| where + // S3 object read/write activity + event.dataset == "aws.cloudtrail" + and event.provider == "s3.amazonaws.com" + and event.action in ("GetObject", "PutObject") + + // IAM users or assumed roles only + and aws.cloudtrail.user_identity.type in ("IAMUser", "AssumedRole") + + // Requests for static site bundles + and aws.cloudtrail.request_parameters like "*static/js/*.js*" + + // Exclude IaC and automation tools + and not ( + user_agent.original like "*Terraform*" + or user_agent.original like "*Ansible*" + or user_agent.original like "*Pulumni*" + ) + +// Extract fields from request parameters +| dissect aws.cloudtrail.request_parameters + "%{{?bucket.name.key}=%{Esql.aws_cloudtrail_request_parameters_bucket_name}, %{?host.key}=%{Esql_priv.aws_cloudtrail_request_parameters_host}, %{?bucket.object.location.key}=%{Esql.aws_cloudtrail_request_parameters_bucket_object_location}}" + +// Extract file name portion from full object path +| dissect Esql.aws_cloudtrail_request_parameters_object_location "%{}static/js/%{Esql.aws_cloudtrail_request_parameters_object_key}" + +// Match on JavaScript files +| where ends_with(Esql.aws_cloudtrail_request_parameters_object_key, ".js") + +// Retain relevant ECS and dissected fields +| keep + aws.cloudtrail.user_identity.arn, + aws.cloudtrail.user_identity.access_key_id, + aws.cloudtrail.user_identity.type, + aws.cloudtrail.request_parameters, + Esql.aws_cloudtrail_request_parameters_bucket_name, + Esql.aws_cloudtrail_request_parameters_object_key, + user_agent.original, + source.ip, + event.action, + @timestamp + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Impact +** ID: TA0040 +** Reference URL: https://attack.mitre.org/tactics/TA0040/ +* Technique: +** Name: Data Manipulation +** ID: T1565 +** Reference URL: https://attack.mitre.org/techniques/T1565/ +* Sub-technique: +** Name: Stored Data Manipulation +** ID: T1565.001 +** Reference URL: https://attack.mitre.org/techniques/T1565/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-service-quotas-multi-region-getservicequota-requests.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-service-quotas-multi-region-getservicequota-requests.asciidoc new file mode 100644 index 0000000000..26b373b92f --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-service-quotas-multi-region-getservicequota-requests.asciidoc @@ -0,0 +1,147 @@ +[[prebuilt-rule-8-19-4-aws-service-quotas-multi-region-getservicequota-requests]] +=== AWS Service Quotas Multi-Region `GetServiceQuota` Requests + +Identifies when a single AWS resource is making `GetServiceQuota` API calls for the EC2 service quota L-1216C47A in more than 10 regions within a 30-second window. Quota code L-1216C47A represents on-demand instances which are used by adversaries to deploy malware and mine cryptocurrency. This could indicate a potential threat actor attempting to discover the AWS infrastructure across multiple regions using compromised credentials or a compromised instance. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://www.sentinelone.com/labs/exploring-fbot-python-based-malware-targeting-cloud-and-payment-services/ +* https://docs.aws.amazon.com/servicequotas/2019-06-24/apireference/API_GetServiceQuota.html + +*Tags*: + +* Domain: Cloud +* Data Source: AWS +* Data Source: Amazon Web Services +* Data Source: AWS Service Quotas +* Use Case: Threat Detection +* Tactic: Discovery +* Resources: Investigation Guide + +*Version*: 4 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + +> **Disclaimer**: +> 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. + + +*Investigating AWS Service Quotas Multi-Region `GetServiceQuota` Requests* + + +AWS Service Quotas manage resource limits across AWS services, crucial for maintaining operational boundaries. Adversaries may exploit `GetServiceQuota` API calls to probe AWS infrastructure, seeking vulnerabilities for deploying threats like cryptocurrency miners. The detection rule identifies unusual multi-region queries for EC2 quotas, signaling potential credential compromise or unauthorized access attempts. + + +*Possible investigation steps* + + +- Review the AWS CloudTrail logs to identify the specific user or role associated with the `aws.cloudtrail.user_identity.arn` field that triggered the alert. Determine if this user or role should have access to multiple regions. +- Examine the `cloud.region` field to identify which regions were accessed and verify if these regions are typically used by your organization. Investigate any unfamiliar regions for unauthorized activity. +- Check the AWS IAM policies and permissions associated with the identified user or role to ensure they align with the principle of least privilege. Look for any recent changes or anomalies in permissions. +- Investigate the source IP addresses and locations from which the `GetServiceQuota` API calls were made to determine if they match expected patterns for your organization. Look for any unusual or suspicious IP addresses. +- Review recent activity logs for the identified user or role to detect any other unusual or unauthorized actions, such as attempts to launch EC2 instances or access other AWS services. +- If a compromise is suspected, consider rotating the credentials for the affected user or role and implementing additional security measures, such as multi-factor authentication (MFA) and enhanced monitoring. + + +*False positive analysis* + + +- Legitimate multi-region operations: Organizations with a global presence may have legitimate reasons for querying EC2 service quotas across multiple regions. To handle this, users can create exceptions for known accounts or roles that regularly perform such operations. +- Automated infrastructure management tools: Some tools or scripts designed for infrastructure management might perform multi-region `GetServiceQuota` requests as part of their normal operation. Users should identify these tools and exclude their activity from triggering alerts by whitelisting their associated user identities or ARNs. +- Testing and development activities: Developers or testers might intentionally perform multi-region queries during testing phases. Users can mitigate false positives by setting up temporary exceptions for specific time frames or user identities involved in testing. +- Cloud service providers or partners: Third-party services or partners managing AWS resources on behalf of an organization might generate similar patterns. Users should establish trust relationships and exclude these entities from detection by verifying their activities and adding them to an exception list. + + +*Response and remediation* + + +- Immediately isolate the AWS account or IAM user identified in the alert to prevent further unauthorized access. This can be done by disabling the access keys or suspending the account temporarily. +- Conduct a thorough review of the AWS CloudTrail logs for the identified user or resource to determine the extent of the unauthorized activity and identify any other potentially compromised resources. +- Rotate all access keys and passwords associated with the compromised account or IAM user to prevent further unauthorized access. +- Implement additional security measures such as enabling multi-factor authentication (MFA) for all IAM users and roles to enhance account security. +- Notify the security operations team and relevant stakeholders about the potential compromise and the steps being taken to remediate the issue. +- If evidence of compromise is confirmed, consider engaging AWS Support or a third-party incident response team for further investigation and assistance. +- Review and update IAM policies and permissions to ensure the principle of least privilege is enforced, reducing the risk of future unauthorized access attempts. + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws.cloudtrail-* + +// filter for GetServiceQuota API calls +| where + event.dataset == "aws.cloudtrail" + and event.provider == "servicequotas.amazonaws.com" + and event.action == "GetServiceQuota" + +// truncate the timestamp to a 30-second window +| eval Esql.time_window_date_trunc = date_trunc(30 seconds, @timestamp) + +// dissect request parameters to extract service and quota code +| dissect aws.cloudtrail.request_parameters "{%{?Esql.aws_cloudtrail_request_parameters_service_code_key}=%{Esql.aws_cloudtrail_request_parameters_service_code}, %{?quota_code_key}=%{Esql.aws_cloudtrail_request_parameters_quota_code}}" + +// filter for EC2 service quota L-1216C47A (vCPU on-demand instances) +| where Esql.aws_cloudtrail_request_parameters_service_code == "ec2" and Esql.aws_cloudtrail_request_parameters_quota_code == "L-1216C47A" + +// keep only the relevant fields +| keep + Esql.time_window_date_trunc, + aws.cloudtrail.user_identity.arn, + cloud.region, + Esql.aws_cloudtrail_request_parameters_service_code, + Esql.aws_cloudtrail_request_parameters_quota_code + +// count the number of unique regions and total API calls within the time window +| stats + Esql.cloud_region_count_distinct = count_distinct(cloud.region), + Esql.event_count = count(*) + by Esql.time_window_date_trunc, aws.cloudtrail.user_identity.arn + +// filter for API calls in more than 10 regions within the 30-second window +| where + Esql.cloud_region_count_distinct >= 10 + and Esql.event_count >= 10 + +// sort by time window descending +| sort Esql.time_window_date_trunc desc + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Discovery +** ID: TA0007 +** Reference URL: https://attack.mitre.org/tactics/TA0007/ +* Technique: +** Name: Cloud Infrastructure Discovery +** ID: T1580 +** Reference URL: https://attack.mitre.org/techniques/T1580/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-signin-single-factor-console-login-with-federated-user.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-signin-single-factor-console-login-with-federated-user.asciidoc new file mode 100644 index 0000000000..99b8b8a7cb --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-aws-signin-single-factor-console-login-with-federated-user.asciidoc @@ -0,0 +1,136 @@ +[[prebuilt-rule-8-19-4-aws-signin-single-factor-console-login-with-federated-user]] +=== AWS Signin Single Factor Console Login with Federated User + +Identifies when a federated user logs into the AWS Management Console without using multi-factor authentication (MFA). Federated users are typically given temporary credentials to access AWS services. If a federated user logs into the AWS Management Console without using MFA, it may indicate a security risk, as MFA adds an additional layer of security to the authentication process. This could also indicate the abuse of STS tokens to bypass MFA requirements. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://hackingthe.cloud/aws/post_exploitation/create_a_console_session_from_iam_credentials/ + +*Tags*: + +* Domain: Cloud +* Data Source: Amazon Web Services +* Data Source: AWS +* Data Source: AWS Sign-In +* Use Case: Threat Detection +* Tactic: Initial Access +* Resources: Investigation Guide + +*Version*: 4 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + +> **Disclaimer**: +> 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. + + +*Investigating AWS Signin Single Factor Console Login with Federated User* + + +Federated users in AWS are granted temporary credentials to access resources, often without the need for a permanent account. This setup is convenient but can be risky if not properly secured with multi-factor authentication (MFA). Adversaries might exploit this by using stolen or misconfigured credentials to gain unauthorized access. The detection rule identifies instances where federated users log in without MFA, flagging potential security risks by analyzing specific AWS CloudTrail events and dissecting login data to check for the absence of MFA, thus helping to mitigate unauthorized access attempts. + + +*Possible investigation steps* + + +- Review the AWS CloudTrail logs to confirm the event details, focusing on the event.provider, event.action, and aws.cloudtrail.user_identity.type fields to ensure the alert corresponds to a federated user login without MFA. +- Identify the federated user involved by examining the aws.cloudtrail.user_identity.arn field to determine which user or service is associated with the login attempt. +- Check the aws.cloudtrail.additional_eventdata field to verify the mfa_used value is "No" and assess if this is expected behavior for the identified user or service. +- Investigate the source IP address and location of the login attempt to determine if it aligns with typical access patterns for the federated user. +- Review recent activity associated with the federated user to identify any unusual or unauthorized actions that may have occurred following the login event. +- Assess the configuration and policies of the Identity Provider (IdP) used for federated access to ensure MFA is enforced and properly configured for all users. + + +*False positive analysis* + + +- Federated users with specific roles or permissions may frequently log in without MFA due to operational requirements. Review these roles and consider adding them to an exception list if they are deemed non-threatening. +- Automated processes or scripts using federated credentials might trigger this rule if they are not configured to use MFA. Verify these processes and, if legitimate, exclude them from the rule to prevent unnecessary alerts. +- Temporary testing or development accounts might be set up without MFA for convenience. Ensure these accounts are monitored and, if necessary, excluded from the rule to avoid false positives. +- Third-party integrations or services that rely on federated access without MFA could be flagged. Assess these integrations and whitelist them if they are secure and necessary for business operations. +- Users accessing AWS from secure, controlled environments might not use MFA as part of a risk-based authentication strategy. Evaluate the security of these environments and consider excluding them if they meet your organization's security standards. + + +*Response and remediation* + + +- Immediately revoke the temporary credentials associated with the federated user account to prevent further unauthorized access. +- Conduct a thorough review of AWS CloudTrail logs to identify any suspicious activities or unauthorized access attempts associated with the federated user account. +- Notify the security team and relevant stakeholders about the potential security breach to ensure coordinated response efforts. +- Implement or enforce multi-factor authentication (MFA) for all federated user accounts to enhance security and prevent similar incidents in the future. +- Review and update IAM policies and roles associated with federated users to ensure they follow the principle of least privilege. +- Escalate the incident to the incident response team if any malicious activities are detected, and initiate a full security investigation to assess the impact and scope of the breach. +- Monitor AWS CloudTrail and other relevant logs closely for any further unauthorized access attempts or anomalies related to federated user accounts. + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws.cloudtrail-* metadata _id, _version, _index + +| where + event.provider == "signin.amazonaws.com" + and event.action == "GetSigninToken" + and aws.cloudtrail.event_type == "AwsConsoleSignIn" + and aws.cloudtrail.user_identity.type == "FederatedUser" + +// Extract mobile version and MFA usage +| dissect aws.cloudtrail.additional_eventdata + "{%{?mobile_version_key}=%{Esql.aws_cloudtrail_additional_eventdata_device_version}, %{?mfa_used_key}=%{Esql.aws_cloudtrail_additional_eventdata_auth_mfa_used}}" + +// Only keep events where MFA was not used +| where Esql.aws_cloudtrail_additional_eventdata_auth_mfa_used == "No" + +// keep relevant ECS and dissected fields +| keep + @timestamp, + event.action, + aws.cloudtrail.event_type, + aws.cloudtrail.user_identity.type, + Esql.aws_cloudtrail_additional_eventdata_device_version, + Esql.aws_cloudtrail_additional_eventdata_auth_mfa_used + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Initial Access +** ID: TA0001 +** Reference URL: https://attack.mitre.org/tactics/TA0001/ +* Technique: +** Name: Valid Accounts +** ID: T1078 +** Reference URL: https://attack.mitre.org/techniques/T1078/ +* Sub-technique: +** Name: Cloud Accounts +** ID: T1078.004 +** Reference URL: https://attack.mitre.org/techniques/T1078/004/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-azure-openai-insecure-output-handling.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-azure-openai-insecure-output-handling.asciidoc new file mode 100644 index 0000000000..2aa330ca1e --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-azure-openai-insecure-output-handling.asciidoc @@ -0,0 +1,125 @@ +[[prebuilt-rule-8-19-4-azure-openai-insecure-output-handling]] +=== Azure OpenAI Insecure Output Handling + +Detects when Azure OpenAI requests result in zero response length, potentially indicating issues in output handling that might lead to security exploits such as data leaks or code execution. This can occur in cases where the API fails to handle outputs correctly under certain input conditions. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 10m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://genai.owasp.org/llmrisk/llm02-insecure-output-handling + +*Tags*: + +* Domain: LLM +* Data Source: Azure OpenAI +* Data Source: Azure Event Hubs +* Use Case: Insecure Output Handling +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + +> **Disclaimer**: +> 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. + + +*Investigating Azure OpenAI Insecure Output Handling* + + +Azure OpenAI integrates AI capabilities into applications, enabling natural language processing tasks. However, improper output handling can lead to vulnerabilities, such as data leaks or unauthorized code execution. Adversaries might exploit these by crafting inputs that cause the API to mishandle responses. The detection rule identifies anomalies by flagging instances where API responses are unexpectedly empty, suggesting potential misuse or misconfiguration, especially when such events occur frequently. + + +*Possible investigation steps* + + +- Review the logs for the specific Azure resource name flagged in the alert to understand the context and frequency of zero-length responses. +- Examine the request lengths associated with the zero-length responses to identify any patterns or anomalies in the input data that might be causing the issue. +- Check the cloud account ID associated with the alert to determine if there are any known issues or recent changes in configuration that could affect output handling. +- Investigate the operation name "ChatCompletions_Create" to ensure that the API is being used as intended and that there are no unauthorized or unexpected uses. +- Assess the overall environment for any recent updates or changes in the Azure OpenAI configuration that might have impacted output handling. + + +*False positive analysis* + + +- Frequent legitimate requests with zero response length can occur during testing or development phases. To manage this, exclude known test environments or accounts from the detection rule by adding exceptions for specific cloud.account.id or azure.resource.name values. +- Some applications may intentionally send requests that do not require a response, resulting in zero response length. Identify these applications and adjust the rule to exclude their specific azure.resource.name. +- Network issues or temporary service disruptions can lead to zero-length responses. Monitor for patterns of such occurrences and consider excluding specific time frames or network segments if they are known to cause false positives. +- Automated scripts or bots that interact with the API might generate zero-length responses as part of their normal operation. Identify these scripts and exclude their associated identifiers from the rule to prevent false alerts. + + +*Response and remediation* + + +- Immediately isolate the affected Azure OpenAI resource to prevent further exploitation. This can be done by temporarily disabling the API or restricting access to it. +- Review and validate the input handling mechanisms of the affected API to ensure they are robust against malformed or malicious inputs that could lead to insecure output handling. +- Conduct a thorough audit of recent API requests and responses to identify any unauthorized access or data leaks. Pay special attention to requests with zero response length. +- Implement additional logging and monitoring for the affected API to capture detailed information about requests and responses, which can help in identifying patterns or repeated attempts of exploitation. +- Notify the security team and relevant stakeholders about the incident, providing them with detailed findings and any potential impact on data security. +- If unauthorized access or data leakage is confirmed, follow the organization's incident response plan to notify affected parties and comply with any regulatory requirements. +- Enhance detection capabilities by integrating anomaly detection tools that can identify unusual patterns in API usage, such as frequent zero-length responses, to prevent similar threats in the future. + + +==== Setup + + + +*Setup* + + +For more information on streaming events, see the Azure OpenAI documentation: + +https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/stream-monitoring-data-event-hubs + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-azure_openai.logs-* +| where + azure.open_ai.properties.response_length == 0 and + azure.open_ai.result_signature == "200" and + azure.open_ai.operation_name == "ChatCompletions_Create" +| keep + azure.open_ai.properties.request_length, + azure.open_ai.result_signature, + cloud.account.id, + azure.resource.name +| stats + Esql.event_count = count(*) + by + azure.resource.name +| where + Esql.event_count >= 10 +| sort + Esql.event_count desc + +---------------------------------- diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-dynamic-iex-reconstruction-via-method-string-access.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-dynamic-iex-reconstruction-via-method-string-access.asciidoc new file mode 100644 index 0000000000..f667d67aff --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-dynamic-iex-reconstruction-via-method-string-access.asciidoc @@ -0,0 +1,180 @@ +[[prebuilt-rule-8-19-4-dynamic-iex-reconstruction-via-method-string-access]] +=== Dynamic IEX Reconstruction via Method String Access + +Identifies PowerShell scripts that reconstruct the IEX (Invoke-Expression) command by accessing and indexing the string representation of method references. This obfuscation technique uses constructs like ''.IndexOf.ToString() to expose method metadata as a string, then extracts specific characters through indexed access and joins them to form IEX, bypassing static keyword detection and evading defenses such as AMSI. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Windows +* Use Case: Threat Detection +* Tactic: Defense Evasion +* Data Source: PowerShell Logs +* Resources: Investigation Guide + +*Version*: 4 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Dynamic IEX Reconstruction via Method String Access* + + +PowerShell's flexibility allows dynamic command execution, which adversaries exploit by obfuscating commands like Invoke-Expression (IEX). They manipulate method strings to reconstruct IEX, evading static detection. The detection rule identifies scripts using this obfuscation by analyzing patterns in method string access, flagging suspicious activity for further investigation. + + +*Possible investigation steps* + + +- Review the powershell.file.script_block_text field to understand the content and intent of the script that triggered the alert. Look for any suspicious patterns or obfuscation techniques. +- Examine the file.path field to determine the location of the script on the host system, which can provide context about its origin and potential legitimacy. +- Check the host.name and user.id fields to identify the machine and user account involved in executing the script, which can help assess whether the activity aligns with expected behavior. +- Analyze the powershell.file.script_block_id and powershell.sequence fields to trace the execution sequence and correlate it with other PowerShell activities on the host, providing a broader view of the script's execution context. +- Investigate the agent.id field to verify the endpoint's security posture and ensure that it is up-to-date with the latest security patches and configurations. + + +*False positive analysis* + + +- Scripts with legitimate use of string manipulation methods like IndexOf or SubString may trigger false positives if they are part of complex PowerShell scripts used in administrative tasks. To manage this, review the context of the script and consider adding exceptions for known safe scripts or users. +- Automated scripts from trusted software that perform extensive string operations for configuration or data processing might be flagged. Identify these scripts and exclude them by their script block ID or file path to prevent unnecessary alerts. +- Development environments where PowerShell is used for testing or debugging purposes may generate alerts due to frequent use of string manipulation. Implement exclusions based on host names or user IDs associated with these environments to reduce noise. +- Security tools or monitoring solutions that use PowerShell for log analysis or system checks might inadvertently match the detection pattern. Verify the source of the script and whitelist these tools by agent ID or specific script characteristics. +- Regularly review and update the exclusion list to ensure it reflects the current environment and does not inadvertently allow malicious activity. + + +*Response and remediation* + + +- Isolate the affected host immediately to prevent further execution of potentially malicious scripts and limit lateral movement within the network. +- Terminate any suspicious PowerShell processes identified by the alert to stop ongoing malicious activity. +- Review the PowerShell script block text and script block ID from the alert to understand the scope and intent of the obfuscation technique used. +- Remove any unauthorized or malicious scripts from the affected system to prevent re-execution. +- Conduct a thorough scan of the isolated host using updated antivirus and anti-malware tools to identify and remove any additional threats. +- Restore the affected system from a known good backup if the integrity of the system is compromised and cannot be assured. +- Escalate the incident to the security operations center (SOC) or incident response team for further analysis and to determine if additional systems are affected. + + +==== Setup + + + +*Setup* + + +The 'PowerShell Script Block Logging' logging policy must be enabled. +Steps to implement the logging policy with Advanced Audit Configuration: + +``` +Computer Configuration > +Administrative Templates > +Windows PowerShell > +Turn on PowerShell Script Block Logging (Enable) +``` + +Steps to implement the logging policy via registry: + +``` +reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1 +``` + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" + +// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for +| eval Esql.script_block_length = length(powershell.file.script_block_text) +| where Esql.script_block_length > 500 + +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them +// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 +| eval Esql.script_block_tmp = replace( + powershell.file.script_block_text, + """(?i)['"]['"].(Insert|Normalize|Chars|substring|Remove|LastIndexOfAny|LastIndexOf|IsNormalized|IndexOfAny|IndexOf)[^\[]+\[\d+,\d+,\d+\]""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_length, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least once +| where Esql.script_block_pattern_count >= 1 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Defense Evasion +** ID: TA0005 +** Reference URL: https://attack.mitre.org/tactics/TA0005/ +* Technique: +** Name: Obfuscated Files or Information +** ID: T1027 +** Reference URL: https://attack.mitre.org/techniques/T1027/ +* Technique: +** Name: Deobfuscate/Decode Files or Information +** ID: T1140 +** Reference URL: https://attack.mitre.org/techniques/T1140/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: PowerShell +** ID: T1059.001 +** Reference URL: https://attack.mitre.org/techniques/T1059/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-elastic-security-external-alerts.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-elastic-security-external-alerts.asciidoc new file mode 100644 index 0000000000..01f24bb7b9 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-elastic-security-external-alerts.asciidoc @@ -0,0 +1,118 @@ +[[prebuilt-rule-8-19-4-elastic-security-external-alerts]] +=== Elastic Security External Alerts + +Generates a detection alert for each Elastic Security alert written to the configured indices. Enabling this rule allows you to immediately begin investigating Elastic Security alerts in the app. + +*Rule type*: query + +*Rule indices*: + +* logs-elastic_security.alert-* + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 1m + +*Searches indices from*: now-2m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 1000 + +*References*: + +* https://docs.elastic.co/en/integrations/elastic_security + +*Tags*: + +* Data Source: Elastic Security +* Use Case: Threat Detection +* Resources: Investigation Guide +* Promotion: External Alerts + +*Version*: 2 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Elastic Security External Alerts* + + +The Elastic Security integration facilitates transferring security alert data from another Elasticsearch instance to your own, enabling threats to be investigated in a centralized manner. + + +*Possible investigation steps* + + +- Correlate the alert with recent activity on the affected endpoint to identify any unusual or suspicious behavior patterns. +- Check for any additional alerts or logs related to the same endpoint or user to determine if this is part of a broader attack or isolated incident. +- Investigate the source and destination IP addresses involved in the alert to assess if they are known to be malicious or associated with previous threats. +- Analyze any files or processes flagged in the alert to determine if they are legitimate or potentially malicious, using threat intelligence sources if necessary. +- Consult the Elastic Security investigation guide and resources tagged in the alert for specific guidance on handling similar threats. + + +*False positive analysis* + + +- Alerts triggered by routine software updates or patches can be false positives. Review the context of the alert to determine if it aligns with scheduled maintenance activities. +- Legitimate administrative tools or scripts may trigger alerts. Identify and whitelist these tools if they are verified as non-threatening. +- Frequent alerts from known safe applications or processes can be excluded by creating exceptions for these specific behaviors in the Elastic Security configuration. +- Network scanning or monitoring tools used by IT teams might be flagged. Ensure these tools are documented and excluded from triggering alerts if they are part of regular operations. +- User behavior that is consistent with their role but triggers alerts should be reviewed. If deemed non-malicious, adjust the rule to exclude these specific user actions. + + +*Response and remediation* + + +- Isolate the affected endpoint immediately to prevent lateral movement and further compromise within the network. +- Analyze the specific alert details to identify the nature of the threat and any associated indicators of compromise (IOCs). +- Remove or quarantine any malicious files or processes identified by the Elastic Security alert to neutralize the threat. +- Apply relevant security patches or updates to address any exploited vulnerabilities on the affected endpoint. +- Conduct a thorough scan of the network to identify any additional endpoints that may have been compromised or are exhibiting similar behavior. +- Document the incident and escalate to the appropriate security team or management if the threat is part of a larger attack campaign or if additional resources are needed for remediation. +- Review and update endpoint protection policies and configurations to enhance detection and prevention capabilities against similar threats in the future. + + +==== Setup + + + +*Setup* + + + +*Elastic Security Alert Integration* + +This rule is designed to capture alert events generated by the Elastic Security integration and promote them as Elastic detection alerts. + +To capture Elastic Security alerts, install and configure the Elastic Security integration to ingest alert events into the `logs-elastic_security.alert-*` index pattern. + +If this rule is enabled alongside the External Alerts promotion rule (UUID: eb079c62-4481-4d6e-9643-3ca499df7aaa), you may receive duplicate alerts for the same Elastic Security events. Consider adding a rule exception for the External Alert rule to exclude data_stream.dataset:elastic_security.alert to avoid receiving duplicate alerts. + + +*Additional notes* + + +For information on troubleshooting the maximum alerts warning please refer to this https://www.elastic.co/guide/en/security/current/alerts-ui-monitor.html#troubleshoot-max-alerts[guide]. + + +==== Rule query + + +[source, js] +---------------------------------- +event.kind: alert and data_stream.dataset: elastic_security.alert + +---------------------------------- diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-excessive-secret-or-key-retrieval-from-azure-key-vault.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-excessive-secret-or-key-retrieval-from-azure-key-vault.asciidoc new file mode 100644 index 0000000000..c5adc73a9b --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-excessive-secret-or-key-retrieval-from-azure-key-vault.asciidoc @@ -0,0 +1,208 @@ +[[prebuilt-rule-8-19-4-excessive-secret-or-key-retrieval-from-azure-key-vault]] +=== Excessive Secret or Key Retrieval from Azure Key Vault + +Identifies excessive secret or key retrieval operations from Azure Key Vault. This rule detects when a user principal retrieves secrets or keys from Azure Key Vault multiple times within a short time frame, which may indicate potential abuse or unauthorized access attempts. The rule focuses on high-frequency retrieval operations that deviate from normal user behavior, suggesting possible credential harvesting or misuse of sensitive information. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 43 + +*Runs every*: 8m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://www.inversecos.com/2022/05/detection-and-compromise-azure-key.html + +*Tags*: + +* Domain: Cloud +* Domain: Storage +* Domain: Identity +* Data Source: Azure +* Data Source: Azure Platform Logs +* Data Source: Azure Key Vault +* Use Case: Threat Detection +* Use Case: Identity and Access Audit +* Tactic: Credential Access +* Resources: Investigation Guide + +*Version*: 2 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Excessive Secret or Key Retrieval from Azure Key Vault* + + +Azure Key Vault is a cloud service that safeguards encryption keys and secrets like certificates, connection strings, and passwords. It is crucial for managing sensitive data in Azure environments. Unauthorized modifications to Key Vaults can lead to data breaches or service disruptions. This rule detects excessive secret or key retrieval operations from Azure Key Vault, which may indicate potential abuse or unauthorized access attempts. + + +*Possible investigation steps* + +- Review the `azure.platformlogs.identity.claim.upn` field to identify the user principal making the retrieval requests. This can help determine if the activity is legitimate or suspicious. +- Check the `azure.platformlogs.identity.claim.appid` or `azure.platformlogs.identity.claim.appid_display_name` to identify the application or service making the requests. If the application is not recognized or authorized, it may indicate a potential security incident. It is plausible that the application is a FOCI compliant application, which are commonly abused by adversaries to evade security controls or conditional access policies. +- Analyze the `azure.platformlogs.resource.name` field to determine which Key Vault is being accessed. This can help assess the impact of the retrieval operations and whether they target sensitive resources. +- Review the `event.action` field to confirm the specific actions being performed, such as `KeyGet`, `SecretGet`, or `CertificateGet`. These actions indicate retrieval of keys, secrets, or certificates from the Key Vault. +- Check the `source.ip` or `geo.*` fields to identify the source of the retrieval requests. Look for unusual or unexpected IP addresses, especially those associated with known malicious activity or geographic locations that do not align with the user's typical behavior. +- Use the `time_window` field to analyze the frequency of retrieval operations. If multiple retrievals occur within a short time frame (e.g., within a few minutes), it may indicate excessive or suspicious activity. +- Correlate the retrieval operations with other security events or alerts in the environment to identify any patterns or related incidents. +- Triage the user with Entra ID sign-in logs to gather more context about their authentication behavior and any potential anomalies. + + +*False positive analysis* + +- Routine administrative tasks or automated scripts may trigger excessive retrievals, especially in environments where Key Vaults are heavily utilized for application configurations or secrets management. If this is expected behavior, consider adjusting the rule or adding exceptions for specific applications or user principals. +- Legitimate applications or services may perform frequent retrievals of keys or secrets for operational purposes, such as configuration updates or secret rotation. If this is expected behavior, consider adjusting the rule or adding exceptions for specific applications or user principals. +- Security teams may perform periodic audits or assessments that involve retrieving keys or secrets from Key Vaults. If this is expected behavior, consider adjusting the rule or adding exceptions for specific user principals or applications. +- Some applications may require frequent access to keys or secrets for normal operation, leading to high retrieval counts. If this is expected behavior, consider adjusting the rule or adding exceptions for specific applications or user principals. + + +*Response and remediation* + +- Investigate the user principal making the excessive retrieval requests to determine if they are authorized to access the Key Vault and its contents. If the user is not authorized, take appropriate actions to block their access and prevent further unauthorized retrievals. +- Review the application or service making the requests to ensure it is legitimate and authorized to access the Key Vault. If the application is unauthorized or suspicious, consider blocking it and revoking its permissions to access the Key Vault. +- Assess the impact of the excessive retrieval operations on the Key Vault and its contents. Determine if any sensitive data was accessed or compromised during the retrievals. +- Implement additional monitoring and alerting for the Key Vault to detect any further suspicious activity or unauthorized access attempts. +- Consider implementing stricter access controls or policies for Key Vaults to limit excessive retrievals and ensure that only authorized users and applications can access sensitive keys and secrets. +- Educate users and administrators about the risks associated with excessive retrievals from Key Vaults and encourage them to follow best practices for managing keys and secrets in Azure environments. + + +==== Setup + + + +*Required Azure Key Vault Diagnostic Logs* + + +To ensure this rule functions correctly, the following diagnostic logs must be enabled for Azure Key Vault: +- AuditEvent: This log captures all read and write operations performed on the Key Vault, including secret, key, and certificate retrievals. These logs should be streamed to the Event Hub used for the Azure integration configuration. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-azure.platformlogs-* metadata _id, _index + +// Filter for Azure Key Vault read operations +| where event.dataset == "azure.platformlogs" + and event.action in ( + "VaultGet", + "KeyGet", + "KeyList", + "KeyListVersions", + "KeyGetDeleted", + "KeyListDeleted", + "SecretGet", + "SecretList", + "SecretListVersions", + "SecretGetDeleted", + "SecretListDeleted", + "CertificateGet", + "CertificateList", + "CertificateListVersions", + "CertificateGetDeleted", + "CertificateListDeleted", + "CertificatePolicyGet", + "CertificateContactsGet", + "CertificateIssuerGet", + "CertificateIssuersList" + ) + +// Truncate timestamps into 1-minute windows +| eval Esql.time_window_date_trunc = date_trunc(1 minute, @timestamp) + +// Aggregate identity, geo, resource, and activity info +| stats + Esql_priv.azure_platformlogs_identity_claim_upn_values = values(azure.platformlogs.identity.claim.upn), + Esql.azure_platformlogs_identity_claim_upn_count_distinct = count_distinct(azure.platformlogs.identity.claim.upn), + Esql.azure_platformlogs_identity_claim_appid_values = values(azure.platformlogs.identity.claim.appid), + Esql.azure_platformlogs_identity_claim_objectid_values = values(azure.platformlogs.identity.claim.objectid), + + Esql.source_ip_values = values(source.ip), + Esql.geo_city_values = values(geo.city_name), + Esql.geo_region_values = values(geo.region_name), + Esql.geo_country_values = values(geo.country_name), + Esql.source_as_organization_name_values = values(source.as.organization.name), + + Esql.event_action_values = values(event.action), + Esql.event_count = count(*), + Esql.event_action_count_distinct = count_distinct(event.action), + Esql.azure_resource_name_count_distinct = count_distinct(azure.resource.name), + Esql.azure_resource_name_values = values(azure.resource.name), + Esql.azure_platformlogs_result_type_values = values(azure.platformlogs.result_type), + Esql.cloud_region_values = values(cloud.region), + + Esql.agent_name_values = values(agent.name), + Esql.azure_subscription_id_values = values(azure.subscription_id), + Esql.azure_resource_group_values = values(azure.resource.group), + Esql.azure_resource_id_values = values(azure.resource.id) + +by Esql.time_window_date_trunc, azure.platformlogs.identity.claim.upn + +// keep relevant fields +| keep + Esql.time_window_date_trunc, + Esql_priv.azure_platformlogs_identity_claim_upn_values, + Esql.azure_platformlogs_identity_claim_upn_count_distinct, + Esql.azure_platformlogs_identity_claim_appid_values, + Esql.azure_platformlogs_identity_claim_objectid_values, + Esql.source_ip_values, + Esql.geo_city_values, + Esql.geo_region_values, + Esql.geo_country_values, + Esql.source_as_organization_name_values, + Esql.event_action_values, + Esql.event_count, + Esql.event_action_count_distinct, + Esql.azure_resource_name_count_distinct, + Esql.azure_resource_name_values, + Esql.azure_platformlogs_result_type_values, + Esql.cloud_region_values, + Esql.agent_name_values, + Esql.azure_subscription_id_values, + Esql.azure_resource_group_values, + Esql.azure_resource_id_values + +// Filter for suspiciously high volume of distinct Key Vault reads by a single actor +| where Esql.azure_platformlogs_identity_claim_upn_count_distinct == 1 and Esql.event_count >= 10 and Esql.event_action_count_distinct >= 2 + +| sort Esql.time_window_date_trunc desc + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Credential Access +** ID: TA0006 +** Reference URL: https://attack.mitre.org/tactics/TA0006/ +* Technique: +** Name: Credentials from Password Stores +** ID: T1555 +** Reference URL: https://attack.mitre.org/techniques/T1555/ +* Sub-technique: +** Name: Cloud Secrets Management Stores +** ID: T1555.006 +** Reference URL: https://attack.mitre.org/techniques/T1555/006/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-high-number-of-egress-network-connections-from-unusual-executable.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-high-number-of-egress-network-connections-from-unusual-executable.asciidoc new file mode 100644 index 0000000000..c6b0177e9a --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-high-number-of-egress-network-connections-from-unusual-executable.asciidoc @@ -0,0 +1,190 @@ +[[prebuilt-rule-8-19-4-high-number-of-egress-network-connections-from-unusual-executable]] +=== High Number of Egress Network Connections from Unusual Executable + +This rule detects a high number of egress network connections from an unusual executable on a Linux system. This could indicate a command and control (C2) communication attempt, a brute force attack via a malware infection, or other malicious activity. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 1h + +*Searches indices from*: now-61m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Linux +* Use Case: Threat Detection +* Tactic: Command and Control +* Data Source: Elastic Defend +* Resources: Investigation Guide + +*Version*: 5 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + +> **Disclaimer**: +> 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. + + +*Investigating High Number of Egress Network Connections from Unusual Executable* + + +In Linux environments, executables can initiate network connections for legitimate purposes. However, adversaries exploit this by deploying malware in temporary directories to establish command and control (C2) channels. The detection rule identifies unusual executables making numerous outbound connections, excluding trusted IP ranges and known benign paths, to flag potential threats. + + +*Possible investigation steps* + + +- Review the process.executable field to identify the specific executable making the connections and determine if it is known or expected in the environment. +- Examine the destination.ip field to identify the external IP addresses the executable is attempting to connect to and check if they are known malicious or suspicious. +- Check the host.os.type and agent.id fields to identify the specific host and agent involved, and gather additional context about the system's role and recent activity. +- Analyze the @timestamp field to correlate the timing of the connections with other events or activities on the network or host. +- Cross-reference the identified executable and IP addresses with threat intelligence sources to determine if they are associated with known threats or campaigns. +- If the executable is determined to be malicious or suspicious, isolate the affected host and perform a deeper forensic analysis to identify any additional indicators of compromise or lateral movement. + + +*False positive analysis* + + +- Executables in temporary directories used by legitimate applications or scripts can trigger alerts. Review the process name and executable path to determine if they are associated with known applications or scripts. +- Automated scripts or cron jobs that perform network operations might be flagged. Identify these scripts and consider excluding their paths from the rule if they are verified as non-malicious. +- Development or testing environments often use temporary directories for network operations. If these environments are known and trusted, add their specific paths to the exclusion list. +- Backup or synchronization tools that use temporary directories for data transfer can generate numerous connections. Verify these tools and exclude their paths if they are confirmed to be safe. +- Security tools or monitoring agents that operate in temporary directories might be mistakenly flagged. Confirm their legitimacy and exclude their paths to prevent false positives. + + +*Response and remediation* + + +- Isolate the affected host immediately from the network to prevent further potential malicious communication and lateral movement. +- Terminate the suspicious process identified by the alert to stop any ongoing malicious activity. +- Conduct a forensic analysis of the affected system to identify any additional indicators of compromise (IOCs) and assess the extent of the infection. +- Remove any malicious executables or files found in temporary directories such as /tmp, /var/tmp, or /dev/shm to eliminate the threat. +- Patch and update the affected system to the latest security standards to close any vulnerabilities that may have been exploited. +- Monitor network traffic for any unusual outbound connections from other systems to detect potential spread or similar threats. +- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to ensure comprehensive remediation. + + +==== Setup + + + +*Setup* + + +This rule requires data coming in from Elastic Defend. + + +*Elastic Defend Integration Setup* + +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. + + +*Prerequisite Requirements:* + +- Fleet is required for Elastic Defend. +- To configure Fleet Server refer to the https://www.elastic.co/guide/en/fleet/current/fleet-server.html[documentation]. + + +*The following steps should be executed in order to add the Elastic Defend integration on a Linux System:* + +- Go to the Kibana home page and click "Add integrations". +- In the query bar, search for "Elastic Defend" and select the integration to see more details about it. +- Click "Add Elastic Defend". +- Configure the integration name and optionally add a description. +- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads". +- 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. https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html[Helper guide]. +- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions" +- 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. +For more details on Elastic Agent configuration settings, refer to the https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html[helper guide]. +- Click "Save and Continue". +- 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 https://www.elastic.co/guide/en/security/current/install-endpoint.html[helper guide]. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-endpoint.events.network-* +| where + @timestamp > now() - 1h and + host.os.type == "linux" and + event.type == "start" and + event.action == "connection_attempted" and + ( + process.executable like "/tmp/*" or + process.executable like "/var/tmp/*" or + process.executable like "/dev/shm/*" or + process.name rlike ".*" + ) and not ( + cidr_match(destination.ip, + "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", + "192.0.0.0/24", "192.0.0.29/32", "192.0.0.8/32", "192.0.0.9/32", + "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24", + "192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", + "224.0.0.0/4", "100.64.0.0/10", "192.175.48.0/24", "198.18.0.0/15", + "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1", "FE80::/10", "FF00::/8" + ) or + process.executable like "/nix/store/*" or + process.executable like "/tmp/newroot/*" or + process.executable like "/tmp/.mount*" or + process.executable like "/tmp/go-build*" + ) +| keep + @timestamp, + host.os.type, + event.type, + event.action, + process.name, + process.executable, + destination.ip, + agent.id, + host.name +| stats + Esql.event_count = count(), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.executable +| where + Esql.agent_id_count_distinct == 1 and + Esql.event_count > 15 +| sort Esql.event_count asc +| limit 100 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Command and Control +** ID: TA0011 +** Reference URL: https://attack.mitre.org/tactics/TA0011/ +* Technique: +** Name: Application Layer Protocol +** ID: T1071 +** Reference URL: https://attack.mitre.org/techniques/T1071/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-high-number-of-okta-device-token-cookies-generated-for-authentication.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-high-number-of-okta-device-token-cookies-generated-for-authentication.asciidoc new file mode 100644 index 0000000000..5b7a504bab --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-high-number-of-okta-device-token-cookies-generated-for-authentication.asciidoc @@ -0,0 +1,164 @@ +[[prebuilt-rule-8-19-4-high-number-of-okta-device-token-cookies-generated-for-authentication]] +=== High Number of Okta Device Token Cookies Generated for Authentication + +Detects when an Okta client address has a certain threshold of Okta user authentication events with multiple device token hashes generated for single user authentication. Adversaries may attempt to launch a credential stuffing or password spraying attack from the same device by using a list of known usernames and passwords to gain unauthorized access to user accounts. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://support.okta.com/help/s/article/How-does-the-Device-Token-work?language=en_US +* https://developer.okta.com/docs/reference/api/event-types/ +* https://www.elastic.co/security-labs/testing-okta-visibility-and-detection-dorothy +* https://sec.okta.com/articles/2023/08/cross-tenant-impersonation-prevention-and-detection +* https://www.okta.com/resources/whitepaper-how-adaptive-mfa-can-help-in-mitigating-brute-force-attacks/ +* https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security +* https://www.elastic.co/security-labs/starter-guide-to-understanding-okta + +*Tags*: + +* Use Case: Identity and Access Audit +* Data Source: Okta +* Tactic: Credential Access +* Resources: Investigation Guide + +*Version*: 206 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating High Number of Okta Device Token Cookies Generated for Authentication* + + +This rule detects when a certain threshold of Okta user authentication events are reported for multiple users from the same client address. Adversaries may attempt to launch a credential stuffing attack from the same device by using a list of known usernames and passwords to gain unauthorized access to user accounts. Note that Okta does not log unrecognized usernames supplied during authentication attempts, so this rule may not detect all credential stuffing attempts or may indicate a targeted attack. + + +*Possible investigation steps:* + +- Since this is an ESQL rule, the `okta.actor.alternate_id` and `okta.client.ip` values can be used to pivot into the raw authentication events related to this activity. +- Identify the users involved in this action by examining the `okta.actor.id`, `okta.actor.type`, `okta.actor.alternate_id`, and `okta.actor.display_name` fields. +- Determine the device client used for these actions by analyzing `okta.client.ip`, `okta.client.user_agent.raw_user_agent`, `okta.client.zone`, `okta.client.device`, and `okta.client.id` fields. +- Review the `okta.security_context.is_proxy` field to determine if the device is a proxy. + - If the device is a proxy, this may indicate that a user is using a proxy to access multiple accounts for password spraying. +- With the list of `okta.actor.alternate_id` values, review `event.outcome` results to determine if the authentication was successful. + - If the authentication was successful for any user, pivoting to `event.action` values for those users may provide additional context. +- With Okta end users identified, review the `okta.debug_context.debug_data.dt_hash` field. + - Historical analysis should indicate if this device token hash is commonly associated with the user. +- Review the `okta.event_type` field to determine the type of authentication event that occurred. + - If the event type is `user.authentication.sso`, the user may have legitimately started a session via a proxy for security or privacy reasons. + - If the event type is `user.authentication.password`, the user may be using a proxy to access multiple accounts for password spraying. + - If the event type is `user.session.start`, the source may have attempted to establish a session via the Okta authentication API. +- Examine the `okta.outcome.result` field to determine if the authentication was successful. +- Review the past activities of the actor(s) involved in this action by checking their previous actions. +- Evaluate the actions that happened just before and after this event in the `okta.event_type` field to help understand the full context of the activity. + - This may help determine the authentication and authorization actions that occurred between the user, Okta and application. + + +*False positive analysis:* + +- A user may have legitimately started a session via a proxy for security or privacy reasons. +- Users may share an endpoint related to work or personal use in which separate Okta accounts are used. + - Architecturally, this shared endpoint may leverage a proxy for security or privacy reasons. + - Shared systems such as Kiosks and conference room computers may be used by multiple users. + - Shared working spaces may have a single endpoint that is used by multiple users. + + +*Response and remediation:* + +- Review the profile of the users involved in this action to determine if proxy usage may be expected. +- If the user is legitimate and the authentication behavior is not suspicious based on device analysis, no action is required. +- If the user is legitimate but the authentication behavior is suspicious, consider resetting passwords for the users involves and enabling multi-factor authentication (MFA). + - If MFA is already enabled, consider resetting MFA for the users. +- If any of the users are not legitimate, consider deactivating the user's account. +- Conduct a review of Okta policies and ensure they are in accordance with security best practices. +- Check with internal IT teams to determine if the accounts involved recently had MFA reset at the request of the user. + - If so, confirm with the user this was a legitimate request. + - If so and this was not a legitimate request, consider deactivating the user's account temporarily. + - Reset passwords and reset MFA for the user. +- If this is a false positive, consider adding the `okta.debug_context.debug_data.dt_hash` field to the `exceptions` list in the rule. + - This will prevent future occurrences of this event for this device from triggering the rule. + - Alternatively adding `okta.client.ip` or a CIDR range to the `exceptions` list can prevent future occurrences of this event from triggering the rule. + - This should be done with caution as it may prevent legitimate alerts from being generated. + + +==== Setup + + +The Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule. + +==== Rule query + + +[source, js] +---------------------------------- +from logs-okta* +| where + event.dataset == "okta.system" and + (event.action rlike "user\.authentication(.*)" or event.action == "user.session.start") and + okta.debug_context.debug_data.request_uri == "/api/v1/authn" and + okta.outcome.reason == "INVALID_CREDENTIALS" +| keep + event.action, + okta.debug_context.debug_data.dt_hash, + okta.client.ip, + okta.actor.alternate_id, + okta.debug_context.debug_data.request_uri, + okta.outcome.reason +| stats + Esql.okta_debug_context_debug_data_dt_hash_count_distinct = count_distinct(okta.debug_context.debug_data.dt_hash) + by + okta.client.ip, + okta.actor.alternate_id +| where + Esql.okta_debug_context_debug_data_dt_hash_count_distinct >= 30 +| sort + Esql.okta_debug_context_debug_data_dt_hash_count_distinct desc + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Credential Access +** ID: TA0006 +** Reference URL: https://attack.mitre.org/tactics/TA0006/ +* Technique: +** Name: Brute Force +** ID: T1110 +** Reference URL: https://attack.mitre.org/techniques/T1110/ +* Sub-technique: +** Name: Password Spraying +** ID: T1110.003 +** Reference URL: https://attack.mitre.org/techniques/T1110/003/ +* Technique: +** Name: Brute Force +** ID: T1110 +** Reference URL: https://attack.mitre.org/techniques/T1110/ +* Sub-technique: +** Name: Credential Stuffing +** ID: T1110.004 +** Reference URL: https://attack.mitre.org/techniques/T1110/004/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-m365-onedrive-excessive-file-downloads-with-oauth-token.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-m365-onedrive-excessive-file-downloads-with-oauth-token.asciidoc new file mode 100644 index 0000000000..2d16c8bb5e --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-m365-onedrive-excessive-file-downloads-with-oauth-token.asciidoc @@ -0,0 +1,142 @@ +[[prebuilt-rule-8-19-4-m365-onedrive-excessive-file-downloads-with-oauth-token]] +=== M365 OneDrive Excessive File Downloads with OAuth Token + +Identifies when an excessive number of files are downloaded from OneDrive using OAuth authentication. Adversaries may conduct phishing campaigns to steal OAuth tokens and impersonate users. These access tokens can then be used to download files from OneDrive. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://www.volexity.com/blog/2025/02/13/multiple-russian-threat-actors-targeting-microsoft-device-code-authentication/ + +*Tags*: + +* Domain: Cloud +* Domain: SaaS +* Data Source: Microsoft 365 +* Data Source: SharePoint +* Data Source: OneDrive +* Use Case: Threat Detection +* Tactic: Collection +* Tactic: Exfiltration +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and Analysis* + + + +*Investigating M365 OneDrive Excessive File Downloads with OAuth Token* + + +This rule detects an excessive number of files downloaded from OneDrive using OAuth authentication. Threat actors may use OAuth phishing attacks, such as **Device Code Authentication phishing**, to obtain valid access tokens and perform unauthorized data exfiltration. This method allows adversaries to bypass traditional authentication mechanisms, making it a stealthy and effective technique. + +This rule leverages ESQL aggregations which limit the field values available in the alert document. To investigate further, it is recommended to identify the original documents ingested. + + +*Possible Investigation Steps* + + +- Review the `o365.audit.UserId` field to identify the user who performed the downloads. Check if this user typically downloads large amounts of data from OneDrive. +- Correlate `o365.audit.UserId` with Entra Sign-In logs to verify the authentication method used and determine if it was expected for this user. +- Review the authentication method used. If OAuth authentication was used, investigate whether it was expected for this user. +- Identify the client application used for authentication. Determine if it is a legitimate enterprise-approved app or an unauthorized third-party application. +- Check the number of unique files downloaded. If a user downloads a high volume of unique files in a short period, it may indicate data exfiltration. +- Analyze the file types and directories accessed to determine if sensitive or confidential data was involved. +- Investigate the source IP address and geolocation of the download activity. If it originates from an unusual or anonymized location, further scrutiny is needed. +- Review other recent activities from the same user, such as file access, sharing, or permission changes, that may indicate further compromise. +- Check for signs of session persistence using OAuth. If Azure sign-in logs are correlated where `authentication_protocol` or `originalTransferMethod` field shows `deviceCode`, the session was established through device code authentication. +- Look for multiple authentication attempts from different devices or locations within a short timeframe, which could indicate unauthorized access. +- Investigate if other OAuth-related anomalies exist, such as consent grants for unfamiliar applications or unexpected refresh token activity. +- Review the `file.directory` value from the original documents to identify the specific folders or paths where the files were downloaded. + + +*False Positive Analysis* + + +- Verify if the user regularly downloads large batches of files as part of their job function. +- Determine if the downloads were triggered by an authorized automated process, such as a data backup or synchronization tool. +- Confirm if the detected OAuth application is approved for enterprise use and aligns with expected usage patterns. + + +*Response and Remediation* + + +- If unauthorized activity is confirmed, revoke the OAuth token used and terminate active OneDrive sessions. +- Reset the affected user's password and require reauthentication to prevent continued unauthorized access. +- Restrict OAuth app permissions and enforce conditional access policies to limit authentication to trusted devices and applications. +- Monitor for additional signs of compromise, such as unusual email forwarding rules, external sharing of OneDrive files, or privilege escalation attempts. +- Educate users on OAuth phishing risks and encourage the use of **Microsoft Defender for Office 365 Safe Links** to mitigate credential-based attacks. +- Enable continuous monitoring for OAuth authentication anomalies using **Microsoft Entra ID sign-in logs** and security tools. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-o365.audit-* +| where + @timestamp > now() - 14d and + event.dataset == "o365.audit" and + event.provider == "OneDrive" and + event.action == "FileDownloaded" and + o365.audit.AuthenticationType == "OAuth" and + event.outcome == "success" +| eval + Esql.time_window_date_trunc = date_trunc(1 minutes, @timestamp) +| keep + Esql.time_window_date_trunc, + o365.audit.UserId, + file.name, + source.ip +| stats + Esql.file_name_count_distinct = count_distinct(file.name), + Esql.event_count = count(*) + by + Esql.time_window_date_trunc, + o365.audit.UserId, + source.ip +| where + Esql.file_name_count_distinct >= 25 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Collection +** ID: TA0009 +** Reference URL: https://attack.mitre.org/tactics/TA0009/ +* Technique: +** Name: Data from Cloud Storage +** ID: T1530 +** Reference URL: https://attack.mitre.org/techniques/T1530/ +* Tactic: +** Name: Exfiltration +** ID: TA0010 +** Reference URL: https://attack.mitre.org/tactics/TA0010/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-365-brute-force-via-entra-id-sign-ins.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-365-brute-force-via-entra-id-sign-ins.asciidoc new file mode 100644 index 0000000000..2525b3f54c --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-365-brute-force-via-entra-id-sign-ins.asciidoc @@ -0,0 +1,275 @@ +[[prebuilt-rule-8-19-4-microsoft-365-brute-force-via-entra-id-sign-ins]] +=== Microsoft 365 Brute Force via Entra ID Sign-Ins + +Identifies potential brute-force attacks targeting Microsoft 365 user accounts by analyzing failed sign-in patterns in Microsoft Entra ID Sign-In Logs. This detection focuses on a high volume of failed interactive or non-interactive authentication attempts within a short time window, often indicative of password spraying, credential stuffing, or password guessing. Adversaries may use these techniques to gain unauthorized access to Microsoft 365 services such as Exchange Online, SharePoint, or Teams. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 15m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://cloud.hacktricks.xyz/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-password-spraying +* https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray +* https://learn.microsoft.com/en-us/purview/audit-log-detailed-properties +* https://securityscorecard.com/research/massive-botnet-targets-m365-with-stealthy-password-spraying-attacks/ +* https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes +* https://github.com/0xZDH/Omnispray +* https://github.com/0xZDH/o365spray + +*Tags*: + +* Domain: Cloud +* Domain: SaaS +* Domain: Identity +* Data Source: Azure +* Data Source: Entra ID +* Data Source: Entra ID Sign-in Logs +* Use Case: Identity and Access Audit +* Use Case: Threat Detection +* Tactic: Credential Access +* Resources: Investigation Guide + +*Version*: 106 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Microsoft 365 Brute Force via Entra ID Sign-Ins* + + +Identifies brute-force authentication activity against Microsoft 365 services using Entra ID sign-in logs. This detection groups and classifies failed sign-in attempts based on behavior indicative of password spraying, credential stuffing, or password guessing. The classification (`bf_type`) is included for immediate triage. + + +*Possible investigation steps* + + +- Review `bf_type`: Classifies the brute-force behavior (`password_spraying`, `credential_stuffing`, `password_guessing`). +- Examine `user_id_list`: Review the identities targeted. Are they admins, service accounts, or external identities? +- Review `login_errors`: Multiple identical errors (e.g., `"Invalid grant..."`) suggest automated abuse or tooling. +- Check `ip_list` and `source_orgs`: Determine if requests came from known VPNs, hosting providers, or anonymized infrastructure. +- Validate `unique_ips` and `countries`: Multiple countries or IPs in a short window may indicate credential stuffing or distributed spray attempts. +- Compare `total_attempts` vs `duration_seconds`: High volume over a short duration supports non-human interaction. +- Inspect `user_agent.original` via `device_detail_browser`: Clients like `Python Requests` or `curl` are highly suspicious. +- Investigate `client_app_display_name` and `incoming_token_type`: Identify non-browser-based logins, token abuse or commonly mimicked clients like VSCode. +- Review `target_resource_display_name`: Confirm the service being targeted (e.g., SharePoint, Exchange). This may be what authorization is being attempted against. +- Pivot using `session_id` and `device_detail_device_id`: Determine if a single device is spraying multiple accounts. +- Check `conditional_access_status`: If "notApplied", determine whether conditional access is properly scoped. +- Correlate `user_principal_name` with successful sign-ins: Investigate surrounding logs for lateral movement or privilege abuse. + + +*False positive analysis* + + +- Developer automation (e.g., CI/CD logins) or mobile sync errors may create noisy but benign login failures. +- Red team exercises or pentesting can resemble brute-force patterns. +- Legacy protocols or misconfigured service principals may trigger repeated login failures from the same IP or session. + + +*Response and remediation* + + +- Notify identity or security operations teams to investigate further. +- Lock or reset affected user accounts if compromise is suspected. +- Block the source IP(s) or ASN temporarily using conditional access or firewall rules. +- Review tenant-wide MFA and conditional access enforcement. +- Audit targeted accounts for password reuse across systems or tenants. +- Enable lockout or throttling policies for repeated failed login attempts. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-azure.signinlogs* + +| eval + Esql.time_window_date_trunc = date_trunc(15 minutes, @timestamp), + Esql_priv.azure_signinlogs_properties_user_principal_name_lower = to_lower(azure.signinlogs.properties.user_principal_name), + Esql.azure_signinlogs_properties_incoming_token_type_lower = to_lower(azure.signinlogs.properties.incoming_token_type), + Esql.azure_signinlogs_properties_app_display_name_lower = to_lower(azure.signinlogs.properties.app_display_name), + Esql.user_agent_original = user_agent.original + +| where event.dataset == "azure.signinlogs" + and event.category == "authentication" + and azure.signinlogs.category in ("NonInteractiveUserSignInLogs", "SignInLogs") + and azure.signinlogs.properties.resource_display_name rlike "(.*)365|SharePoint|Exchange|Teams|Office(.*)" + and event.outcome == "failure" + and azure.signinlogs.properties.status.error_code != 50053 + and azure.signinlogs.properties.status.error_code in ( + 50034, // UserAccountNotFound + 50126, // InvalidUsernameOrPassword + 50055, // PasswordExpired + 50056, // InvalidPassword + 50057, // UserDisabled + 50064, // CredentialValidationFailure + 50076, // MFARequiredButNotPassed + 50079, // MFARegistrationRequired + 50105, // EntitlementGrantsNotFound + 70000, // InvalidGrant + 70008, // ExpiredOrRevokedRefreshToken + 70043, // BadTokenDueToSignInFrequency + 80002, // OnPremisePasswordValidatorRequestTimedOut + 80005, // OnPremisePasswordValidatorUnpredictableWebException + 50144, // InvalidPasswordExpiredOnPremPassword + 50135, // PasswordChangeCompromisedPassword + 50142, // PasswordChangeRequiredConditionalAccess + 120000, // PasswordChangeIncorrectCurrentPassword + 120002, // PasswordChangeInvalidNewPasswordWeak + 120020 // PasswordChangeFailure + ) + and azure.signinlogs.properties.user_principal_name is not null + and azure.signinlogs.properties.user_principal_name != "" + and user_agent.original != "Mozilla/5.0 (compatible; MSAL 1.0) PKeyAuth/1.0" + +| stats + Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement), + Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id), + Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name), + Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id), + Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name), + Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status), + Esql.azure_signinlogs_properties_device_detail_browser_values = values(azure.signinlogs.properties.device_detail.browser), + Esql.azure_signinlogs_properties_device_detail_device_id_values = values(azure.signinlogs.properties.device_detail.device_id), + Esql.azure_signinlogs_properties_device_detail_operating_system_values = values(azure.signinlogs.properties.device_detail.operating_system), + Esql.azure_signinlogs_properties_incoming_token_type_values = values(azure.signinlogs.properties.incoming_token_type), + Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state), + Esql.azure_signinlogs_properties_session_id_values = values(azure.signinlogs.properties.session_id), + Esql.azure_signinlogs_properties_user_id_values = values(azure.signinlogs.properties.user_id), + Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name), + Esql.azure_signinlogs_result_description_values = values(azure.signinlogs.result_description), + Esql.azure_signinlogs_result_signature_values = values(azure.signinlogs.result_signature), + Esql.azure_signinlogs_result_type_values = values(azure.signinlogs.result_type), + + Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct = count_distinct(Esql_priv.azure_signinlogs_properties_user_principal_name_lower), + Esql_priv.azure_signinlogs_properties_user_principal_name_lower_values = values(Esql_priv.azure_signinlogs_properties_user_principal_name_lower), + Esql.azure_signinlogs_result_description_count_distinct = count_distinct(azure.signinlogs.result_description), + Esql.azure_signinlogs_result_description_values = values(azure.signinlogs.result_description), + Esql.azure_signinlogs_properties_status_error_code_count_distinct = count_distinct(azure.signinlogs.properties.status.error_code), + Esql.azure_signinlogs_properties_status_error_code_values = values(azure.signinlogs.properties.status.error_code), + Esql.azure_signinlogs_properties_incoming_token_type_lower_values = values(Esql.azure_signinlogs_properties_incoming_token_type_lower), + Esql.azure_signinlogs_properties_app_display_name_lower_values = values(Esql.azure_signinlogs_properties_app_display_name_lower), + Esql.source_ip_values = values(source.ip), + Esql.source_ip_count_distinct = count_distinct(source.ip), + Esql.source_as_organization_name_values = values(source.`as`.organization.name), + Esql.source_as_organization_name_count_distinct = count_distinct(source.`as`.organization.name), + Esql.source_geo_country_name_values = values(source.geo.country_name), + Esql.source_geo_country_name_count_distinct = count_distinct(source.geo.country_name), + Esql.@timestamp.min = min(@timestamp), + Esql.@timestamp.max = max(@timestamp), + Esql.event_count = count() +by Esql.time_window_date_trunc + +| eval + Esql.event_duration_seconds = date_diff("seconds", Esql.@timestamp.min, Esql.@timestamp.max), + Esql.event_bf_type = case( + Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct >= 10 + and Esql.event_count >= 30 + and Esql.azure_signinlogs_result_description_count_distinct <= 3 + and Esql.source_ip_count_distinct >= 5 + and Esql.event_duration_seconds <= 600 + and Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct > Esql.source_ip_count_distinct, + "credential_stuffing", + + Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct >= 15 + and Esql.azure_signinlogs_result_description_count_distinct == 1 + and Esql.event_count >= 15 + and Esql.event_duration_seconds <= 1800, + "password_spraying", + + (Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct == 1 + and Esql.azure_signinlogs_result_description_count_distinct == 1 + and Esql.event_count >= 30 + and Esql.event_duration_seconds <= 300) + or (Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct <= 3 + and Esql.source_ip_count_distinct > 30 + and Esql.event_count >= 100), + "password_guessing", + + "other" + ) + +| where Esql.event_bf_type != "other" + +| keep + Esql.time_window_date_trunc, + Esql.event_bf_type, + Esql.event_duration_seconds, + Esql.event_count, + Esql.@timestamp.min, + Esql.@timestamp.max, + Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct, + Esql_priv.azure_signinlogs_properties_user_principal_name_lower_values, + Esql.azure_signinlogs_result_description_count_distinct, + Esql.azure_signinlogs_result_description_values, + Esql.azure_signinlogs_properties_status_error_code_count_distinct, + Esql.azure_signinlogs_properties_status_error_code_values, + Esql.azure_signinlogs_properties_incoming_token_type_lower_values, + Esql.azure_signinlogs_properties_app_display_name_lower_values, + Esql.source_ip_values, + Esql.source_ip_count_distinct, + Esql.source_as_organization_name_values, + Esql.source_as_organization_name_count_distinct, + Esql.source_geo_country_name_values, + Esql.source_geo_country_name_count_distinct, + Esql.azure_signinlogs_properties_authentication_requirement_values, + Esql.azure_signinlogs_properties_app_id_values, + Esql.azure_signinlogs_properties_app_display_name_values, + Esql.azure_signinlogs_properties_resource_id_values, + Esql.azure_signinlogs_properties_resource_display_name_values, + Esql.azure_signinlogs_properties_conditional_access_status_values, + Esql.azure_signinlogs_properties_device_detail_browser_values, + Esql.azure_signinlogs_properties_device_detail_device_id_values, + Esql.azure_signinlogs_properties_device_detail_operating_system_values, + Esql.azure_signinlogs_properties_incoming_token_type_values, + Esql.azure_signinlogs_properties_risk_state_values, + Esql.azure_signinlogs_properties_session_id_values, + Esql.azure_signinlogs_properties_user_id_values + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Credential Access +** ID: TA0006 +** Reference URL: https://attack.mitre.org/tactics/TA0006/ +* Technique: +** Name: Brute Force +** ID: T1110 +** Reference URL: https://attack.mitre.org/techniques/T1110/ +* Sub-technique: +** Name: Password Guessing +** ID: T1110.001 +** Reference URL: https://attack.mitre.org/techniques/T1110/001/ +* Sub-technique: +** Name: Password Spraying +** ID: T1110.003 +** Reference URL: https://attack.mitre.org/techniques/T1110/003/ +* Sub-technique: +** Name: Credential Stuffing +** ID: T1110.004 +** Reference URL: https://attack.mitre.org/techniques/T1110/004/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-concurrent-sign-ins-with-suspicious-properties.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-concurrent-sign-ins-with-suspicious-properties.asciidoc new file mode 100644 index 0000000000..98661796ae --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-concurrent-sign-ins-with-suspicious-properties.asciidoc @@ -0,0 +1,168 @@ +[[prebuilt-rule-8-19-4-microsoft-entra-id-concurrent-sign-ins-with-suspicious-properties]] +=== Microsoft Entra ID Concurrent Sign-Ins with Suspicious Properties + +Identifies concurrent azure signin events for the same user and from multiple sources, and where one of the authentication event has some suspicious properties often associated to DeviceCode and OAuth phishing. Adversaries may steal Refresh Tokens (RTs) via phishing to bypass multi-factor authentication (MFA) and gain unauthorized access to Azure resources. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: high + +*Risk score*: 73 + +*Runs every*: 5m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://learn.microsoft.com/en-us/entra/identity/ +* https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-ins +* https://docs.microsoft.com/en-us/azure/active-directory/reports-monitoring/reference-azure-monitor-sign-ins-log-schema +* https://www.volexity.com/blog/2025/04/22/phishing-for-codes-russian-threat-actors-target-microsoft-365-oauth-workflows/ + +*Tags*: + +* Domain: Cloud +* Domain: SaaS +* Data Source: Azure +* Data Source: Entra ID +* Data Source: Entra ID Sign-in +* Use Case: Identity and Access Audit +* Use Case: Threat Detection +* Tactic: Credential Access +* Resources: Investigation Guide + +*Version*: 2 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Microsoft Entra ID Concurrent Sign-Ins with Suspicious Properties* + + + +*Possible investigation steps* + + +- Review the sign-in logs to assess the context and reputation of the source.ip address. +- Investigate the user account associated with the successful sign-in to determine if the activity aligns with expected behavior or if it appears suspicious. +- Check for any recent changes or anomalies in the user's account settings or permissions that could indicate compromise. +- Review the history of sign-ins for the user to identify any patterns or unusual access times that could suggest unauthorized access. +- Assess the device from which the sign-in was attempted to ensure it is a recognized and authorized device for the user. + + +*Response and remediation* + + +- Immediately revoke the compromised Primary Refresh Tokens (PRTs) to prevent further unauthorized access. This can be done through the Azure portal by navigating to the user's account and invalidating all active sessions. +- Enforce a password reset for the affected user accounts to ensure that any credentials potentially compromised during the attack are no longer valid. +- Implement additional Conditional Access policies that require device compliance checks and restrict access to trusted locations or devices only, to mitigate the risk of future PRT abuse. +- Conduct a thorough review of the affected accounts' recent activity logs to identify any unauthorized actions or data access that may have occurred during the compromise. +- Escalate the incident to the security operations team for further investigation and to determine if there are any broader implications or additional compromised accounts. +- Enhance monitoring by configuring alerts for unusual sign-in patterns or device code authentication attempts from unexpected locations or devices, to improve early detection of similar threats. +- Coordinate with the incident response team to perform a post-incident analysis and update the incident response plan with lessons learned from this event. + +==== Setup + + + +*Required Azure Entra Sign-In Logs* + +This rule requires the Azure logs integration be enabled and configured to collect all logs, including sign-in logs from Entra. In Entra, sign-in logs must be enabled and streaming to the Event Hub used for the Azure logs integration. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-azure.signinlogs* metadata _id, _version, _index + +// Scheduled to run every hour, reviewing events from past hour +| where + @timestamp > now() - 1 hours + and event.dataset == "azure.signinlogs" + and source.ip is not null + and azure.signinlogs.identity is not null + and to_lower(event.outcome) == "success" + +// keep relevant raw fields +| keep + @timestamp, + azure.signinlogs.identity, + source.ip, + azure.signinlogs.properties.authentication_requirement, + azure.signinlogs.properties.app_id, + azure.signinlogs.properties.resource_display_name, + azure.signinlogs.properties.authentication_protocol, + azure.signinlogs.properties.app_display_name + +// case classifications for identity usage +| eval + Esql.azure_signinlogs_properties_authentication_device_code_case = case( + azure.signinlogs.properties.authentication_protocol == "deviceCode" + and azure.signinlogs.properties.authentication_requirement != "multiFactorAuthentication", + azure.signinlogs.identity, + null), + + Esql.azure_signinlogs_auth_visual_studio_case = case( + azure.signinlogs.properties.app_id == "aebc6443-996d-45c2-90f0-388ff96faa56" + and azure.signinlogs.properties.resource_display_name == "Microsoft Graph", + azure.signinlogs.identity, + null), + + Esql.azure_signinlogs_auth_other_case = case( + azure.signinlogs.properties.authentication_protocol != "deviceCode" + and azure.signinlogs.properties.app_id != "aebc6443-996d-45c2-90f0-388ff96faa56", + azure.signinlogs.identity, + null) + +// Aggregate metrics by user identity +| stats + Esql.event_count = count(*), + Esql.azure_signinlogs_properties_authentication_device_code_case_count_distinct = count_distinct(Esql.azure_signinlogs_properties_authentication_device_code_case), + Esql.azure_signinlogs_properties_auth_visual_studio_count_distinct = count_distinct(Esql.azure_signinlogs_auth_visual_studio_case), + Esql.azure_signinlogs_properties_auth_other_count_distinct = count_distinct(Esql.azure_signinlogs_auth_other_case), + Esql.azure_signinlogs_properties_source_ip_count_distinct = count_distinct(source.ip), + Esql.azure_signinlogs_properties_source_ip_values = values(source.ip), + Esql.azure_signinlogs_properties_client_app_values = values(azure.signinlogs.properties.app_display_name), + Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name), + Esql.azure_signinlogs_properties_auth_requirement_values = values(azure.signinlogs.properties.authentication_requirement) + by azure.signinlogs.identity + +// Detect multiple unique IPs for one user with signs of deviceCode or VSC OAuth usage +| where + Esql.azure_signinlogs_properties_source_ip_count_distinct >= 2 + and ( + Esql.azure_signinlogs_properties_authentication_device_code_case_count_distinct > 0 + or Esql.azure_signinlogs_properties_auth_visual_studio_count_distinct > 0 + ) + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Credential Access +** ID: TA0006 +** Reference URL: https://attack.mitre.org/tactics/TA0006/ +* Technique: +** Name: Steal Application Access Token +** ID: T1528 +** Reference URL: https://attack.mitre.org/techniques/T1528/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-exccessive-account-lockouts-detected.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-exccessive-account-lockouts-detected.asciidoc new file mode 100644 index 0000000000..6b9b058ac7 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-exccessive-account-lockouts-detected.asciidoc @@ -0,0 +1,222 @@ +[[prebuilt-rule-8-19-4-microsoft-entra-id-exccessive-account-lockouts-detected]] +=== Microsoft Entra ID Exccessive Account Lockouts Detected + +Identifies a high count of failed Microsoft Entra ID sign-in attempts as the result of the target user account being locked out. Adversaries may attempt to brute-force user accounts by repeatedly trying to authenticate with incorrect credentials, leading to account lockouts by Entra ID Smart Lockout policies. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: high + +*Risk score*: 73 + +*Runs every*: 15m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://www.microsoft.com/en-us/security/blog/2025/05/27/new-russia-affiliated-actor-void-blizzard-targets-critical-sectors-for-espionage/ +* https://cloud.hacktricks.xyz/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-password-spraying +* https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray +* https://www.sprocketsecurity.com/blog/exploring-modern-password-spraying +* https://learn.microsoft.com/en-us/purview/audit-log-detailed-properties +* https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes +* https://github.com/0xZDH/Omnispray +* https://github.com/0xZDH/o365spray + +*Tags*: + +* Domain: Cloud +* Domain: Identity +* Data Source: Azure +* Data Source: Entra ID +* Data Source: Entra ID Sign-in Logs +* Use Case: Identity and Access Audit +* Use Case: Threat Detection +* Tactic: Credential Access +* Resources: Investigation Guide + +*Version*: 2 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Microsoft Entra ID Exccessive Account Lockouts Detected* + + +This rule detects a high number of sign-in failures due to account lockouts (error code `50053`) in Microsoft Entra ID sign-in logs. These lockouts are typically caused by repeated authentication failures, often as a result of brute-force tactics such as password spraying, credential stuffing, or automated guessing. This detection is time-bucketed and aggregates attempts to identify bursts or coordinated campaigns targeting multiple users. + + +*Possible investigation steps* + + +- Review `user_id_list` and `user_principal_name`: Check if targeted users include high-value accounts such as administrators, service principals, or shared inboxes. +- Check `error_codes` and `result_description`: Validate that `50053` (account locked) is the consistent failure type. Messages indicating "malicious IP" activity suggest Microsoft’s backend flagged the source. +- Analyze `ip_list` and `source_orgs`: Identify whether the activity originated from known malicious infrastructure (e.g., VPNs, botnets, or public cloud providers). In the example, traffic originates from `MASSCOM`, which should be validated. +- Inspect `device_detail_browser` and `user_agent`: Clients like `"Python Requests"` indicate scripted automation rather than legitimate login attempts. +- Evaluate `unique_users` vs. `total_attempts`: A high ratio suggests distributed attacks across multiple accounts, characteristic of password spraying. +- Correlate `client_app_display_name` and `incoming_token_type`: PowerShell or unattended sign-in clients may be targeted for automation or legacy auth bypass. +- Review `conditional_access_status` and `risk_state`: If Conditional Access was not applied and risk was not flagged, policy scope or coverage should be reviewed. +- Validate time range (`first_seen`, `last_seen`): Determine whether the attack is a short burst or part of a longer campaign. + + +*False positive analysis* + + +- Misconfigured clients, scripts, or services with outdated credentials may inadvertently cause lockouts. +- Repeated lockouts from known internal IPs or during credential rotation windows could be benign. +- Legacy applications without modern auth support may repeatedly fail and trigger Smart Lockout. +- Specific known user agents (e.g., corporate service accounts). +- Internal IPs or cloud-hosted automation with expected failure behavior. + + +*Response and remediation* + + +- Investigate locked accounts immediately. Confirm if the account was successfully accessed prior to lockout. +- Reset credentials for impacted users and enforce MFA before re-enabling accounts. +- Block malicious IPs or ASN at the firewall, identity provider, or Conditional Access level. +- Audit authentication methods in use, and enforce modern auth (OAuth, SAML) over legacy protocols. +- Strengthen Conditional Access policies to reduce exposure from weak locations, apps, or clients. +- Conduct credential hygiene audits to assess reuse and rotation for targeted accounts. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-azure.signinlogs* + +| eval + Esql.time_window_date_trunc = date_trunc(30 minutes, @timestamp), + Esql_priv.azure_signinlogs_properties_user_principal_name_lower = to_lower(azure.signinlogs.properties.user_principal_name), + Esql.azure_signinlogs_properties_incoming_token_type_lower = to_lower(azure.signinlogs.properties.incoming_token_type), + Esql.azure_signinlogs_properties_app_display_name_lower = to_lower(azure.signinlogs.properties.app_display_name) + +| where event.dataset == "azure.signinlogs" + and event.category == "authentication" + and azure.signinlogs.category in ("NonInteractiveUserSignInLogs", "SignInLogs") + and event.outcome == "failure" + and azure.signinlogs.properties.authentication_requirement == "singleFactorAuthentication" + and azure.signinlogs.properties.status.error_code == 50053 + and azure.signinlogs.properties.user_principal_name is not null + and azure.signinlogs.properties.user_principal_name != "" + and source.`as`.organization.name != "MICROSOFT-CORP-MSN-as-BLOCK" + +| stats + Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement), + Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id), + Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name), + Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id), + Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name), + Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status), + Esql.azure_signinlogs_properties_device_detail_browser_values = values(azure.signinlogs.properties.device_detail.browser), + Esql.azure_signinlogs_properties_device_detail_device_id_values = values(azure.signinlogs.properties.device_detail.device_id), + Esql.azure_signinlogs_properties_device_detail_operating_system_values = values(azure.signinlogs.properties.device_detail.operating_system), + Esql.azure_signinlogs_properties_incoming_token_type_values = values(azure.signinlogs.properties.incoming_token_type), + Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state), + Esql.azure_signinlogs_properties_session_id_values = values(azure.signinlogs.properties.session_id), + Esql.azure_signinlogs_properties_user_id_values = values(azure.signinlogs.properties.user_id), + Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name), + Esql.azure_signinlogs_result_description_values = values(azure.signinlogs.result_description), + Esql.azure_signinlogs_result_signature_values = values(azure.signinlogs.result_signature), + Esql.azure_signinlogs_result_type_values = values(azure.signinlogs.result_type), + + Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct = count_distinct(Esql_priv.azure_signinlogs_properties_user_principal_name_lower), + Esql_priv.azure_signinlogs_properties_user_principal_name_lower_values = values(Esql_priv.azure_signinlogs_properties_user_principal_name_lower), + Esql.azure_signinlogs_result_description_count_distinct = count_distinct(azure.signinlogs.result_description), + Esql.azure_signinlogs_properties_status_error_code_count_distinct = count_distinct(azure.signinlogs.properties.status.error_code), + Esql.azure_signinlogs_properties_status_error_code_values = values(azure.signinlogs.properties.status.error_code), + Esql.azure_signinlogs_properties_incoming_token_type_lower_values = values(Esql.azure_signinlogs_properties_incoming_token_type_lower), + Esql.azure_signinlogs_properties_app_display_name_lower_values = values(Esql.azure_signinlogs_properties_app_display_name_lower), + Esql.source_ip_values = values(source.ip), + Esql.source_ip_count_distinct = count_distinct(source.ip), + Esql.source_as_organization_name_values = values(source.`as`.organization.name), + Esql.source_as_organization_name_count_distinct = count_distinct(source.`as`.organization.name), + Esql.source_geo_country_name_values = values(source.geo.country_name), + Esql.source_geo_country_name_count_distinct = count_distinct(source.geo.country_name), + Esql.@timestamp.min = min(@timestamp), + Esql.@timestamp.max = max(@timestamp), + Esql.event_count = count() +by Esql.time_window_date_trunc + +| where Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct >= 15 and Esql.event_count >= 20 + +| keep + Esql.time_window_date_trunc, + Esql.event_count, + Esql.@timestamp.min, + Esql.@timestamp.max, + Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct, + Esql_priv.azure_signinlogs_properties_user_principal_name_lower_values, + Esql.azure_signinlogs_result_description_count_distinct, + Esql.azure_signinlogs_result_description_values, + Esql.azure_signinlogs_properties_status_error_code_count_distinct, + Esql.azure_signinlogs_properties_status_error_code_values, + Esql.azure_signinlogs_properties_incoming_token_type_lower_values, + Esql.azure_signinlogs_properties_app_display_name_lower_values, + Esql.source_ip_values, + Esql.source_ip_count_distinct, + Esql.source_as_organization_name_values, + Esql.source_as_organization_name_count_distinct, + Esql.source_geo_country_name_values, + Esql.source_geo_country_name_count_distinct, + Esql.azure_signinlogs_properties_authentication_requirement_values, + Esql.azure_signinlogs_properties_app_id_values, + Esql.azure_signinlogs_properties_app_display_name_values, + Esql.azure_signinlogs_properties_resource_id_values, + Esql.azure_signinlogs_properties_resource_display_name_values, + Esql.azure_signinlogs_properties_conditional_access_status_values, + Esql.azure_signinlogs_properties_device_detail_browser_values, + Esql.azure_signinlogs_properties_device_detail_device_id_values, + Esql.azure_signinlogs_properties_device_detail_operating_system_values, + Esql.azure_signinlogs_properties_incoming_token_type_values, + Esql.azure_signinlogs_properties_risk_state_values, + Esql.azure_signinlogs_properties_session_id_values, + Esql.azure_signinlogs_properties_user_id_values, + Esql_priv.azure_signinlogs_properties_user_principal_name_values, + Esql.azure_signinlogs_result_description_values, + Esql.azure_signinlogs_result_signature_values, + Esql.azure_signinlogs_result_type_values + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Credential Access +** ID: TA0006 +** Reference URL: https://attack.mitre.org/tactics/TA0006/ +* Technique: +** Name: Brute Force +** ID: T1110 +** Reference URL: https://attack.mitre.org/techniques/T1110/ +* Sub-technique: +** Name: Password Guessing +** ID: T1110.001 +** Reference URL: https://attack.mitre.org/techniques/T1110/001/ +* Sub-technique: +** Name: Password Spraying +** ID: T1110.003 +** Reference URL: https://attack.mitre.org/techniques/T1110/003/ +* Sub-technique: +** Name: Credential Stuffing +** ID: T1110.004 +** Reference URL: https://attack.mitre.org/techniques/T1110/004/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-mfa-totp-brute-force-attempts.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-mfa-totp-brute-force-attempts.asciidoc new file mode 100644 index 0000000000..25a3a02ec4 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-mfa-totp-brute-force-attempts.asciidoc @@ -0,0 +1,199 @@ +[[prebuilt-rule-8-19-4-microsoft-entra-id-mfa-totp-brute-force-attempts]] +=== Microsoft Entra ID MFA TOTP Brute Force Attempts + +Identifies brute force attempts against Azure Entra multi-factor authentication (MFA) Time-based One-Time Password (TOTP) verification codes. This rule detects high frequency failed TOTP code attempts for a single user in a short time-span with a high number of distinct session IDs. Adversaries may programmatically attemopt to brute-force TOTP codes by generating several sessions and attempt to guess the correct code. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://www.oasis.security/resources/blog/oasis-security-research-team-discovers-microsoft-azure-mfa-bypass +* https://learn.microsoft.com/en-us/entra/identity/ +* https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-ins + +*Tags*: + +* Domain: Cloud +* Domain: Identity +* Data Source: Azure +* Data Source: Entra ID +* Data Source: Entra ID Sign-in logs +* Use Case: Identity and Access Audit +* Use Case: Threat Detection +* Tactic: Credential Access +* Resources: Investigation Guide + +*Version*: 4 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Microsoft Entra ID MFA TOTP Brute Force Attempts* + + +This rule detects brute force attempts against Azure Entra multi-factor authentication (MFA) Time-based One-Time Password (TOTP) verification codes. It identifies high-frequency failed TOTP code attempts for a single user in a short time-span with a high number of distinct session IDs. Adversaries may programmatically attempt to brute-force TOTP codes by generating several sessions and attempting to guess the correct code. + + +*Possible Investigation Steps:* + + + - Check the source addresses associated with the failed TOTP attempts. + - Determine if the source IP address is consistent with the user’s typical login locations. + - Look for unusual geographic patterns or anomalous IP addresses (e.g., proxies, VPNs, or locations outside the user’s normal activity). + - Review the error code associated with the failed attempts. This can help identify if the failures are due to incorrect TOTP codes or other issues. + - Verify that that auth metho reported is `OAth` as it indicates the use of TOTP codes. + - Pivot into signin logs for the target user and check if auth via TOTP was successful which would indicate a successful brute force attempt. + - Review conditional access policies applied to the user or group as reported by the sign-in logs. + - Analyze the client application ID and display name to determine if the attempts are coming from a legitimate application or a potentially malicious script. + - Adversaries may use legitimate FOCI applications to bypass security controls or make login attempts appear legitimate. + - Review the resource ID access is being attempted against such as MyApps, Microsoft Graph, or other resources. This can help identify if the attempts are targeting specific applications or services. + - The correlation IDs or session IDs can be used to trace the authentication attempts across different logs or systems. Note that for this specific behavior, unique session ID count is high and could be challenging to correlate. + + +*False Positive Analysis:* + + + - Verify if the failed attempts could result from the user’s unfamiliarity with TOTP codes or issues with device synchronization. + - Check if the user recently switched MFA methods or devices, which could explain multiple failures. + - Determine if this is whitebox testing or a developer testing MFA integration. + + +*Response and Remediation:* + + + - If proven malicious, lock the affected account temporarily to prevent further unauthorized attempts. + - Notify the user of suspicious activity and validate their access to the account. + - Reset passwords and MFA settings for the affected user to prevent unauthorized access while communicating with the user. + - Ensure conditional access policies are configured to monitor and restrict anomalous login behavior. + - Consider a different MFA method or additional security controls to prevent future bypass attempts. + - Implement additional monitoring to track high-frequency authentication failures across the environment. + - Audit historical logs for similar patterns involving other accounts to identify broader threats. + - Provide guidance on the secure use of MFA and the importance of recognizing and reporting suspicious activity. + + +==== Setup + + + +*Required Entra ID Sign-In Logs* + +This rule requires the Entra ID sign-in logs via the Azure integration be enabled. In Entra ID, sign-in logs must be enabled and streaming to the Event Hub used for the Entra ID logs integration. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-azure.signinlogs* metadata _id, _version, _index + +| where + // filter for Entra Sign-in Logs + event.dataset == "azure.signinlogs" + and azure.signinlogs.operation_name == "Sign-in activity" + and azure.signinlogs.properties.user_type == "Member" + + // filter for MFA attempts with OATH conditional access attempts or TOTP + and azure.signinlogs.properties.mfa_detail.auth_method == "OATH verification code" + + // filter on failures only from brute-force attempts + and ( + ( + azure.signinlogs.result_signature == "FAILURE" and + azure.signinlogs.result_description == "Authentication failed during strong authentication request." + ) or azure.signinlogs.properties.status.error_code == 500121 + ) + +| stats + Esql.event_count = count(*), + Esql.azure_signinlogs_properties_session_id_count_distinct = count_distinct(azure.signinlogs.properties.session_id), + Esql.source_address_values = values(source.address), + Esql.azure_tenant_id_valuues = values(azure.tenant_id), + Esql_priv.azure_identity_values = values(azure.signinlogs.identity), + Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name), + Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id), + Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name), + Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement), + Esql.azure_signinlogs_properties_authentication_protocol_values = values(azure.signinlogs.properties.authentication_protocol), + Esql.azure_signinlogs_properties_client_app_used_values = values(azure.signinlogs.properties.client_app_used), + Esql.azure_signinlogs_properties_client_credential_type_values = values(azure.signinlogs.properties.client_credential_type), + Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status), + Esql.azure_signinlogs_properties_correlation_id_values = values(azure.signinlogs.properties.correlation_id), + Esql.azure_signinlogs_properties_is_interactive_values = values(azure.signinlogs.properties.is_interactive), + Esql.azure_signinlogs_properties_mfa_detail_auth_method_values = values(azure.signinlogs.properties.mfa_detail.auth_method), + Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name), + Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id), + Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state), + Esql.azure_signinlogs_properties_risk_detail_values = values(azure.signinlogs.properties.risk_detail), + Esql.azure_signinlogs_properties_status_error_code_values = values(azure.signinlogs.properties.status.error_code), + Esql.azure_signinlogs_properties_original_request_id_values = values(azure.signinlogs.properties.original_request_id), + Esql.user_id_values = values(user.id) + by user.id + +| where Esql.event_count >= 20 and Esql.azure_signinlogs_properties_session_id_count_distinct >= 10 + +| keep + Esql.event_count, + Esql.azure_signinlogs_properties_session_id_count_distinct, + Esql.source_address_values, + Esql.azure_tenant_id_valuues, + Esql_priv.azure_identity_values, + Esql_priv.azure_signinlogs_properties_user_principal_name_values, + Esql.azure_signinlogs_properties_app_id_values, + Esql.azure_signinlogs_properties_app_display_name_values, + Esql.azure_signinlogs_properties_authentication_requirement_values, + Esql.azure_signinlogs_properties_authentication_protocol_values, + Esql.azure_signinlogs_properties_client_app_used_values, + Esql.azure_signinlogs_properties_client_credential_type_values, + Esql.azure_signinlogs_properties_conditional_access_status_values, + Esql.azure_signinlogs_properties_correlation_id_values, + Esql.azure_signinlogs_properties_is_interactive_values, + Esql.azure_signinlogs_properties_mfa_detail_auth_method_values, + Esql.azure_signinlogs_properties_resource_display_name_values, + Esql.azure_signinlogs_properties_resource_id_values, + Esql.azure_signinlogs_properties_risk_state_values, + Esql.azure_signinlogs_properties_risk_detail_values, + Esql.azure_signinlogs_properties_status_error_code_values, + Esql.azure_signinlogs_properties_original_request_id_values, + Esql.user_id_values + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Credential Access +** ID: TA0006 +** Reference URL: https://attack.mitre.org/tactics/TA0006/ +* Technique: +** Name: Brute Force +** ID: T1110 +** Reference URL: https://attack.mitre.org/techniques/T1110/ +* Sub-technique: +** Name: Password Guessing +** ID: T1110.001 +** Reference URL: https://attack.mitre.org/techniques/T1110/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-session-reuse-with-suspicious-graph-access.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-session-reuse-with-suspicious-graph-access.asciidoc new file mode 100644 index 0000000000..8cf2eac6ac --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-session-reuse-with-suspicious-graph-access.asciidoc @@ -0,0 +1,200 @@ +[[prebuilt-rule-8-19-4-microsoft-entra-id-session-reuse-with-suspicious-graph-access]] +=== Microsoft Entra ID Session Reuse with Suspicious Graph Access + +Identifies potential session hijacking or token replay in Microsoft Entra ID. This rule detects cases where a user signs in and subsequently accesses Microsoft Graph from a different IP address using the same session ID within a short time window. This may indicate the use of a stolen refresh/access token or session cookie to impersonate the user and interact with Microsoft services. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: high + +*Risk score*: 73 + +*Runs every*: 5m + +*Searches indices from*: now-1h ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://www.volexity.com/blog/2025/04/22/phishing-for-codes-russian-threat-actors-target-microsoft-365-oauth-workflows/ +* https://github.com/dirkjanm/ROADtools +* https://attack.mitre.org/techniques/T1078/004/ + +*Tags*: + +* Domain: Cloud +* Data Source: Azure +* Data Source: Microsoft Entra ID +* Data Source: Microsoft Entra ID Sign-In Logs +* Data Source: Microsoft Graph +* Data Source: Microsoft Graph Activity Logs +* Use Case: Identity and Access Audit +* Use Case: Threat Detection +* Resources: Investigation Guide +* Tactic: Defense Evasion +* Tactic: Initial Access + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Microsoft Entra ID Session Reuse with Suspicious Graph Access* + + +This rule identifies when Microsoft Graph is accessed from a different IP than the one used for the original sign-in, +but using the same session ID within 5 minutes. This may suggest an adversary has stolen a session cookie or refresh/access +token and is impersonating the user from an alternate host or location. + +This rule uses ESQL aggregations and thus has dynamically generated fields. Correlation of the values in the alert document may need to be +performed to the original sign-in and Graph events for further context. + + +*Investigation Steps* + + +- Review the `user_id`, `session_id`, and `source_ip_list`. Confirm whether both IPs belong to the same user and geography. +- Check for inconsistencies in `client_id_list` (e.g., unknown apps) or user agents across correlated events. +- Investigate recent phishing reports or device infections for the `user_id`. +- Pivot to Entra ID `auditlogs` to see if a device was registered or privileges were modified. +- Review `graph_time` to determine what action was taken after the sign-in. +- Use the `session_id` to correlate with other logs in the same time window to identify any additional suspicious activity. + + +*False Positive Analysis* + +- This pattern may occur if the user is switching between networks (e.g., corporate to mobile) or using a VPN. +- Developers or power users leveraging multiple environments may also trigger this detection if session persistence spans IP ranges. +- However, this behavior is rare and warrants investigation when rapid IP switching and Graph access are involved. +- If the user is a developer or automation engineer, validate if this behavior was for testing purposes. +- If the user is a system administrator, validate if this behavior was for administrative purposes. + + +*Response Recommendations* + + +- If confirmed malicious, revoke all refresh/access tokens for the `user_id`. +- Block the source IP(s) involved in the Graph access. +- Notify the user and reset credentials. +- Review session control policies and conditional access enforcement. +- Monitor for follow-on activity, such as lateral movement or privilege escalation. +- Review conditional access policies to ensure they are enforced correctly. + + +==== Setup + + + +*Required Microsoft Entra ID Sign-In and Graph Activity Logs* + +This rule requires the Microsoft Entra ID Sign-In Logs and Microsoft Graph Activity Logs integration to be enabled and configured to collect audit and activity logs via Azure Event Hub. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-azure.* +| where + (event.dataset == "azure.signinlogs" + and source.`as`.organization.name != "MICROSOFT-CORP-MSN-as-BLOCK" + and azure.signinlogs.properties.session_id is not null) + or + (event.dataset == "azure.graphactivitylogs" + and source.`as`.organization.name != "MICROSOFT-CORP-MSN-as-BLOCK" + and azure.graphactivitylogs.properties.c_sid is not null) + +| eval + Esql.azure_signinlogs_properties_session_id_coalesce = coalesce(azure.signinlogs.properties.session_id, azure.graphactivitylogs.properties.c_sid), + Esql.azure_signinlogs_properties_user_id_coalesce = coalesce(azure.signinlogs.properties.user_id, azure.graphactivitylogs.properties.user_principal_object_id), + Esql.azure_signinlogs_properties_app_id_coalesce = coalesce(azure.signinlogs.properties.app_id, azure.graphactivitylogs.properties.app_id), + Esql.source_ip = source.ip, + Esql.@timestamp = @timestamp, + Esql.event_type_case = case( + event.dataset == "azure.signinlogs", "signin", + event.dataset == "azure.graphactivitylogs", "graph", + "other" + ), + Esql.time_window_date_trunc = date_trunc(5 minutes, @timestamp) + +| keep + Esql.azure_signinlogs_properties_session_id_coalesce, + Esql.source_ip, + Esql.@timestamp, + Esql.event_type_case, + Esql.time_window_date_trunc, + Esql.azure_signinlogs_properties_user_id_coalesce, + Esql.azure_signinlogs_properties_app_id_coalesce + +| stats + Esql.azure_signinlogs_properties_user_id_coalesce_values = values(Esql.azure_signinlogs_properties_user_id_coalesce), + Esql.azure_signinlogs_properties_session_id_coalesce_values = values(Esql.azure_signinlogs_properties_session_id_coalesce), + Esql.source_ip_values = values(Esql.source_ip), + Esql.source_ip_count_distinct = count_distinct(Esql.source_ip), + Esql.azure_signinlogs_properties_app_id_coalesce_values = values(Esql.azure_signinlogs_properties_app_id_coalesce), + Esql.azure_signinlogs_properties_app_id_coalesce_count_distinct = count_distinct(Esql.azure_signinlogs_properties_app_id_coalesce), + Esql.event_type_case_values = values(Esql.event_type_case), + Esql.event_type_case_count_distinct = count_distinct(Esql.event_type_case), + Esql.@timestamp.min = min(Esql.@timestamp), + Esql.@timestamp.max = max(Esql.@timestamp), + Esql.signin_time_min = min(case(Esql.event_type_case == "signin", Esql.@timestamp, null)), + Esql.graph_time_min = min(case(Esql.event_type_case == "graph", Esql.@timestamp, null)), + Esql.event_count = count() + by Esql.azure_signinlogs_properties_session_id_coalesce, Esql.time_window_date_trunc + +| eval + Esql.event_duration_minutes_date_diff = date_diff("minutes", Esql.@timestamp.min, Esql.@timestamp.max), + Esql.event_signin_to_graph_delay_minutes_date_diff = date_diff("minutes", Esql.signin_time_min, Esql.graph_time_min) + +| where + Esql.event_type_case_count_distinct > 1 and + Esql.source_ip_count_distinct > 1 and + Esql.event_duration_minutes_date_diff <= 5 and + Esql.signin_time_min is not null and + Esql.graph_time_min is not null and + Esql.event_signin_to_graph_delay_minutes_date_diff >= 0 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Initial Access +** ID: TA0001 +** Reference URL: https://attack.mitre.org/tactics/TA0001/ +* Technique: +** Name: Valid Accounts +** ID: T1078 +** Reference URL: https://attack.mitre.org/techniques/T1078/ +* Sub-technique: +** Name: Cloud Accounts +** ID: T1078.004 +** Reference URL: https://attack.mitre.org/techniques/T1078/004/ +* Tactic: +** Name: Defense Evasion +** ID: TA0005 +** Reference URL: https://attack.mitre.org/tactics/TA0005/ +* Technique: +** Name: Use Alternate Authentication Material +** ID: T1550 +** Reference URL: https://attack.mitre.org/techniques/T1550/ +* Sub-technique: +** Name: Application Access Token +** ID: T1550.001 +** Reference URL: https://attack.mitre.org/techniques/T1550/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-sign-in-brute-force-activity.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-sign-in-brute-force-activity.asciidoc new file mode 100644 index 0000000000..141ee042e6 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-microsoft-entra-id-sign-in-brute-force-activity.asciidoc @@ -0,0 +1,265 @@ +[[prebuilt-rule-8-19-4-microsoft-entra-id-sign-in-brute-force-activity]] +=== Microsoft Entra ID Sign-In Brute Force Activity + +Identifies potential brute-force attacks targeting user accounts by analyzing failed sign-in patterns in Microsoft Entra ID Sign-In Logs. This detection focuses on a high volume of failed interactive or non-interactive authentication attempts within a short time window, often indicative of password spraying, credential stuffing, or password guessing. Adversaries may use these techniques to gain unauthorized access to applications integrated with Entra ID or to compromise valid user accounts. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 15m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://www.proofpoint.com/us/blog/threat-insight/attackers-unleash-teamfiltration-account-takeover-campaign +* https://www.microsoft.com/en-us/security/blog/2025/05/27/new-russia-affiliated-actor-void-blizzard-targets-critical-sectors-for-espionage/ +* https://cloud.hacktricks.xyz/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-password-spraying +* https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray +* https://learn.microsoft.com/en-us/purview/audit-log-detailed-properties +* https://securityscorecard.com/research/massive-botnet-targets-m365-with-stealthy-password-spraying-attacks/ +* https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes +* https://github.com/0xZDH/Omnispray +* https://github.com/0xZDH/o365spray + +*Tags*: + +* Domain: Cloud +* Domain: Identity +* Data Source: Azure +* Data Source: Entra ID +* Data Source: Entra ID Sign-in Logs +* Use Case: Identity and Access Audit +* Use Case: Threat Detection +* Tactic: Credential Access +* Resources: Investigation Guide + +*Version*: 4 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Microsoft Entra ID Sign-In Brute Force Activity* + + +This rule detects brute-force authentication activity in Entra ID sign-in logs. It classifies failed sign-in attempts into behavior types such as password spraying, credential stuffing, or password guessing. The classification (`bf_type`) helps prioritize triage and incident response. + + +*Possible investigation steps* + + +- Review `bf_type`: Determines the brute-force technique being used (`password_spraying`, `credential_stuffing`, or `password_guessing`). +- Examine `user_id_list`: Identify if high-value accounts (e.g., administrators, service principals, federated identities) are being targeted. +- Review `login_errors`: Repetitive error types like `"Invalid Grant"` or `"User Not Found"` suggest automated attacks. +- Check `ip_list` and `source_orgs`: Investigate if the activity originates from suspicious infrastructure (VPNs, hosting providers, etc.). +- Validate `unique_ips` and `countries`: Geographic diversity and IP volume may indicate distributed or botnet-based attacks. +- Compare `total_attempts` vs `duration_seconds`: High rate of failures in a short time period implies automation. +- Analyze `user_agent.original` and `device_detail_browser`: User agents like `curl`, `Python`, or generic libraries may indicate scripting tools. +- Investigate `client_app_display_name` and `incoming_token_type`: Detect potential abuse of legacy or unattended login mechanisms. +- Inspect `target_resource_display_name`: Understand what application or resource the attacker is trying to access. +- Pivot using `session_id` and `device_detail_device_id`: Determine if a device is targeting multiple accounts. +- Review `conditional_access_status`: If not enforced, ensure Conditional Access policies are scoped correctly. + + +*False positive analysis* + + +- Legitimate automation (e.g., misconfigured scripts, sync processes) can trigger repeated failures. +- Internal red team activity or penetration tests may mimic brute-force behaviors. +- Certain service accounts or mobile clients may generate repetitive sign-in noise if not properly configured. + + +*Response and remediation* + + +- Notify your identity security team for further analysis. +- Investigate and lock or reset impacted accounts if compromise is suspected. +- Block offending IPs or ASNs at the firewall, proxy, or using Conditional Access. +- Confirm MFA and Conditional Access are enforced for all user types. +- Audit targeted accounts for credential reuse across services. +- Implement account lockout or throttling for failed sign-in attempts where possible. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-azure.signinlogs* + +// Define a time window for grouping and maintain the original event timestamp +| eval Esql.time_window_date_trunc = date_trunc(15 minutes, @timestamp) + +// Filter relevant failed authentication events with specific error codes +| where event.dataset == "azure.signinlogs" + and event.category == "authentication" + and azure.signinlogs.category in ("NonInteractiveUserSignInLogs", "SignInLogs") + and event.outcome == "failure" + and azure.signinlogs.properties.authentication_requirement == "singleFactorAuthentication" + and azure.signinlogs.properties.status.error_code in ( + 50034, // UserAccountNotFound + 50126, // InvalidUsernameOrPassword + 50055, // PasswordExpired + 50056, // InvalidPassword + 50057, // UserDisabled + 50064, // CredentialValidationFailure + 50076, // MFARequiredButNotPassed + 50079, // MFARegistrationRequired + 50105, // EntitlementGrantsNotFound + 70000, // InvalidGrant + 70008, // ExpiredOrRevokedRefreshToken + 70043, // BadTokenDueToSignInFrequency + 80002, // OnPremisePasswordValidatorRequestTimedOut + 80005, // OnPremisePasswordValidatorUnpredictableWebException + 50144, // InvalidPasswordExpiredOnPremPassword + 50135, // PasswordChangeCompromisedPassword + 50142, // PasswordChangeRequiredConditionalAccess + 120000, // PasswordChangeIncorrectCurrentPassword + 120002, // PasswordChangeInvalidNewPasswordWeak + 120020 // PasswordChangeFailure + ) + and azure.signinlogs.properties.user_principal_name is not null and azure.signinlogs.properties.user_principal_name != "" + and user_agent.original != "Mozilla/5.0 (compatible; MSAL 1.0) PKeyAuth/1.0" + and source.`as`.organization.name != "MICROSOFT-CORP-MSN-as-BLOCK" + +| stats + Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement), + Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id), + Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name), + Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id), + Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name), + Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status), + Esql.azure_signinlogs_properties_device_detail_browser_values = values(azure.signinlogs.properties.device_detail.browser), + Esql.azure_signinlogs_properties_device_detail_device_id_values = values(azure.signinlogs.properties.device_detail.device_id), + Esql.azure_signinlogs_properties_device_detail_operating_system_values = values(azure.signinlogs.properties.device_detail.operating_system), + Esql.azure_signinlogs_properties_incoming_token_type_values = values(azure.signinlogs.properties.incoming_token_type), + Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state), + Esql.azure_signinlogs_properties_session_id_values = values(azure.signinlogs.properties.session_id), + Esql.azure_signinlogs_properties_user_id_values = values(azure.signinlogs.properties.user_id), + Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name), + Esql.azure_signinlogs_result_description_values = values(azure.signinlogs.result_description), + Esql.azure_signinlogs_result_signature_values = values(azure.signinlogs.result_signature), + Esql.azure_signinlogs_result_type_values = values(azure.signinlogs.result_type), + + Esql.azure_signinlogs_properties_user_id_count_distinct = count_distinct(azure.signinlogs.properties.user_id), + Esql.azure_signinlogs_properties_user_id_list = values(azure.signinlogs.properties.user_id), + Esql.azure_signinlogs_result_description_values_all = values(azure.signinlogs.result_description), + Esql.azure_signinlogs_result_description_count_distinct = count_distinct(azure.signinlogs.result_description), + Esql.azure_signinlogs_properties_status_error_code_values = values(azure.signinlogs.properties.status.error_code), + Esql.azure_signinlogs_properties_status_error_code_count_distinct = count_distinct(azure.signinlogs.properties.status.error_code), + Esql.azure_signinlogs_properties_incoming_token_type_values_all = values(azure.signinlogs.properties.incoming_token_type), + Esql.azure_signinlogs_properties_app_display_name_values_all = values(azure.signinlogs.properties.app_display_name), + Esql.source_ip_values = values(source.ip), + Esql.source_ip_count_distinct = count_distinct(source.ip), + Esql.source_as_organization_name_values = values(source.`as`.organization.name), + Esql.source_geo_country_name_values = values(source.geo.country_name), + Esql.source_geo_country_name_count_distinct = count_distinct(source.geo.country_name), + Esql.source_as_organization_name_count_distinct = count_distinct(source.`as`.organization.name), + Esql.timestamp_first_seen = min(@timestamp), + Esql.timestamp_last_seen = max(@timestamp), + Esql.event_count = count() +by Esql.time_window_date_trunc + +| eval + Esql.duration_seconds = date_diff("seconds", Esql.timestamp_first_seen, Esql.timestamp_last_seen), + Esql.brute_force_type = case( + Esql.azure_signinlogs_properties_user_id_count_distinct >= 10 and Esql.event_count >= 30 and Esql.azure_signinlogs_result_description_count_distinct <= 3 + and Esql.source_ip_count_distinct >= 5 + and Esql.duration_seconds <= 600 + and Esql.azure_signinlogs_properties_user_id_count_distinct > Esql.source_ip_count_distinct, + "credential_stuffing", + + Esql.azure_signinlogs_properties_user_id_count_distinct >= 15 and Esql.azure_signinlogs_result_description_count_distinct == 1 and Esql.event_count >= 15 and Esql.duration_seconds <= 1800, + "password_spraying", + + (Esql.azure_signinlogs_properties_user_id_count_distinct == 1 and Esql.azure_signinlogs_result_description_count_distinct == 1 and Esql.event_count >= 30 and Esql.duration_seconds <= 300) + or (Esql.azure_signinlogs_properties_user_id_count_distinct <= 3 and Esql.source_ip_count_distinct > 30 and Esql.event_count >= 100), + "password_guessing", + + "other" + ) + +| keep + Esql.time_window_date_trunc, + Esql.brute_force_type, + Esql.duration_seconds, + Esql.event_count, + Esql.timestamp_first_seen, + Esql.timestamp_last_seen, + Esql.azure_signinlogs_properties_user_id_count_distinct, + Esql.azure_signinlogs_properties_user_id_list, + Esql.azure_signinlogs_result_description_values_all, + Esql.azure_signinlogs_result_description_count_distinct, + Esql.azure_signinlogs_properties_status_error_code_count_distinct, + Esql.azure_signinlogs_properties_status_error_code_values, + Esql.azure_signinlogs_properties_incoming_token_type_values_all, + Esql.azure_signinlogs_properties_app_display_name_values_all, + Esql.source_ip_values, + Esql.source_ip_count_distinct, + Esql.source_as_organization_name_values, + Esql.source_geo_country_name_values, + Esql.source_geo_country_name_count_distinct, + Esql.source_as_organization_name_count_distinct, + Esql.azure_signinlogs_properties_authentication_requirement_values, + Esql.azure_signinlogs_properties_app_id_values, + Esql.azure_signinlogs_properties_app_display_name_values, + Esql.azure_signinlogs_properties_resource_id_values, + Esql.azure_signinlogs_properties_resource_display_name_values, + Esql.azure_signinlogs_properties_conditional_access_status_values, + Esql.azure_signinlogs_properties_device_detail_browser_values, + Esql.azure_signinlogs_properties_device_detail_device_id_values, + Esql.azure_signinlogs_properties_device_detail_operating_system_values, + Esql.azure_signinlogs_properties_incoming_token_type_values, + Esql.azure_signinlogs_properties_risk_state_values, + Esql.azure_signinlogs_properties_session_id_values, + Esql.azure_signinlogs_properties_user_id_values, + Esql_priv.azure_signinlogs_properties_user_principal_name_values, + Esql.azure_signinlogs_result_description_values, + Esql.azure_signinlogs_result_signature_values, + Esql.azure_signinlogs_result_type_values + +| where Esql.brute_force_type != "other" + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Credential Access +** ID: TA0006 +** Reference URL: https://attack.mitre.org/tactics/TA0006/ +* Technique: +** Name: Brute Force +** ID: T1110 +** Reference URL: https://attack.mitre.org/techniques/T1110/ +* Sub-technique: +** Name: Password Guessing +** ID: T1110.001 +** Reference URL: https://attack.mitre.org/techniques/T1110/001/ +* Sub-technique: +** Name: Password Spraying +** ID: T1110.003 +** Reference URL: https://attack.mitre.org/techniques/T1110/003/ +* Sub-technique: +** Name: Credential Stuffing +** ID: T1110.004 +** Reference URL: https://attack.mitre.org/techniques/T1110/004/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-multiple-device-token-hashes-for-single-okta-session.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-multiple-device-token-hashes-for-single-okta-session.asciidoc new file mode 100644 index 0000000000..10f3bda503 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-multiple-device-token-hashes-for-single-okta-session.asciidoc @@ -0,0 +1,148 @@ +[[prebuilt-rule-8-19-4-multiple-device-token-hashes-for-single-okta-session]] +=== Multiple Device Token Hashes for Single Okta Session + +This rule detects when a specific Okta actor has multiple device token hashes for a single Okta session. This may indicate an authenticated session has been hijacked or is being used by multiple devices. Adversaries may hijack a session to gain unauthorized access to Okta admin console, applications, tenants, or other resources. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://developer.okta.com/docs/reference/api/system-log/ +* https://developer.okta.com/docs/reference/api/event-types/ +* https://www.elastic.co/security-labs/testing-okta-visibility-and-detection-dorothy +* https://sec.okta.com/articles/2023/08/cross-tenant-impersonation-prevention-and-detection +* https://support.okta.com/help/s/article/session-hijacking-attack-definition-damage-defense?language=en_US +* https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security +* https://www.elastic.co/security-labs/starter-guide-to-understanding-okta + +*Tags*: + +* Use Case: Identity and Access Audit +* Data Source: Okta +* Tactic: Credential Access +* Domain: SaaS +* Resources: Investigation Guide + +*Version*: 307 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Multiple Device Token Hashes for Single Okta Session* + + +This rule detects when a specific Okta actor has multiple device token hashes for a single Okta session. This may indicate an authenticated session has been hijacked or is being used by multiple devices. Adversaries may hijack a session to gain unauthorized access to Okta admin console, applications, tenants, or other resources. + + +*Possible investigation steps:* + +- Since this is an ESQL rule, the `okta.actor.alternate_id` and `okta.authentication_context.external_session_id` values can be used to pivot into the raw authentication events related to this alert. +- Identify the users involved in this action by examining the `okta.actor.id`, `okta.actor.type`, `okta.actor.alternate_id`, and `okta.actor.display_name` fields. +- Determine the device client used for these actions by analyzing `okta.client.ip`, `okta.client.user_agent.raw_user_agent`, `okta.client.zone`, `okta.client.device`, and `okta.client.id` fields. +- With Okta end users identified, review the `okta.debug_context.debug_data.dt_hash` field. + - Historical analysis should indicate if this device token hash is commonly associated with the user. +- Review the `okta.event_type` field to determine the type of authentication event that occurred. + - Authentication events have been filtered out to focus on Okta activity via established sessions. +- Review the past activities of the actor(s) involved in this action by checking their previous actions. +- Evaluate the actions that happened just before and after this event in the `okta.event_type` field to help understand the full context of the activity. + - This may help determine the authentication and authorization actions that occurred between the user, Okta and application. +- Aggregate by `okta.actor.alternate_id` and `event.action` to determine the type of actions that are being performed by the actor(s) involved in this action. + - If various activity is reported that seems to indicate actions from separate users, consider deactivating the user's account temporarily. + + +*False positive analysis:* + +- It is very rare that a legitimate user would have multiple device token hashes for a single Okta session as DT hashes do not change after an authenticated session is established. + + +*Response and remediation:* + +- Consider stopping all sessions for the user(s) involved in this action. +- If this does not appear to be a false positive, consider resetting passwords for the users involved and enabling multi-factor authentication (MFA). + - If MFA is already enabled, consider resetting MFA for the users. +- If any of the users are not legitimate, consider deactivating the user's account. +- Conduct a review of Okta policies and ensure they are in accordance with security best practices. +- Check with internal IT teams to determine if the accounts involved recently had MFA reset at the request of the user. + - If so, confirm with the user this was a legitimate request. + - If so and this was not a legitimate request, consider deactivating the user's account temporarily. + - Reset passwords and reset MFA for the user. +- Alternatively adding `okta.client.ip` or a CIDR range to the `exceptions` list can prevent future occurrences of this event from triggering the rule. + - This should be done with caution as it may prevent legitimate alerts from being generated. + + +==== Setup + + + +*Setup* + + +The Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule. + +==== Rule query + + +[source, js] +---------------------------------- +from logs-okta* +| where + event.dataset == "okta.system" and + not event.action in ( + "policy.evaluate_sign_on", + "user.session.start", + "user.authentication.sso" + ) and + okta.actor.alternate_id != "system@okta.com" and + okta.actor.alternate_id rlike "[^@\s]+\@[^@\s]+" and + okta.authentication_context.external_session_id != "unknown" +| keep + event.action, + okta.actor.alternate_id, + okta.authentication_context.external_session_id, + okta.debug_context.debug_data.dt_hash +| stats + Esql.okta_debug_context_debug_data_dt_hash_count_distinct = count_distinct(okta.debug_context.debug_data.dt_hash) + by + okta.actor.alternate_id, + okta.authentication_context.external_session_id +| where + Esql.okta_debug_context_debug_data_dt_hash_count_distinct >= 2 +| sort + Esql.okta_debug_context_debug_data_dt_hash_count_distinct desc + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Credential Access +** ID: TA0006 +** Reference URL: https://attack.mitre.org/tactics/TA0006/ +* Technique: +** Name: Steal Web Session Cookie +** ID: T1539 +** Reference URL: https://attack.mitre.org/techniques/T1539/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-multiple-microsoft-365-user-account-lockouts-in-short-time-window.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-multiple-microsoft-365-user-account-lockouts-in-short-time-window.asciidoc new file mode 100644 index 0000000000..023eb03d65 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-multiple-microsoft-365-user-account-lockouts-in-short-time-window.asciidoc @@ -0,0 +1,162 @@ +[[prebuilt-rule-8-19-4-multiple-microsoft-365-user-account-lockouts-in-short-time-window]] +=== Multiple Microsoft 365 User Account Lockouts in Short Time Window + +Detects a burst of Microsoft 365 user account lockouts within a short 5-minute window. A high number of IdsLocked login errors across multiple user accounts may indicate brute-force attempts for the same users resulting in lockouts. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray +* https://learn.microsoft.com/en-us/purview/audit-log-detailed-properties +* https://securityscorecard.com/research/massive-botnet-targets-m365-with-stealthy-password-spraying-attacks/ +* https://github.com/0xZDH/Omnispray +* https://github.com/0xZDH/o365spray + +*Tags*: + +* Domain: Cloud +* Domain: SaaS +* Data Source: Microsoft 365 +* Data Source: Microsoft 365 Audit Logs +* Use Case: Threat Detection +* Use Case: Identity and Access Audit +* Tactic: Credential Access +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and Analysis* + + + +*Investigating Multiple Microsoft 365 User Account Lockouts in Short Time Window* + + +Detects a burst of Microsoft 365 user account lockouts within a short 5-minute window. A high number of IdsLocked login errors across multiple user accounts may indicate brute-force attempts for the same users resulting in lockouts. + +This rule uses ESQL aggregations and thus has dynamically generated fields. Correlation of the values in the alert document may need to be performed to the original sign-in and Graph events for further context. + + +*Investigation Steps* + + +- Review the `user_id_list`: Are specific naming patterns targeted (e.g., admin, helpdesk)? +- Examine `ip_list` and `source_orgs`: Look for suspicious ISPs or hosting providers. +- Check `duration_seconds`: A very short window with a high lockout rate often indicates automation. +- Confirm lockout policy thresholds with IAM or Entra ID admins. Did the policy trigger correctly? +- Use the `first_seen` and `last_seen` values to pivot into related authentication or audit logs. +- Correlate with any recent detection of password spraying or credential stuffing activity. +- Review the `request_type` field to identify which authentication methods were used (e.g., OAuth, SAML, etc.). +- Check for any successful logins from the same IP or ASN after the lockouts. + + +*False Positive Analysis* + + +- Automated systems with stale credentials may cause repeated failed logins. +- Legitimate bulk provisioning or scripted tests could unintentionally cause account lockouts. +- Red team exercises or penetration tests may resemble the same lockout pattern. +- Some organizations may have a high volume of lockouts due to user behavior or legacy systems. + + +*Response Recommendations* + + +- Notify affected users and confirm whether activity was expected or suspicious. +- Lock or reset credentials for impacted accounts. +- Block the source IP(s) or ASN temporarily using conditional access or firewall rules. +- Strengthen lockout and retry delay policies if necessary. +- Review the originating application(s) involved via `request_types`. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-o365.audit-* +| mv_expand event.category +| eval + Esql.time_window_date_trunc = date_trunc(5 minutes, @timestamp) +| where + event.dataset == "o365.audit" and + event.category == "authentication" and + event.provider in ("AzureActiveDirectory", "Exchange") and + event.action in ("UserLoginFailed", "PasswordLogonInitialAuthUsingPassword") and + to_lower(o365.audit.ExtendedProperties.RequestType) rlike "(oauth.*||.*login.*)" and + o365.audit.LogonError == "IdsLocked" and + to_lower(o365.audit.UserId) != "not available" and + o365.audit.Target.Type in ("0", "2", "6", "10") and + source.`as`.organization.name != "MICROSOFT-CORP-MSN-as-BLOCK" +| stats + Esql_priv.o365_audit_UserId_count_distinct = count_distinct(to_lower(o365.audit.UserId)), + Esql_priv.o365_audit_UserId_values = values(to_lower(o365.audit.UserId)), + Esql.source_ip_values = values(source.ip), + Esql.source_ip_count_distinct = count_distinct(source.ip), + Esql.source_as_organization_name_values = values(source.`as`.organization.name), + Esql.source_as_organization_name_count_distinct = count_distinct(source.`as`.organization.name), + Esql.source_geo_country_name_values = values(source.geo.country_name), + Esql.source_geo_country_name_count_distinct = count_distinct(source.geo.country_name), + Esql.o365_audit_ExtendedProperties_RequestType_values = values(to_lower(o365.audit.ExtendedProperties.RequestType)), + Esql.timestamp_first_seen = min(@timestamp), + Esql.timestamp_last_seen = max(@timestamp), + Esql.event_count = count(*) + by Esql.time_window_date_trunc +| eval + Esql.event_duration_seconds = date_diff("seconds", Esql.timestamp_first_seen, Esql.timestamp_last_seen) +| keep + Esql.time_window_date_trunc, + Esql_priv.o365_audit_UserId_count_distinct, + Esql_priv.o365_audit_UserId_values, + Esql.source_ip_values, + Esql.source_ip_count_distinct, + Esql.source_as_organization_name_values, + Esql.source_as_organization_name_count_distinct, + Esql.source_geo_country_name_values, + Esql.source_geo_country_name_count_distinct, + Esql.o365_audit_ExtendedProperties_RequestType_values, + Esql.timestamp_first_seen, + Esql.timestamp_last_seen, + Esql.event_count, + Esql.event_duration_seconds +| where + Esql_priv.o365_audit_UserId_count_distinct >= 10 and + Esql.event_count >= 10 and + Esql.event_duration_seconds <= 300 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Credential Access +** ID: TA0006 +** Reference URL: https://attack.mitre.org/tactics/TA0006/ +* Technique: +** Name: Brute Force +** ID: T1110 +** Reference URL: https://attack.mitre.org/techniques/T1110/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-multiple-okta-user-authentication-events-with-client-address.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-multiple-okta-user-authentication-events-with-client-address.asciidoc new file mode 100644 index 0000000000..b724748d10 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-multiple-okta-user-authentication-events-with-client-address.asciidoc @@ -0,0 +1,162 @@ +[[prebuilt-rule-8-19-4-multiple-okta-user-authentication-events-with-client-address]] +=== Multiple Okta User Authentication Events with Client Address + +Detects when a certain threshold of Okta user authentication events are reported for multiple users from the same client address. Adversaries may attempt to launch a credential stuffing or password spraying attack from the same device by using a list of known usernames and passwords to gain unauthorized access to user accounts. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://support.okta.com/help/s/article/How-does-the-Device-Token-work?language=en_US +* https://developer.okta.com/docs/reference/api/event-types/ +* https://www.elastic.co/security-labs/testing-okta-visibility-and-detection-dorothy +* https://sec.okta.com/articles/2023/08/cross-tenant-impersonation-prevention-and-detection +* https://www.okta.com/resources/whitepaper-how-adaptive-mfa-can-help-in-mitigating-brute-force-attacks/ +* https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security +* https://www.elastic.co/security-labs/starter-guide-to-understanding-okta + +*Tags*: + +* Use Case: Identity and Access Audit +* Data Source: Okta +* Tactic: Credential Access +* Resources: Investigation Guide + +*Version*: 206 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Multiple Okta User Authentication Events with Client Address* + + +This rule detects when a certain threshold of Okta user authentication events are reported for multiple users from the same client address. Adversaries may attempt to launch a credential stuffing attack from the same device by using a list of known usernames and passwords to gain unauthorized access to user accounts. Note that Okta does not log unrecognized usernames supplied during authentication attempts, so this rule may not detect all credential stuffing attempts or may indicate a targeted attack. + + +*Possible investigation steps:* + +Since this is an ESQL rule, the `okta.actor.alternate_id` and `okta.client.ip` values can be used to pivot into the raw authentication events related to this activity. +- Identify the users involved in this action by examining the `okta.actor.id`, `okta.actor.type`, `okta.actor.alternate_id`, and `okta.actor.display_name` fields. +- Determine the device client used for these actions by analyzing `okta.client.ip`, `okta.client.user_agent.raw_user_agent`, `okta.client.zone`, `okta.client.device`, and `okta.client.id` fields. +- Review the `okta.security_context.is_proxy` field to determine if the device is a proxy. + - If the device is a proxy, this may indicate that a user is using a proxy to access multiple accounts for password spraying. +- With the list of `okta.actor.alternate_id` values, review `event.outcome` results to determine if the authentication was successful. + - If the authentication was successful for any user, pivoting to `event.action` values for those users may provide additional context. +- With Okta end users identified, review the `okta.debug_context.debug_data.dt_hash` field. + - Historical analysis should indicate if this device token hash is commonly associated with the user. +- Review the `okta.event_type` field to determine the type of authentication event that occurred. + - If the event type is `user.authentication.sso`, the user may have legitimately started a session via a proxy for security or privacy reasons. + - If the event type is `user.authentication.password`, the user may be using a proxy to access multiple accounts for password spraying. + - If the event type is `user.session.start`, the source may have attempted to establish a session via the Okta authentication API. +- Examine the `okta.outcome.result` field to determine if the authentication was successful. +- Review the past activities of the actor(s) involved in this action by checking their previous actions. +- Evaluate the actions that happened just before and after this event in the `okta.event_type` field to help understand the full context of the activity. + - This may help determine the authentication and authorization actions that occurred between the user, Okta and application. + + +*False positive analysis:* + +- A user may have legitimately started a session via a proxy for security or privacy reasons. +- Users may share an endpoint related to work or personal use in which separate Okta accounts are used. + - Architecturally, this shared endpoint may leverage a proxy for security or privacy reasons. + - Shared systems such as Kiosks and conference room computers may be used by multiple users. + - Shared working spaces may have a single endpoint that is used by multiple users. + + +*Response and remediation:* + +- Review the profile of the users involved in this action to determine if proxy usage may be expected. +- If the user is legitimate and the authentication behavior is not suspicious based on device analysis, no action is required. +- If the user is legitimate but the authentication behavior is suspicious, consider resetting passwords for the users involves and enabling multi-factor authentication (MFA). + - If MFA is already enabled, consider resetting MFA for the users. +- If any of the users are not legitimate, consider deactivating the user's account. +- Conduct a review of Okta policies and ensure they are in accordance with security best practices. +- Check with internal IT teams to determine if the accounts involved recently had MFA reset at the request of the user. + - If so, confirm with the user this was a legitimate request. + - If so and this was not a legitimate request, consider deactivating the user's account temporarily. + - Reset passwords and reset MFA for the user. +- If this is a false positive, consider adding the `okta.debug_context.debug_data.dt_hash` field to the `exceptions` list in the rule. + - This will prevent future occurrences of this event for this device from triggering the rule. + - Alternatively adding `okta.client.ip` or a CIDR range to the `exceptions` list can prevent future occurrences of this event from triggering the rule. + - This should be done with caution as it may prevent legitimate alerts from being generated. + + +==== Setup + + +The Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule. + +==== Rule query + + +[source, js] +---------------------------------- +from logs-okta* +| where + event.dataset == "okta.system" and + (event.action == "user.session.start" or event.action rlike "user\.authentication(.*)") and + okta.outcome.reason == "INVALID_CREDENTIALS" +| keep + okta.client.ip, + okta.actor.alternate_id, + okta.actor.id, + event.action, + okta.outcome.reason +| stats + Esql.okta_actor_id_count_distinct = count_distinct(okta.actor.id) + by + okta.client.ip, + okta.actor.alternate_id +| where + Esql.okta_actor_id_count_distinct > 5 +| sort + Esql.okta_actor_id_count_distinct desc + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Credential Access +** ID: TA0006 +** Reference URL: https://attack.mitre.org/tactics/TA0006/ +* Technique: +** Name: Brute Force +** ID: T1110 +** Reference URL: https://attack.mitre.org/techniques/T1110/ +* Sub-technique: +** Name: Password Spraying +** ID: T1110.003 +** Reference URL: https://attack.mitre.org/techniques/T1110/003/ +* Technique: +** Name: Brute Force +** ID: T1110 +** Reference URL: https://attack.mitre.org/techniques/T1110/ +* Sub-technique: +** Name: Credential Stuffing +** ID: T1110.004 +** Reference URL: https://attack.mitre.org/techniques/T1110/004/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-multiple-okta-user-authentication-events-with-same-device-token-hash.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-multiple-okta-user-authentication-events-with-same-device-token-hash.asciidoc new file mode 100644 index 0000000000..fcc04ca657 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-multiple-okta-user-authentication-events-with-same-device-token-hash.asciidoc @@ -0,0 +1,160 @@ +[[prebuilt-rule-8-19-4-multiple-okta-user-authentication-events-with-same-device-token-hash]] +=== Multiple Okta User Authentication Events with Same Device Token Hash + +Detects when a high number of Okta user authentication events are reported for multiple users in a short time frame. Adversaries may attempt to launch a credential stuffing or password spraying attack from the same device by using a list of known usernames and passwords to gain unauthorized access to user accounts. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://support.okta.com/help/s/article/How-does-the-Device-Token-work?language=en_US +* https://developer.okta.com/docs/reference/api/event-types/ +* https://www.elastic.co/security-labs/testing-okta-visibility-and-detection-dorothy +* https://sec.okta.com/articles/2023/08/cross-tenant-impersonation-prevention-and-detection +* https://www.okta.com/resources/whitepaper-how-adaptive-mfa-can-help-in-mitigating-brute-force-attacks/ +* https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security +* https://www.elastic.co/security-labs/starter-guide-to-understanding-okta + +*Tags*: + +* Use Case: Identity and Access Audit +* Data Source: Okta +* Tactic: Credential Access +* Resources: Investigation Guide + +*Version*: 206 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Multiple Okta User Authentication Events with Same Device Token Hash* + + +This rule detects when a high number of Okta user authentication events are reported for multiple users in a short time frame. Adversaries may attempt to launch a credential stuffing attack from the same device by using a list of known usernames and passwords to gain unauthorized access to user accounts. Note that Okta does not log unrecognized usernames supplied during authentication attempts, so this rule may not detect all credential stuffing attempts or may indicate a targeted attack. + + +*Possible investigation steps:* + +- Since this is an ESQL rule, the `okta.actor.alternate_id` and `okta.debug_context.debug_data.dt_hash` values can be used to pivot into the raw authentication events related to this activity. +- Identify the users involved in this action by examining the `okta.actor.id`, `okta.actor.type`, `okta.actor.alternate_id`, and `okta.actor.display_name` fields. +- Determine the device client used for these actions by analyzing `okta.client.ip`, `okta.client.user_agent.raw_user_agent`, `okta.client.zone`, `okta.client.device`, and `okta.client.id` fields. +- Review the `okta.security_context.is_proxy` field to determine if the device is a proxy. + - If the device is a proxy, this may indicate that a user is using a proxy to access multiple accounts for password spraying. +- With the list of `okta.actor.alternate_id` values, review `event.outcome` results to determine if the authentication was successful. + - If the authentication was successful for any user, pivoting to `event.action` values for those users may provide additional context. +- With Okta end users identified, review the `okta.debug_context.debug_data.dt_hash` field. + - Historical analysis should indicate if this device token hash is commonly associated with the user. +- Review the `okta.event_type` field to determine the type of authentication event that occurred. + - If the event type is `user.authentication.sso`, the user may have legitimately started a session via a proxy for security or privacy reasons. + - If the event type is `user.authentication.password`, the user may be using a proxy to access multiple accounts for password spraying. +- Examine the `okta.outcome.result` field to determine if the authentication was successful. +- Review the past activities of the actor(s) involved in this action by checking their previous actions. +- Evaluate the actions that happened just before and after this event in the `okta.event_type` field to help understand the full context of the activity. + - This may help determine the authentication and authorization actions that occurred between the user, Okta and application. + + +*False positive analysis:* + +- A user may have legitimately started a session via a proxy for security or privacy reasons. +- Users may share an endpoint related to work or personal use in which separate Okta accounts are used. + - Architecturally, this shared endpoint may leverage a proxy for security or privacy reasons. + - Shared systems such as Kiosks and conference room computers may be used by multiple users. + - Shared working spaces may have a single endpoint that is used by multiple users. + + +*Response and remediation:* + +- Review the profile of the users involved in this action to determine if proxy usage may be expected. +- If the user is legitimate and the authentication behavior is not suspicious based on device analysis, no action is required. +- If the user is legitimate but the authentication behavior is suspicious, consider resetting passwords for the users involves and enabling multi-factor authentication (MFA). + - If MFA is already enabled, consider resetting MFA for the users. +- If any of the users are not legitimate, consider deactivating the user's account. +- Conduct a review of Okta policies and ensure they are in accordance with security best practices. +- Check with internal IT teams to determine if the accounts involved recently had MFA reset at the request of the user. + - If so, confirm with the user this was a legitimate request. + - If so and this was not a legitimate request, consider deactivating the user's account temporarily. + - Reset passwords and reset MFA for the user. +- If this is a false positive, consider adding the `okta.debug_context.debug_data.dt_hash` field to the `exceptions` list in the rule. + - This will prevent future occurrences of this event for this device from triggering the rule. + + +==== Setup + + +The Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule. + +==== Rule query + + +[source, js] +---------------------------------- +from logs-okta* +| where + event.dataset == "okta.system" and + (event.action rlike "user\.authentication(.*)" or event.action == "user.session.start") and + okta.debug_context.debug_data.dt_hash != "-" and + okta.outcome.reason == "INVALID_CREDENTIALS" +| keep + event.action, + okta.debug_context.debug_data.dt_hash, + okta.actor.id, + okta.actor.alternate_id, + okta.outcome.reason +| stats + Esql.okta_actor_id_count_distinct = count_distinct(okta.actor.id) + by + okta.debug_context.debug_data.dt_hash, + okta.actor.alternate_id +| where + Esql.okta_actor_id_count_distinct > 20 +| sort + Esql.okta_actor_id_count_distinct desc + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Credential Access +** ID: TA0006 +** Reference URL: https://attack.mitre.org/tactics/TA0006/ +* Technique: +** Name: Brute Force +** ID: T1110 +** Reference URL: https://attack.mitre.org/techniques/T1110/ +* Sub-technique: +** Name: Password Spraying +** ID: T1110.003 +** Reference URL: https://attack.mitre.org/techniques/T1110/003/ +* Technique: +** Name: Brute Force +** ID: T1110 +** Reference URL: https://attack.mitre.org/techniques/T1110/ +* Sub-technique: +** Name: Credential Stuffing +** ID: T1110.004 +** Reference URL: https://attack.mitre.org/techniques/T1110/004/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-oidc-discovery-url-changed-in-entra-id.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-oidc-discovery-url-changed-in-entra-id.asciidoc new file mode 100644 index 0000000000..31687429b2 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-oidc-discovery-url-changed-in-entra-id.asciidoc @@ -0,0 +1,127 @@ +[[prebuilt-rule-8-19-4-oidc-discovery-url-changed-in-entra-id]] +=== OIDC Discovery URL Changed in Entra ID + +Detects a change to the OpenID Connect (OIDC) discovery URL in the Entra ID Authentication Methods Policy. This behavior may indicate an attempt to federate Entra ID with an attacker-controlled identity provider, enabling bypass of multi-factor authentication (MFA) and unauthorized access through bring-your-own IdP (BYOIDP) methods. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: high + +*Risk score*: 73 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://dirkjanm.io/persisting-with-federated-credentials-entra-apps-managed-identities/ + +*Tags*: + +* Domain: Cloud +* Domain: Identity +* Data Source: Azure +* Data Source: Microsoft Entra ID +* Data Source: Microsoft Entra ID Audit Logs +* Use Case: Identity and Access Audit +* Tactic: Persistence +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating OIDC Discovery URL Changed in Entra ID* + + +This rule detects when the OIDC `discoveryUrl` is changed within the Entra ID Authentication Methods policy. Adversaries may leverage this to federate Entra ID with a rogue Identity Provider (IdP) under their control, allowing them to authenticate users with attacker-owned credentials and bypass MFA. This misconfiguration allows an attacker to impersonate valid users by issuing tokens via a third-party OIDC IdP while still passing validation in Entra ID. This technique has been publicly demonstrated and has critical implications for trust in federated identity. + + +*Possible investigation steps* + +- Review `azure.auditlogs.properties.initiated_by.user.userPrincipalName` and `ipAddress` to identify who made the change and from where. +- Examine the `old_oidc_discovery` and `new_oidc_discovery` to confirm if the new `discoveryUrl` points to an unexpected or untrusted IdP. +- Check that the discovery URLs have `.well-known/openid-configuration` endpoints, which are standard for OIDC providers. +- Use `azure.auditlogs.properties.correlation_id` to pivot to related changes and activity from the same session. +- Review any subsequent sign-in activity that may have originated from the new IdP. +- Pivot to additional logs associated with the user or application that made the change to identify any further suspicious activity. + + +*False positive analysis* + +- Entra ID administrators may intentionally reconfigure OIDC trust relationships to support new business requirements. +- Validate any changes with the identity or security operations team before taking action. + + +*Response and remediation* + +- If the change is unauthorized, immediately revert the discovery URL to the trusted IdP via the Entra ID portal. +- Revoke tokens or sessions issued after the configuration change. +- Investigate how the unauthorized change occurred (e.g., compromised account or over-privileged app). +- Apply conditional access policies and change control procedures to protect IdP configuration changes. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-azure.auditlogs-* metadata _id, _version, _index +| where event.action == "Authentication Methods Policy Update" +| eval Esql.azure_auditlogs_properties_target_resources_modified_properties_new_value_replace = replace(`azure.auditlogs.properties.target_resources.0.modified_properties.0.new_value`, "\\\\", "") +| eval Esql.azure_auditlogs_properties_target_resources_modified_properties_old_value_replace = replace(`azure.auditlogs.properties.target_resources.0.modified_properties.0.old_value`, "\\\\", "") +| dissect Esql.azure_auditlogs_properties_target_resources_modified_properties_new_value_replace "%{}discoveryUrl\":\"%{Esql.azure_auditlogs_properties_auth_oidc_discovery_url_new}\"}%{}" +| dissect Esql.azure_auditlogs_properties_target_resources_modified_properties_old_value_replace "%{}discoveryUrl\":\"%{Esql.azure_auditlogs_properties_auth_oidc_discovery_url_old}\"}%{}" +| where Esql.azure_auditlogs_properties_auth_oidc_discovery_url_new is not null and Esql.azure_auditlogs_properties_auth_oidc_discovery_url_old is not null +| where Esql.azure_auditlogs_properties_auth_oidc_discovery_url_new != Esql.azure_auditlogs_properties_auth_oidc_discovery_url_old +| keep + @timestamp, + event.action, + event.outcome, + azure.tenant_id, + azure.correlation_id, + azure.auditlogs.properties.activity_datetime, + azure.auditlogs.properties.operation_type, + azure.auditlogs.properties.initiated_by.user.userPrincipalName, + azure.auditlogs.properties.initiated_by.user.displayName, + azure.auditlogs.properties.initiated_by.user.ipAddress, + source.geo.city_name, + source.geo.region_name, + source.geo.country_name, + Esql.azure_auditlogs_properties_auth_oidc_discovery_url_new, + Esql.azure_auditlogs_properties_auth_oidc_discovery_url_old + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Persistence +** ID: TA0003 +** Reference URL: https://attack.mitre.org/tactics/TA0003/ +* Technique: +** Name: Modify Authentication Process +** ID: T1556 +** Reference URL: https://attack.mitre.org/techniques/T1556/ +* Sub-technique: +** Name: Conditional Access Policies +** ID: T1556.009 +** Reference URL: https://attack.mitre.org/techniques/T1556/009/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-okta-user-sessions-started-from-different-geolocations.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-okta-user-sessions-started-from-different-geolocations.asciidoc new file mode 100644 index 0000000000..39a96d2a7c --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-okta-user-sessions-started-from-different-geolocations.asciidoc @@ -0,0 +1,146 @@ +[[prebuilt-rule-8-19-4-okta-user-sessions-started-from-different-geolocations]] +=== Okta User Sessions Started from Different Geolocations + +Detects when a specific Okta actor has multiple sessions started from different geolocations. Adversaries may attempt to launch an attack by using a list of known usernames and passwords to gain unauthorized access to user accounts from different locations. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 15m + +*Searches indices from*: now-30m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://developer.okta.com/docs/reference/api/system-log/ +* https://developer.okta.com/docs/reference/api/event-types/ +* https://www.elastic.co/security-labs/testing-okta-visibility-and-detection-dorothy +* https://sec.okta.com/articles/2023/08/cross-tenant-impersonation-prevention-and-detection +* https://www.rezonate.io/blog/okta-logs-decoded-unveiling-identity-threats-through-threat-hunting/ +* https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security +* https://www.elastic.co/security-labs/starter-guide-to-understanding-okta + +*Tags*: + +* Use Case: Identity and Access Audit +* Data Source: Okta +* Tactic: Initial Access +* Resources: Investigation Guide + +*Version*: 307 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Okta User Sessions Started from Different Geolocations* + + +This rule detects when a specific Okta actor has multiple sessions started from different geolocations. Adversaries may attempt to launch an attack by using a list of known usernames and passwords to gain unauthorized access to user accounts from different locations. + + +*Possible investigation steps:* + +- Since this is an ESQL rule, the `okta.actor.alternate_id` and `okta.client.id` values can be used to pivot into the raw authentication events related to this alert. +- Identify the users involved in this action by examining the `okta.actor.id`, `okta.actor.type`, `okta.actor.alternate_id`, and `okta.actor.display_name` fields. +- Determine the device client used for these actions by analyzing `okta.client.ip`, `okta.client.user_agent.raw_user_agent`, `okta.client.zone`, `okta.client.device`, and `okta.client.id` fields. +- With Okta end users identified, review the `okta.debug_context.debug_data.dt_hash` field. + - Historical analysis should indicate if this device token hash is commonly associated with the user. +- Review the `okta.event_type` field to determine the type of authentication event that occurred. + - If the event type is `user.authentication.sso`, the user may have legitimately started a session via a proxy for security or privacy reasons. + - If the event type is `user.authentication.password`, the user may be using a proxy to access multiple accounts for password spraying. + - If the event type is `user.session.start`, the source may have attempted to establish a session via the Okta authentication API. +- Review the past activities of the actor(s) involved in this action by checking their previous actions. +- Evaluate the actions that happened just before and after this event in the `okta.event_type` field to help understand the full context of the activity. + - This may help determine the authentication and authorization actions that occurred between the user, Okta and application. + + +*False positive analysis:* + +- It is very rare that a legitimate user would have multiple sessions started from different geo-located countries in a short time frame. + + +*Response and remediation:* + +- If the user is legitimate and the authentication behavior is not suspicious based on device analysis, no action is required. +- If the user is legitimate but the authentication behavior is suspicious, consider resetting passwords for the users involves and enabling multi-factor authentication (MFA). + - If MFA is already enabled, consider resetting MFA for the users. +- If any of the users are not legitimate, consider deactivating the user's account. +- Conduct a review of Okta policies and ensure they are in accordance with security best practices. +- Check with internal IT teams to determine if the accounts involved recently had MFA reset at the request of the user. + - If so, confirm with the user this was a legitimate request. + - If so and this was not a legitimate request, consider deactivating the user's account temporarily. + - Reset passwords and reset MFA for the user. +- If this is a false positive, consider adding the `okta.debug_context.debug_data.dt_hash` field to the `exceptions` list in the rule. + - This will prevent future occurrences of this event for this device from triggering the rule. + - Alternatively adding `okta.client.ip` or a CIDR range to the `exceptions` list can prevent future occurrences of this event from triggering the rule. + - This should be done with caution as it may prevent legitimate alerts from being generated. + + +==== Setup + + +The Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-okta* +| where + event.dataset == "okta.system" and + (event.action rlike "user\.authentication(.*)" or event.action == "user.session.start") and + okta.security_context.is_proxy != true and + okta.actor.id != "unknown" and + event.outcome == "success" +| keep + event.action, + okta.security_context.is_proxy, + okta.actor.id, + okta.actor.alternate_id, + event.outcome, + client.geo.country_name +| stats + Esql.client_geo_country_name_count_distinct = count_distinct(client.geo.country_name) + by okta.actor.id, okta.actor.alternate_id +| where + Esql.client_geo_country_name_count_distinct >= 2 +| sort + Esql.client_geo_country_name_count_distinct desc + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Initial Access +** ID: TA0001 +** Reference URL: https://attack.mitre.org/tactics/TA0001/ +* Technique: +** Name: Valid Accounts +** ID: T1078 +** Reference URL: https://attack.mitre.org/techniques/T1078/ +* Sub-technique: +** Name: Cloud Accounts +** ID: T1078.004 +** Reference URL: https://attack.mitre.org/techniques/T1078/004/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-abuse-of-resources-by-high-token-count-and-large-response-sizes.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-abuse-of-resources-by-high-token-count-and-large-response-sizes.asciidoc new file mode 100644 index 0000000000..377761a8d9 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-abuse-of-resources-by-high-token-count-and-large-response-sizes.asciidoc @@ -0,0 +1,145 @@ +[[prebuilt-rule-8-19-4-potential-abuse-of-resources-by-high-token-count-and-large-response-sizes]] +=== Potential Abuse of Resources by High Token Count and Large Response Sizes + +Detects potential resource exhaustion or data breach attempts by monitoring for users who consistently generate high input token counts, submit numerous requests, and receive large responses. This behavior could indicate an attempt to overload the system or extract an unusually large amount of data, possibly revealing sensitive information or causing service disruptions. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 10m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://atlas.mitre.org/techniques/AML.T0051 +* https://owasp.org/www-project-top-10-for-large-language-model-applications/ +* https://www.elastic.co/security-labs/elastic-advances-llm-security + +*Tags*: + +* Domain: LLM +* Data Source: AWS Bedrock +* Data Source: Amazon Web Services +* Data Source: AWS S3 +* Use Case: Potential Overload +* Use Case: Resource Exhaustion +* Mitre Atlas: LLM04 +* Resources: Investigation Guide + +*Version*: 5 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Potential Abuse of Resources by High Token Count and Large Response Sizes* + + +Amazon Bedrock is AWS’s managed service that enables developers to build and scale generative AI applications using large foundation models (FMs) from top providers. + +Bedrock offers a variety of pretrained models from Amazon (such as the Titan series), as well as models from providers like Anthropic, Meta, Cohere, and AI21 Labs. + + +*Possible investigation steps* + + +- Identify the user account that used high prompt token counts and whether it should perform this kind of action. +- Investigate large response sizes and the number of requests made by the user account. +- Investigate other alerts associated with the user account during the past 48 hours. +- Consider the time of day. If the user is a human (not a program or script), did the activity take place during a normal time of day? +- Examine the account's prompts and responses in the last 24 hours. +- If you suspect the account has been compromised, scope potentially compromised assets by tracking Amazon Bedrock model access, prompts generated, and responses to the prompts by the account in the last 24 hours. + + +*False positive analysis* + + +- Verify the user account that used high prompt and large response sizes, has a business justification for the heavy usage of the system. + + +*Response and remediation* + + +- Initiate the incident response process based on the outcome of the triage. +- Disable or limit the account during the investigation and response. +- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context: + - Identify the account role in the cloud environment. + - Identify if the attacker is moving laterally and compromising other Amazon Bedrock Services. + - Identify any regulatory or legal ramifications related to this activity. + - Identify potential resource exhaustion and impact on billing. +- Review the permissions assigned to the implicated user group or role behind these requests to ensure they are authorized and expected to access bedrock and ensure that the least privilege principle is being followed. +- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector. +- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR). + + +==== Setup + + + +*Setup* + + +This rule requires that guardrails are configured in AWS Bedrock. For more information, see the AWS Bedrock documentation: + +https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws_bedrock.invocation-* + +// keep token usage data +| keep + user.id, + gen_ai.usage.prompt_tokens, + gen_ai.usage.completion_tokens + +// Aggregate usage metrics +| stats + Esql.ml_usage_prompt_tokens_max = max(gen_ai.usage.prompt_tokens), + Esql.ml_invocations_total_count = count(*), + Esql.ml_usage_completion_tokens_avg = avg(gen_ai.usage.completion_tokens) + by + user.id + +// Filter for suspicious usage patterns +| where + Esql.ml_usage_prompt_tokens_max > 5000 + and Esql.ml_invocations_total_count > 10 + and Esql.ml_usage_completion_tokens_avg > 500 + +// Calculate a custom risk factor +| eval Esql.ml_risk_score = + (Esql.ml_usage_prompt_tokens_max / 1000) * + Esql.ml_invocations_total_count * + (Esql.ml_usage_completion_tokens_avg / 500) + +// Filter on risk score +| where Esql.ml_risk_score > 10 + +// sort high risk users to top +| sort Esql.ml_risk_score desc + +---------------------------------- diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-aws-s3-bucket-ransomware-note-uploaded.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-aws-s3-bucket-ransomware-note-uploaded.asciidoc new file mode 100644 index 0000000000..dd8c5a2ac6 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-aws-s3-bucket-ransomware-note-uploaded.asciidoc @@ -0,0 +1,153 @@ +[[prebuilt-rule-8-19-4-potential-aws-s3-bucket-ransomware-note-uploaded]] +=== Potential AWS S3 Bucket Ransomware Note Uploaded + +Identifies potential ransomware note being uploaded to an AWS S3 bucket. This rule detects the `PutObject` S3 API call with a common ransomware note file extension such as `.ransom`, or `.lock`. Adversaries with access to a misconfigured S3 bucket may retrieve, delete, and replace objects with ransom notes to extort victims. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://s3.amazonaws.com/bizzabo.file.upload/PtZzA0eFQwV2RA5ysNeo_ERMETIC%20REPORT%20-%20AWS%20S3%20Ransomware%20Exposure%20in%20the%20Wild.pdf +* https://stratus-red-team.cloud/attack-techniques/AWS/aws.impact.s3-ransomware-batch-deletion/ +* https://rhinosecuritylabs.com/aws/s3-ransomware-part-1-attack-vector/ + +*Tags*: + +* Domain: Cloud +* Data Source: AWS +* Data Source: Amazon Web Services +* Data Source: AWS S3 +* Use Case: Threat Detection +* Tactic: Impact +* Resources: Investigation Guide + +*Version*: 6 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Potential AWS S3 Bucket Ransomware Note Uploaded* + + +This rule detects the `PutObject` S3 API call with a common ransomware note file extension such as `.ransom`, or `.lock`. Adversaries with access to a misconfigured S3 bucket may retrieve, delete, and replace objects with ransom notes to extort victims. + + +*Possible Investigation Steps:* + + +- **Identify the Actor**: Review the `aws.cloudtrail.user_identity.arn` and `aws.cloudtrail.user_identity.access_key_id` fields to identify who performed the action. Verify if this actor typically performs such actions and if they have the necessary permissions. +- **Review the Request Details**: Examine the `aws.cloudtrail.request_parameters` to understand the specific details of the `PutObject` action. Look for any unusual parameters that could suggest unauthorized or malicious modifications. +- **Analyze the Source of the Request**: Investigate the `source.ip` and `source.geo` fields to determine the geographical origin of the request. An external or unexpected location might indicate compromised credentials or unauthorized access. +- **Contextualize with Timestamp**: Use the `@timestamp` field to check when the ransom note was uploaded. Changes during non-business hours or outside regular maintenance windows might require further scrutiny. +- **Inspect the Ransom Note**: Review the `aws.cloudtrail.request_parameters` for the `PutObject` action to identify the characteristics of the uploaded ransom note. Look for common ransomware file extensions such as `.txt`, `.note`, `.ransom`, or `.html`. +- **Correlate with Other Activities**: Search for related CloudTrail events before and after this action to see if the same actor or IP address engaged in other potentially suspicious activities. +- **Check for Object Deletion or Access**: Look for `DeleteObject`, `DeleteObjects`, or `GetObject` API calls to the same S3 bucket that may indicate the adversary accessing and destroying objects before placing the ransom note. + + +*False Positive Analysis:* + + +- **Legitimate Administrative Actions**: Confirm if the `PutObject` action aligns with scheduled updates, maintenance activities, or legitimate administrative tasks documented in change management systems. +- **Consistency Check**: Compare the action against historical data of similar activities performed by the user or within the organization. If the action is consistent with past legitimate activities, it might indicate a false alarm. +- **Verify through Outcomes**: Check the `aws.cloudtrail.response_elements` and the `event.outcome` to confirm if the upload was successful and intended according to policy. + + +*Response and Remediation:* + + +- **Immediate Review and Reversal if Necessary**: If the activity was unauthorized, remove the uploaded ransom notes from the S3 bucket and review the bucket's access logs for any suspicious activity. +- **Enhance Monitoring and Alerts**: Adjust monitoring systems to alert on similar `PutObject` actions, especially those involving sensitive data or unusual file extensions. +- **Educate and Train**: Provide additional training to users with administrative rights on the importance of security best practices concerning S3 bucket management and the risks of ransomware. +- **Audit S3 Bucket Policies and Permissions**: Conduct a comprehensive audit of all S3 bucket policies and associated permissions to ensure they adhere to the principle of least privilege. +- **Incident Response**: If there's an indication of malicious intent or a security breach, initiate the incident response protocol to mitigate any damage and prevent future occurrences. + + +*Additional Information:* + + +For further guidance on managing S3 bucket security and protecting against ransomware, refer to the https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html[AWS S3 documentation] and AWS best practices for security. Additionally, consult the following resources for specific details on S3 ransomware protection: +- https://s3.amazonaws.com/bizzabo.file.upload/PtZzA0eFQwV2RA5ysNeo_ERMETIC%20REPORT%20-%20AWS%20S3%20Ransomware%20Exposure%20in%20the%20Wild.pdf[ERMETIC REPORT - AWS S3 Ransomware Exposure in the Wild] +- https://stratus-red-team.cloud/attack-techniques/AWS/aws.impact.s3-ransomware-batch-deletion/[AWS S3 Ransomware Batch Deletion] +- https://rhinosecuritylabs.com/aws/s3-ransomware-part-1-attack-vector/[S3 Ransomware Part 1: Attack Vector] + + +==== Setup + + +AWS S3 data types need to be enabled in the CloudTrail trail configuration. + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws.cloudtrail-* + +// any successful uploads via S3 API requests +| where + event.dataset == "aws.cloudtrail" + and event.provider == "s3.amazonaws.com" + and event.action == "PutObject" + and event.outcome == "success" + +// extract object key from API request parameters +| dissect aws.cloudtrail.request_parameters "%{?ignore_values}key=%{Esql.aws_cloudtrail_request_parameters_object_key}}" + +// regex match against common ransomware naming patterns +| where + Esql.aws_cloudtrail_request_parameters_object_key rlike "(.*)(ransom|lock|crypt|enc|readme|how_to_decrypt|decrypt_instructions|recovery|datarescue)(.*)" + and not Esql.aws_cloudtrail_request_parameters_object_key rlike "(.*)(AWSLogs|CloudTrail|access-logs)(.*)" + +// keep relevant ECS and derived fields +| keep + tls.client.server_name, + aws.cloudtrail.user_identity.arn, + Esql.aws_cloudtrail_request_parameters_object_key + +// aggregate by server name, actor, and object key +| stats + Esql.event_count = count(*) + by + tls.client.server_name, + aws.cloudtrail.user_identity.arn, + Esql.aws_cloudtrail_request_parameters_object_key + +// filter for rare single uploads (likely test/detonation) +| where Esql.event_count == 1 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Impact +** ID: TA0040 +** Reference URL: https://attack.mitre.org/tactics/TA0040/ +* Technique: +** Name: Data Destruction +** ID: T1485 +** Reference URL: https://attack.mitre.org/techniques/T1485/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-azure-openai-model-theft.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-azure-openai-model-theft.asciidoc new file mode 100644 index 0000000000..2f85b7effb --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-azure-openai-model-theft.asciidoc @@ -0,0 +1,132 @@ +[[prebuilt-rule-8-19-4-potential-azure-openai-model-theft]] +=== Potential Azure OpenAI Model Theft + +Monitors for suspicious activities that may indicate theft or unauthorized duplication of machine learning (ML) models, such as unauthorized API calls, atypical access patterns, or large data transfers that are unusual during model interactions. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 10m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://genai.owasp.org/llmrisk/llm10-model-theft +* https://atlas.mitre.org/techniques/AML.T0044 + +*Tags*: + +* Domain: LLM +* Data Source: Azure OpenAI +* Data Source: Azure Event Hubs +* Use Case: Model Theft +* Mitre Atlas: T0044 +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + +> **Disclaimer**: +> 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. + + +*Investigating Potential Azure OpenAI Model Theft* + + +Azure OpenAI models are integral to many applications, providing advanced machine learning capabilities. Adversaries may exploit these models by making unauthorized API calls or transferring large volumes of data, potentially indicating model theft. The detection rule identifies such threats by monitoring audit logs for unusual access patterns or excessive data transfers, flagging activities that deviate from normal usage. + + +*Possible investigation steps* + + +- Review the audit logs for the specific resource group and resource name flagged in the alert to understand the context of the access patterns. +- Analyze the timestamps associated with the suspicious activities to determine if they align with known operational periods or if they occur during unusual times. +- Investigate the source of the API calls by identifying the IP addresses or user accounts involved in the "ListKey" operations to determine if they are authorized or known entities. +- Examine the response length data to assess whether the volume of data transferred is consistent with legitimate use cases or if it suggests potential data exfiltration. +- Cross-reference the flagged activities with other security logs or alerts to identify any correlated suspicious behavior or potential indicators of compromise. + + +*False positive analysis* + + +- High-frequency legitimate API calls from automated scripts or applications may trigger the rule. Users can create exceptions for known scripts by identifying their specific access patterns and excluding them from the rule. +- Large data transfers during scheduled model updates or backups can be mistaken for suspicious activity. Users should whitelist these operations by correlating them with scheduled maintenance windows or known update events. +- Regular access by trusted internal teams for model evaluation or testing might appear as atypical patterns. Users can mitigate this by maintaining a list of authorized personnel and their expected access behaviors, then excluding these from the alert criteria. +- Integration with other Azure services that require frequent access to OpenAI models could generate false positives. Users should document these integrations and adjust the rule to recognize and exclude these legitimate interactions. + + +*Response and remediation* + + +- Immediately isolate the affected Azure resources by restricting network access to prevent further unauthorized API calls or data transfers. +- Revoke and regenerate API keys associated with the compromised Azure OpenAI resources to prevent further unauthorized access. +- Conduct a thorough review of audit logs to identify any additional unauthorized access attempts or data transfers, and document all findings for further analysis. +- Notify the security operations team and relevant stakeholders about the potential model theft incident to ensure coordinated response efforts. +- Implement additional monitoring on the affected resources to detect any further suspicious activities, focusing on access patterns and data transfer volumes. +- Escalate the incident to the organization's incident response team for a comprehensive investigation and to determine if any data exfiltration occurred. +- Review and update access controls and permissions for Azure OpenAI resources to ensure they adhere to the principle of least privilege, reducing the risk of future unauthorized access. + + +==== Setup + + + +*Setup* + + +For more information on +streaming events, see the Azure OpenAI documentation: + +https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/stream-monitoring-data-event-hubs + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-azure_openai.logs-* +| where + azure.open_ai.operation_name == "ListKey" and + azure.open_ai.category == "Audit" +| keep + @timestamp, + azure.open_ai.operation_name, + azure.open_ai.category, + azure.resource.group, + azure.resource.name, + azure.open_ai.properties.response_length +| stats + Esql.event_count = count(*), + Esql.azure_open_ai_properties_response_length_max = max(azure.open_ai.properties.response_length) + by + azure.resource.group, + azure.resource.name +| where + Esql.event_count >= 100 or + Esql.azure_open_ai_properties_response_length_max >= 1000000 +| sort + Esql.event_count desc + +---------------------------------- diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-denial-of-azure-openai-ml-service.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-denial-of-azure-openai-ml-service.asciidoc new file mode 100644 index 0000000000..8523be676b --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-denial-of-azure-openai-ml-service.asciidoc @@ -0,0 +1,129 @@ +[[prebuilt-rule-8-19-4-potential-denial-of-azure-openai-ml-service]] +=== Potential Denial of Azure OpenAI ML Service + +Detects patterns indicative of Denial-of-Service (DoS) attacks on machine learning (ML) models, focusing on unusually high volume and frequency of requests or patterns of requests that are known to cause performance degradation or service disruption, such as large input sizes or rapid API calls. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 10m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://genai.owasp.org/llmrisk/llm04-model-denial-of-service +* https://atlas.mitre.org/techniques/AML.T0029 + +*Tags*: + +* Domain: LLM +* Data Source: Azure OpenAI +* Data Source: Azure Event Hubs +* Use Case: Denial of Service +* Mitre Atlas: T0029 +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + +> **Disclaimer**: +> 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. + + +*Investigating Potential Denial of Azure OpenAI ML Service* + + +Azure OpenAI ML services enable scalable deployment of machine learning models, crucial for AI-driven applications. Adversaries may exploit these services by overwhelming them with excessive or malformed requests, leading to service degradation or outages. The detection rule identifies such threats by monitoring for high-frequency, large-size requests, which are indicative of potential denial-of-service attacks. + + +*Possible investigation steps* + + +- Review the logs for the specific time window identified by the target_time_window field to understand the context and volume of requests. +- Identify the specific Azure resource involved using the azure.resource.name field to determine if the service is critical or sensitive. +- Examine the cloud.account.id field to ascertain if the requests are originating from a known or trusted account, or if they are potentially malicious. +- Analyze the request patterns, focusing on the avg_request_size and count fields, to determine if the requests are consistent with normal usage or indicative of a potential attack. +- Check for any recent changes or updates to the Azure OpenAI ML service configuration or deployment that might have affected its performance or security posture. +- Correlate the findings with other security logs or alerts to identify any related suspicious activities or broader attack patterns. + + +*False positive analysis* + + +- High-volume legitimate usage patterns can trigger false positives, such as during scheduled batch processing or data analysis tasks. Users can mitigate this by setting exceptions for known time windows or specific resource names associated with these activities. +- Large input sizes from legitimate applications, like those processing extensive datasets or complex queries, may be misidentified as threats. Users should identify and whitelist these applications by their resource names or account IDs. +- Testing and development environments often generate high-frequency requests as part of load testing or performance tuning. Users can exclude these environments by filtering out specific resource names or account IDs associated with non-production activities. +- Automated scripts or integrations that interact with the Azure OpenAI ML service at high frequencies for valid business processes might be flagged. Users should document and exclude these scripts by identifying their unique request patterns or resource identifiers. + + +*Response and remediation* + + +- Immediately throttle or block the IP addresses or accounts responsible for the high-frequency, large-size requests to prevent further service degradation. +- Notify the Azure OpenAI service administrators and relevant stakeholders about the detected potential denial-of-service attack for awareness and further action. +- Review and adjust rate limiting and request size policies on the Azure OpenAI ML service to mitigate the impact of similar attacks in the future. +- Conduct a post-incident analysis to identify any vulnerabilities or misconfigurations that allowed the attack to occur and address them promptly. +- Escalate the incident to the security operations team for further investigation and to determine if the attack is part of a larger threat campaign. +- Implement additional monitoring and alerting for unusual patterns of requests, focusing on high volume and frequency, to enhance early detection of similar threats. +- Coordinate with the cloud provider's support team to ensure any necessary infrastructure adjustments or protections are in place to prevent recurrence. + + +==== Setup + + + +*Setup* + + +For more information on streaming events, see the Azure OpenAI documentation: + +https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/stream-monitoring-data-event-hubs + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-azure_openai.logs-* +| eval + Esql.time_window_date_trunc = date_trunc(1 minutes, @timestamp) +| where azure.open_ai.operation_name == "ChatCompletions_Create" +| keep + azure.open_ai.properties.request_length, + azure.resource.name, + cloud.account.id, + Esql.time_window_date_trunc +| stats + Esql.event_count = count(*), + Esql.azure_open_ai_properties_request_length_avg = avg(azure.open_ai.properties.request_length) + by + Esql.time_window_date_trunc, + azure.resource.name +| where + Esql.event_count >= 10 and + Esql.azure_open_ai_properties_request_length_avg >= 5000 +| sort Esql.event_count desc + +---------------------------------- diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-dynamic-iex-reconstruction-via-environment-variables.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-dynamic-iex-reconstruction-via-environment-variables.asciidoc new file mode 100644 index 0000000000..336e0b9751 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-dynamic-iex-reconstruction-via-environment-variables.asciidoc @@ -0,0 +1,180 @@ +[[prebuilt-rule-8-19-4-potential-dynamic-iex-reconstruction-via-environment-variables]] +=== Potential Dynamic IEX Reconstruction via Environment Variables + +Identifies PowerShell scripts that reconstruct the IEX (Invoke-Expression) command at runtime using indexed slices of environment variables. This technique leverages character access and join operations to build execution logic dynamically, bypassing static keyword detection and evading defenses such as AMSI. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Windows +* Use Case: Threat Detection +* Tactic: Defense Evasion +* Data Source: PowerShell Logs +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Potential Dynamic IEX Reconstruction via Environment Variables* + + +PowerShell's Invoke-Expression (IEX) command is a powerful tool for executing strings as code, often exploited by attackers to run obfuscated scripts. Adversaries may dynamically reconstruct IEX using environment variables to evade static detection. The detection rule identifies scripts that manipulate environment variables to form IEX commands, focusing on patterns of character slicing and joining, which are indicative of obfuscation techniques. By analyzing script length and specific patterns, the rule effectively flags potential misuse, aiding in defense against such evasion tactics. + + +*Possible investigation steps* + + +- Review the powershell.file.script_block_text field to understand the content and intent of the script, focusing on how environment variables are manipulated to reconstruct the IEX command. +- Examine the file.path and host.name fields to determine the origin and location of the script execution, which can provide context on whether the activity is expected or suspicious. +- Analyze the user.id and agent.id fields to identify the user and agent responsible for executing the script, checking for any anomalies or unauthorized access. +- Investigate the powershell.file.script_block_id and powershell.sequence fields to trace the execution sequence and correlate it with other related PowerShell activities on the host. +- Assess the count field to understand the extent of obfuscation patterns detected, which can indicate the complexity and potential maliciousness of the script. + + +*False positive analysis* + + +- Scripts with legitimate use of environment variables for configuration management may trigger the rule. Users can create exceptions for specific scripts or processes known to use environment variables in a non-threatening manner. +- Automated scripts that dynamically construct commands for legitimate administrative tasks might be flagged. Review the script's purpose and source, and whitelist trusted scripts or processes. +- Development environments where scripts are frequently tested and modified may produce false positives. Implement monitoring exclusions for development machines or specific user accounts involved in script testing. +- Scripts using environment variables for localization or language settings can be mistakenly identified. Identify and exclude scripts that are part of standard localization processes. +- PowerShell scripts from trusted vendors or software packages that use environment variables for legitimate functionality should be reviewed and excluded from detection if verified as safe. + + +*Response and remediation* + + +- Isolate the affected system from the network to prevent further execution of potentially malicious scripts and limit lateral movement. +- Terminate any suspicious PowerShell processes identified by the alert to stop ongoing malicious activity. +- Review the PowerShell script block text and associated file paths to understand the scope and intent of the script, focusing on any obfuscated commands or environment variable manipulations. +- Restore the system from a known good backup if malicious activity is confirmed and system integrity is compromised. +- Update endpoint protection and intrusion detection systems to recognize and block similar obfuscation patterns in PowerShell scripts. +- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems are affected. +- Implement additional monitoring for unusual PowerShell activity and environment variable manipulations to enhance detection of similar threats in the future. + + +==== Setup + + + +*Setup* + + +The 'PowerShell Script Block Logging' logging policy must be enabled. +Steps to implement the logging policy with Advanced Audit Configuration: + +``` +Computer Configuration > +Administrative Templates > +Windows PowerShell > +Turn on PowerShell Script Block Logging (Enable) +``` + +Steps to implement the logging policy via registry: + +``` +reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1 +``` + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" + +// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for +| eval Esql.script_block_length = length(powershell.file.script_block_text) +| where Esql.script_block_length > 500 + +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them +// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 +| eval Esql.script_block_tmp = replace( + powershell.file.script_block_text, + """(?i)(\$(?:\w+|\w+\:\w+)\[\d++\]\+\$(?:\w+|\w+\:\w+)\[\d++\]\+['"]x['"]|\$(?:\w+\:\w+)\[\d++,\d++,\d++\]|\.name\[\d++,\d++,\d++\])""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_length, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least once +| where Esql.script_block_pattern_count >= 1 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Defense Evasion +** ID: TA0005 +** Reference URL: https://attack.mitre.org/tactics/TA0005/ +* Technique: +** Name: Obfuscated Files or Information +** ID: T1027 +** Reference URL: https://attack.mitre.org/techniques/T1027/ +* Technique: +** Name: Deobfuscate/Decode Files or Information +** ID: T1140 +** Reference URL: https://attack.mitre.org/techniques/T1140/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: PowerShell +** ID: T1059.001 +** Reference URL: https://attack.mitre.org/techniques/T1059/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-malicious-powershell-based-on-alert-correlation.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-malicious-powershell-based-on-alert-correlation.asciidoc new file mode 100644 index 0000000000..29400b561b --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-malicious-powershell-based-on-alert-correlation.asciidoc @@ -0,0 +1,151 @@ +[[prebuilt-rule-8-19-4-potential-malicious-powershell-based-on-alert-correlation]] +=== Potential Malicious PowerShell Based on Alert Correlation + +Identifies PowerShell script blocks associated with multiple distinct detections, indicating likely malicious behavior. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: high + +*Risk score*: 73 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Windows +* Use Case: Threat Detection +* Tactic: Execution +* Rule Type: Higher-Order Rule +* Resources: Investigation Guide + +*Version*: 2 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Potential Malicious PowerShell Based on Alert Correlation* + + +This detection rule aggregates alert data to identify PowerShell Scripts that have triggered various PowerShell-related detection logic, thereby producing higher-fidelity results. + +> **Note**: +> This investigation guide uses the https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html[Osquery Markdown Plugin] introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide. + + +*Possible investigation steps* + + +- Analyzing the detections triggered by the script should offer insight into the suspicious behaviors it exhibits. This information can be found in the `distinct_alerts` field. +- Examine the script content that triggered the detection; look for suspicious DLL imports, collection or exfiltration capabilities, suspicious functions, encoded or compressed data, and other potentially malicious characteristics. +- 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. +- Examine the script's execution context, such as the user account, privileges, the role of the system on which it was executed, and any relevant timestamps. +- Investigate other alerts associated with the user/host during the past 48 hours. +- Evaluate whether the user needs to use PowerShell to complete tasks. +- Investigate the origin of the PowerShell script, including its source, download method, and any associated URLs or IP addresses. +- Examine the host for derived artifacts that indicate suspicious activities: + - Analyze the script 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's `process.entity_id`. + - Examine the DNS cache for suspicious or anomalous entries. + - !{osquery{"label":"Osquery - Retrieve DNS Cache","query":"SELECT * FROM dns_cache"}} + - Use the Elastic Defend registry events to examine registry keys accessed, modified, or created by the related processes in the process tree. + - Examine the host services for suspicious or anomalous entries. + - !{osquery{"label":"Osquery - Retrieve All Services","query":"SELECT description, display_name, name, path, pid, service_type, start_type, status, user_account FROM services"}} + - !{osquery{"label":"Osquery - Retrieve Services Running on User Accounts","query":"SELECT description, display_name, name, path, pid, service_type, start_type, status, user_account FROM services WHERE\nNOT (user_account LIKE '%LocalSystem' OR user_account LIKE '%LocalService' OR user_account LIKE '%NetworkService' OR\nuser_account == null)\n"}} + - !{osquery{"label":"Osquery - Retrieve Service Unsigned Executables with Virustotal Link","query":"SELECT concat('https://www.virustotal.com/gui/file/', sha1) AS VtLink, name, description, start_type, status, pid,\nservices.path FROM services JOIN authenticode ON services.path = authenticode.path OR services.module_path =\nauthenticode.path JOIN hash ON services.path = hash.path WHERE authenticode.result != 'trusted'\n"}} + - 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* + + +- This rule is unlikely to trigger on legitimate activity. Benign true positives (B-TPs) can be added as exceptions if necessary. + + +*Response and Remediation* + + +- Initiate the incident response process based on the outcome of the triage. + - If malicious activity is confirmed, perform a broader investigation to identify the scope of the compromise and determine the appropriate remediation steps. +- Isolate the involved hosts to prevent further post-compromise behavior. +- If the triage identified malware, search the environment for additional compromised hosts. + - Implement temporary network rules, procedures, and segmentation to contain the malware. + - Stop suspicious processes. + - Immediately block the identified indicators of compromise (IoCs). + - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system. +- Remove and block malicious artifacts identified during triage. +- Reimage the host operating system or restore the compromised files to clean versions. +- Restrict PowerShell usage outside of IT and engineering business units using GPOs, AppLocker, Intune, or similar software. +- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services. +- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components. +- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector. +- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR). + + +==== Rule query + + +[source, js] +---------------------------------- +from .alerts-security.* metadata _id + +// Filter for PowerShell related alerts +| where kibana.alert.rule.name like "*PowerShell*" + +// as alerts don't have non-ECS fields, parse the script block ID using grok +| grok message "ScriptBlock ID: (?.+)" +| where Esql.script_block_id is not null + +// keep relevant fields for further processing +| keep kibana.alert.rule.name, Esql.script_block_id, _id + +// count distinct alerts and filter for matches above the threshold +| stats + Esql.kibana_alert_rule_name_count_distinct = count_distinct(kibana.alert.rule.name), + Esql.kibana_alert_rule_name_values = values(kibana.alert.rule.name), + Esql._id_values = values(_id) + by Esql.script_block_id + +// Apply detection threshold +| where Esql.kibana_alert_rule_name_count_distinct >= 5 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: PowerShell +** ID: T1059.001 +** Reference URL: https://attack.mitre.org/techniques/T1059/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-malware-driven-ssh-brute-force-attempt.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-malware-driven-ssh-brute-force-attempt.asciidoc new file mode 100644 index 0000000000..e8deb9553b --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-malware-driven-ssh-brute-force-attempt.asciidoc @@ -0,0 +1,191 @@ +[[prebuilt-rule-8-19-4-potential-malware-driven-ssh-brute-force-attempt]] +=== Potential Malware-Driven SSH Brute Force Attempt + +This detection identifies a Linux host that has potentially been infected with malware and is being used to conduct brute-force attacks against external systems over SSH (port 22 and common alternative SSH ports). The detection looks for a high volume of outbound connection attempts to non-private IP addresses from a single process. A compromised host may be part of a botnet or controlled by an attacker, attempting to gain unauthorized access to remote systems. This behavior is commonly observed in SSH brute-force campaigns where malware hijacks vulnerable machines to expand its attack surface. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 1h + +*Searches indices from*: now-61m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Linux +* Use Case: Threat Detection +* Tactic: Impact +* Tactic: Execution +* Tactic: Command and Control +* Data Source: Elastic Defend +* Resources: Investigation Guide + +*Version*: 5 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Potential Malware-Driven SSH Brute Force Attempt* + + +SSH is a protocol used to securely access remote systems. Adversaries exploit it by deploying malware on compromised Linux hosts to perform brute-force attacks, attempting unauthorized access to other systems. The detection rule identifies such abuse by monitoring high volumes of outbound SSH connection attempts from a single process to external IPs, indicating potential malware activity. + + +*Possible investigation steps* + + +- Review the process executable identified in the alert to determine if it is a legitimate application or potentially malicious. Check for known malware signatures or unusual file paths. +- Analyze the destination IP addresses involved in the connection attempts to identify if they are known malicious hosts or part of a larger attack infrastructure. Use threat intelligence sources to gather more information. +- Examine the host's recent activity logs to identify any unusual behavior or signs of compromise, such as unexpected process executions or changes in system configurations. +- Investigate the specific agent.id associated with the alert to determine if other alerts or suspicious activities have been reported from the same host, indicating a broader compromise. +- Check for any recent changes or updates to the host's software or configurations that could have introduced vulnerabilities exploited by the malware. +- Assess the network traffic patterns from the host to identify any other unusual outbound connections that may indicate additional malicious activity or data exfiltration attempts. + + +*False positive analysis* + + +- High-volume legitimate SSH operations from a single process can trigger alerts. Exclude known safe processes or scripts that perform frequent SSH operations by adding them to an exception list. +- Automated backup or synchronization tools using SSH to connect to external servers may be misidentified. Identify these tools and exclude their process names or IP addresses from the detection rule. +- Development or testing environments where SSH connections are frequently initiated to external systems for legitimate purposes can cause false positives. Document these environments and adjust the rule to exclude their specific IP ranges or process identifiers. +- Security scanning tools that perform SSH checks on external systems might be flagged. Ensure these tools are recognized and their activities are excluded by specifying their process names or IP addresses in the rule exceptions. + + +*Response and remediation* + + +- Isolate the affected Linux host from the network immediately to prevent further unauthorized access attempts and potential spread of malware to other systems. +- Terminate the suspicious process identified by the detection rule to stop ongoing brute-force attempts and reduce the risk of further compromise. +- Conduct a thorough malware scan on the isolated host using updated antivirus or endpoint detection and response (EDR) tools to identify and remove any malicious software. +- Review and reset credentials for any accounts that may have been targeted or compromised during the brute-force attempts to ensure account security. +- Apply security patches and updates to the affected host and any other vulnerable systems to mitigate known vulnerabilities that could be exploited by similar threats. +- Monitor network traffic for any signs of continued or new suspicious activity, particularly focusing on outbound SSH connections, to detect and respond to any further attempts promptly. +- Escalate the incident to the security operations center (SOC) or relevant security team for further investigation and to assess the potential impact on the broader network infrastructure. + + +==== Setup + + + +*Setup* + + +This rule requires data coming in from Elastic Defend. + + +*Elastic Defend Integration Setup* + +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. + + +*Prerequisite Requirements:* + +- Fleet is required for Elastic Defend. +- To configure Fleet Server refer to the https://www.elastic.co/guide/en/fleet/current/fleet-server.html[documentation]. + + +*The following steps should be executed in order to add the Elastic Defend integration on a Linux System:* + +- Go to the Kibana home page and click "Add integrations". +- In the query bar, search for "Elastic Defend" and select the integration to see more details about it. +- Click "Add Elastic Defend". +- Configure the integration name and optionally add a description. +- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads". +- 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. https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html[Helper guide]. +- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions" +- 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. +For more details on Elastic Agent configuration settings, refer to the https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html[helper guide]. +- Click "Save and Continue". +- 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 https://www.elastic.co/guide/en/security/current/install-endpoint.html[helper guide]. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-endpoint.events.network-* +| keep @timestamp, host.os.type, event.type, event.action, destination.port, process.executable, destination.ip, agent.id, host.name +| where + @timestamp > now() - 1 hours and + host.os.type == "linux" and + event.type == "start" and + event.action == "connection_attempted" and + destination.port in (22, 222, 2222, 10022, 2022, 2200, 62612, 8022) and + not cidr_match( + destination.ip, + "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", + "192.0.0.0/24", "192.0.0.0/29", "192.0.0.8/32", "192.0.0.9/32", + "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24", + "192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", + "224.0.0.0/4", "100.64.0.0/10", "192.175.48.0/24", "198.18.0.0/15", + "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1", "FE80::/10", "FF00::/8" + ) +| stats + Esql.event_count = count(), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.executable, destination.port +| where + Esql.agent_id_count_distinct == 1 and + Esql.event_count > 15 +| sort Esql.event_count asc +| limit 100 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Impact +** ID: TA0040 +** Reference URL: https://attack.mitre.org/tactics/TA0040/ +* Technique: +** Name: Resource Hijacking +** ID: T1496 +** Reference URL: https://attack.mitre.org/techniques/T1496/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: Unix Shell +** ID: T1059.004 +** Reference URL: https://attack.mitre.org/techniques/T1059/004/ +* Tactic: +** Name: Command and Control +** ID: TA0011 +** Reference URL: https://attack.mitre.org/tactics/TA0011/ +* Technique: +** Name: Application Layer Protocol +** ID: T1071 +** Reference URL: https://attack.mitre.org/techniques/T1071/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-microsoft-365-user-account-brute-force.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-microsoft-365-user-account-brute-force.asciidoc new file mode 100644 index 0000000000..7d804c06bd --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-microsoft-365-user-account-brute-force.asciidoc @@ -0,0 +1,195 @@ +[[prebuilt-rule-8-19-4-potential-microsoft-365-user-account-brute-force]] +=== Potential Microsoft 365 User Account Brute Force + +Identifies brute-force authentication activity targeting Microsoft 365 user accounts using failed sign-in patterns that match password spraying, credential stuffing, or password guessing behavior. Adversaries may attempt brute-force authentication with credentials obtained from previous breaches, leaks, marketplaces or guessable passwords. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 10m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray +* https://learn.microsoft.com/en-us/purview/audit-log-detailed-properties +* https://securityscorecard.com/research/massive-botnet-targets-m365-with-stealthy-password-spraying-attacks/ +* https://github.com/0xZDH/Omnispray +* https://github.com/0xZDH/o365spray + +*Tags*: + +* Domain: Cloud +* Domain: SaaS +* Data Source: Microsoft 365 +* Data Source: Microsoft 365 Audit Logs +* Use Case: Identity and Access Audit +* Use Case: Threat Detection +* Tactic: Credential Access +* Resources: Investigation Guide + +*Version*: 414 + +*Rule authors*: + +* Elastic +* Willem D'Haese +* Austin Songer + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and Analysis* + + + +*Investigating Potential Microsoft 365 User Account Brute Force* + + +Identifies brute-force authentication activity targeting Microsoft 365 user accounts using failed sign-in patterns that match password spraying, credential stuffing, or password guessing behavior. Adversaries may attempt brute-force authentication with credentials obtained from previous breaches, leaks, marketplaces or guessable passwords. + + +*Possible investigation steps* + + +- Review `user_id_list`: Enumerates the user accounts targeted. Look for naming patterns or privilege levels (e.g., admins). +- Check `login_errors`: A consistent error such as `"InvalidUserNameOrPassword"` confirms a spray-style attack using one or a few passwords. +- Examine `ip_list` and `source_orgs`: Determine if the traffic originates from a known corporate VPN, datacenter, or suspicious ASN like hosting providers or anonymizers. +- Review `countries` and `unique_country_count`: Geographic anomalies (e.g., login attempts from unexpected regions) may indicate malicious automation. +- Validate `total_attempts` vs `duration_seconds`: A high frequency of login attempts over a short period may suggest automation rather than manual logins. +- Cross-reference with successful logins: Pivot to surrounding sign-in logs (`azure.signinlogs`) or risk detections (`identityprotection`) for any account that eventually succeeded. +- Check for multi-factor challenges or bypasses: Determine if any of the accounts were protected or if the attack bypassed MFA. + + +*False positive analysis* + + +- IT administrators using automation tools (e.g., PowerShell) during account provisioning may trigger false positives if login attempts cluster. +- Penetration testing or red team simulations may resemble spray activity. +- Infrequent, low-volume login testing tools like ADFS testing scripts can exhibit similar patterns. + + +*Response and remediation* + + +- Initiate an internal incident ticket and inform the affected identity/IT team. +- Temporarily disable impacted user accounts if compromise is suspected. +- Investigate whether any login attempts succeeded after the spray window. +- Block the offending IPs or ASN temporarily via firewall or conditional access policies. +- Rotate passwords for all targeted accounts and audit for password reuse. +- Enforce or verify MFA is enabled for all user accounts. +- Consider deploying account lockout or progressive delay mechanisms if not already enabled. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-o365.audit-* +| mv_expand event.category +| eval + Esql.time_window_date_trunc = date_trunc(5 minutes, @timestamp), + Esql_priv.o365_audit_UserId_lower = to_lower(o365.audit.UserId), + Esql.o365_audit_LogonError = o365.audit.LogonError, + Esql.o365_audit_ExtendedProperties_RequestType_lower = to_lower(o365.audit.ExtendedProperties.RequestType) +| where + event.dataset == "o365.audit" and + event.category == "authentication" and + event.provider in ("AzureActiveDirectory", "Exchange") and + event.action in ("UserLoginFailed", "PasswordLogonInitialAuthUsingPassword") and + Esql.o365_audit_ExtendedProperties_RequestType_lower rlike "(oauth.*||.*login.*)" and + Esql.o365_audit_LogonError != "IdsLocked" and + Esql.o365_audit_LogonError not in ( + "EntitlementGrantsNotFound", + "UserStrongAuthEnrollmentRequired", + "UserStrongAuthClientAuthNRequired", + "InvalidReplyTo", + "SsoArtifactExpiredDueToConditionalAccess", + "PasswordResetRegistrationRequiredInterrupt", + "SsoUserAccountNotFoundInResourceTenant", + "UserStrongAuthExpired", + "CmsiInterrupt" + ) and + Esql_priv.o365_audit_UserId_lower != "not available" and + o365.audit.Target.Type in ("0", "2", "6", "10") +| stats + Esql.o365_audit_UserId_lower_count_distinct = count_distinct(Esql_priv.o365_audit_UserId_lower), + Esql_priv.o365_audit_UserId_lower_values = values(Esql_priv.o365_audit_UserId_lower), + Esql.o365_audit_LogonError_values = values(Esql.o365_audit_LogonError), + Esql.o365_audit_LogonError_count_distinct = count_distinct(Esql.o365_audit_LogonError), + Esql.o365_audit_ExtendedProperties_RequestType_values = values(Esql.o365_audit_ExtendedProperties_RequestType_lower), + Esql.source_ip_values = values(source.ip), + Esql.source_ip_count_distinct = count_distinct(source.ip), + Esql.source_as_organization_name_values = values(source.`as`.organization.name), + Esql.source_geo_country_name_values = values(source.geo.country_name), + Esql.source_geo_country_name_count_distinct = count_distinct(source.geo.country_name), + Esql.source_as_organization_name_count_distinct = count_distinct(source.`as`.organization.name), + Esql.timestamp_first_seen = min(@timestamp), + Esql.timestamp_last_seen = max(@timestamp), + Esql.event_count = count(*) + by Esql.time_window_date_trunc +| eval + Esql.event_duration_seconds = date_diff("seconds", Esql.timestamp_first_seen, Esql.timestamp_last_seen), + Esql.brute_force_type = case( + Esql.o365_audit_UserId_lower_count_distinct >= 15 and Esql.o365_audit_LogonError_count_distinct == 1 and Esql.event_count >= 10 and Esql.event_duration_seconds <= 1800, "password_spraying", + Esql.o365_audit_UserId_lower_count_distinct >= 8 and Esql.event_count >= 15 and Esql.o365_audit_LogonError_count_distinct <= 3 and Esql.source_ip_count_distinct <= 5 and Esql.event_duration_seconds <= 600, "credential_stuffing", + Esql.o365_audit_UserId_lower_count_distinct == 1 and Esql.o365_audit_LogonError_count_distinct == 1 and Esql.event_count >= 20 and Esql.event_duration_seconds <= 300, "password_guessing", + "other" + ) +| keep + Esql.time_window_date_trunc, + Esql.o365_audit_UserId_lower_count_distinct, + Esql_priv.o365_audit_UserId_lower_values, + Esql.o365_audit_LogonError_values, + Esql.o365_audit_LogonError_count_distinct, + Esql.o365_audit_ExtendedProperties_RequestType_values, + Esql.source_ip_values, + Esql.source_ip_count_distinct, + Esql.source_as_organization_name_values, + Esql.source_geo_country_name_values, + Esql.source_geo_country_name_count_distinct, + Esql.source_as_organization_name_count_distinct, + Esql.timestamp_first_seen, + Esql.timestamp_last_seen, + Esql.event_duration_seconds, + Esql.event_count, + Esql.brute_force_type +| where Esql.brute_force_type != "other" + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Credential Access +** ID: TA0006 +** Reference URL: https://attack.mitre.org/tactics/TA0006/ +* Technique: +** Name: Brute Force +** ID: T1110 +** Reference URL: https://attack.mitre.org/techniques/T1110/ +* Sub-technique: +** Name: Password Guessing +** ID: T1110.001 +** Reference URL: https://attack.mitre.org/techniques/T1110/001/ +* Sub-technique: +** Name: Password Spraying +** ID: T1110.003 +** Reference URL: https://attack.mitre.org/techniques/T1110/003/ +* Sub-technique: +** Name: Credential Stuffing +** ID: T1110.004 +** Reference URL: https://attack.mitre.org/techniques/T1110/004/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-port-scanning-activity-from-compromised-host.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-port-scanning-activity-from-compromised-host.asciidoc new file mode 100644 index 0000000000..0c03f6cf9a --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-port-scanning-activity-from-compromised-host.asciidoc @@ -0,0 +1,170 @@ +[[prebuilt-rule-8-19-4-potential-port-scanning-activity-from-compromised-host]] +=== Potential Port Scanning Activity from Compromised Host + +This rule detects potential port scanning activity from a compromised host. Port scanning is a common reconnaissance technique used by attackers to identify open ports and services on a target system. A compromised host may exhibit port scanning behavior when an attacker is attempting to map out the network topology, identify vulnerable services, or prepare for further exploitation. This rule identifies potential port scanning activity by monitoring network connection attempts from a single host to a large number of ports within a short time frame. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 1h + +*Searches indices from*: now-61m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Linux +* Use Case: Threat Detection +* Tactic: Discovery +* Data Source: Elastic Defend +* Resources: Investigation Guide + +*Version*: 5 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Potential Port Scanning Activity from Compromised Host* + + +Port scanning is a reconnaissance method used by attackers to identify open ports and services on a network, often as a precursor to exploitation. In Linux environments, compromised hosts may perform rapid connection attempts to numerous ports, signaling potential scanning activity. The detection rule identifies such behavior by analyzing network logs for a high number of distinct port connections from a single host within a short timeframe, indicating possible malicious intent. + + +*Possible investigation steps* + + +- Review the network logs to identify the specific host exhibiting the port scanning behavior by examining the destination.ip and process.executable fields. +- Analyze the @timestamp field to determine the exact time frame of the scanning activity and correlate it with any other suspicious activities or alerts from the same host. +- Investigate the process.executable field to understand which application or service initiated the connection attempts, and verify if it is a legitimate process or potentially malicious. +- Check the destination.port field to identify the range and types of ports targeted by the scanning activity, which may provide insights into the attacker's objectives or the services they are interested in. +- Assess the host's security posture by reviewing recent changes, installed software, and user activity to determine if the host has been compromised or if the scanning is part of legitimate network operations. +- Consult the original documents and logs for additional context and details that may not be captured in the alert to aid in a comprehensive investigation. + + +*False positive analysis* + + +- Legitimate network scanning tools used by system administrators for network maintenance or security assessments can trigger this rule. To handle this, identify and whitelist the IP addresses or processes associated with these tools. +- Automated vulnerability scanners or monitoring systems that perform regular checks on network services may cause false positives. Exclude these systems by creating exceptions for their known IP addresses or process names. +- High-volume legitimate services that open multiple connections to different ports, such as load balancers or proxy servers, might be flagged. Review and exclude these services by specifying their IP addresses or process executables. +- Development or testing environments where frequent port scanning is part of routine operations can be mistakenly identified. Implement exceptions for these environments by excluding their specific network segments or host identifiers. +- Scheduled network discovery tasks that are part of IT operations can mimic port scanning behavior. Document and exclude these tasks by setting up time-based exceptions or identifying their unique process signatures. + + +*Response and remediation* + + +- Isolate the compromised host from the network immediately to prevent further scanning and potential lateral movement. +- Terminate any suspicious processes identified by the process.executable field to halt ongoing malicious activities. +- Conduct a thorough review of the compromised host's system logs and network traffic to identify any unauthorized access or data exfiltration attempts. +- Patch and update all software and services on the compromised host to close any vulnerabilities that may have been exploited. +- Change all credentials associated with the compromised host and any potentially affected systems to prevent unauthorized access. +- Monitor the network for any further signs of scanning activity or other suspicious behavior from other hosts, indicating potential additional compromises. +- Escalate the incident to the security operations team for further investigation and to determine if additional systems are affected. + + +==== Setup + + + +*Setup* + + +This rule requires data coming in from Elastic Defend. + + +*Elastic Defend Integration Setup* + +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. + + +*Prerequisite Requirements:* + +- Fleet is required for Elastic Defend. +- To configure Fleet Server refer to the https://www.elastic.co/guide/en/fleet/current/fleet-server.html[documentation]. + + +*The following steps should be executed in order to add the Elastic Defend integration on a Linux System:* + +- Go to the Kibana home page and click "Add integrations". +- In the query bar, search for "Elastic Defend" and select the integration to see more details about it. +- Click "Add Elastic Defend". +- Configure the integration name and optionally add a description. +- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads". +- 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. https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html[Helper guide]. +- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions" +- 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. +For more details on Elastic Agent configuration settings, refer to the https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html[helper guide]. +- Click "Save and Continue". +- 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 https://www.elastic.co/guide/en/security/current/install-endpoint.html[helper guide]. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-endpoint.events.network-* +| where + @timestamp > now() - 1h and + host.os.type == "linux" and + event.type == "start" and + event.action == "connection_attempted" +| keep + @timestamp, + host.os.type, + event.type, + event.action, + destination.port, + process.executable, + destination.ip, + agent.id, + host.name +| stats + Esql.event_count = count(), + Esql.destination_port_count_distinct = count_distinct(destination.port), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.executable, destination.ip +| where + Esql.agent_id_count_distinct == 1 and + Esql.destination_port_count_distinct > 100 +| sort Esql.event_count asc +| limit 100 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Discovery +** ID: TA0007 +** Reference URL: https://attack.mitre.org/tactics/TA0007/ +* Technique: +** Name: Network Service Discovery +** ID: T1046 +** Reference URL: https://attack.mitre.org/techniques/T1046/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-backtick-escaped-variable-expansion.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-backtick-escaped-variable-expansion.asciidoc new file mode 100644 index 0000000000..5e7fea34e8 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-backtick-escaped-variable-expansion.asciidoc @@ -0,0 +1,178 @@ +[[prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-backtick-escaped-variable-expansion]] +=== Potential PowerShell Obfuscation via Backtick-Escaped Variable Expansion + +Identifies PowerShell scripts that use backtick-escaped characters inside ${} variable expansion as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Windows +* Use Case: Threat Detection +* Tactic: Defense Evasion +* Data Source: PowerShell Logs +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Potential PowerShell Obfuscation via Backtick-Escaped Variable Expansion* + + +PowerShell, a powerful scripting language in Windows environments, can be exploited by adversaries using obfuscation techniques like backtick-escaped variable expansion to evade detection. This method involves disguising malicious scripts to bypass security measures. The detection rule identifies scripts with excessive length and specific obfuscation patterns, flagging potential threats for further analysis. + + +*Possible investigation steps* + + +- Review the `powershell.file.script_block_text` field to understand the content of the script and identify any suspicious or malicious commands. +- Examine the `file.path` and `file.name` fields to determine the origin and context of the script execution, which may provide insights into whether the script is part of a legitimate process or potentially malicious activity. +- Check the `host.name` and `agent.id` fields to identify the affected system and correlate with other security events or logs from the same host for additional context. +- Analyze the `user.id` field to determine which user account executed the script, and assess whether this activity aligns with the user's typical behavior or role. +- Investigate the `powershell.file.script_block_id` and `powershell.sequence` fields to trace the execution flow of the script and identify any related script blocks that may have been executed in sequence. +- Consider the `count` field to evaluate the extent of obfuscation used in the script, which may indicate the level of sophistication or intent behind the script. + + +*False positive analysis* + + +- Scripts with legitimate administrative functions may use backtick-escaped variable expansion for complex string manipulations. Review the script's context and purpose to determine if it aligns with expected administrative tasks. +- Automated scripts generated by trusted software might include obfuscation patterns as part of their normal operation. Verify the source and integrity of the software to ensure it is from a reputable vendor. +- Developers and IT professionals may use obfuscation techniques during testing or development phases. Establish a process to whitelist known development environments or user accounts to reduce unnecessary alerts. +- PowerShell scripts that are part of legitimate security tools or monitoring solutions may trigger the rule. Identify and exclude these tools by their file path or script block ID to prevent false positives. +- Regularly update the list of known false positives based on historical data and feedback from users to refine the detection rule and improve its accuracy. + + +*Response and remediation* + + +- Isolate the affected host immediately to prevent further spread of the potentially malicious script across the network. +- Terminate any suspicious PowerShell processes identified by the alert to halt the execution of obfuscated scripts. +- Conduct a thorough review of the script block text and associated file paths to identify and remove any malicious scripts or files from the system. +- Reset credentials for any user accounts involved in the alert to mitigate the risk of compromised credentials being used for further attacks. +- Escalate the incident to the security operations team for a deeper investigation into potential lateral movement or additional compromised systems. +- Implement enhanced monitoring on the affected host and similar systems to detect any recurrence of obfuscation techniques or related suspicious activities. +- Update endpoint protection and intrusion detection systems with indicators of compromise (IOCs) derived from the analysis to improve detection capabilities for similar threats in the future. + + +==== Setup + + + +*Setup* + + +The 'PowerShell Script Block Logging' logging policy must be enabled. +Steps to implement the logging policy with Advanced Audit Configuration: + +``` +Computer Configuration > +Administrative Templates > +Windows PowerShell > +Turn on PowerShell Script Block Logging (Enable) +``` + +Steps to implement the logging policy via registry: + +``` +reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1 +``` + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" + +// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for +| eval Esql.script_block_length = length(powershell.file.script_block_text) +| where Esql.script_block_length > 500 + +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them +// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 +| eval Esql.script_block_tmp = replace(powershell.file.script_block_text, """\$\{(\w++`){2,}\w++\}""", "πŸ”₯") + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_length, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + file.name, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least once +| where Esql.script_block_pattern_count >= 1 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Defense Evasion +** ID: TA0005 +** Reference URL: https://attack.mitre.org/tactics/TA0005/ +* Technique: +** Name: Obfuscated Files or Information +** ID: T1027 +** Reference URL: https://attack.mitre.org/techniques/T1027/ +* Technique: +** Name: Deobfuscate/Decode Files or Information +** ID: T1140 +** Reference URL: https://attack.mitre.org/techniques/T1140/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: PowerShell +** ID: T1059.001 +** Reference URL: https://attack.mitre.org/techniques/T1059/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-character-array-reconstruction.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-character-array-reconstruction.asciidoc new file mode 100644 index 0000000000..2e7fdebb72 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-character-array-reconstruction.asciidoc @@ -0,0 +1,178 @@ +[[prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-character-array-reconstruction]] +=== Potential PowerShell Obfuscation via Character Array Reconstruction + +Identifies PowerShell scripts that use character arrays and runtime string reconstruction as a form of obfuscation. This technique breaks strings into individual characters, often using constructs like char[] with index-based access or joining logic. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Windows +* Use Case: Threat Detection +* Tactic: Defense Evasion +* Data Source: PowerShell Logs +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Potential PowerShell Obfuscation via Character Array Reconstruction* + + +PowerShell, a powerful scripting language, is often targeted by adversaries for obfuscation to bypass security measures. By reconstructing strings from character arrays, attackers evade static analysis and detection. The detection rule identifies scripts using such obfuscation by searching for patterns indicative of character array manipulation, thus flagging potential threats for further investigation. + + +*Possible investigation steps* + + +- Review the powershell.file.script_block_text field to understand the content and intent of the script, focusing on the obfuscated parts indicated by the presence of the "char" keyword and the πŸ”₯ character. +- Examine the file.path and host.name fields to determine the origin and location of the script execution, which can provide context about the environment and potential risk. +- Check the user.id and agent.id fields to identify the user and agent responsible for executing the script, which can help assess whether the activity is expected or suspicious. +- Analyze the powershell.file.script_block_id and powershell.sequence fields to trace the execution sequence and correlate it with other related script blocks, providing a broader view of the script's behavior. +- Investigate the count field to assess the extent of obfuscation, as a higher count may indicate more complex or extensive obfuscation techniques being used. + + +*False positive analysis* + + +- Scripts used for legitimate administrative tasks may use character arrays for performance optimization or to handle special characters. Review the script's purpose and context to determine if it aligns with known administrative functions. +- PowerShell scripts from trusted sources or vendors might use character arrays for legitimate obfuscation to protect intellectual property. Verify the script's origin and check for digital signatures or hashes to confirm authenticity. +- Automated scripts generated by development tools or frameworks could include character array manipulation as part of their standard output. Identify and whitelist these tools if they are commonly used in your environment. +- Security tools or monitoring solutions might use character arrays in their scripts for legitimate purposes. Cross-reference with known security software and consider excluding these from the detection rule if they are verified as safe. +- Regularly update the exclusion list to include new trusted scripts or tools as they are introduced into the environment, ensuring that legitimate activities are not flagged as false positives. + + +*Response and remediation* + + +- Isolate the affected host immediately to prevent further spread of potentially malicious scripts or unauthorized access. +- Terminate any suspicious PowerShell processes identified by the alert to halt ongoing obfuscation activities. +- Conduct a thorough review of the script block text and associated logs to identify any malicious payloads or commands executed. +- Remove any identified malicious scripts or files from the affected system to prevent re-execution. +- Reset credentials for any user accounts involved in the alert to mitigate potential credential compromise. +- Update endpoint protection and ensure that AMSI and other security features are fully enabled and configured to detect similar threats. +- Escalate the incident to the security operations center (SOC) for further analysis and to determine if additional systems are affected. + + +==== Setup + + + +*Setup* + + +The 'PowerShell Script Block Logging' logging policy must be enabled. +Steps to implement the logging policy with Advanced Audit Configuration: + +``` +Computer Configuration > +Administrative Templates > +Windows PowerShell > +Turn on PowerShell Script Block Logging (Enable) +``` + +Steps to implement the logging policy via registry: + +``` +reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1 +``` + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" + +// Filter for scripts that contain the "char" keyword using MATCH, boosts the query performance +| where powershell.file.script_block_text : "char" + +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them +// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 +| eval Esql.script_block_tmp = replace( + powershell.file.script_block_text, + """(char\[\]\]\(\d+,\d+[^)]+|(\s?\(\[char\]\d+\s?\)\+){2,})""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least once +| where Esql.script_block_pattern_count >= 1 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Defense Evasion +** ID: TA0005 +** Reference URL: https://attack.mitre.org/tactics/TA0005/ +* Technique: +** Name: Obfuscated Files or Information +** ID: T1027 +** Reference URL: https://attack.mitre.org/techniques/T1027/ +* Technique: +** Name: Deobfuscate/Decode Files or Information +** ID: T1140 +** Reference URL: https://attack.mitre.org/techniques/T1140/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: PowerShell +** ID: T1059.001 +** Reference URL: https://attack.mitre.org/techniques/T1059/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-concatenated-dynamic-command-invocation.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-concatenated-dynamic-command-invocation.asciidoc new file mode 100644 index 0000000000..3165bb3313 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-concatenated-dynamic-command-invocation.asciidoc @@ -0,0 +1,175 @@ +[[prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-concatenated-dynamic-command-invocation]] +=== Potential PowerShell Obfuscation via Concatenated Dynamic Command Invocation + +Identifies PowerShell scripts that use concatenated strings within dynamic command invocation (&() or .()) as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Windows +* Use Case: Threat Detection +* Tactic: Defense Evasion +* Data Source: PowerShell Logs +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Potential PowerShell Obfuscation via Concatenated Dynamic Command Invocation* + + +PowerShell is a powerful scripting language used for task automation and configuration management in Windows environments. Adversaries exploit its capabilities by obfuscating commands to evade detection, often using concatenated strings in dynamic invocations. This detection rule identifies such obfuscation by analyzing script patterns, specifically looking for concatenated strings within dynamic command invocations, which are indicative of attempts to bypass security measures like AMSI. By counting these patterns, the rule effectively flags suspicious scripts, aiding in the identification of potential threats. + + +*Possible investigation steps* + + +- Review the `powershell.file.script_block_text` field to understand the content and purpose of the script, focusing on the concatenated strings and dynamic command invocations. +- Check the `host.name` and `user.id` fields to identify the machine and user account associated with the execution of the suspicious script, which can help determine if the activity is expected or anomalous. +- Analyze the `file.path` field to locate the script's source or storage location, which may provide additional context or indicate if the script is part of a known application or process. +- Investigate the `powershell.file.script_block_id` and `powershell.sequence` fields to trace the execution sequence and correlate it with other related PowerShell activities, which might reveal a broader pattern of behavior. +- Assess the `agent.id` field to determine the specific endpoint agent involved, which can assist in further endpoint-specific investigations or actions. + + +*False positive analysis* + + +- Scripts with legitimate concatenated strings for dynamic command execution may trigger the rule. Review the script context to determine if the concatenation serves a valid administrative purpose. +- Automated scripts from trusted sources that use concatenation for modularity or readability might be flagged. Consider adding these scripts to an allowlist if they are verified as safe. +- Development or testing environments where PowerShell scripts are frequently modified and tested could generate false positives. Implement exceptions for known development hosts or user accounts. +- Security tools or monitoring solutions that use PowerShell for legitimate operations may inadvertently match the pattern. Identify these tools and exclude their operations from the rule. +- Regularly review and update the exclusion list to ensure it reflects the current environment and does not inadvertently allow malicious activity. + + +*Response and remediation* + + +- Isolate the affected host immediately to prevent further execution of potentially malicious scripts and limit lateral movement within the network. +- Terminate any suspicious PowerShell processes identified by the alert to halt the execution of obfuscated commands. +- Conduct a thorough review of the script block text and associated script block ID to understand the intent and potential impact of the obfuscated commands. +- Remove any unauthorized or malicious scripts from the affected system and ensure that all legitimate scripts are verified and signed. +- Restore the affected system from a known good backup if any malicious activity is confirmed, ensuring that all data integrity checks are performed. +- Escalate the incident to the security operations team for further analysis and to determine if additional systems have been compromised. +- Update endpoint protection and monitoring tools to enhance detection capabilities for similar obfuscation techniques, leveraging insights from the MITRE ATT&CK framework. + + +==== Setup + + + +*Setup* + + +The 'PowerShell Script Block Logging' logging policy must be enabled. +Steps to implement the logging policy with Advanced Audit Configuration: + +``` +Computer Configuration > +Administrative Templates > +Windows PowerShell > +Turn on PowerShell Script Block Logging (Enable) +``` + +Steps to implement the logging policy via registry: + +``` +reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1 +``` + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" and powershell.file.script_block_text like "*+*" + +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them +// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 +| eval Esql.script_block_tmp = replace( + powershell.file.script_block_text, + """[.&]\(\s*(['"][A-Za-z0-9.-]+['"]\s*\+\s*)+['"][A-Za-z0-9.-]+['"]\s*\)""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least once +| where Esql.script_block_pattern_count >= 1 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Defense Evasion +** ID: TA0005 +** Reference URL: https://attack.mitre.org/tactics/TA0005/ +* Technique: +** Name: Obfuscated Files or Information +** ID: T1027 +** Reference URL: https://attack.mitre.org/techniques/T1027/ +* Technique: +** Name: Deobfuscate/Decode Files or Information +** ID: T1140 +** Reference URL: https://attack.mitre.org/techniques/T1140/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: PowerShell +** ID: T1059.001 +** Reference URL: https://attack.mitre.org/techniques/T1059/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-high-numeric-character-proportion.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-high-numeric-character-proportion.asciidoc new file mode 100644 index 0000000000..b67e611f20 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-high-numeric-character-proportion.asciidoc @@ -0,0 +1,183 @@ +[[prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-high-numeric-character-proportion]] +=== Potential PowerShell Obfuscation via High Numeric Character Proportion + +Identifies PowerShell scripts with a disproportionately high number of numeric characters, often indicating the presence of obfuscated or encoded payloads. This behavior is typical of obfuscation methods involving byte arrays, character code manipulation, or embedded encoded strings used to deliver and execute malicious content. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Windows +* Use Case: Threat Detection +* Tactic: Defense Evasion +* Data Source: PowerShell Logs +* Resources: Investigation Guide + +*Version*: 4 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Potential PowerShell Obfuscation via High Numeric Character Proportion* + + +PowerShell is a powerful scripting language used for system administration, but adversaries exploit its capabilities to obfuscate malicious scripts. Obfuscation often involves encoding payloads using numeric characters, making detection challenging. The detection rule identifies scripts with a high proportion of numeric characters, signaling potential obfuscation. By analyzing script length and numeric density, it flags suspicious activity, aiding in defense evasion detection. + + +*Possible investigation steps* + + +- Review the script block text from the alert to understand the context and identify any obvious signs of obfuscation or malicious intent. +- Examine the file path and host name fields to determine the origin and location of the script execution, which can help assess the potential impact and scope. +- Check the user ID and agent ID fields to identify the user and system involved, which may provide insights into whether the activity is expected or suspicious. +- Analyze the powershell.sequence and powershell.total fields to understand the sequence of script execution and the total number of scripts executed, which can indicate whether this is part of a larger pattern of behavior. +- Investigate any related logs or alerts from the same host or user to identify patterns or correlations that might suggest broader malicious activity. + + +*False positive analysis* + + +- Scripts with legitimate numeric-heavy content such as data processing or mathematical calculations may trigger the rule. To handle this, identify and whitelist specific scripts or script patterns that are known to be safe. +- Automated scripts that generate or manipulate large datasets often contain high numeric content. Consider creating exceptions for scripts executed by trusted users or from known safe directories. +- PowerShell scripts used for legitimate software installations or updates might include encoded data blocks. Review and exclude these scripts by verifying their source and purpose. +- Scripts containing large hexadecimal strings for legitimate purposes, such as cryptographic operations, may be flagged. Use the exclusion pattern to filter out these known safe operations. +- Regularly review and update the exclusion list to ensure it reflects the current environment and any new legitimate scripts that may be introduced. + + +*Response and remediation* + + +- Immediately isolate the affected host to prevent further execution of potentially malicious scripts and limit lateral movement within the network. +- Review the PowerShell script block text and script block ID to identify any malicious payloads or encoded strings. If confirmed malicious, remove or quarantine the script. +- Conduct a thorough scan of the isolated host using updated antivirus and anti-malware tools to detect and remove any additional threats or remnants of the obfuscated script. +- Analyze the file path and user ID associated with the script execution to determine if unauthorized access or privilege escalation occurred. Revoke any suspicious user access and reset credentials if necessary. +- Escalate the incident to the security operations center (SOC) for further investigation and correlation with other alerts to assess the scope and impact of the threat across the network. +- Implement enhanced monitoring and logging for PowerShell activities on all endpoints to detect similar obfuscation attempts in the future, focusing on scripts with high numeric character proportions. +- Review and update endpoint protection policies to restrict the execution of scripts with high numeric density, ensuring compliance with security best practices and reducing the risk of obfuscation-based attacks. + + +==== Setup + + + +*Setup* + + +The 'PowerShell Script Block Logging' logging policy must be enabled. +Steps to implement the logging policy with Advanced Audit Configuration: + +``` +Computer Configuration > +Administrative Templates > +Windows PowerShell > +Turn on PowerShell Script Block Logging (Enable) +``` + +Steps to implement the logging policy via registry: + +``` +reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1 +``` + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" + +// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for +| eval Esql.script_block_length = length(powershell.file.script_block_text) +| where Esql.script_block_length > 1000 + +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them +// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 +| eval Esql.script_block_tmp = replace(powershell.file.script_block_text, """[0-9]""", "πŸ”₯") + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = Esql.script_block_length - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// Calculate the ratio of special characters to total length +| eval Esql.script_block_ratio = Esql.script_block_pattern_count::double / Esql.script_block_length::double + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_ratio, + Esql.script_block_length, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts with high numeric character ratio +| where Esql.script_block_ratio > 0.30 + +// Exclude noisy patterns such as 64-character hash lists +| where not powershell.file.script_block_text rlike """.*\"[a-fA-F0-9]{64}\"\,.*""" + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Defense Evasion +** ID: TA0005 +** Reference URL: https://attack.mitre.org/tactics/TA0005/ +* Technique: +** Name: Obfuscated Files or Information +** ID: T1027 +** Reference URL: https://attack.mitre.org/techniques/T1027/ +* Technique: +** Name: Deobfuscate/Decode Files or Information +** ID: T1140 +** Reference URL: https://attack.mitre.org/techniques/T1140/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: PowerShell +** ID: T1059.001 +** Reference URL: https://attack.mitre.org/techniques/T1059/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-invalid-escape-sequences.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-invalid-escape-sequences.asciidoc new file mode 100644 index 0000000000..27c4b2164a --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-invalid-escape-sequences.asciidoc @@ -0,0 +1,184 @@ +[[prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-invalid-escape-sequences]] +=== Potential PowerShell Obfuscation via Invalid Escape Sequences + +Identifies PowerShell scripts that use invalid escape sequences as a form of obfuscation. This technique introduces backticks (`) between characters in a way that does not correspond to valid PowerShell escape sequences, breaking up strings and bypassing pattern-based detections while preserving execution logic. This is designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Windows +* Use Case: Threat Detection +* Tactic: Defense Evasion +* Data Source: PowerShell Logs +* Resources: Investigation Guide + +*Version*: 4 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Potential PowerShell Obfuscation via Invalid Escape Sequences* + + +PowerShell, a powerful scripting language in Windows environments, can be exploited by adversaries using obfuscation techniques to evade detection. By inserting invalid escape sequences, attackers can obscure malicious scripts, bypassing static analysis and security tools like AMSI. The detection rule identifies such obfuscation by analyzing script patterns, specifically targeting unusual backtick usage, to flag potential threats. + + +*Possible investigation steps* + + +- Review the `powershell.file.script_block_text` field to understand the context and content of the script block that triggered the alert. Look for patterns of invalid escape sequences and assess whether they appear intentionally obfuscated. +- Examine the `file.name` and `file.path` fields to determine the origin and location of the script. This can help identify whether the script is part of a legitimate application or potentially malicious. +- Check the `host.name` and `agent.id` fields to identify the affected system and the agent responsible for logging the event. This information is crucial for understanding the scope of the potential threat. +- Analyze the `user.id` field to ascertain which user executed the script. This can provide insights into whether the user has a history of executing suspicious scripts or if their account may be compromised. +- Investigate the `powershell.file.script_block_id` and `powershell.sequence` fields to trace the execution sequence and correlate it with other related script blocks, which may reveal additional obfuscation or malicious activity. +- Assess the `count` field to evaluate the extent of obfuscation detected. A higher count may indicate more aggressive obfuscation techniques, warranting further scrutiny. + + +*False positive analysis* + + +- Scripts from Visual Studio Code's PowerShell extension may trigger false positives due to its shell integration. To handle this, exclude scripts containing the pattern "$([char]0x1b)]633" from detection. +- PowerShell modules with names starting with "TSS_" may be flagged incorrectly. Exclude these by adding a condition to ignore files matching the pattern "TSS_*.psm1". +- Legitimate scripts that use backticks for formatting or other non-obfuscation purposes might be detected. Review such scripts and, if verified as safe, add them to an exception list based on their script block ID or file path. +- Regularly update the exclusion list to reflect changes in legitimate script usage patterns, ensuring that new false positives are addressed promptly. + + +*Response and remediation* + + +- Isolate the affected host immediately to prevent lateral movement and further execution of potentially malicious scripts. Disconnect the host from the network and disable remote access. + +- Analyze the script block text and file path to identify the source and nature of the obfuscated script. Determine if the script is part of a larger attack or if other systems are affected. + +- Remove or quarantine the identified malicious script and any associated files from the host. Ensure that all remnants of the obfuscated code are eliminated to prevent re-execution. + +- Conduct a thorough scan of the host using updated antivirus and antimalware tools to detect and remove any additional threats or indicators of compromise. + +- Review and update PowerShell execution policies and security settings to restrict the execution of scripts with invalid escape sequences. Implement stricter controls to prevent similar obfuscation techniques. + +- Escalate the incident to the security operations center (SOC) or relevant cybersecurity team for further investigation and monitoring. Provide detailed logs and findings to assist in understanding the scope and impact of the threat. + +- Implement enhanced logging and monitoring for PowerShell activities across the network to detect and respond to similar obfuscation attempts promptly. Use the identified patterns to refine detection capabilities. + + +==== Setup + + + +*Setup* + + +The 'PowerShell Script Block Logging' logging policy must be enabled. +Steps to implement the logging policy with Advanced Audit Configuration: + +``` +Computer Configuration > +Administrative Templates > +Windows PowerShell > +Turn on PowerShell Script Block Logging (Enable) +``` + +Steps to implement the logging policy via registry: + +``` +reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1 +``` + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" and powershell.file.script_block_text like "*`*" + +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them +// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 +| eval Esql.script_block_tmp = replace(powershell.file.script_block_text, """[A-Za-z0-9_-]`(?![rntb]|\r|\n|\d)[A-Za-z0-9_-]""", "πŸ”₯") + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.name, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least 10 times +| where Esql.script_block_pattern_count >= 10 + +// Filter FPs, and due to the behavior of the like operator, allow null values +| where (file.name not like "TSS_*.psm1" or file.name is null) + +// VSCode Shell integration +| where not powershell.file.script_block_text like "*$([char]0x1b)]633*" + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Defense Evasion +** ID: TA0005 +** Reference URL: https://attack.mitre.org/tactics/TA0005/ +* Technique: +** Name: Obfuscated Files or Information +** ID: T1027 +** Reference URL: https://attack.mitre.org/techniques/T1027/ +* Technique: +** Name: Deobfuscate/Decode Files or Information +** ID: T1140 +** Reference URL: https://attack.mitre.org/techniques/T1140/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: PowerShell +** ID: T1059.001 +** Reference URL: https://attack.mitre.org/techniques/T1059/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-reverse-keywords.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-reverse-keywords.asciidoc new file mode 100644 index 0000000000..62ada014b9 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-reverse-keywords.asciidoc @@ -0,0 +1,177 @@ +[[prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-reverse-keywords]] +=== Potential PowerShell Obfuscation via Reverse Keywords + +Identifies PowerShell scripts that use reversed strings as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Windows +* Use Case: Threat Detection +* Tactic: Defense Evasion +* Data Source: PowerShell Logs +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Potential PowerShell Obfuscation via Reverse Keywords* + + +PowerShell, a powerful scripting language in Windows environments, is often targeted by adversaries for obfuscation to bypass security measures like AMSI. Attackers reverse keywords in scripts to evade static analysis. The detection rule identifies such obfuscation by searching for reversed keywords, replacing them with a unique marker, and counting occurrences. This helps in flagging scripts with multiple obfuscated elements, indicating potential malicious activity. + + +*Possible investigation steps* + + +- Review the `powershell.file.script_block_text` field to understand the context and content of the script that triggered the alert. Look for any suspicious or unexpected behavior in the script logic. +- Examine the `file.path` field to determine the location of the script on the system. This can provide insights into whether the script is part of a legitimate application or potentially malicious. +- Check the `powershell.file.script_block_id` and `powershell.sequence` fields to identify if the script is part of a larger sequence of commands. This can help in understanding the full scope of the script's execution. +- Investigate the `agent.id` field to identify the specific endpoint where the script was executed. This can help in correlating with other alerts or logs from the same machine. +- Assess the `count` field to determine the extent of obfuscation. A higher count may indicate a more heavily obfuscated script, suggesting a higher likelihood of malicious intent. + + +*False positive analysis* + + +- Scripts with legitimate administrative functions may use reversed keywords for benign purposes, such as custom logging or debugging. Review the context of the script to determine if the usage is intentional and non-malicious. +- Automated scripts generated by legitimate software tools might include reversed keywords as part of their normal operation. Identify these tools and create exceptions for their known script patterns to prevent unnecessary alerts. +- Developers or IT personnel might use reversed keywords in test environments to simulate obfuscation techniques. Ensure these environments are well-documented and excluded from production monitoring to avoid false positives. +- PowerShell scripts used in educational or training settings may intentionally include obfuscation techniques for learning purposes. Exclude these scripts by identifying their unique characteristics or file paths. +- Regularly update the list of excluded scripts or patterns as new legitimate use cases are identified, ensuring the detection rule remains effective without generating excessive false positives. + + +*Response and remediation* + + +- Isolate the affected system from the network to prevent further spread of potentially malicious scripts. +- Terminate any suspicious PowerShell processes identified by the alert to halt ongoing malicious activity. +- Conduct a thorough review of the script block text and associated files to understand the scope and intent of the obfuscation. +- Remove or quarantine any identified malicious scripts or files from the system to prevent re-execution. +- Restore affected systems from a known good backup if malicious activity has altered system integrity. +- Update endpoint protection and security tools to recognize and block similar obfuscation techniques in the future. +- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and monitoring of potential lateral movement or additional threats. + + +==== Setup + + + +*Setup* + + +The 'PowerShell Script Block Logging' logging policy must be enabled. +Steps to implement the logging policy with Advanced Audit Configuration: + +``` +Computer Configuration > +Administrative Templates > +Windows PowerShell > +Turn on PowerShell Script Block Logging (Enable) +``` + +Steps to implement the logging policy via registry: + +``` +reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1 +``` + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" + +// Filter for scripts that contains these keywords using MATCH, boosts the query performance, +// match will ignore the | and look for the individual words +| where powershell.file.script_block_text : "rahc|metsys|stekcos|tcejboimw|ecalper|ecnerferpe|noitcennoc|nioj|eman|vne|gnirts|tcejbo-wen|_23niw|noisserpxe|ekovni|daolnwod" + +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them +// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 +| eval Esql.script_block_tmp = replace( + powershell.file.script_block_text, + """(?i)(rahc|metsys|stekcos|tcejboimw|ecalper|ecnerferpe|noitcennoc|nioj|eman\.|:vne|gnirts|tcejbo-wen|_23niw|noisserpxe|ekovni|daolnwod)""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + agent.id + +// Filter for scripts that match the pattern at least twice +| where Esql.script_block_pattern_count >= 2 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Defense Evasion +** ID: TA0005 +** Reference URL: https://attack.mitre.org/tactics/TA0005/ +* Technique: +** Name: Obfuscated Files or Information +** ID: T1027 +** Reference URL: https://attack.mitre.org/techniques/T1027/ +* Technique: +** Name: Deobfuscate/Decode Files or Information +** ID: T1140 +** Reference URL: https://attack.mitre.org/techniques/T1140/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: PowerShell +** ID: T1059.001 +** Reference URL: https://attack.mitre.org/techniques/T1059/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-special-character-overuse.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-special-character-overuse.asciidoc new file mode 100644 index 0000000000..30afbb34b4 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-special-character-overuse.asciidoc @@ -0,0 +1,187 @@ +[[prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-special-character-overuse]] +=== Potential PowerShell Obfuscation via Special Character Overuse + +Identifies PowerShell scripts with an unusually high proportion of whitespace and special characters, often indicative of obfuscation. This behavior is commonly associated with techniques such as SecureString encoding, formatting obfuscation, or character-level manipulation designed to bypass static analysis and AMSI inspection. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Windows +* Use Case: Threat Detection +* Tactic: Defense Evasion +* Data Source: PowerShell Logs +* Resources: Investigation Guide + +*Version*: 4 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Potential PowerShell Obfuscation via Special Character Overuse* + + +PowerShell is a powerful scripting language used for task automation and configuration management in Windows environments. Adversaries exploit PowerShell's flexibility to obfuscate scripts, using excessive special characters to evade detection. The detection rule identifies scripts with high special character density, indicating potential obfuscation, by analyzing script length and character patterns, thus aiding in uncovering malicious activities. + + +*Possible investigation steps* + + +- Review the dedup_space_script_block field to understand the script's structure and identify any suspicious patterns or keywords that might indicate obfuscation techniques. +- Analyze the replaced_with_fire field to assess the density and distribution of special characters, which can provide insights into the obfuscation methods used. +- Examine the file.path and host.name fields to determine the origin and context of the script execution, which can help identify if the script was run on a critical system or by a privileged user. +- Check the user.id and agent.id fields to verify the identity of the user or agent executing the script, which can help assess if the activity aligns with expected behavior or if it might be unauthorized. +- Correlate the powershell.file.script_block_id with other logs or alerts to identify if similar scripts have been executed elsewhere in the environment, indicating a broader attack pattern. + + +*False positive analysis* + + +- Scripts with legitimate use of special characters for formatting or encoding may trigger false positives. Review the script's purpose and context to determine if the use of special characters is justified. +- Automated scripts that heavily rely on string manipulation or dynamic content generation might be flagged. Consider adding exceptions for known scripts or trusted sources to reduce unnecessary alerts. +- PowerShell scripts used in development or testing environments often contain high special character density. Implement environment-based exclusions to prevent these from being flagged in non-production settings. +- Scripts utilizing SecureString or other security-related encoding methods may appear obfuscated. Verify the script's origin and purpose, and whitelist these methods if they are part of standard security practices. +- Regularly update the detection rule to refine the pattern matching and reduce false positives by incorporating feedback from security analysts and system administrators. + + +*Response and remediation* + + +- Isolate the affected host immediately to prevent lateral movement and further execution of potentially malicious scripts. +- Terminate any suspicious PowerShell processes identified by the alert to halt ongoing malicious activity. +- Conduct a thorough review of the script block text and associated metadata to understand the intent and potential impact of the obfuscated script. +- Remove any unauthorized or malicious scripts from the affected system to prevent re-execution. +- Restore the system from a known good backup if the script has caused significant changes or damage to the system. +- Update endpoint protection and intrusion detection systems to recognize and block similar obfuscation techniques in the future. +- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems are affected. + + +==== Setup + + + +*Setup* + + +The 'PowerShell Script Block Logging' logging policy must be enabled. +Steps to implement the logging policy with Advanced Audit Configuration: + +``` +Computer Configuration > +Administrative Templates > +Windows PowerShell > +Turn on PowerShell Script Block Logging (Enable) +``` + +Steps to implement the logging policy via registry: + +``` +reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1 +``` + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" + +// replace repeated spaces used for formatting after a new line with a single space to reduce FPs +| eval Esql.script_block_tmp = replace(powershell.file.script_block_text, """\n\s+""", "\n ") + +// Look for scripts with more than 1000 chars +| eval Esql.script_block_length = length(Esql.script_block_tmp) +| where Esql.script_block_length > 1000 + +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them +// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 +| eval Esql.script_block_tmp = replace( + Esql.script_block_tmp, + """[\s\$\{\}\+\@\=\(\)\^\\\"~\[\]\?\.]""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_count = Esql.script_block_length - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// Calculate the ratio of special characters to total length +| eval Esql.script_block_ratio = Esql.script_block_count::double / Esql.script_block_length::double + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_count, + Esql.script_block_length, + Esql.script_block_ratio, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts with high whitespace and special character ratio +| where Esql.script_block_ratio > 0.75 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Defense Evasion +** ID: TA0005 +** Reference URL: https://attack.mitre.org/tactics/TA0005/ +* Technique: +** Name: Obfuscated Files or Information +** ID: T1027 +** Reference URL: https://attack.mitre.org/techniques/T1027/ +* Technique: +** Name: Deobfuscate/Decode Files or Information +** ID: T1140 +** Reference URL: https://attack.mitre.org/techniques/T1140/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: PowerShell +** ID: T1059.001 +** Reference URL: https://attack.mitre.org/techniques/T1059/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-string-concatenation.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-string-concatenation.asciidoc new file mode 100644 index 0000000000..525abc250f --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-string-concatenation.asciidoc @@ -0,0 +1,181 @@ +[[prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-string-concatenation]] +=== Potential PowerShell Obfuscation via String Concatenation + +Identifies PowerShell scripts that use string concatenation as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Windows +* Use Case: Threat Detection +* Tactic: Defense Evasion +* Data Source: PowerShell Logs +* Resources: Investigation Guide + +*Version*: 4 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Potential PowerShell Obfuscation via String Concatenation* + + +PowerShell is a powerful scripting language used for task automation and configuration management. Adversaries exploit its flexibility to obfuscate malicious scripts, often using string concatenation to evade detection. The detection rule identifies scripts with excessive concatenation patterns, flagging potential obfuscation by analyzing script length and pattern frequency, thus aiding in uncovering hidden threats. + + +*Possible investigation steps* + + +- Review the powershell.file.script_block_text field to understand the content and purpose of the script, focusing on the sections identified by the string concatenation patterns. +- Examine the file.path field to determine the location of the script on the host system, which can provide context about its origin and potential legitimacy. +- Check the host.name and agent.id fields to identify the affected system and correlate with other security events or alerts from the same host for broader context. +- Investigate the user.id field to determine which user executed the script, assessing their role and whether they have a legitimate reason to run such scripts. +- Analyze the powershell.file.script_block_id and powershell.sequence fields to trace the execution flow and sequence of the script blocks, which may reveal additional obfuscation or malicious behavior. +- Cross-reference the _id and _index fields with other logs or alerts to identify any related incidents or patterns of activity that might indicate a larger threat campaign. + + +*False positive analysis* + + +- Scripts with legitimate string concatenation for logging or configuration purposes may trigger the rule. Review the script context to determine if the concatenation is part of a benign operation. +- Automated scripts generated by development tools might use string concatenation extensively. Identify these tools and consider excluding their output directories or specific script patterns from the rule. +- PowerShell scripts used in complex data processing tasks may naturally contain high levels of string concatenation. Analyze the script's purpose and, if deemed safe, add exceptions for specific script block IDs or paths. +- Frequent administrative scripts that concatenate strings for dynamic command execution could be flagged. Verify the script's source and function, then whitelist known safe scripts by user ID or host name. +- Consider adjusting the threshold for pattern detection if legitimate scripts frequently exceed the current limit, ensuring that the rule remains effective without generating excessive false positives. + + +*Response and remediation* + + +- Isolate the affected host immediately to prevent further spread of potentially malicious scripts across the network. Disconnect it from the network and any shared resources. +- Terminate any suspicious PowerShell processes identified by the alert to halt the execution of potentially obfuscated scripts. +- Conduct a thorough examination of the script block text and associated files to identify and remove any malicious code or artifacts. Use a secure, isolated environment for analysis. +- Restore the affected system from a known good backup if malicious activity is confirmed and cannot be easily remediated. +- Update and run a full antivirus and antimalware scan on the affected system to ensure no additional threats are present. +- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems are compromised. +- Implement enhanced monitoring and logging for PowerShell activities across the network to detect similar obfuscation attempts in the future, ensuring that alerts are configured to notify the appropriate personnel promptly. + + +==== Setup + + + +*Setup* + + +The 'PowerShell Script Block Logging' logging policy must be enabled. +Steps to implement the logging policy with Advanced Audit Configuration: + +``` +Computer Configuration > +Administrative Templates > +Windows PowerShell > +Turn on PowerShell Script Block Logging (Enable) +``` + +Steps to implement the logging policy via registry: + +``` +reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1 +``` + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" + +// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for +| eval Esql.script_block_length = length(powershell.file.script_block_text) +| where Esql.script_block_length > 500 + +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them +// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 +| eval Esql.script_block_tmp = replace( + powershell.file.script_block_text, + """['"][A-Za-z0-9.]+['"](\s?\+\s?['"][A-Za-z0-9.,\-\s]+['"]){2,}""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_length, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least twice +| where Esql.script_block_pattern_count >= 2 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Defense Evasion +** ID: TA0005 +** Reference URL: https://attack.mitre.org/tactics/TA0005/ +* Technique: +** Name: Obfuscated Files or Information +** ID: T1027 +** Reference URL: https://attack.mitre.org/techniques/T1027/ +* Technique: +** Name: Deobfuscate/Decode Files or Information +** ID: T1140 +** Reference URL: https://attack.mitre.org/techniques/T1140/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: PowerShell +** ID: T1059.001 +** Reference URL: https://attack.mitre.org/techniques/T1059/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-string-reordering.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-string-reordering.asciidoc new file mode 100644 index 0000000000..4eed96e677 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-string-reordering.asciidoc @@ -0,0 +1,195 @@ +[[prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-string-reordering]] +=== Potential PowerShell Obfuscation via String Reordering + +Identifies PowerShell scripts that use string reordering and runtime reconstruction techniques as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Windows +* Use Case: Threat Detection +* Tactic: Defense Evasion +* Data Source: PowerShell Logs +* Resources: Investigation Guide + +*Version*: 5 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Potential PowerShell Obfuscation via String Reordering* + + +PowerShell, a powerful scripting language in Windows environments, can be exploited by adversaries using obfuscation techniques like string reordering to evade detection. This involves rearranging strings and reconstructing them at runtime, bypassing static analysis and security measures. The detection rule identifies scripts with excessive length and specific patterns, flagging those with multiple occurrences of string format expressions, which are indicative of obfuscation attempts. By filtering out known benign patterns, it reduces false positives, focusing on genuine threats. + + +*Possible investigation steps* + + +- Review the script block text by examining the powershell.file.script_block_text field to understand the nature of the obfuscation and identify any potentially malicious commands or patterns. +- Check the file.path and file.name fields to determine the origin and context of the script, which can provide insights into whether the script is part of a legitimate application or a potential threat. +- Investigate the host.name and user.id fields to identify the affected system and user, which can help in assessing the potential impact and scope of the incident. +- Analyze the powershell.file.script_block_id and powershell.sequence fields to trace the execution sequence and history of the script, which may reveal additional suspicious activities or related scripts. +- Correlate the alert with other security events or logs from the same host or user to identify any patterns or additional indicators of compromise that may suggest a broader attack campaign. + + +*False positive analysis* + + +- Scripts related to the Icinga Framework may trigger false positives due to their use of string formatting. To handle this, ensure that the file name "framework_cache.psm1" is excluded from the detection rule. +- PowerShell scripts that include specific sentinel patterns, such as "sentinelbreakpoints" or paths like ":::::\windows\sentinel", combined with variables like "$local:Bypassed" or "origPSExecutionPolicyPreference", are known to be benign. These should be excluded to reduce noise. +- Regularly review and update the exclusion list to include any new benign patterns that are identified over time, ensuring the rule remains effective without generating unnecessary alerts. +- Consider implementing a whitelist of known safe scripts or script authors to further minimize false positives, especially in environments with frequent legitimate use of complex PowerShell scripts. + + +*Response and remediation* + + +- Isolate the affected system from the network to prevent further spread of potentially malicious scripts. +- Terminate any suspicious PowerShell processes identified by the alert to stop ongoing malicious activity. +- Conduct a thorough review of the PowerShell script block text flagged by the alert to understand the intent and potential impact of the obfuscated script. +- Remove any malicious scripts or files identified during the investigation from the affected system to prevent re-execution. +- Restore the system from a known good backup if the script has caused significant changes or damage to the system. +- Update and strengthen endpoint protection measures, ensuring that AMSI and other security tools are fully operational and configured to detect similar obfuscation techniques. +- Escalate the incident to the security operations center (SOC) or incident response team for further analysis and to determine if additional systems are affected. + + +==== Setup + + + +*Setup* + + +The 'PowerShell Script Block Logging' logging policy must be enabled. +Steps to implement the logging policy with Advanced Audit Configuration: + +``` +Computer Configuration > +Administrative Templates > +Windows PowerShell > +Turn on PowerShell Script Block Logging (Enable) +``` + +Steps to implement the logging policy via registry: + +``` +reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1 +``` + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" and powershell.file.script_block_text like "*{0}*" + +// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for +| eval Esql.script_block_length = length(powershell.file.script_block_text) +| where Esql.script_block_length > 500 + +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them +// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 +| eval Esql.script_block_tmp = replace( + powershell.file.script_block_text, + """((\{\d+\}){2,}["']\s?-f|::Format[^\{]+(\{\d+\}){2,})""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_length, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + file.name, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least four times +| where Esql.script_block_pattern_count >= 4 + +// Exclude Noisy Patterns + +// Icinga Framework +| where (file.name not like "framework_cache.psm1" or file.name is null) + +| where not + // https://wtfbins.wtf/17 + ( + (powershell.file.script_block_text like "*sentinelbreakpoints*" or + powershell.file.script_block_text like "*:::::\\\\windows\\\\sentinel*") + and + (powershell.file.script_block_text like "*$local:Bypassed*" or + powershell.file.script_block_text like "*origPSExecutionPolicyPreference*") + ) + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Defense Evasion +** ID: TA0005 +** Reference URL: https://attack.mitre.org/tactics/TA0005/ +* Technique: +** Name: Obfuscated Files or Information +** ID: T1027 +** Reference URL: https://attack.mitre.org/techniques/T1027/ +* Technique: +** Name: Deobfuscate/Decode Files or Information +** ID: T1140 +** Reference URL: https://attack.mitre.org/techniques/T1140/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: PowerShell +** ID: T1059.001 +** Reference URL: https://attack.mitre.org/techniques/T1059/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-subnet-scanning-activity-from-compromised-host.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-subnet-scanning-activity-from-compromised-host.asciidoc new file mode 100644 index 0000000000..795f40b816 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-subnet-scanning-activity-from-compromised-host.asciidoc @@ -0,0 +1,160 @@ +[[prebuilt-rule-8-19-4-potential-subnet-scanning-activity-from-compromised-host]] +=== Potential Subnet Scanning Activity from Compromised Host + +This rule detects potential subnet scanning activity from a compromised host. Subnet scanning is a common reconnaissance technique used by attackers to identify live hosts within a network range. A compromised host may exhibit subnet scanning behavior when an attacker is attempting to map out the network topology, identify vulnerable hosts, or prepare for further exploitation. This rule identifies potential subnet scanning activity by monitoring network connection attempts from a single host to a large number of hosts within a short time frame. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 1h + +*Searches indices from*: now-61m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Linux +* Use Case: Threat Detection +* Tactic: Discovery +* Data Source: Elastic Defend +* Resources: Investigation Guide + +*Version*: 5 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Potential Subnet Scanning Activity from Compromised Host* + + +Subnet scanning is a reconnaissance method used by attackers to map network topology and identify active hosts. Adversaries exploit compromised hosts to perform these scans, seeking vulnerabilities for further attacks. The detection rule identifies such activity by monitoring Linux hosts for numerous connection attempts to different IPs within a short period, indicating potential scanning behavior. This helps in early detection and mitigation of network threats. + + +*Possible investigation steps* + + +- Review the process executable identified in the alert to determine if it is a known or legitimate application that should be making network connections. +- Examine the destination IP addresses to identify any patterns or known malicious IPs, and check if these IPs are part of the organization's network or external. +- Investigate the specific host (using the agent.id) to assess if there are any signs of compromise, such as unusual processes or unauthorized access. +- Correlate the event timestamp with other logs or alerts to identify any concurrent suspicious activities or anomalies on the host. +- Check for any recent changes or updates on the host that might explain the scanning behavior, such as new software installations or configuration changes. + + +*False positive analysis* + + +- High-volume legitimate network monitoring tools may trigger the rule. Identify and exclude these tools by adding their process executables to an exception list. +- Automated backup systems that connect to multiple hosts within a short timeframe can be mistaken for scanning activity. Review and exclude these systems by their process executable or agent ID. +- Security software performing routine network health checks might generate false positives. Verify these activities and create exceptions based on the specific process executable involved. +- Internal IT scripts or administrative tasks that involve connecting to numerous hosts for maintenance purposes can trigger alerts. Document these tasks and exclude them by process executable or agent ID. +- Cloud-based services or applications that require frequent connections to various hosts for functionality may appear as scanning. Identify these services and exclude them by their process executable or agent ID. + + +*Response and remediation* + + +- Isolate the compromised host immediately from the network to prevent further scanning and potential lateral movement by the attacker. +- Terminate any suspicious processes identified by the executable name in the alert to stop ongoing scanning activities. +- Conduct a thorough examination of the compromised host to identify and remove any malware or unauthorized access tools that may have been installed. +- Reset credentials and review access permissions for the compromised host to ensure no unauthorized access persists. +- Update and patch the compromised host and any other vulnerable systems identified during the investigation to close security gaps. +- Monitor network traffic closely for any signs of continued scanning or other suspicious activities from other hosts, indicating potential further compromise. +- Escalate the incident to the security operations center (SOC) or incident response team for a comprehensive investigation and to determine if additional hosts are affected. + + +==== Setup + + + +*Setup* + + +This rule requires data coming in from Elastic Defend. + + +*Elastic Defend Integration Setup* + +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. + + +*Prerequisite Requirements:* + +- Fleet is required for Elastic Defend. +- To configure Fleet Server refer to the https://www.elastic.co/guide/en/fleet/current/fleet-server.html[documentation]. + + +*The following steps should be executed in order to add the Elastic Defend integration on a Linux System:* + +- Go to the Kibana home page and click "Add integrations". +- In the query bar, search for "Elastic Defend" and select the integration to see more details about it. +- Click "Add Elastic Defend". +- Configure the integration name and optionally add a description. +- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads". +- 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. https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html[Helper guide]. +- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions" +- 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. +For more details on Elastic Agent configuration settings, refer to the https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html[helper guide]. +- Click "Save and Continue". +- 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 https://www.elastic.co/guide/en/security/current/install-endpoint.html[helper guide]. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-endpoint.events.network-* +| keep @timestamp, host.os.type, event.type, event.action, process.executable, destination.ip, agent.id, host.name +| where + @timestamp > now() - 1 hours and + host.os.type == "linux" and + event.type == "start" and + event.action == "connection_attempted" +| stats + Esql.event_count = count(), + Esql.destination_ip_count_distinct = count_distinct(destination.ip), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.executable +| where + Esql.agent_id_count_distinct == 1 and + Esql.destination_ip_count_distinct > 250 +| sort Esql.event_count asc +| limit 100 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Discovery +** ID: TA0007 +** Reference URL: https://attack.mitre.org/tactics/TA0007/ +* Technique: +** Name: Network Service Discovery +** ID: T1046 +** Reference URL: https://attack.mitre.org/techniques/T1046/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-widespread-malware-infection-across-multiple-hosts.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-widespread-malware-infection-across-multiple-hosts.asciidoc new file mode 100644 index 0000000000..3135541555 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-potential-widespread-malware-infection-across-multiple-hosts.asciidoc @@ -0,0 +1,117 @@ +[[prebuilt-rule-8-19-4-potential-widespread-malware-infection-across-multiple-hosts]] +=== Potential Widespread Malware Infection Across Multiple Hosts + +This rule uses alert data to determine when a malware signature is triggered in multiple hosts. Analysts can use this to prioritize triage and response, as this can potentially indicate a widespread malware infection. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: high + +*Risk score*: 73 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://github.com/elastic/protections-artifacts/tree/main/yara/rules + +*Tags*: + +* Domain: Endpoint +* Data Source: Elastic Defend +* Use Case: Threat Detection +* Tactic: Execution +* Rule Type: Higher-Order Rule +* Resources: Investigation Guide + +*Version*: 4 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + +> **Disclaimer**: +> 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. + + +*Investigating Potential Widespread Malware Infection Across Multiple Hosts* + + +Endpoint security technologies monitor and analyze activities on devices to detect malicious behavior. Adversaries exploit these systems by deploying malware that triggers specific signatures across multiple hosts, indicating a coordinated attack. The detection rule identifies such threats by analyzing alert data for specific malware signatures across several hosts, flagging potential widespread infections for prioritized investigation. + + +*Possible investigation steps* + + +- Review the alert details to identify the specific rule.name and event.code that triggered the alert, focusing on those with a high count of distinct host.id values. +- Correlate the identified rule.name with known malware signatures or recent threat intelligence reports to understand the potential impact and behavior of the malware. +- Examine the affected host.id entries to determine if there are any commonalities, such as shared network segments, user accounts, or software versions, that could indicate the initial infection vector. +- Investigate the timeline of events for each affected host to identify any suspicious activities or anomalies preceding the alert, such as unusual file downloads or execution of unknown processes. +- Check for any additional alerts or logs related to the same host.id entries to assess if there are other indicators of compromise or related malicious activities. +- Coordinate with IT and security teams to isolate affected hosts if necessary, and initiate containment and remediation procedures based on the findings. + + +*False positive analysis* + + +- Legitimate software updates or installations may trigger malware signatures, especially if they involve new or uncommon software. Users can create exceptions for known software update processes to prevent these alerts from being flagged as potential threats. +- Security testing tools or penetration testing activities might mimic malware behavior, leading to false positives. Analysts should coordinate with IT and security teams to whitelist these activities during scheduled tests. +- Custom scripts or administrative tools that perform automated tasks across multiple hosts can be mistaken for malicious activity. Identifying and excluding these scripts from the rule can reduce unnecessary alerts. +- Frequent use of remote management tools that execute scripts or commands on multiple hosts may trigger alerts. Users should ensure these tools are recognized and excluded from the rule to avoid false positives. +- Known benign applications that use shellcode or memory manipulation techniques for legitimate purposes should be reviewed and added to an exception list to prevent them from being flagged. + + +*Response and remediation* + + +- Isolate affected hosts immediately to prevent further spread of the malware across the network. This can be done by disconnecting them from the network or using network segmentation techniques. +- Conduct a thorough scan of the isolated hosts using updated antivirus or endpoint detection and response (EDR) tools to identify and remove the malicious files or processes associated with the detected signatures. +- Analyze the identified malware to understand its behavior and entry points. This will help in determining if additional hosts may be compromised and require similar remediation actions. +- Apply security patches and updates to all affected systems to close any vulnerabilities that the malware may have exploited. +- Restore affected systems from clean backups if the malware has caused significant damage or if the integrity of the system cannot be assured after cleaning. +- Monitor network traffic and endpoint activities closely for any signs of persistence or re-infection, using enhanced detection rules and updated threat intelligence feeds. +- Escalate the incident to the appropriate internal or external cybersecurity teams if the infection appears to be part of a larger coordinated attack, ensuring that all relevant data and findings are shared for further investigation and response. + +==== Rule query + + +[source, js] +---------------------------------- +from logs-endpoint.alerts-* +| where event.code in ("malicious_file", "memory_signature", "shellcode_thread") and rule.name is not null +| keep host.id, rule.name, event.code +| stats Esql.host_id_count_distinct = count_distinct(host.id) by rule.name, event.code +| where Esql.host_id_count_distinct >= 3 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: User Execution +** ID: T1204 +** Reference URL: https://attack.mitre.org/techniques/T1204/ +* Sub-technique: +** Name: Malicious File +** ID: T1204.002 +** Reference URL: https://attack.mitre.org/techniques/T1204/002/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-powershell-obfuscation-via-negative-index-string-reversal.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-powershell-obfuscation-via-negative-index-string-reversal.asciidoc new file mode 100644 index 0000000000..baaa825bb0 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-powershell-obfuscation-via-negative-index-string-reversal.asciidoc @@ -0,0 +1,184 @@ +[[prebuilt-rule-8-19-4-powershell-obfuscation-via-negative-index-string-reversal]] +=== PowerShell Obfuscation via Negative Index String Reversal + +Identifies PowerShell scripts that use negative index ranges to reverse the contents of a string or array at runtime as a form of obfuscation. This technique avoids direct use of reversal functions by iterating through array elements in reverse order. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 5m + +*Searches indices from*: now-9m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Windows +* Use Case: Threat Detection +* Tactic: Defense Evasion +* Data Source: PowerShell Logs +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating PowerShell Obfuscation via Negative Index String Reversal* + + +PowerShell, a powerful scripting language, can be exploited by adversaries using obfuscation techniques like negative index string reversal to evade detection. This method manipulates strings or arrays by iterating in reverse, bypassing static analysis tools. The detection rule identifies scripts with obfuscation patterns by analyzing script length and specific indexing patterns, flagging potential threats for further investigation. + + +*Possible investigation steps* + + +- Review the `powershell.file.script_block_text` to understand the script's intent and identify any suspicious or malicious behavior. +- Check the `host.name` and `user.id` fields to determine the affected system and user, assessing if they are high-value targets or have a history of similar alerts. +- Analyze the `file.path` to identify the location of the script and assess if it is in a common or suspicious directory. +- Investigate the `powershell.file.script_block_id` and `powershell.sequence` to trace the execution flow and determine if this script is part of a larger, potentially malicious sequence. +- Correlate the `agent.id` with other logs to see if there are additional related activities or alerts from the same endpoint. +- Examine the `count` of detected patterns to assess the level of obfuscation and potential threat severity. + + +*False positive analysis* + + +- Scripts containing the keyword "GENESIS-5654" are known false positives and are automatically excluded from triggering alerts. Ensure that any legitimate scripts using this keyword are documented to prevent unnecessary investigations. +- Legitimate administrative scripts that use negative indexing for valid purposes may trigger false positives. Review these scripts and consider adding them to an exception list if they are frequently flagged but verified as non-malicious. +- Automated scripts generated by trusted software that use similar obfuscation patterns for performance or compatibility reasons can be excluded by identifying unique identifiers or patterns within these scripts and updating the exclusion criteria accordingly. +- Regularly update the exclusion list to include new patterns or identifiers from trusted sources as they are identified, ensuring that legitimate activities are not hindered by the detection rule. +- Collaborate with IT and security teams to maintain a list of known safe scripts and their characteristics, which can be referenced when analyzing potential false positives. + + +*Response and remediation* + + +- Isolate the affected host immediately to prevent further spread of potentially malicious scripts or unauthorized access. +- Terminate any suspicious PowerShell processes identified by the alert to halt ongoing obfuscation activities. +- Conduct a thorough review of the PowerShell script block text and related logs to identify any malicious payloads or commands executed. +- Remove any identified malicious scripts or files from the affected system to prevent re-execution. +- Reset credentials for any user accounts involved in the alert to mitigate potential unauthorized access. +- Escalate the incident to the security operations team for further analysis and to determine if additional systems are compromised. +- Update endpoint protection and monitoring tools to enhance detection capabilities for similar obfuscation techniques in the future. + + +==== Setup + + + +*Setup* + + +The 'PowerShell Script Block Logging' logging policy must be enabled. +Steps to implement the logging policy with Advanced Audit Configuration: + +``` +Computer Configuration > +Administrative Templates > +Windows PowerShell > +Turn on PowerShell Script Block Logging (Enable) +``` + +Steps to implement the logging policy via registry: + +``` +reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1 +``` + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" + +// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for +| eval Esql.script_block_length = length(powershell.file.script_block_text) +| where Esql.script_block_length > 500 + +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them +// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 +| eval Esql.script_block_tmp = replace( + powershell.file.script_block_text, + """\$\w+\[\-\s?1\.\.""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_length, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least once +| where Esql.script_block_pattern_count >= 1 + +// FP Patterns +| where not powershell.file.script_block_text like "*GENESIS-5654*" + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Defense Evasion +** ID: TA0005 +** Reference URL: https://attack.mitre.org/tactics/TA0005/ +* Technique: +** Name: Obfuscated Files or Information +** ID: T1027 +** Reference URL: https://attack.mitre.org/techniques/T1027/ +* Technique: +** Name: Deobfuscate/Decode Files or Information +** ID: T1140 +** Reference URL: https://attack.mitre.org/techniques/T1140/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: PowerShell +** ID: T1059.001 +** Reference URL: https://attack.mitre.org/techniques/T1059/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-rare-connection-to-webdav-target.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-rare-connection-to-webdav-target.asciidoc new file mode 100644 index 0000000000..66ff054546 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-rare-connection-to-webdav-target.asciidoc @@ -0,0 +1,122 @@ +[[prebuilt-rule-8-19-4-rare-connection-to-webdav-target]] +=== Rare Connection to WebDAV Target + +Identifies rare connection attempts to a Web Distributed Authoring and Versioning (WebDAV) resource. Attackers may inject WebDAV paths in files or features opened by a victim user to leak their NTLM credentials via forced authentication. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 5m + +*Searches indices from*: now-3660s ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://attack.mitre.org/techniques/T1187/ + +*Tags*: + +* Domain: Endpoint +* OS: Windows +* Use Case: Threat Detection +* Tactic: Credential Access +* Data Source: Elastic Defend +* Data Source: Windows Security Event Logs +* Data Source: Microsoft Defender for Endpoint +* Data Source: Crowdstrike +* Resources: Investigation Guide + +*Version*: 2 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Rare Connection to WebDAV Target* + + + +*Possible investigation steps* + + +- Examine the reputation of the destination domain or IP address. +- Verify if the target user opened any attachments or clicked links pointing to the same target within seconds from the alert timestamp. +- Correlate the findings with other security logs and alerts to identify any patterns or additional indicators of compromise related to the potential relay attack. + + +*False positive analysis* + + +- User accessing legit WebDAV resources. + + +*Response and remediation* + + +- Conduct a password reset for the target account that may have been compromised or are at risk, ensuring the use of strong, unique passwords. +- Verify whether other users were targeted but did not open the lure.. +- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine the full scope of the breach. +- Conduct a post-incident review to identify any gaps in security controls and update policies or procedures to prevent recurrence, ensuring lessons learned are applied to improve overall security posture. + +==== Rule query + + +[source, js] +---------------------------------- +from logs-* +| where + @timestamp > now() - 8 hours and + event.category == "process" and + event.type == "start" and + process.name == "rundll32.exe" and + process.command_line like "*DavSetCookie*" +| keep host.id, process.command_line, user.name +| grok + process.command_line """(?DavSetCookie .* http)""" +| eval + Esql.server_webdav_cookie_replace = replace(Esql.server_webdav_cookie, "(DavSetCookie | http)", "") +| where + Esql.server_webdav_cookie_replace is not null and + Esql.server_webdav_cookie_replace rlike """(([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,3}(@SSL.*)*|(\d{1,3}\.){3}\d{1,3})""" and + not Esql.server_webdav_cookie_replace in ("www.google.com@SSL", "www.elastic.co@SSL") and + not Esql.server_webdav_cookie_replace rlike """(10\.(\d{1,3}\.){2}\d{1,3}|172\.(1[6-9]|2\d|3[0-1])\.(\d{1,3}\.)\d{1,3}|192\.168\.(\d{1,3}\.)\d{1,3})""" +| stats + Esql.event_count = count(*), + Esql.host_id_count_distinct = count_distinct(host.id), + Esql.host_id_values = values(host.id), + Esql.user_name_values = values(user.name) + by Esql.server_webdav_cookie_replace +| where + Esql.host_id_count_distinct == 1 and + Esql.event_count <= 3 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Credential Access +** ID: TA0006 +** Reference URL: https://attack.mitre.org/tactics/TA0006/ +* Technique: +** Name: Forced Authentication +** ID: T1187 +** Reference URL: https://attack.mitre.org/techniques/T1187/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-suspicious-microsoft-365-userloggedin-via-oauth-code.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-suspicious-microsoft-365-userloggedin-via-oauth-code.asciidoc new file mode 100644 index 0000000000..652490b99c --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-suspicious-microsoft-365-userloggedin-via-oauth-code.asciidoc @@ -0,0 +1,163 @@ +[[prebuilt-rule-8-19-4-suspicious-microsoft-365-userloggedin-via-oauth-code]] +=== Suspicious Microsoft 365 UserLoggedIn via OAuth Code + +Identifies sign-ins on behalf of a principal user to the Microsoft Graph API from multiple IPs using the Microsoft Authentication Broker or Visual Studio Code application. This behavior may indicate an adversary using a phished OAuth refresh token. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: high + +*Risk score*: 73 + +*Runs every*: 59m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://www.volexity.com/blog/2025/04/22/phishing-for-codes-russian-threat-actors-target-microsoft-365-oauth-workflows/ +* https://github.com/dirkjanm/ROADtools +* https://dirkjanm.io/phishing-for-microsoft-entra-primary-refresh-tokens/ + +*Tags*: + +* Domain: Cloud +* Domain: Email +* Domain: Identity +* Data Source: Microsoft 365 +* Data Source: Microsoft 365 Audit Logs +* Use Case: Identity and Access Audit +* Use Case: Threat Detection +* Resources: Investigation Guide +* Tactic: Defense Evasion + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Suspicious Microsoft 365 UserLoggedIn via OAuth Code* + + + +*Possible Investigation Steps:* + + +- `o365.audit.UserId`: The identity value the application is acting on behalf of principal user. +- `unique_ips`: Analyze the list of unique IP addresses used within the 30-minute window. Determine whether these originate from different geographic regions, cloud providers, or anonymizing infrastructure (e.g., Tor or VPNs). +- `target_time_window`: Use the truncated time window to pivot into raw events to reconstruct the full sequence of resource access events, including exact timestamps and service targets. +- `azure.auditlogs` to check for device join or registration events around the same timeframe. +- `azure.identityprotection` to identify correlated risk detections, such as anonymized IP access or token replay. +- Any additional sign-ins from the `ips` involved, even outside the broker, to determine if tokens have been reused elsewhere. + + +*False Positive Analysis* + + +- Developers or IT administrators working across environments may also produce similar behavior. + + +*Response and Remediation* + + +- If confirmed unauthorized, revoke all refresh tokens for the affected user and remove any devices registered during this session. +- Notify the user and determine whether the device join or authentication activity was expected. +- Audit Conditional Access and broker permissions (`29d9ed98-a469-4536-ade2-f981bc1d605e`) to ensure policies enforce strict access controls. +- Consider blocking token-based reauthentication to Microsoft Graph and DRS from suspicious locations or user agents. +- Continue monitoring for follow-on activity like lateral movement or privilege escalation. + + +==== Setup + + + +*Setup* + + +The Office 365 Logs Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-o365.audit-* +| where + event.dataset == "o365.audit" and + event.action == "UserLoggedIn" and + source.ip is not null and + o365.audit.UserId is not null and + o365.audit.ApplicationId is not null and + o365.audit.UserType in ("0", "2", "3", "10") and + o365.audit.ApplicationId in ("aebc6443-996d-45c2-90f0-388ff96faa56", "29d9ed98-a469-4536-ade2-f981bc1d605e") and + o365.audit.ObjectId in ("00000003-0000-0000-c000-000000000000") +| eval + Esql.time_window_date_trunc = date_trunc(30 minutes, @timestamp), + Esql.oauth_authorize_user_id_case = case( + o365.audit.ExtendedProperties.RequestType == "OAuth2:Authorize" and o365.audit.ExtendedProperties.ResultStatusDetail == "Redirect", + o365.audit.UserId, + null + ), + Esql.oauth_token_user_id_case = case( + o365.audit.ExtendedProperties.RequestType == "OAuth2:Token", + o365.audit.UserId, + null + ) +| stats + Esql.source_ip_count_distinct = count_distinct(source.ip), + Esql.source_ip_values = values(source.ip), + Esql.o365_audit_ApplicationId_values = values(o365.audit.ApplicationId), + Esql.source_as_organization_name_values = values(source.`as`.organization.name), + Esql.oauth_token_count_distinct = count_distinct(Esql.oauth_token_user_id_case), + Esql.oauth_authorize_count_distinct = count_distinct(Esql.oauth_authorize_user_id_case) + by + o365.audit.UserId, + Esql.time_window_date_trunc, + o365.audit.ApplicationId, + o365.audit.ObjectId +| keep + Esql.time_window_date_trunc, + Esql.source_ip_values, + Esql.source_ip_count_distinct, + Esql.o365_audit_ApplicationId_values, + Esql.source_as_organization_name_values, + Esql.oauth_token_count_distinct, + Esql.oauth_authorize_count_distinct +| where + Esql.source_ip_count_distinct >= 2 and + Esql.oauth_token_count_distinct > 0 and + Esql.oauth_authorize_count_distinct > 0 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Defense Evasion +** ID: TA0005 +** Reference URL: https://attack.mitre.org/tactics/TA0005/ +* Technique: +** Name: Use Alternate Authentication Material +** ID: T1550 +** Reference URL: https://attack.mitre.org/techniques/T1550/ +* Sub-technique: +** Name: Application Access Token +** ID: T1550.001 +** Reference URL: https://attack.mitre.org/techniques/T1550/001/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-suspicious-microsoft-oauth-flow-via-auth-broker-to-drs.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-suspicious-microsoft-oauth-flow-via-auth-broker-to-drs.asciidoc new file mode 100644 index 0000000000..a243f30e00 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-suspicious-microsoft-oauth-flow-via-auth-broker-to-drs.asciidoc @@ -0,0 +1,227 @@ +[[prebuilt-rule-8-19-4-suspicious-microsoft-oauth-flow-via-auth-broker-to-drs]] +=== Suspicious Microsoft OAuth Flow via Auth Broker to DRS + +Identifies separate OAuth authorization flows in Microsoft Entra ID where the same user principal and session ID are observed across multiple IP addresses within a 5-minute window. These flows involve the Microsoft Authentication Broker (MAB) as the client application and the Device Registration Service (DRS) as the target resource. This pattern is highly indicative of OAuth phishing activity, where an adversary crafts a legitimate Microsoft login URL to trick a user into completing authentication and sharing the resulting authorization code, which is then exchanged for an access and refresh token by the attacker. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: high + +*Risk score*: 73 + +*Runs every*: 60m + +*Searches indices from*: now-61m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://www.volexity.com/blog/2025/04/22/phishing-for-codes-russian-threat-actors-target-microsoft-365-oauth-workflows/ +* https://github.com/dirkjanm/ROADtools +* https://dirkjanm.io/phishing-for-microsoft-entra-primary-refresh-tokens/ + +*Tags*: + +* Domain: Cloud +* Domain: Identity +* Data Source: Azure +* Data Source: Entra ID +* Data Source: Entra ID Sign-in Logs +* Use Case: Identity and Access Audit +* Use Case: Threat Detection +* Resources: Investigation Guide +* Tactic: Initial Access + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Suspicious Microsoft OAuth Flow via Auth Broker to DRS* + + +This rule identifies potential OAuth phishing behavior in Microsoft Entra ID where two OAuth authorization flows are observed in quick succession, sharing the same user principal and session ID but originating from different IP addresses. The client application is the Microsoft Authentication Broker, and the target resource is the Device Registration Service (DRS). This pattern is indicative of adversaries attempting to phish targets for OAuth sessions by tricking users into authenticating through a crafted URL, which then allows the attacker to obtain an authorization code and exchange it for access and refresh tokens. + + +*Possible Investigation Steps:* + + +- `target`: The user principal name targeted by the authentication broker. Investigate whether this user has recently registered a device, signed in from new IPs, or had password resets or MFA changes. +- `session_id`: Used to correlate all events in the OAuth flow. All sign-ins in the alert share the same session, suggesting shared or hijacked state. +- `unique_token_id`: Lists tokens generated in the flow. If multiple IDs exist in the same session, this indicates token issuance from different locations. +- `source_ip`, `city_name`, `country_name`, `region_name`: Review the IPs and geolocations involved. A mismatch in geographic origin within minutes can signal adversary involvement. +- `user_agent`: Conflicting user agents (e.g., `python-requests` and `Chrome`) suggest one leg of the session was scripted or automated. +- `os`: If multiple operating systems are observed in the same short session (e.g., macOS and Windows), this may suggest activity from different environments. +- `incoming_token_type`: Look for values like `"none"` or `"refreshToken"` that can indicate abnormal or re-authenticated activity. +- `token_session_status`: A value of `"unbound"` means the issued token is not tied to a device or CAE session, making it reusable from another IP. +- `conditional_access_status`: If this is `"notApplied"`, it may indicate that expected access policies were not enforced. +- `auth_count`: Number of events in the session. More than one indicates the session was reused within the time window. +- `target_time_window`: Use this to pivot into raw sign-in logs to review the exact sequence and timing of the activity. +- Search `azure.auditlogs` for any device join or registration activity around the `target_time_window`. +- Review `azure.identityprotection` logs for anonymized IPs, impossible travel, or token replay alerts. +- Search for other activity from the same IPs across all users to identify horizontal movement. + + +*False Positive Analysis* + + +- A legitimate device join from a user switching networks (e.g., mobile hotspot to Wi-Fi) could explain multi-IP usage. +- Some identity management agents or EDR tools may use MAB for background device registration flows. +- Developers or IT administrators may access DRS across environments when testing. + + +*Response and Remediation* + + +- If confirmed unauthorized, revoke all refresh tokens for the user and disable any suspicious registered devices. +- Notify the user and verify if the authentication or device join was expected. +- Review Conditional Access policies for the Microsoft Authentication Broker (`29d9ed98-a469-4536-ade2-f981bc1d605e`) to ensure enforcement of MFA and device trust. +- Consider restricting token-based reauthentication from anonymized infrastructure or unusual user agents. +- Continue monitoring for follow-on activity, such as privilege escalation, token misuse, or lateral movement. + + +==== Setup + + + +*Required Microsoft Entra ID Sign-In Logs* + +This rule requires the Microsoft Entra ID Sign-In Logs integration be enabled and configured to collect sign-in logs. In Entra ID, sign-in logs must be enabled and streaming to the Event Hub used for the Azure integration. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-azure.signinlogs* metadata _id, _version, _index +| where + event.dataset == "azure.signinlogs" and + event.outcome == "success" and + azure.signinlogs.properties.user_type == "Member" and + azure.signinlogs.identity is not null and + azure.signinlogs.properties.user_principal_name is not null and + source.address is not null and + azure.signinlogs.properties.app_id == "29d9ed98-a469-4536-ade2-f981bc1d605e" and // MAB + azure.signinlogs.properties.resource_id == "01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9" // DRS + +| eval + Esql.time_window_date_trunc = date_trunc(30 minutes, @timestamp), + Esql.azure_signinlogs_properties_session_id = azure.signinlogs.properties.session_id, + Esql.is_browser_case = case( + to_lower(azure.signinlogs.properties.device_detail.browser) rlike "(chrome|firefox|edge|safari).*", 1, 0 + ) + +| stats + Esql_priv.azure_signinlogs_properties_user_display_name_values = values(azure.signinlogs.properties.user_display_name), + Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name), + Esql.azure_signinlogs_properties_session_id_values = values(azure.signinlogs.properties.session_id), + Esql.azure_signinlogs_properties_unique_token_identifier_values = values(azure.signinlogs.properties.unique_token_identifier), + + Esql.source_geo_city_name_values = values(source.geo.city_name), + Esql.source_geo_country_name_values = values(source.geo.country_name), + Esql.source_geo_region_name_values = values(source.geo.region_name), + Esql.source_address_values = values(source.address), + Esql.source_address_count_distinct = count_distinct(source.address), + Esql.source_as_organization_name_values = values(source.`as`.organization.name), + + Esql.azure_signinlogs_properties_authentication_protocol_values = values(azure.signinlogs.properties.authentication_protocol), + Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement), + Esql.azure_signinlogs_properties_is_interactive_values = values(azure.signinlogs.properties.is_interactive), + + Esql.azure_signinlogs_properties_incoming_token_type_values = values(azure.signinlogs.properties.incoming_token_type), + Esql.azure_signinlogs_properties_token_protection_status_details_sign_in_session_status_values = values(azure.signinlogs.properties.token_protection_status_details.sign_in_session_status), + Esql.azure_signinlogs_properties_session_id_count_distinct = count_distinct(azure.signinlogs.properties.session_id), + Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name), + Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id), + Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id), + Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name), + + Esql.azure_signinlogs_properties_app_owner_tenant_id_values = values(azure.signinlogs.properties.app_owner_tenant_id), + Esql.azure_signinlogs_properties_resource_owner_tenant_id_values = values(azure.signinlogs.properties.resource_owner_tenant_id), + + Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status), + Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state), + Esql.azure_signinlogs_properties_risk_level_aggregated_values = values(azure.signinlogs.properties.risk_level_aggregated), + + Esql.azure_signinlogs_properties_device_detail_browser_values = values(azure.signinlogs.properties.device_detail.browser), + Esql.azure_signinlogs_properties_device_detail_operating_system_values = values(azure.signinlogs.properties.device_detail.operating_system), + Esql.user_agent_original_values = values(user_agent.original), + Esql.is_browser_case_max = max(Esql.is_browser_case), + + Esql.event_count = count(*) + by + Esql.time_window_date_trunc, + azure.signinlogs.properties.user_principal_name, + azure.signinlogs.properties.session_id + +| keep + Esql.time_window_date_trunc, + Esql_priv.azure_signinlogs_properties_user_display_name_values, + Esql_priv.azure_signinlogs_properties_user_principal_name_values, + Esql.azure_signinlogs_properties_session_id_values, + Esql.azure_signinlogs_properties_unique_token_identifier_values, + Esql.source_geo_city_name_values, + Esql.source_geo_country_name_values, + Esql.source_geo_region_name_values, + Esql.source_address_values, + Esql.source_address_count_distinct, + Esql.source_as_organization_name_values, + Esql.azure_signinlogs_properties_authentication_protocol_values, + Esql.azure_signinlogs_properties_authentication_requirement_values, + Esql.azure_signinlogs_properties_is_interactive_values, + Esql.azure_signinlogs_properties_incoming_token_type_values, + Esql.azure_signinlogs_properties_token_protection_status_details_sign_in_session_status_values, + Esql.azure_signinlogs_properties_session_id_count_distinct, + Esql.azure_signinlogs_properties_app_display_name_values, + Esql.azure_signinlogs_properties_app_id_values, + Esql.azure_signinlogs_properties_resource_id_values, + Esql.azure_signinlogs_properties_resource_display_name_values, + Esql.azure_signinlogs_properties_app_owner_tenant_id_values, + Esql.azure_signinlogs_properties_resource_owner_tenant_id_values, + Esql.azure_signinlogs_properties_conditional_access_status_values, + Esql.azure_signinlogs_properties_risk_state_values, + Esql.azure_signinlogs_properties_risk_level_aggregated_values, + Esql.azure_signinlogs_properties_device_detail_browser_values, + Esql.azure_signinlogs_properties_device_detail_operating_system_values, + Esql.user_agent_original_values, + Esql.is_browser_case_max, + Esql.event_count + +| where + Esql.source_address_count_distinct >= 2 and + Esql.azure_signinlogs_properties_session_id_count_distinct == 1 and + Esql.is_browser_case_max >= 1 and + Esql.event_count >= 2 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Initial Access +** ID: TA0001 +** Reference URL: https://attack.mitre.org/tactics/TA0001/ +* Technique: +** Name: Phishing +** ID: T1566 +** Reference URL: https://attack.mitre.org/techniques/T1566/ +* Sub-technique: +** Name: Spearphishing Link +** ID: T1566.002 +** Reference URL: https://attack.mitre.org/techniques/T1566/002/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-base64-encoding-decoding-activity.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-base64-encoding-decoding-activity.asciidoc new file mode 100644 index 0000000000..6f9a39850d --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-base64-encoding-decoding-activity.asciidoc @@ -0,0 +1,228 @@ +[[prebuilt-rule-8-19-4-unusual-base64-encoding-decoding-activity]] +=== Unusual Base64 Encoding/Decoding Activity + +This rule leverages ESQL to detect unusual base64 encoding/decoding activity on Linux systems. Attackers may use base64 encoding/decoding to obfuscate data, such as command and control traffic or payloads, to evade detection by host- or network-based security controls. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 1h + +*Searches indices from*: now-61m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Linux +* Use Case: Threat Detection +* Tactic: Defense Evasion +* Data Source: Elastic Defend +* Resources: Investigation Guide + +*Version*: 5 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + +> **Disclaimer**: +> 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. + + +*Investigating Unusual Base64 Encoding/Decoding Activity* + +Base64 encoding is a method to convert binary data into ASCII text, often used for data transmission. Adversaries exploit this to obfuscate malicious payloads or commands, bypassing security controls. The detection rule identifies suspicious Base64 activity on Linux by monitoring specific processes and command patterns, flagging anomalies for further investigation. + + +*Possible investigation steps* + + +- Review the process name and command line arguments to understand the context of the Base64 activity. Check if the process name matches known legitimate applications or scripts. +- Examine the timestamp of the event to determine if the activity occurred during normal operational hours or if it coincides with other suspicious activities. +- Investigate the host operating system type and agent ID to identify the specific Linux system involved and assess if it has a history of similar alerts or other security incidents. +- Analyze the process command line for any unusual patterns or parameters that might indicate obfuscation or malicious intent, such as the presence of decode flags or unexpected Base64 operations. +- Correlate the event with other logs or alerts from the same host or network to identify potential lateral movement or coordinated attacks. +- Check for any recent changes or deployments on the affected system that might explain the Base64 activity, such as new software installations or updates. +- Consult threat intelligence sources to determine if the observed Base64 patterns or command line arguments are associated with known malware or attack techniques. + + +*False positive analysis* + + +- Routine administrative scripts may use base64 encoding for legitimate data processing tasks. Review the process.command_line and process.args fields to identify known scripts and consider excluding them from the rule. +- Backup or data transfer operations might employ base64 encoding to handle binary data. Verify the process.name and process.command_line to ensure these operations are recognized and add exceptions for these specific processes. +- Development environments often use base64 encoding for testing purposes. Identify development-related processes by examining the process.name and process.command_line and exclude them if they are part of regular development activities. +- Automated system monitoring tools might trigger this rule if they use base64 encoding for log or data analysis. Check the agent.id and process.command_line to confirm these tools and exclude them from the rule if they are verified as non-threatening. +- Security tools that perform data encoding for analysis or reporting could be flagged. Validate these tools by reviewing the process.name and process.command_line and create exceptions for them if they are part of the security infrastructure. + + +*Response and remediation* + + +- Isolate the affected Linux system from the network to prevent further data exfiltration or lateral movement by the adversary. +- Terminate any suspicious processes identified by the alert, particularly those involving base64 encoding/decoding, to halt potential malicious activity. +- Conduct a thorough review of the process command lines and arguments flagged by the alert to identify any malicious scripts or payloads. Remove or quarantine these files as necessary. +- Check for any unauthorized user accounts or privilege escalations that may have been established during the attack and revoke access immediately. +- Restore any affected systems or files from a known good backup to ensure the integrity of the system and data. +- Implement additional monitoring on the affected system and similar environments to detect any recurrence of the suspicious base64 activity. +- Escalate the incident to the security operations center (SOC) or incident response team for further analysis and to determine if broader organizational impacts exist. + + +==== Setup + + + +*Setup* + + +This rule requires data coming in from one of the following integrations: +- Elastic Defend + + +*Elastic Defend Integration Setup* + +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. + + +*Prerequisite Requirements:* + +- Fleet is required for Elastic Defend. +- To configure Fleet Server refer to the https://www.elastic.co/guide/en/fleet/current/fleet-server.html[documentation]. + + +*The following steps should be executed in order to add the Elastic Defend integration on a Linux System:* + +- Go to the Kibana home page and click "Add integrations". +- In the query bar, search for "Elastic Defend" and select the integration to see more details about it. +- Click "Add Elastic Defend". +- Configure the integration name and optionally add a description. +- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads". +- 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. https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html[Helper guide]. +- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions" +- 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. +For more details on Elastic Agent configuration settings, refer to the https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html[helper guide]. +- Click "Save and Continue". +- 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 https://www.elastic.co/guide/en/security/current/install-endpoint.html[helper guide]. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-endpoint.events.process-* +| where + @timestamp > now() - 1h and + host.os.type == "linux" and + event.type == "start" and + event.action == "exec" and ( + ( + process.name in ("base64", "base64plain", "base64url", "base64mime", "base64pem", "base32", "base16") and + process.command_line like "*-*d*" + ) or + ( + process.name == "openssl" and + process.args == "enc" and + process.args in ("-d", "-base64", "-a") + ) or + ( + process.name like "python*" and ( + ( + process.args == "base64" and + process.args in ("-d", "-u", "-t") + ) or + ( + process.args == "-c" and + process.command_line like "*base64*" and + process.command_line like "*b64decode*" + ) + ) + ) or + ( + process.name like "perl*" and + process.command_line like "*decode_base64*" + ) or + ( + process.name like "ruby*" and + process.args == "-e" and + process.command_line like "*Base64.decode64*" + ) + ) +| keep + @timestamp, + host.os.type, + event.type, + event.action, + process.name, + process.args, + process.command_line, + agent.id, + host.name +| stats + Esql.event_count = count(), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.name, process.command_line +| where + Esql.agent_id_count_distinct == 1 and + Esql.event_count < 15 +| sort Esql.event_count asc +| limit 100 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Defense Evasion +** ID: TA0005 +** Reference URL: https://attack.mitre.org/tactics/TA0005/ +* Technique: +** Name: Obfuscated Files or Information +** ID: T1027 +** Reference URL: https://attack.mitre.org/techniques/T1027/ +* Technique: +** Name: Deobfuscate/Decode Files or Information +** ID: T1140 +** Reference URL: https://attack.mitre.org/techniques/T1140/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: Unix Shell +** ID: T1059.004 +** Reference URL: https://attack.mitre.org/techniques/T1059/004/ +* Technique: +** Name: User Execution +** ID: T1204 +** Reference URL: https://attack.mitre.org/techniques/T1204/ +* Sub-technique: +** Name: Malicious File +** ID: T1204.002 +** Reference URL: https://attack.mitre.org/techniques/T1204/002/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-command-execution-from-web-server-parent.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-command-execution-from-web-server-parent.asciidoc new file mode 100644 index 0000000000..0d71390ca1 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-command-execution-from-web-server-parent.asciidoc @@ -0,0 +1,228 @@ +[[prebuilt-rule-8-19-4-unusual-command-execution-from-web-server-parent]] +=== Unusual Command Execution from Web Server Parent + +This rule detects potential command execution from a web server parent process on a Linux host. Adversaries may attempt to execute commands from a web server parent process to blend in with normal web server activity and evade detection. This behavior is commonly observed in web shell attacks where adversaries exploit web server vulnerabilities to execute arbitrary commands on the host. The detection rule identifies unusual command execution from web server parent processes, which may indicate a compromised host or an ongoing attack. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 1h + +*Searches indices from*: now-61m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Linux +* Use Case: Threat Detection +* Tactic: Persistence +* Tactic: Execution +* Tactic: Command and Control +* Data Source: Elastic Defend +* Resources: Investigation Guide + +*Version*: 5 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Unusual Command Execution from Web Server Parent* + + +Web servers, such as Apache or Nginx, are crucial for hosting web applications, often running on Linux systems. Adversaries exploit vulnerabilities in these servers to execute arbitrary commands, typically through web shells, blending malicious activity with legitimate server processes. The detection rule identifies suspicious command executions originating from web server processes, focusing on unusual patterns and contexts, such as unexpected working directories or command structures, to flag potential compromises. + + +*Possible investigation steps* + + +- Review the process.command_line field to understand the specific command executed and assess its legitimacy or potential malicious intent. +- Examine the process.working_directory to determine if the command was executed from an unusual or suspicious directory, which could indicate a compromise. +- Check the process.parent.executable and process.parent.name fields to identify the parent process and verify if it is a known web server or related service that could be exploited. +- Investigate the user.name and user.id fields to confirm if the command was executed by a legitimate user or service account, or if it was potentially executed by an unauthorized user. +- Correlate the @timestamp with other logs and events to identify any related activities or anomalies occurring around the same time, which could provide additional context or evidence of an attack. +- Assess the agent.id to determine if the alert is isolated to a single host or if similar activities are observed across multiple hosts, indicating a broader issue. + + +*False positive analysis* + + +- Web development or testing environments may frequently execute commands from web server processes. To handle this, exclude specific working directories like /var/www/dev or /var/www/test from the rule. +- Automated scripts or cron jobs running under web server user accounts can trigger alerts. Identify these scripts and add exceptions for their specific command lines or user IDs. +- Legitimate administrative tasks performed by web server administrators might appear suspicious. Document these tasks and exclude their associated command lines or parent executables. +- Continuous integration or deployment processes that involve web server interactions can be mistaken for threats. Exclude known CI/CD tool command lines or working directories from the rule. +- Monitoring or logging tools that interact with web server processes may generate false positives. Identify these tools and exclude their specific process names or parent executables. + + +*Response and remediation* + + +- Isolate the affected host immediately to prevent further malicious activity and lateral movement within the network. This can be done by removing the host from the network or applying network segmentation. + +- Terminate any suspicious processes identified by the detection rule, especially those originating from web server parent processes executing shell commands. Use process IDs and command lines from the alert to target specific processes. + +- Conduct a thorough review of the web server logs and application logs to identify any unauthorized access or modifications. Look for patterns that match the command execution detected and any other anomalies. + +- Patch the web server and any associated applications to address known vulnerabilities that may have been exploited. Ensure that all software is up to date with the latest security patches. + +- Restore the affected system from a known good backup if any unauthorized changes or persistent threats are detected. Ensure that the backup is free from compromise before restoration. + +- Implement additional monitoring and alerting for similar activities, focusing on unusual command executions and web server behavior. Enhance logging and alerting to capture more detailed information about process executions and network connections. + +- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if the attack is part of a larger campaign. Provide them with all relevant data and findings from the initial containment and remediation steps. + + +==== Setup + + + +*Setup* + + +This rule requires data coming in from Elastic Defend. + + +*Elastic Defend Integration Setup* + +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. + + +*Prerequisite Requirements:* + +- Fleet is required for Elastic Defend. +- To configure Fleet Server refer to the https://www.elastic.co/guide/en/fleet/current/fleet-server.html[documentation]. + + +*The following steps should be executed in order to add the Elastic Defend integration on a Linux System:* + +- Go to the Kibana home page and click "Add integrations". +- In the query bar, search for "Elastic Defend" and select the integration to see more details about it. +- Click "Add Elastic Defend". +- Configure the integration name and optionally add a description. +- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads". +- 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. https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html[Helper guide]. +- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions" +- 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. +For more details on Elastic Agent configuration settings, refer to the https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html[helper guide]. +- Click "Save and Continue". +- 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 https://www.elastic.co/guide/en/security/current/install-endpoint.html[helper guide]. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-endpoint.events.process-* +| keep + @timestamp, + host.os.type, + event.type, + event.action, + process.parent.name, + user.name, + user.id, + process.working_directory, + process.name, + process.command_line, + process.parent.executable, + agent.id, + host.name +| where + @timestamp > now() - 1 hours and + host.os.type == "linux" and + event.type == "start" and + event.action == "exec" and ( + process.parent.name in ( + "apache", "nginx", "apache2", "httpd", "lighttpd", "caddy", "node", "mongrel_rails", "java", "gunicorn", + "uwsgi", "openresty", "cherokee", "h2o", "resin", "puma", "unicorn", "traefik", "tornado", "hypercorn", + "daphne", "twistd", "yaws", "webfsd", "httpd.worker", "flask", "rails", "mongrel" + ) or + process.parent.name like "php-*" or + process.parent.name like "python*" or + process.parent.name like "ruby*" or + process.parent.name like "perl*" or + user.name in ( + "apache", "www-data", "httpd", "nginx", "lighttpd", "tomcat", "tomcat8", "tomcat9", "ftp", "ftpuser", "ftpd" + ) or + user.id in ("99", "33", "498", "48") or + process.working_directory like "/var/www/*" + ) and + process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and + process.command_line like "* -c *" and not ( + process.working_directory like "/home/*" or + process.working_directory == "/" or + process.working_directory like "/vscode/vscode-server/*" or + process.parent.executable like "/vscode/vscode-server/*" or + process.parent.executable == "/usr/bin/xfce4-terminal" + ) +| stats + Esql.event_count = count(), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.command_line, process.working_directory, process.parent.executable +| where + Esql.agent_id_count_distinct == 1 and + Esql.event_count < 5 +| sort Esql.event_count asc +| limit 100 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Persistence +** ID: TA0003 +** Reference URL: https://attack.mitre.org/tactics/TA0003/ +* Technique: +** Name: Server Software Component +** ID: T1505 +** Reference URL: https://attack.mitre.org/techniques/T1505/ +* Sub-technique: +** Name: Web Shell +** ID: T1505.003 +** Reference URL: https://attack.mitre.org/techniques/T1505/003/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: Unix Shell +** ID: T1059.004 +** Reference URL: https://attack.mitre.org/techniques/T1059/004/ +* Tactic: +** Name: Command and Control +** ID: TA0011 +** Reference URL: https://attack.mitre.org/tactics/TA0011/ +* Technique: +** Name: Application Layer Protocol +** ID: T1071 +** Reference URL: https://attack.mitre.org/techniques/T1071/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-file-transfer-utility-launched.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-file-transfer-utility-launched.asciidoc new file mode 100644 index 0000000000..0342de60aa --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-file-transfer-utility-launched.asciidoc @@ -0,0 +1,162 @@ +[[prebuilt-rule-8-19-4-unusual-file-transfer-utility-launched]] +=== Unusual File Transfer Utility Launched + +This rule leverages ESQL to detect the execution of unusual file transfer utilities on Linux systems. Attackers may use these utilities to exfiltrate data from a compromised system. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: low + +*Risk score*: 21 + +*Runs every*: 1h + +*Searches indices from*: now-61m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Linux +* Use Case: Threat Detection +* Tactic: Exfiltration +* Tactic: Execution +* Data Source: Elastic Defend +* Resources: Investigation Guide + +*Version*: 5 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Unusual File Transfer Utility Launched* + + +File transfer utilities like scp, ftp, and rsync are essential for data movement in Linux environments. However, adversaries can exploit these tools to exfiltrate sensitive data. The detection rule identifies suspicious executions of these utilities by monitoring process activities, focusing on rare occurrences and unique agent IDs, which may indicate unauthorized data transfers. This helps in early detection of potential data breaches. + + +*Possible investigation steps* + + +- Review the process.command_line field to understand the exact command executed and assess if it aligns with typical usage patterns or if it appears suspicious. +- Examine the process.parent.executable field to determine the parent process that initiated the file transfer utility, which may provide insights into whether the execution was part of a legitimate workflow or potentially malicious activity. +- Check the agent.id field to identify the specific host involved in the alert and correlate it with other security events or logs from the same host to gather additional context. +- Investigate the @timestamp field to verify the timing of the event and cross-reference with any known scheduled tasks or user activities that could explain the execution. +- Analyze the host.os.type field to confirm the operating system and ensure that the alert pertains to a Linux environment, as expected by the rule. + + +*False positive analysis* + + +- Routine administrative tasks using file transfer utilities may trigger alerts. Regularly scheduled backups or updates using scp, rsync, or ftp should be documented and excluded from alerts by creating exceptions for known scripts or cron jobs. +- Automated system updates or patches that utilize these utilities can be mistaken for suspicious activity. Identify and whitelist the processes and command lines associated with these updates to prevent false positives. +- Internal data transfers between trusted servers for legitimate business purposes might be flagged. Establish a list of trusted agent IDs and exclude them from the rule to avoid unnecessary alerts. +- Development and testing environments often use these utilities for transferring test data. Ensure that these environments are recognized and excluded by specifying their hostnames or IP addresses in the rule configuration. +- User-initiated file transfers for legitimate reasons, such as data analysis or reporting, can be misinterpreted. Educate users to notify the security team of such activities in advance, allowing for temporary exceptions to be made. + + +*Response and remediation* + + +- Immediately isolate the affected Linux system from the network to prevent further data exfiltration and unauthorized access. +- Terminate any suspicious file transfer processes identified by the alert, such as scp, ftp, or rsync, to halt ongoing data transfers. +- Conduct a thorough review of the process command lines and parent executables to identify any malicious scripts or unauthorized software that initiated the file transfer. +- Change credentials and access keys associated with the compromised system to prevent further unauthorized access. +- Escalate the incident to the security operations team for a deeper forensic analysis to determine the extent of the breach and identify any additional compromised systems. +- Implement network monitoring to detect any further attempts of unauthorized file transfers or suspicious activities from the affected system. +- Update and enhance endpoint detection and response (EDR) solutions to improve detection capabilities for similar threats in the future. + + +==== Setup + + + +*Setup* + + +This rule requires data coming in from one of the following integrations: +- Elastic Defend + + +*Elastic Defend Integration Setup* + +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. + + +*Prerequisite Requirements:* + +- Fleet is required for Elastic Defend. +- To configure Fleet Server refer to the https://www.elastic.co/guide/en/fleet/current/fleet-server.html[documentation]. + + +*The following steps should be executed in order to add the Elastic Defend integration on a Linux System:* + +- Go to the Kibana home page and click "Add integrations". +- In the query bar, search for "Elastic Defend" and select the integration to see more details about it. +- Click "Add Elastic Defend". +- Configure the integration name and optionally add a description. +- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads". +- 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. https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html[Helper guide]. +- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions" +- 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. +For more details on Elastic Agent configuration settings, refer to the https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html[helper guide]. +- Click "Save and Continue". +- 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 https://www.elastic.co/guide/en/security/current/install-endpoint.html[helper guide]. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-endpoint.events.process-* +| keep @timestamp, host.os.type, event.type, event.action, process.name, process.executable, process.parent.executable, process.command_line, agent.id, host.name +| where + @timestamp > now() - 1 hours and + host.os.type == "linux" and + event.type == "start" and + event.action == "exec" and + process.name in ("scp", "ftp", "sftp", "vsftpd", "sftp-server", "rsync") +| stats + Esql.event_count = count(), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.executable, process.parent.executable, process.command_line +| where + Esql.agent_id_count_distinct == 1 and + Esql.event_count < 5 +| sort Esql.event_count asc +| limit 100 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Exfiltration +** ID: TA0010 +** Reference URL: https://attack.mitre.org/tactics/TA0010/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-high-confidence-content-filter-blocks-detected.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-high-confidence-content-filter-blocks-detected.asciidoc new file mode 100644 index 0000000000..6637ae9471 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-high-confidence-content-filter-blocks-detected.asciidoc @@ -0,0 +1,150 @@ +[[prebuilt-rule-8-19-4-unusual-high-confidence-content-filter-blocks-detected]] +=== Unusual High Confidence Content Filter Blocks Detected + +Detects repeated high-confidence 'BLOCKED' actions coupled with specific 'Content Filter' policy violation having codes such as 'MISCONDUCT', 'HATE', 'SEXUAL', INSULTS', 'PROMPT_ATTACK', 'VIOLENCE' indicating persistent misuse or attempts to probe the model's ethical boundaries. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 10m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-components.html +* https://atlas.mitre.org/techniques/AML.T0051 +* https://atlas.mitre.org/techniques/AML.T0054 +* https://www.elastic.co/security-labs/elastic-advances-llm-security + +*Tags*: + +* Domain: LLM +* Data Source: AWS Bedrock +* Data Source: AWS S3 +* Use Case: Policy Violation +* Mitre Atlas: T0051 +* Mitre Atlas: T0054 +* Resources: Investigation Guide + +*Version*: 7 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Unusual High Confidence Content Filter Blocks Detected* + + +Amazon Bedrock Guardrail is a set of features within Amazon Bedrock designed to help businesses apply robust safety and privacy controls to their generative AI applications. + +It enables users to set guidelines and filters that manage content quality, relevancy, and adherence to responsible AI practices. + +Through Guardrail, organizations can enable Content filter for Hate, Insults, Sexual Violence and Misconduct along with Prompt Attack filters prompts +to prevent the model from generating content on specific, undesired subjects, and they can establish thresholds for harmful content categories. + + +*Possible investigation steps* + + +- Identify the user account whose prompts caused high confidence content filter blocks and whether it should perform this kind of action. +- Investigate other alerts associated with the user account during the past 48 hours. +- Consider the time of day. If the user is a human (not a program or script), did the activity take place during a normal time of day? +- Examine the account's prompts and responses in the last 24 hours. +- If you suspect the account has been compromised, scope potentially compromised assets by tracking Amazon Bedrock model access, prompts generated, and responses to the prompts by the account in the last 24 hours. + + +*False positive analysis* + + +- Verify the user account that queried denied topics, is not testing any new model deployments or updated compliance policies in Amazon Bedrock guardrails. + + +*Response and remediation* + + +- Initiate the incident response process based on the outcome of the triage. +- Disable or limit the account during the investigation and response. +- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context: + - Identify the account role in the cloud environment. + - Identify if the attacker is moving laterally and compromising other Amazon Bedrock Services. + - Identify any regulatory or legal ramifications related to this activity. +- Review the permissions assigned to the implicated user group or role behind these requests to ensure they are authorized and expected to access bedrock and ensure that the least privilege principle is being followed. +- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector. +- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR). + + +==== Setup + + + +*Setup* + + +This rule requires that guardrails are configured in AWS Bedrock. For more information, see the AWS Bedrock documentation: + +https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws_bedrock.invocation-* + +// Expand multi-value fields +| mv_expand gen_ai.compliance.violation_code +| mv_expand gen_ai.policy.confidence +| mv_expand gen_ai.policy.name + +// Filter for high-confidence content policy blocks with targeted violations +| where + gen_ai.policy.action == "BLOCKED" + and gen_ai.policy.name == "content_policy" + and gen_ai.policy.confidence like "HIGH" + and gen_ai.compliance.violation_code in ("HATE", "MISCONDUCT", "SEXUAL", "INSULTS", "PROMPT_ATTACK", "VIOLENCE") + +// keep ECS + compliance fields +| keep + user.id, + gen_ai.compliance.violation_code + +// count blocked violations per user per violation type +| stats + Esql.ml_policy_blocked_violation_count = count() + by + user.id, + gen_ai.compliance.violation_code + +// Aggregate all violation types per user +| stats + Esql.ml_policy_blocked_violation_total_count = sum(Esql.ml_policy_blocked_violation_count) + by + user.id + +// Filter for users with more than 5 total violations +| where Esql.ml_policy_blocked_violation_total_count > 5 + +// sort by violation volume +| sort Esql.ml_policy_blocked_violation_total_count desc + +---------------------------------- diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-high-denied-sensitive-information-policy-blocks-detected.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-high-denied-sensitive-information-policy-blocks-detected.asciidoc new file mode 100644 index 0000000000..c585377c78 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-high-denied-sensitive-information-policy-blocks-detected.asciidoc @@ -0,0 +1,137 @@ +[[prebuilt-rule-8-19-4-unusual-high-denied-sensitive-information-policy-blocks-detected]] +=== Unusual High Denied Sensitive Information Policy Blocks Detected + +Detects repeated compliance violation 'BLOCKED' actions coupled with specific policy name such as 'sensitive_information_policy', indicating persistent misuse or attempts to probe the model's denied topics. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 10m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-components.html +* https://atlas.mitre.org/techniques/AML.T0051 +* https://atlas.mitre.org/techniques/AML.T0054 +* https://www.elastic.co/security-labs/elastic-advances-llm-security + +*Tags*: + +* Domain: LLM +* Data Source: AWS Bedrock +* Data Source: AWS S3 +* Use Case: Policy Violation +* Mitre Atlas: T0051 +* Mitre Atlas: T0054 +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Unusual High Denied Sensitive Information Policy Blocks Detected* + + +Amazon Bedrock Guardrail is a set of features within Amazon Bedrock designed to help businesses apply robust safety and privacy controls to their generative AI applications. + +It enables users to set guidelines and filters that manage content quality, relevancy, and adherence to responsible AI practices. + +Through Guardrail, organizations can define "sensitive information filters" to prevent the model from generating content on specific, undesired subjects, +and they can establish thresholds for harmful content categories. + + +*Possible investigation steps* + + +- Identify the user account that queried sensitive information and whether it should perform this kind of action. +- Investigate other alerts associated with the user account during the past 48 hours. +- Consider the time of day. If the user is a human (not a program or script), did the activity take place during a normal time of day? +- Examine the account's prompts and responses in the last 24 hours. +- If you suspect the account has been compromised, scope potentially compromised assets by tracking Amazon Bedrock model access, prompts generated, and responses to the prompts by the account in the last 24 hours. + + +*False positive analysis* + + +- Verify the user account that queried denied topics, is not testing any new model deployments or updated compliance policies in Amazon Bedrock guardrails. + + +*Response and remediation* + + +- Initiate the incident response process based on the outcome of the triage. +- Disable or limit the account during the investigation and response. +- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context: + - Identify the account role in the cloud environment. + - Identify if the attacker is moving laterally and compromising other Amazon Bedrock Services. + - Identify any regulatory or legal ramifications related to this activity. +- Review the permissions assigned to the implicated user group or role behind these requests to ensure they are authorized and expected to access bedrock and ensure that the least privilege principle is being followed. +- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector. +- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR). + + +==== Setup + + + +*Setup* + + +This rule requires that guardrails are configured in AWS Bedrock. For more information, see the AWS Bedrock documentation: + +https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws_bedrock.invocation-* + +// Expand multi-valued policy name field +| mv_expand gen_ai.policy.name + +// Filter for blocked actions related to sensitive info policy +| where + gen_ai.policy.action == "BLOCKED" + and gen_ai.compliance.violation_detected == "true" + and gen_ai.policy.name == "sensitive_information_policy" + +// keep only relevant fields +| keep user.id + +// count how many times each user triggered a sensitive info block +| stats + Esql.ml_policy_blocked_sensitive_info_count = count() + by user.id + +// Filter for users with more than 5 violations +| where Esql.ml_policy_blocked_sensitive_info_count > 5 + +// sort highest to lowest +| sort Esql.ml_policy_blocked_sensitive_info_count desc + +---------------------------------- diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-high-denied-topic-blocks-detected.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-high-denied-topic-blocks-detected.asciidoc new file mode 100644 index 0000000000..7f40d19e4b --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-high-denied-topic-blocks-detected.asciidoc @@ -0,0 +1,137 @@ +[[prebuilt-rule-8-19-4-unusual-high-denied-topic-blocks-detected]] +=== Unusual High Denied Topic Blocks Detected + +Detects repeated compliance violation 'BLOCKED' actions coupled with specific policy name such as 'topic_policy', indicating persistent misuse or attempts to probe the model's denied topics. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 10m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-components.html +* https://atlas.mitre.org/techniques/AML.T0051 +* https://atlas.mitre.org/techniques/AML.T0054 +* https://www.elastic.co/security-labs/elastic-advances-llm-security + +*Tags*: + +* Domain: LLM +* Data Source: AWS Bedrock +* Data Source: AWS S3 +* Use Case: Policy Violation +* Mitre Atlas: T0051 +* Mitre Atlas: T0054 +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Unusual High Denied Topic Blocks Detected* + + +Amazon Bedrock Guardrail is a set of features within Amazon Bedrock designed to help businesses apply robust safety and privacy controls to their generative AI applications. + +It enables users to set guidelines and filters that manage content quality, relevancy, and adherence to responsible AI practices. + +Through Guardrail, organizations can define "denied topics" to prevent the model from generating content on specific, undesired subjects, +and they can establish thresholds for harmful content categories, including hate speech, violence, or offensive language. + + +*Possible investigation steps* + + +- Identify the user account that queried denied topics and whether it should perform this kind of action. +- Investigate other alerts associated with the user account during the past 48 hours. +- Consider the time of day. If the user is a human (not a program or script), did the activity take place during a normal time of day? +- Examine the account's prompts and responses in the last 24 hours. +- If you suspect the account has been compromised, scope potentially compromised assets by tracking Amazon Bedrock model access, prompts generated, and responses to the prompts by the account in the last 24 hours. + + +*False positive analysis* + + +- Verify the user account that queried denied topics, is not testing any new model deployments or updated compliance policies in Amazon Bedrock guardrails. + + +*Response and remediation* + + +- Initiate the incident response process based on the outcome of the triage. +- Disable or limit the account during the investigation and response. +- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context: + - Identify the account role in the cloud environment. + - Identify if the attacker is moving laterally and compromising other Amazon Bedrock Services. + - Identify any regulatory or legal ramifications related to this activity. +- Review the permissions assigned to the implicated user group or role behind these requests to ensure they are authorized and expected to access bedrock and ensure that the least privilege principle is being followed. +- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector. +- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR). + + +==== Setup + + + +*Setup* + + +This rule requires that guardrails are configured in AWS Bedrock. For more information, see the AWS Bedrock documentation: + +https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws_bedrock.invocation-* + +// Expand multi-value policy name field +| mv_expand gen_ai.policy.name + +// Filter for blocked topic policy violations +| where + gen_ai.policy.action == "BLOCKED" + and gen_ai.compliance.violation_detected == "true" + and gen_ai.policy.name == "topic_policy" + +// keep only user info +| keep user.id + +// count how many times each user triggered a blocked topic policy +| stats + Esql.ml_policy_blocked_topic_count = count() + by user.id + +// Filter for excessive violations +| where Esql.ml_policy_blocked_topic_count > 5 + +// sort highest to lowest +| sort Esql.ml_policy_blocked_topic_count desc + +---------------------------------- diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-high-word-policy-blocks-detected.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-high-word-policy-blocks-detected.asciidoc new file mode 100644 index 0000000000..ef5d584afc --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-high-word-policy-blocks-detected.asciidoc @@ -0,0 +1,137 @@ +[[prebuilt-rule-8-19-4-unusual-high-word-policy-blocks-detected]] +=== Unusual High Word Policy Blocks Detected + +Detects repeated compliance violation 'BLOCKED' actions coupled with specific policy name such as 'word_policy', indicating persistent misuse or attempts to probe the model's denied topics. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 10m + +*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: + +* https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-components.html +* https://atlas.mitre.org/techniques/AML.T0051 +* https://atlas.mitre.org/techniques/AML.T0054 +* https://www.elastic.co/security-labs/elastic-advances-llm-security + +*Tags*: + +* Domain: LLM +* Data Source: AWS Bedrock +* Data Source: AWS S3 +* Use Case: Policy Violation +* Mitre Atlas: T0051 +* Mitre Atlas: T0054 +* Resources: Investigation Guide + +*Version*: 3 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + +*Triage and analysis* + + + +*Investigating Unusual High Word Policy Blocks Detected* + + +Amazon Bedrock Guardrail is a set of features within Amazon Bedrock designed to help businesses apply robust safety and privacy controls to their generative AI applications. + +It enables users to set guidelines and filters that manage content quality, relevancy, and adherence to responsible AI practices. + +Through Guardrail, organizations can define "word filters" to prevent the model from generating content on profanity, undesired subjects, +and they can establish thresholds for harmful content categories, including hate speech, violence, or offensive language. + + +*Possible investigation steps* + + +- Identify the user account whose prompts contained profanity and whether it should perform this kind of action. +- Investigate other alerts associated with the user account during the past 48 hours. +- Consider the time of day. If the user is a human (not a program or script), did the activity take place during a normal time of day? +- Examine the account's prompts and responses in the last 24 hours. +- If you suspect the account has been compromised, scope potentially compromised assets by tracking Amazon Bedrock model access, prompts generated, and responses to the prompts by the account in the last 24 hours. + + +*False positive analysis* + + +- Verify the user account that queried denied topics, is not testing any new model deployments or updated compliance policies in Amazon Bedrock guardrails. + + +*Response and remediation* + + +- Initiate the incident response process based on the outcome of the triage. +- Disable or limit the account during the investigation and response. +- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context: + - Identify the account role in the cloud environment. + - Identify if the attacker is moving laterally and compromising other Amazon Bedrock Services. + - Identify any regulatory or legal ramifications related to this activity. +- Review the permissions assigned to the implicated user group or role behind these requests to ensure they are authorized and expected to access bedrock and ensure that the least privilege principle is being followed. +- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector. +- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR). + + +==== Setup + + + +*Setup* + + +This rule requires that guardrails are configured in AWS Bedrock. For more information, see the AWS Bedrock documentation: + +https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-aws_bedrock.invocation-* + +// Expand multivalued policy names +| mv_expand gen_ai.policy.name + +// Filter for blocked profanity-related policy violations +| where + gen_ai.policy.action == "BLOCKED" + and gen_ai.compliance.violation_detected == "true" + and gen_ai.policy.name == "word_policy" + +// keep relevant user field +| keep user.id + +// count blocked profanity attempts per user +| stats + Esql.ml_policy_blocked_profanity_count = count() + by user.id + +// Filter for excessive policy violations +| where Esql.ml_policy_blocked_profanity_count > 5 + +// sort by violation volume +| sort Esql.ml_policy_blocked_profanity_count desc + +---------------------------------- diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-process-spawned-from-web-server-parent.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-process-spawned-from-web-server-parent.asciidoc new file mode 100644 index 0000000000..7aa34f253e --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rule-8-19-4-unusual-process-spawned-from-web-server-parent.asciidoc @@ -0,0 +1,219 @@ +[[prebuilt-rule-8-19-4-unusual-process-spawned-from-web-server-parent]] +=== Unusual Process Spawned from Web Server Parent + +This rule detects unusual processes spawned from a web server parent process by identifying low frequency counts of process spawning activity. Unusual process spawning activity may indicate an attacker attempting to establish persistence, execute malicious commands, or establish command and control channels on the host system. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. + +*Rule type*: esql + +*Rule indices*: None + +*Severity*: medium + +*Risk score*: 47 + +*Runs every*: 1h + +*Searches indices from*: now-61m ({ref}/common-options.html#date-math[Date Math format], see also <>) + +*Maximum alerts per execution*: 100 + +*References*: None + +*Tags*: + +* Domain: Endpoint +* OS: Linux +* Use Case: Threat Detection +* Tactic: Persistence +* Tactic: Execution +* Tactic: Command and Control +* Data Source: Elastic Defend +* Resources: Investigation Guide + +*Version*: 5 + +*Rule authors*: + +* Elastic + +*Rule license*: Elastic License v2 + + +==== Investigation guide + + + ## Triage and analysis + +> **Disclaimer**: +> 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. + + +*Investigating Unusual Process Spawned from Web Server Parent* + + +Web servers like Apache, Nginx, and others are crucial for hosting applications and services. Adversaries exploit these servers by spawning unauthorized processes to maintain persistence or execute malicious commands. The detection rule identifies anomalies by monitoring low-frequency process spawns from web server parents, focusing on unusual user IDs, directories, and process counts, which may indicate potential threats. + + +*Possible investigation steps* + + +- Review the process.executable and process.command_line fields to understand the nature of the process that was spawned and assess if it aligns with expected behavior for the web server environment. +- Examine the process.working_directory to determine if the directory is a legitimate location for web server operations or if it appears suspicious, such as being outside typical web server directories. +- Check the user.name and user.id fields to verify if the process was executed by a legitimate web server user or if it was initiated by an unexpected or unauthorized user account. +- Investigate the process.parent.executable to confirm whether the parent process is a known and trusted web server executable or if it has been tampered with or replaced. +- Correlate the event with other logs or alerts from the same agent.id to identify any additional suspicious activities or patterns that may indicate a broader compromise. +- Assess the host.os.type to ensure the alert pertains to a Linux system, as specified in the query, and verify if there are any known vulnerabilities or misconfigurations on the host that could have been exploited. + + +*False positive analysis* + + +- Processes related to legitimate web server maintenance tasks may trigger alerts. Review scheduled tasks or cron jobs that align with the alert timing and consider excluding these specific processes if they are verified as non-threatening. +- Development environments often spawn processes that mimic attack patterns. Identify and exclude processes originating from known development directories or executed by development user accounts. +- Automated scripts or monitoring tools running under web server user accounts can be mistaken for malicious activity. Verify these scripts and add exceptions for their specific process names or working directories. +- Frequent updates or deployments in web applications can lead to unusual process spawns. Document these activities and exclude related processes if they consistently match the alert criteria during known update windows. +- Custom web server modules or plugins may execute processes that appear suspicious. Validate these modules and exclude their associated processes if they are part of normal operations. + + +*Response and remediation* + + +- Immediately isolate the affected host from the network to prevent further malicious activity and potential lateral movement. +- Terminate any suspicious processes identified by the alert that are not part of legitimate web server operations. +- Conduct a thorough review of the process command lines and executables flagged by the alert to identify any malicious scripts or binaries. Remove or quarantine these files as necessary. +- Check for unauthorized changes in web server configurations or files within the working directories flagged by the alert. Restore any altered files from a known good backup. +- Review user accounts and permissions associated with the web server processes to ensure no unauthorized accounts or privilege escalations have occurred. Reset passwords and revoke unnecessary access. +- Monitor network traffic from the affected host for any signs of command and control communication, and block any identified malicious IP addresses or domains. +- Escalate the incident to the security operations center (SOC) or incident response team for further analysis and to determine if additional systems are compromised. + + +==== Setup + + + +*Setup* + + +This rule requires data coming in from Elastic Defend. + + +*Elastic Defend Integration Setup* + +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. + + +*Prerequisite Requirements:* + +- Fleet is required for Elastic Defend. +- To configure Fleet Server refer to the https://www.elastic.co/guide/en/fleet/current/fleet-server.html[documentation]. + + +*The following steps should be executed in order to add the Elastic Defend integration on a Linux System:* + +- Go to the Kibana home page and click "Add integrations". +- In the query bar, search for "Elastic Defend" and select the integration to see more details about it. +- Click "Add Elastic Defend". +- Configure the integration name and optionally add a description. +- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads". +- 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. https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html[Helper guide]. +- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions" +- 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. +For more details on Elastic Agent configuration settings, refer to the https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html[helper guide]. +- Click "Save and Continue". +- 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 https://www.elastic.co/guide/en/security/current/install-endpoint.html[helper guide]. + + +==== Rule query + + +[source, js] +---------------------------------- +from logs-endpoint.events.process-* +| keep + @timestamp, + host.os.type, + event.type, + event.action, + process.parent.name, + user.name, + user.id, + process.working_directory, + process.name, + process.executable, + process.command_line, + process.parent.executable, + agent.id, + host.name +| where + @timestamp > now() - 1 hours and + host.os.type == "linux" and + event.type == "start" and + event.action == "exec" and ( + process.parent.name in ( + "apache", "nginx", "apache2", "httpd", "lighttpd", "caddy", "node", "mongrel_rails", "java", "gunicorn", + "uwsgi", "openresty", "cherokee", "h2o", "resin", "puma", "unicorn", "traefik", "tornado", "hypercorn", + "daphne", "twistd", "yaws", "webfsd", "httpd.worker", "flask", "rails", "mongrel" + ) or + process.parent.name like "php-*" or + process.parent.name like "python*" or + process.parent.name like "ruby*" or + process.parent.name like "perl*" or + user.name in ( + "apache", "www-data", "httpd", "nginx", "lighttpd", "tomcat", "tomcat8", "tomcat9", "ftp", "ftpuser", "ftpd" + ) or + user.id in ("99", "33", "498", "48") or + process.working_directory like "/var/www/*" + ) and not ( + process.working_directory like "/home/*" or + process.working_directory == "/" or + process.parent.executable like "/vscode/vscode-server/*" + ) +| stats + Esql.event_count = count(), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.executable, process.working_directory, process.parent.executable +| where + Esql.agent_id_count_distinct == 1 and + Esql.event_count < 5 +| sort Esql.event_count asc +| limit 100 + +---------------------------------- + +*Framework*: MITRE ATT&CK^TM^ + +* Tactic: +** Name: Persistence +** ID: TA0003 +** Reference URL: https://attack.mitre.org/tactics/TA0003/ +* Technique: +** Name: Server Software Component +** ID: T1505 +** Reference URL: https://attack.mitre.org/techniques/T1505/ +* Sub-technique: +** Name: Web Shell +** ID: T1505.003 +** Reference URL: https://attack.mitre.org/techniques/T1505/003/ +* Tactic: +** Name: Execution +** ID: TA0002 +** Reference URL: https://attack.mitre.org/tactics/TA0002/ +* Technique: +** Name: Command and Scripting Interpreter +** ID: T1059 +** Reference URL: https://attack.mitre.org/techniques/T1059/ +* Sub-technique: +** Name: Unix Shell +** ID: T1059.004 +** Reference URL: https://attack.mitre.org/techniques/T1059/004/ +* Tactic: +** Name: Command and Control +** ID: TA0011 +** Reference URL: https://attack.mitre.org/tactics/TA0011/ +* Technique: +** Name: Application Layer Protocol +** ID: T1071 +** Reference URL: https://attack.mitre.org/techniques/T1071/ diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-appendix.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-appendix.asciidoc new file mode 100644 index 0000000000..6ee37529bc --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-appendix.asciidoc @@ -0,0 +1,77 @@ +["appendix",role="exclude",id="prebuilt-rule-8-19-4-prebuilt-rules-8-19-4-appendix"] += Downloadable rule update v8.19.4 + +This section lists all updates associated with version 8.19.4 of the Fleet integration *Prebuilt Security Detection Rules*. + + +include::prebuilt-rule-8-19-4-potential-widespread-malware-infection-across-multiple-hosts.asciidoc[] +include::prebuilt-rule-8-19-4-aws-ec2-multi-region-describeinstances-api-calls.asciidoc[] +include::prebuilt-rule-8-19-4-aws-discovery-api-calls-via-cli-from-a-single-resource.asciidoc[] +include::prebuilt-rule-8-19-4-aws-service-quotas-multi-region-getservicequota-requests.asciidoc[] +include::prebuilt-rule-8-19-4-aws-ec2-ebs-snapshot-shared-or-made-public.asciidoc[] +include::prebuilt-rule-8-19-4-aws-s3-bucket-enumeration-or-brute-force.asciidoc[] +include::prebuilt-rule-8-19-4-aws-ec2-ebs-snapshot-access-removed.asciidoc[] +include::prebuilt-rule-8-19-4-potential-aws-s3-bucket-ransomware-note-uploaded.asciidoc[] +include::prebuilt-rule-8-19-4-aws-s3-object-encryption-using-external-kms-key.asciidoc[] +include::prebuilt-rule-8-19-4-aws-s3-static-site-javascript-file-uploaded.asciidoc[] +include::prebuilt-rule-8-19-4-aws-access-token-used-from-multiple-addresses.asciidoc[] +include::prebuilt-rule-8-19-4-aws-signin-single-factor-console-login-with-federated-user.asciidoc[] +include::prebuilt-rule-8-19-4-aws-iam-login-profile-added-for-root.asciidoc[] +include::prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-group.asciidoc[] +include::prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-role.asciidoc[] +include::prebuilt-rule-8-19-4-aws-iam-administratoraccess-policy-attached-to-user.asciidoc[] +include::prebuilt-rule-8-19-4-aws-bedrock-invocations-without-guardrails-detected-by-a-single-user-over-a-session.asciidoc[] +include::prebuilt-rule-8-19-4-aws-bedrock-guardrails-detected-multiple-violations-by-a-single-user-over-a-session.asciidoc[] +include::prebuilt-rule-8-19-4-aws-bedrock-guardrails-detected-multiple-policy-violations-within-a-single-blocked-request.asciidoc[] +include::prebuilt-rule-8-19-4-unusual-high-confidence-content-filter-blocks-detected.asciidoc[] +include::prebuilt-rule-8-19-4-potential-abuse-of-resources-by-high-token-count-and-large-response-sizes.asciidoc[] +include::prebuilt-rule-8-19-4-aws-bedrock-detected-multiple-attempts-to-use-denied-models-by-a-single-user.asciidoc[] +include::prebuilt-rule-8-19-4-unusual-high-denied-sensitive-information-policy-blocks-detected.asciidoc[] +include::prebuilt-rule-8-19-4-unusual-high-denied-topic-blocks-detected.asciidoc[] +include::prebuilt-rule-8-19-4-aws-bedrock-detected-multiple-validation-exception-errors-by-a-single-user.asciidoc[] +include::prebuilt-rule-8-19-4-unusual-high-word-policy-blocks-detected.asciidoc[] +include::prebuilt-rule-8-19-4-microsoft-entra-id-concurrent-sign-ins-with-suspicious-properties.asciidoc[] +include::prebuilt-rule-8-19-4-microsoft-entra-id-mfa-totp-brute-force-attempts.asciidoc[] +include::prebuilt-rule-8-19-4-excessive-secret-or-key-retrieval-from-azure-key-vault.asciidoc[] +include::prebuilt-rule-8-19-4-microsoft-entra-id-sign-in-brute-force-activity.asciidoc[] +include::prebuilt-rule-8-19-4-microsoft-entra-id-exccessive-account-lockouts-detected.asciidoc[] +include::prebuilt-rule-8-19-4-microsoft-365-brute-force-via-entra-id-sign-ins.asciidoc[] +include::prebuilt-rule-8-19-4-microsoft-entra-id-session-reuse-with-suspicious-graph-access.asciidoc[] +include::prebuilt-rule-8-19-4-suspicious-microsoft-oauth-flow-via-auth-broker-to-drs.asciidoc[] +include::prebuilt-rule-8-19-4-oidc-discovery-url-changed-in-entra-id.asciidoc[] +include::prebuilt-rule-8-19-4-potential-denial-of-azure-openai-ml-service.asciidoc[] +include::prebuilt-rule-8-19-4-azure-openai-insecure-output-handling.asciidoc[] +include::prebuilt-rule-8-19-4-potential-azure-openai-model-theft.asciidoc[] +include::prebuilt-rule-8-19-4-m365-onedrive-excessive-file-downloads-with-oauth-token.asciidoc[] +include::prebuilt-rule-8-19-4-multiple-microsoft-365-user-account-lockouts-in-short-time-window.asciidoc[] +include::prebuilt-rule-8-19-4-potential-microsoft-365-user-account-brute-force.asciidoc[] +include::prebuilt-rule-8-19-4-suspicious-microsoft-365-userloggedin-via-oauth-code.asciidoc[] +include::prebuilt-rule-8-19-4-multiple-device-token-hashes-for-single-okta-session.asciidoc[] +include::prebuilt-rule-8-19-4-multiple-okta-user-authentication-events-with-client-address.asciidoc[] +include::prebuilt-rule-8-19-4-multiple-okta-user-authentication-events-with-same-device-token-hash.asciidoc[] +include::prebuilt-rule-8-19-4-high-number-of-okta-device-token-cookies-generated-for-authentication.asciidoc[] +include::prebuilt-rule-8-19-4-okta-user-sessions-started-from-different-geolocations.asciidoc[] +include::prebuilt-rule-8-19-4-high-number-of-egress-network-connections-from-unusual-executable.asciidoc[] +include::prebuilt-rule-8-19-4-unusual-base64-encoding-decoding-activity.asciidoc[] +include::prebuilt-rule-8-19-4-potential-port-scanning-activity-from-compromised-host.asciidoc[] +include::prebuilt-rule-8-19-4-potential-subnet-scanning-activity-from-compromised-host.asciidoc[] +include::prebuilt-rule-8-19-4-unusual-file-transfer-utility-launched.asciidoc[] +include::prebuilt-rule-8-19-4-potential-malware-driven-ssh-brute-force-attempt.asciidoc[] +include::prebuilt-rule-8-19-4-unusual-process-spawned-from-web-server-parent.asciidoc[] +include::prebuilt-rule-8-19-4-unusual-command-execution-from-web-server-parent.asciidoc[] +include::prebuilt-rule-8-19-4-elastic-security-external-alerts.asciidoc[] +include::prebuilt-rule-8-19-4-rare-connection-to-webdav-target.asciidoc[] +include::prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-invalid-escape-sequences.asciidoc[] +include::prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-backtick-escaped-variable-expansion.asciidoc[] +include::prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-character-array-reconstruction.asciidoc[] +include::prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-concatenated-dynamic-command-invocation.asciidoc[] +include::prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-high-numeric-character-proportion.asciidoc[] +include::prebuilt-rule-8-19-4-potential-dynamic-iex-reconstruction-via-environment-variables.asciidoc[] +include::prebuilt-rule-8-19-4-dynamic-iex-reconstruction-via-method-string-access.asciidoc[] +include::prebuilt-rule-8-19-4-powershell-obfuscation-via-negative-index-string-reversal.asciidoc[] +include::prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-reverse-keywords.asciidoc[] +include::prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-string-concatenation.asciidoc[] +include::prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-string-reordering.asciidoc[] +include::prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-special-character-overuse.asciidoc[] +include::prebuilt-rule-8-19-4-potential-malicious-powershell-based-on-alert-correlation.asciidoc[] +include::prebuilt-rule-8-19-4-deprecated-azure-entra-sign-in-brute-force-microsoft-365-accounts-by-repeat-source.asciidoc[] diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-summary.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-summary.asciidoc new file mode 100644 index 0000000000..06b31f7ed5 --- /dev/null +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-summary.asciidoc @@ -0,0 +1,154 @@ +[[prebuilt-rule-8-19-4-prebuilt-rules-8-19-4-summary]] +[role="xpack"] +== Update v8.19.4 + +This section lists all updates associated with version 8.19.4 of the Fleet integration *Prebuilt Security Detection Rules*. + + +[width="100%",options="header"] +|============================================== +|Rule |Description |Status |Version + +|<> | This rule uses alert data to determine when a malware signature is triggered in multiple hosts. Analysts can use this to prioritize triage and response, as this can potentially indicate a widespread malware infection. | update | 4 + +|<> | Identifies when a single AWS resource is making `DescribeInstances` API calls in more than 10 regions within a 30-second window. This could indicate a potential threat actor attempting to discover the AWS infrastructure across multiple regions using compromised credentials or a compromised instance. Adversaries may use this information to identify potential targets for further exploitation or to gain a better understanding of the target's infrastructure. | update | 5 + +|<> | Detects when a single AWS resource is running multiple `Describe` and `List` API calls in a 10-second window. This behavior could indicate an actor attempting to discover the AWS infrastructure using compromised credentials or a compromised instance. Adversaries may use this information to identify potential targets for further exploitation or to gain a better understanding of the target's infrastructure. | update | 3 + +|<> | Identifies when a single AWS resource is making `GetServiceQuota` API calls for the EC2 service quota L-1216C47A in more than 10 regions within a 30-second window. Quota code L-1216C47A represents on-demand instances which are used by adversaries to deploy malware and mine cryptocurrency. This could indicate a potential threat actor attempting to discover the AWS infrastructure across multiple regions using compromised credentials or a compromised instance. | update | 4 + +|<> | Identifies AWS EC2 EBS snaphots being shared with another AWS account or made public. EBS virtual disks can be copied into snapshots, which can then be shared with an external AWS account or made public. Adversaries may attempt this in order to copy the snapshot into an environment they control, to access the data. | update | 7 + +|<> | Identifies a high number of failed S3 operations from a single source and account (or anonymous account) within a short timeframe. This activity can be indicative of attempting to cause an increase in billing to an account for excessive random operations, cause resource exhaustion, or enumerating bucket names for discovery. | update | 5 + +|<> | Identifies the removal of access permissions from a shared AWS EC2 EBS snapshot. EBS snapshots are essential for data retention and disaster recovery. Adversaries may revoke or modify snapshot permissions to prevent legitimate users from accessing backups, thereby obstructing recovery efforts after data loss or destructive actions. This tactic can also be used to evade detection or maintain exclusive access to critical backups, ultimately increasing the impact of an attack and complicating incident response. | update | 2 + +|<> | Identifies potential ransomware note being uploaded to an AWS S3 bucket. This rule detects the `PutObject` S3 API call with a common ransomware note file extension such as `.ransom`, or `.lock`. Adversaries with access to a misconfigured S3 bucket may retrieve, delete, and replace objects with ransom notes to extort victims. | update | 6 + +|<> | Identifies `CopyObject` events within an S3 bucket using an AWS KMS key from an external account for encryption. Adversaries with access to a misconfigured S3 bucket and the proper permissions may encrypt objects with an external KMS key to deny their victims access to their own data. | update | 6 + +|<> | This rule detects when a JavaScript file is uploaded or accessed in an S3 static site directory (`static/js/`) by an IAM user or assumed role. This can indicate suspicious modification of web content hosted on S3, such as injecting malicious scripts into a static website frontend. | update | 2 + +|<> | This rule identifies potentially suspicious activity by detecting instances where a single IAM user's temporary session token is accessed from multiple IP addresses within a short time frame. Such behavior may suggest that an adversary has compromised temporary credentials and is utilizing them from various locations. To enhance detection accuracy and minimize false positives, the rule incorporates criteria that evaluate unique IP addresses, user agents, cities, and networks. These additional checks help distinguish between legitimate distributed access patterns and potential credential misuse. Detected activities are classified into different types based on the combination of unique indicators, with each classification assigned a fidelity score reflecting the likelihood of malicious behavior. High fidelity scores are given to patterns most indicative of threats, such as multiple unique IPs, networks, cities, and user agents. Medium and low fidelity scores correspond to less severe patterns, enabling security teams to effectively prioritize alerts. | update | 102 + +|<> | Identifies when a federated user logs into the AWS Management Console without using multi-factor authentication (MFA). Federated users are typically given temporary credentials to access AWS services. If a federated user logs into the AWS Management Console without using MFA, it may indicate a security risk, as MFA adds an additional layer of security to the authentication process. This could also indicate the abuse of STS tokens to bypass MFA requirements. | update | 4 + +|<> | Detects when an AWS IAM login profile is added to a root user account and is self-assigned. Adversaries, with temporary access to the root account, may add a login profile to the root user account to maintain access even if the original access key is rotated or disabled. | update | 3 + +|<> | An adversary with access to a set of compromised credentials may attempt to persist or escalate privileges by attaching additional permissions to user groups the compromised user account belongs to. This rule looks for use of the IAM `AttachGroupPolicy` API operation to attach the highly permissive `AdministratorAccess` AWS managed policy to an existing IAM user group. | update | 6 + +|<> | An adversary with access to a set of compromised credentials may attempt to persist or escalate privileges by attaching additional permissions to compromised IAM roles. This rule looks for use of the IAM `AttachRolePolicy` API operation to attach the highly permissive `AdministratorAccess` AWS managed policy to an existing IAM role. | update | 6 + +|<> | An adversary with access to a set of compromised credentials may attempt to persist or escalate privileges by attaching additional permissions to compromised user accounts. This rule looks for use of the IAM `AttachUserPolicy` API operation to attach the highly permissive `AdministratorAccess` AWS managed policy to an existing IAM user. | update | 7 + +|<> | Identifies multiple AWS Bedrock executions in a one minute time window without guardrails by the same user in the same account over a session. Multiple consecutive executions implies that a user may be intentionally attempting to bypass security controls, by not routing the requests with the desired guardrail configuration in order to access sensitive information, or possibly exploit a vulnerability in the system. | update | 3 + +|<> | Identifies multiple violations of AWS Bedrock guardrails by the same user in the same account over a session. Multiple violations implies that a user may be intentionally attempting to cirvumvent security controls, access sensitive information, or possibly exploit a vulnerability in the system. | update | 6 + +|<> | Identifies multiple violations of AWS Bedrock guardrails within a single request, resulting in a block action, increasing the likelihood of malicious intent. Multiple violations implies that a user may be intentionally attempting to cirvumvent security controls, access sensitive information, or possibly exploit a vulnerability in the system. | update | 5 + +|<> | Detects repeated high-confidence 'BLOCKED' actions coupled with specific 'Content Filter' policy violation having codes such as 'MISCONDUCT', 'HATE', 'SEXUAL', INSULTS', 'PROMPT_ATTACK', 'VIOLENCE' indicating persistent misuse or attempts to probe the model's ethical boundaries. | update | 7 + +|<> | Detects potential resource exhaustion or data breach attempts by monitoring for users who consistently generate high input token counts, submit numerous requests, and receive large responses. This behavior could indicate an attempt to overload the system or extract an unusually large amount of data, possibly revealing sensitive information or causing service disruptions. | update | 5 + +|<> | Identifies multiple successive failed attempts to use denied model resources within AWS Bedrock. This could indicated attempts to bypass limitations of other approved models, or to force an impact on the environment by incurring exhorbitant costs. | update | 5 + +|<> | Detects repeated compliance violation 'BLOCKED' actions coupled with specific policy name such as 'sensitive_information_policy', indicating persistent misuse or attempts to probe the model's denied topics. | update | 3 + +|<> | Detects repeated compliance violation 'BLOCKED' actions coupled with specific policy name such as 'topic_policy', indicating persistent misuse or attempts to probe the model's denied topics. | update | 3 + +|<> | Identifies multiple validation exeception errors within AWS Bedrock. Validation errors occur when you run the InvokeModel or InvokeModelWithResponseStream APIs on a foundation model that uses an incorrect inference parameter or corresponding value. These errors also occur when you use an inference parameter for one model with a model that doesn't have the same API parameter. This could indicate attempts to bypass limitations of other approved models, or to force an impact on the environment by incurring exhorbitant costs. | update | 5 + +|<> | Detects repeated compliance violation 'BLOCKED' actions coupled with specific policy name such as 'word_policy', indicating persistent misuse or attempts to probe the model's denied topics. | update | 3 + +|<> | Identifies concurrent azure signin events for the same user and from multiple sources, and where one of the authentication event has some suspicious properties often associated to DeviceCode and OAuth phishing. Adversaries may steal Refresh Tokens (RTs) via phishing to bypass multi-factor authentication (MFA) and gain unauthorized access to Azure resources. | update | 2 + +|<> | Identifies brute force attempts against Azure Entra multi-factor authentication (MFA) Time-based One-Time Password (TOTP) verification codes. This rule detects high frequency failed TOTP code attempts for a single user in a short time-span with a high number of distinct session IDs. Adversaries may programmatically attemopt to brute-force TOTP codes by generating several sessions and attempt to guess the correct code. | update | 4 + +|<> | Identifies excessive secret or key retrieval operations from Azure Key Vault. This rule detects when a user principal retrieves secrets or keys from Azure Key Vault multiple times within a short time frame, which may indicate potential abuse or unauthorized access attempts. The rule focuses on high-frequency retrieval operations that deviate from normal user behavior, suggesting possible credential harvesting or misuse of sensitive information. | update | 2 + +|<> | Identifies potential brute-force attacks targeting user accounts by analyzing failed sign-in patterns in Microsoft Entra ID Sign-In Logs. This detection focuses on a high volume of failed interactive or non-interactive authentication attempts within a short time window, often indicative of password spraying, credential stuffing, or password guessing. Adversaries may use these techniques to gain unauthorized access to applications integrated with Entra ID or to compromise valid user accounts. | update | 4 + +|<> | Identifies a high count of failed Microsoft Entra ID sign-in attempts as the result of the target user account being locked out. Adversaries may attempt to brute-force user accounts by repeatedly trying to authenticate with incorrect credentials, leading to account lockouts by Entra ID Smart Lockout policies. | update | 2 + +|<> | Identifies potential brute-force attacks targeting Microsoft 365 user accounts by analyzing failed sign-in patterns in Microsoft Entra ID Sign-In Logs. This detection focuses on a high volume of failed interactive or non-interactive authentication attempts within a short time window, often indicative of password spraying, credential stuffing, or password guessing. Adversaries may use these techniques to gain unauthorized access to Microsoft 365 services such as Exchange Online, SharePoint, or Teams. | update | 106 + +|<> | Identifies potential session hijacking or token replay in Microsoft Entra ID. This rule detects cases where a user signs in and subsequently accesses Microsoft Graph from a different IP address using the same session ID within a short time window. This may indicate the use of a stolen refresh/access token or session cookie to impersonate the user and interact with Microsoft services. | update | 3 + +|<> | Identifies separate OAuth authorization flows in Microsoft Entra ID where the same user principal and session ID are observed across multiple IP addresses within a 5-minute window. These flows involve the Microsoft Authentication Broker (MAB) as the client application and the Device Registration Service (DRS) as the target resource. This pattern is highly indicative of OAuth phishing activity, where an adversary crafts a legitimate Microsoft login URL to trick a user into completing authentication and sharing the resulting authorization code, which is then exchanged for an access and refresh token by the attacker. | update | 3 + +|<> | Detects a change to the OpenID Connect (OIDC) discovery URL in the Entra ID Authentication Methods Policy. This behavior may indicate an attempt to federate Entra ID with an attacker-controlled identity provider, enabling bypass of multi-factor authentication (MFA) and unauthorized access through bring-your-own IdP (BYOIDP) methods. | update | 3 + +|<> | Detects patterns indicative of Denial-of-Service (DoS) attacks on machine learning (ML) models, focusing on unusually high volume and frequency of requests or patterns of requests that are known to cause performance degradation or service disruption, such as large input sizes or rapid API calls. | update | 3 + +|<> | Detects when Azure OpenAI requests result in zero response length, potentially indicating issues in output handling that might lead to security exploits such as data leaks or code execution. This can occur in cases where the API fails to handle outputs correctly under certain input conditions. | update | 3 + +|<> | Monitors for suspicious activities that may indicate theft or unauthorized duplication of machine learning (ML) models, such as unauthorized API calls, atypical access patterns, or large data transfers that are unusual during model interactions. | update | 3 + +|<> | Identifies when an excessive number of files are downloaded from OneDrive using OAuth authentication. Adversaries may conduct phishing campaigns to steal OAuth tokens and impersonate users. These access tokens can then be used to download files from OneDrive. | update | 3 + +|<> | Detects a burst of Microsoft 365 user account lockouts within a short 5-minute window. A high number of IdsLocked login errors across multiple user accounts may indicate brute-force attempts for the same users resulting in lockouts. | update | 3 + +|<> | Identifies brute-force authentication activity targeting Microsoft 365 user accounts using failed sign-in patterns that match password spraying, credential stuffing, or password guessing behavior. Adversaries may attempt brute-force authentication with credentials obtained from previous breaches, leaks, marketplaces or guessable passwords. | update | 414 + +|<> | Identifies sign-ins on behalf of a principal user to the Microsoft Graph API from multiple IPs using the Microsoft Authentication Broker or Visual Studio Code application. This behavior may indicate an adversary using a phished OAuth refresh token. | update | 3 + +|<> | This rule detects when a specific Okta actor has multiple device token hashes for a single Okta session. This may indicate an authenticated session has been hijacked or is being used by multiple devices. Adversaries may hijack a session to gain unauthorized access to Okta admin console, applications, tenants, or other resources. | update | 307 + +|<> | Detects when a certain threshold of Okta user authentication events are reported for multiple users from the same client address. Adversaries may attempt to launch a credential stuffing or password spraying attack from the same device by using a list of known usernames and passwords to gain unauthorized access to user accounts. | update | 206 + +|<> | Detects when a high number of Okta user authentication events are reported for multiple users in a short time frame. Adversaries may attempt to launch a credential stuffing or password spraying attack from the same device by using a list of known usernames and passwords to gain unauthorized access to user accounts. | update | 206 + +|<> | Detects when an Okta client address has a certain threshold of Okta user authentication events with multiple device token hashes generated for single user authentication. Adversaries may attempt to launch a credential stuffing or password spraying attack from the same device by using a list of known usernames and passwords to gain unauthorized access to user accounts. | update | 206 + +|<> | Detects when a specific Okta actor has multiple sessions started from different geolocations. Adversaries may attempt to launch an attack by using a list of known usernames and passwords to gain unauthorized access to user accounts from different locations. | update | 307 + +|<> | This rule detects a high number of egress network connections from an unusual executable on a Linux system. This could indicate a command and control (C2) communication attempt, a brute force attack via a malware infection, or other malicious activity. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. | update | 5 + +|<> | This rule leverages ESQL to detect unusual base64 encoding/decoding activity on Linux systems. Attackers may use base64 encoding/decoding to obfuscate data, such as command and control traffic or payloads, to evade detection by host- or network-based security controls. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. | update | 5 + +|<> | This rule detects potential port scanning activity from a compromised host. Port scanning is a common reconnaissance technique used by attackers to identify open ports and services on a target system. A compromised host may exhibit port scanning behavior when an attacker is attempting to map out the network topology, identify vulnerable services, or prepare for further exploitation. This rule identifies potential port scanning activity by monitoring network connection attempts from a single host to a large number of ports within a short time frame. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. | update | 5 + +|<> | This rule detects potential subnet scanning activity from a compromised host. Subnet scanning is a common reconnaissance technique used by attackers to identify live hosts within a network range. A compromised host may exhibit subnet scanning behavior when an attacker is attempting to map out the network topology, identify vulnerable hosts, or prepare for further exploitation. This rule identifies potential subnet scanning activity by monitoring network connection attempts from a single host to a large number of hosts within a short time frame. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. | update | 5 + +|<> | This rule leverages ESQL to detect the execution of unusual file transfer utilities on Linux systems. Attackers may use these utilities to exfiltrate data from a compromised system. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. | update | 5 + +|<> | This detection identifies a Linux host that has potentially been infected with malware and is being used to conduct brute-force attacks against external systems over SSH (port 22 and common alternative SSH ports). The detection looks for a high volume of outbound connection attempts to non-private IP addresses from a single process. A compromised host may be part of a botnet or controlled by an attacker, attempting to gain unauthorized access to remote systems. This behavior is commonly observed in SSH brute-force campaigns where malware hijacks vulnerable machines to expand its attack surface. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. | update | 5 + +|<> | This rule detects unusual processes spawned from a web server parent process by identifying low frequency counts of process spawning activity. Unusual process spawning activity may indicate an attacker attempting to establish persistence, execute malicious commands, or establish command and control channels on the host system. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. | update | 5 + +|<> | This rule detects potential command execution from a web server parent process on a Linux host. Adversaries may attempt to execute commands from a web server parent process to blend in with normal web server activity and evade detection. This behavior is commonly observed in web shell attacks where adversaries exploit web server vulnerabilities to execute arbitrary commands on the host. The detection rule identifies unusual command execution from web server parent processes, which may indicate a compromised host or an ongoing attack. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. | update | 5 + +|<> | Generates a detection alert for each Elastic Security alert written to the configured indices. Enabling this rule allows you to immediately begin investigating Elastic Security alerts in the app. | update | 2 + +|<> | Identifies rare connection attempts to a Web Distributed Authoring and Versioning (WebDAV) resource. Attackers may inject WebDAV paths in files or features opened by a victim user to leak their NTLM credentials via forced authentication. | update | 2 + +|<> | Identifies PowerShell scripts that use invalid escape sequences as a form of obfuscation. This technique introduces backticks (`) between characters in a way that does not correspond to valid PowerShell escape sequences, breaking up strings and bypassing pattern-based detections while preserving execution logic. This is designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). | update | 4 + +|<> | Identifies PowerShell scripts that use backtick-escaped characters inside ${} variable expansion as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). | update | 3 + +|<> | Identifies PowerShell scripts that use character arrays and runtime string reconstruction as a form of obfuscation. This technique breaks strings into individual characters, often using constructs like char[] with index-based access or joining logic. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). | update | 3 + +|<> | Identifies PowerShell scripts that use concatenated strings within dynamic command invocation (&() or .()) as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). | update | 3 + +|<> | Identifies PowerShell scripts with a disproportionately high number of numeric characters, often indicating the presence of obfuscated or encoded payloads. This behavior is typical of obfuscation methods involving byte arrays, character code manipulation, or embedded encoded strings used to deliver and execute malicious content. | update | 4 + +|<> | Identifies PowerShell scripts that reconstruct the IEX (Invoke-Expression) command at runtime using indexed slices of environment variables. This technique leverages character access and join operations to build execution logic dynamically, bypassing static keyword detection and evading defenses such as AMSI. | update | 3 + +|<> | Identifies PowerShell scripts that reconstruct the IEX (Invoke-Expression) command by accessing and indexing the string representation of method references. This obfuscation technique uses constructs like ''.IndexOf.ToString() to expose method metadata as a string, then extracts specific characters through indexed access and joins them to form IEX, bypassing static keyword detection and evading defenses such as AMSI. | update | 4 + +|<> | Identifies PowerShell scripts that use negative index ranges to reverse the contents of a string or array at runtime as a form of obfuscation. This technique avoids direct use of reversal functions by iterating through array elements in reverse order. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). | update | 3 + +|<> | Identifies PowerShell scripts that use reversed strings as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). | update | 3 + +|<> | Identifies PowerShell scripts that use string concatenation as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). | update | 4 + +|<> | Identifies PowerShell scripts that use string reordering and runtime reconstruction techniques as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). | update | 5 + +|<> | Identifies PowerShell scripts with an unusually high proportion of whitespace and special characters, often indicative of obfuscation. This behavior is commonly associated with techniques such as SecureString encoding, formatting obfuscation, or character-level manipulation designed to bypass static analysis and AMSI inspection. | update | 4 + +|<> | Identifies PowerShell script blocks associated with multiple distinct detections, indicating likely malicious behavior. | update | 2 + +|<> | Identifies potential brute-force attempts against Microsoft 365 user accounts by detecting a high number of failed interactive or non-interactive login attempts within a 30-minute window from a single source. Attackers may attempt to brute force user accounts to gain unauthorized access to Microsoft 365 services via different services such as Exchange, SharePoint, or Teams. | deprecated | 4 + +|============================================== diff --git a/docs/detections/prebuilt-rules/prebuilt-rules-downloadable-updates.asciidoc b/docs/detections/prebuilt-rules/prebuilt-rules-downloadable-updates.asciidoc index 9f9d8944c5..edde1e8be5 100644 --- a/docs/detections/prebuilt-rules/prebuilt-rules-downloadable-updates.asciidoc +++ b/docs/detections/prebuilt-rules/prebuilt-rules-downloadable-updates.asciidoc @@ -13,6 +13,10 @@ For previous rule updates, please navigate to the https://www.elastic.co/guide/e |Update version |Date | New rules | Updated rules | Notes +|<> | 06 Aug 2025 | 0 | 70 | +This release includes tuned and deprecated rules. Deprecated rule includes Deprecated - Azure Entra Sign-in Brute Force Microsoft 365 Accounts by Repeat Source. Additionally, ESQL-based rules were tuned for dynamic field standardization along with rule tuning for Elastic Security promotion rule. + + |<> | 05 Aug 2025 | 8 | 3 | This release includes new rules for Windows and SOC integrations New rules for Windows include detection for credential access. New rules for SOC integrations include promotion rules for Google SecOps, Elastic Security, Microsoft Sentinel, SentinelOne, CrowdStrike and Splunk. Additionally, significant rule tuning for Windows and Azure rules has been added for better rule efficacy and performance. @@ -28,3 +32,4 @@ This release includes new rules for Linux, Azure, Kubernetes and Microsoft 365. include::downloadable-packages/8-19-1/prebuilt-rules-8-19-1-summary.asciidoc[leveloffset=+1] include::downloadable-packages/8-19-2/prebuilt-rules-8-19-2-summary.asciidoc[leveloffset=+1] include::downloadable-packages/8-19-3/prebuilt-rules-8-19-3-summary.asciidoc[leveloffset=+1] +include::downloadable-packages/8-19-4/prebuilt-rules-8-19-4-summary.asciidoc[leveloffset=+1] diff --git a/docs/detections/prebuilt-rules/prebuilt-rules-reference.asciidoc b/docs/detections/prebuilt-rules/prebuilt-rules-reference.asciidoc index 9312c58572..8ad0f9870a 100644 --- a/docs/detections/prebuilt-rules/prebuilt-rules-reference.asciidoc +++ b/docs/detections/prebuilt-rules/prebuilt-rules-reference.asciidoc @@ -18,17 +18,17 @@ and their rule type is `machine_learning`. |<> |Detects file creation events in the configuration directory for the APT package manager. In Linux, APT (Advanced Package Tool) is a command-line utility used for handling packages on (by default) Debian-based systems, providing functions for installing, updating, upgrading, and removing software along with managing package repositories. Attackers can backdoor APT to gain persistence by injecting malicious code into scripts that APT runs, thereby ensuring continued unauthorized access or control each time APT is used for package management. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Persistence], [Tactic: Defense Evasion], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |7 -|<> |This rule identifies potentially suspicious activity by detecting instances where a single IAM user's temporary session token is accessed from multiple IP addresses within a short time frame. Such behavior may suggest that an adversary has compromised temporary credentials and is utilizing them from various locations. To enhance detection accuracy and minimize false positives, the rule incorporates criteria that evaluate unique IP addresses, user agents, cities, and networks. These additional checks help distinguish between legitimate distributed access patterns and potential credential misuse. Detected activities are classified into different types based on the combination of unique indicators, with each classification assigned a fidelity score reflecting the likelihood of malicious behavior. High fidelity scores are given to patterns most indicative of threats, such as multiple unique IPs, networks, cities, and user agents. Medium and low fidelity scores correspond to less severe patterns, enabling security teams to effectively prioritize alerts. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS IAM], [Data Source: AWS CloudTrail], [Tactic: Initial Access], [Use Case: Identity and Access Audit], [Resources: Investigation Guide] |None |101 +|<> |This rule identifies potentially suspicious activity by detecting instances where a single IAM user's temporary session token is accessed from multiple IP addresses within a short time frame. Such behavior may suggest that an adversary has compromised temporary credentials and is utilizing them from various locations. To enhance detection accuracy and minimize false positives, the rule incorporates criteria that evaluate unique IP addresses, user agents, cities, and networks. These additional checks help distinguish between legitimate distributed access patterns and potential credential misuse. Detected activities are classified into different types based on the combination of unique indicators, with each classification assigned a fidelity score reflecting the likelihood of malicious behavior. High fidelity scores are given to patterns most indicative of threats, such as multiple unique IPs, networks, cities, and user agents. Medium and low fidelity scores correspond to less severe patterns, enabling security teams to effectively prioritize alerts. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS IAM], [Data Source: AWS CloudTrail], [Tactic: Initial Access], [Use Case: Identity and Access Audit], [Resources: Investigation Guide] |None |102 -|<> |Identifies multiple successive failed attempts to use denied model resources within AWS Bedrock. This could indicated attempts to bypass limitations of other approved models, or to force an impact on the environment by incurring exhorbitant costs. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Resources: Investigation Guide], [Use Case: Policy Violation], [Mitre Atlas: T0015], [Mitre Atlas: T0034] |None |4 +|<> |Identifies multiple successive failed attempts to use denied model resources within AWS Bedrock. This could indicated attempts to bypass limitations of other approved models, or to force an impact on the environment by incurring exhorbitant costs. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Resources: Investigation Guide], [Use Case: Policy Violation], [Mitre Atlas: T0015], [Mitre Atlas: T0034] |None |5 -|<> |Identifies multiple validation exeception errors within AWS Bedrock. Validation errors occur when you run the InvokeModel or InvokeModelWithResponseStream APIs on a foundation model that uses an incorrect inference parameter or corresponding value. These errors also occur when you use an inference parameter for one model with a model that doesn't have the same API parameter. This could indicate attempts to bypass limitations of other approved models, or to force an impact on the environment by incurring exhorbitant costs. |[Domain: LLM], [Data Source: AWS], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Use Case: Policy Violation], [Mitre Atlas: T0015], [Mitre Atlas: T0034], [Mitre Atlas: T0046], [Resources: Investigation Guide] |None |4 +|<> |Identifies multiple validation exeception errors within AWS Bedrock. Validation errors occur when you run the InvokeModel or InvokeModelWithResponseStream APIs on a foundation model that uses an incorrect inference parameter or corresponding value. These errors also occur when you use an inference parameter for one model with a model that doesn't have the same API parameter. This could indicate attempts to bypass limitations of other approved models, or to force an impact on the environment by incurring exhorbitant costs. |[Domain: LLM], [Data Source: AWS], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Use Case: Policy Violation], [Mitre Atlas: T0015], [Mitre Atlas: T0034], [Mitre Atlas: T0046], [Resources: Investigation Guide] |None |5 -|<> |Identifies multiple violations of AWS Bedrock guardrails within a single request, resulting in a block action, increasing the likelihood of malicious intent. Multiple violations implies that a user may be intentionally attempting to cirvumvent security controls, access sensitive information, or possibly exploit a vulnerability in the system. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Resources: Investigation Guide], [Use Case: Policy Violation], [Mitre Atlas: T0051], [Mitre Atlas: T0054] |None |4 +|<> |Identifies multiple violations of AWS Bedrock guardrails within a single request, resulting in a block action, increasing the likelihood of malicious intent. Multiple violations implies that a user may be intentionally attempting to cirvumvent security controls, access sensitive information, or possibly exploit a vulnerability in the system. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Resources: Investigation Guide], [Use Case: Policy Violation], [Mitre Atlas: T0051], [Mitre Atlas: T0054] |None |5 -|<> |Identifies multiple violations of AWS Bedrock guardrails by the same user in the same account over a session. Multiple violations implies that a user may be intentionally attempting to cirvumvent security controls, access sensitive information, or possibly exploit a vulnerability in the system. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Resources: Investigation Guide], [Use Case: Policy Violation], [Mitre Atlas: T0051], [Mitre Atlas: T0054] |None |5 +|<> |Identifies multiple violations of AWS Bedrock guardrails by the same user in the same account over a session. Multiple violations implies that a user may be intentionally attempting to cirvumvent security controls, access sensitive information, or possibly exploit a vulnerability in the system. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Resources: Investigation Guide], [Use Case: Policy Violation], [Mitre Atlas: T0051], [Mitre Atlas: T0054] |None |6 -|<> |Identifies multiple AWS Bedrock executions in a one minute time window without guardrails by the same user in the same account over a session. Multiple consecutive executions implies that a user may be intentionally attempting to bypass security controls, by not routing the requests with the desired guardrail configuration in order to access sensitive information, or possibly exploit a vulnerability in the system. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Resources: Investigation Guide], [Use Case: Policy Violation], [Mitre Atlas: T0051], [Mitre Atlas: T0054] |None |2 +|<> |Identifies multiple AWS Bedrock executions in a one minute time window without guardrails by the same user in the same account over a session. Multiple consecutive executions implies that a user may be intentionally attempting to bypass security controls, by not routing the requests with the desired guardrail configuration in order to access sensitive information, or possibly exploit a vulnerability in the system. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Resources: Investigation Guide], [Use Case: Policy Violation], [Mitre Atlas: T0051], [Mitre Atlas: T0054] |None |3 |<> |Detects the use of the AWS CLI with the `--endpoint-url` argument, which allows users to specify a custom endpoint URL for AWS services. This can be leveraged by adversaries to redirect API requests to non-standard or malicious endpoints, potentially bypassing typical security controls and logging mechanisms. This behavior may indicate an attempt to interact with unauthorized or compromised infrastructure, exfiltrate data, or perform other malicious activities under the guise of legitimate AWS operations. |[Data Source: Elastic Defend], [Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Command and Control], [Resources: Investigation Guide] |None |4 @@ -58,7 +58,7 @@ and their rule type is `machine_learning`. |<> |Identifies the deletion of an Amazon Relational Database Service (RDS) Aurora database cluster, global database cluster, or database instance. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS RDS], [Use Case: Asset Visibility], [Tactic: Impact], [Resources: Investigation Guide] |None |209 -|<> |Detects when a single AWS resource is running multiple `Describe` and `List` API calls in a 10-second window. This behavior could indicate an actor attempting to discover the AWS infrastructure using compromised credentials or a compromised instance. Adversaries may use this information to identify potential targets for further exploitation or to gain a better understanding of the target's infrastructure. |[Domain: Cloud], [Data Source: AWS], [Data Source: AWS EC2], [Data Source: AWS IAM], [Data Source: AWS S3], [Use Case: Threat Detection], [Tactic: Discovery], [Resources: Investigation Guide] |None |2 +|<> |Detects when a single AWS resource is running multiple `Describe` and `List` API calls in a 10-second window. This behavior could indicate an actor attempting to discover the AWS infrastructure using compromised credentials or a compromised instance. Adversaries may use this information to identify potential targets for further exploitation or to gain a better understanding of the target's infrastructure. |[Domain: Cloud], [Data Source: AWS], [Data Source: AWS EC2], [Data Source: AWS IAM], [Data Source: AWS S3], [Use Case: Threat Detection], [Tactic: Discovery], [Resources: Investigation Guide] |None |3 |<> |Identifies when an AWS DynamoDB table is scanned by a user who does not typically perform this action. Adversaries may use the Scan operation to collect sensitive information or exfiltrate data from DynamoDB tables. This rule detects unusual user activity by monitoring for the Scan action in CloudTrail logs. This is a New Terms rule that only flags when this behavior is observed by the `aws.cloudtrail.user_identity.arn` for the first time in the last 14 days. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS DynamoDB], [Resources: Investigation Guide], [Use Case: Threat Detection], [Tactic: Exfiltration] |None |3 @@ -68,9 +68,9 @@ and their rule type is `machine_learning`. |<> |Identifies when a user has queried for deprecated Amazon Machine Images (AMIs) in AWS. This may indicate an adversary looking for outdated AMIs that may be vulnerable to exploitation. While deprecated AMIs are not inherently malicious or indicative of a breach, they may be more susceptible to vulnerabilities and should be investigated for potential security risks. |[Domain: Cloud], [Data Source: AWS], [Data Source: AWS EC2], [Resources: Investigation Guide], [Use Case: Threat Detection], [Tactic: Discovery] |None |6 -|<> |Identifies the removal of access permissions from a shared AWS EC2 EBS snapshot. EBS snapshots are essential for data retention and disaster recovery. Adversaries may revoke or modify snapshot permissions to prevent legitimate users from accessing backups, thereby obstructing recovery efforts after data loss or destructive actions. This tactic can also be used to evade detection or maintain exclusive access to critical backups, ultimately increasing the impact of an attack and complicating incident response. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS EC2], [Use Case: Threat Detection], [Tactic: Impact], [Resources: Investigation Guide] |None |1 +|<> |Identifies the removal of access permissions from a shared AWS EC2 EBS snapshot. EBS snapshots are essential for data retention and disaster recovery. Adversaries may revoke or modify snapshot permissions to prevent legitimate users from accessing backups, thereby obstructing recovery efforts after data loss or destructive actions. This tactic can also be used to evade detection or maintain exclusive access to critical backups, ultimately increasing the impact of an attack and complicating incident response. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS EC2], [Use Case: Threat Detection], [Tactic: Impact], [Resources: Investigation Guide] |None |2 -|<> |Identifies AWS EC2 EBS snaphots being shared with another AWS account or made public. EBS virtual disks can be copied into snapshots, which can then be shared with an external AWS account or made public. Adversaries may attempt this in order to copy the snapshot into an environment they control, to access the data. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS EC2], [Use Case: Threat Detection], [Tactic: Exfiltration], [Resources: Investigation Guide] |None |6 +|<> |Identifies AWS EC2 EBS snaphots being shared with another AWS account or made public. EBS virtual disks can be copied into snapshots, which can then be shared with an external AWS account or made public. Adversaries may attempt this in order to copy the snapshot into an environment they control, to access the data. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS EC2], [Use Case: Threat Detection], [Tactic: Exfiltration], [Resources: Investigation Guide] |None |7 |<> |Identifies disabling of Amazon Elastic Block Store (EBS) encryption by default in the current region. Disabling encryption by default does not change the encryption status of your existing volumes. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS EC2], [Tactic: Impact], [Resources: Investigation Guide] |None |209 @@ -82,7 +82,7 @@ and their rule type is `machine_learning`. |<> |Identifies when an EC2 instance interacts with the AWS IAM service via an assumed role. This is uncommon behavior and could indicate an attacker using compromised credentials to further exploit an environment. For example, an assumed role could be used to create new users for persistence or add permissions for privilege escalation. An EC2 instance assumes a role using their EC2 ID as the session name. This rule looks for the pattern "i-" which is the beginning pattern for assumed role sessions started by an EC2 instance. This is a [building block](https://www.elastic.co/guide/en/security/current/building-block-rule.html) rule and does not generate alerts on its own. It is meant to be used for correlation with other rules to detect suspicious activity. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS EC2], [Data Source: AWS IAM], [Use Case: Identity and Access Audit], [Tactic: Privilege Escalation], [Tactic: Persistence], [Rule Type: BBR] |None |4 -|<> |Identifies when a single AWS resource is making `DescribeInstances` API calls in more than 10 regions within a 30-second window. This could indicate a potential threat actor attempting to discover the AWS infrastructure across multiple regions using compromised credentials or a compromised instance. Adversaries may use this information to identify potential targets for further exploitation or to gain a better understanding of the target's infrastructure. |[Domain: Cloud], [Data Source: AWS], [Data Source: AWS EC2], [Resources: Investigation Guide], [Use Case: Threat Detection], [Tactic: Discovery] |None |4 +|<> |Identifies when a single AWS resource is making `DescribeInstances` API calls in more than 10 regions within a 30-second window. This could indicate a potential threat actor attempting to discover the AWS infrastructure across multiple regions using compromised credentials or a compromised instance. Adversaries may use this information to identify potential targets for further exploitation or to gain a better understanding of the target's infrastructure. |[Domain: Cloud], [Data Source: AWS], [Data Source: AWS EC2], [Resources: Investigation Guide], [Use Case: Threat Detection], [Tactic: Discovery] |None |5 |<> |Identifies the creation of an AWS EC2 network access control list (ACL) or an entry in a network ACL with a specified rule number. Adversaries may exploit ACLs to establish persistence or exfiltrate data by creating permissive rules. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS EC2], [Use Case: Network Security Monitoring], [Tactic: Persistence], [Tactic: Defense Evasion], [Resources: Investigation Guide] |None |210 @@ -110,11 +110,11 @@ and their rule type is `machine_learning`. |<> |Detects use of sensitive AWS IAM API operations using temporary credentials (session tokens starting with 'ASIA'). This may indicate credential theft or abuse of elevated access via a stolen session. It is not common for legitimate users to perform sensitive IAM operations with temporary session tokens. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS CloudTrail], [Data Source: AWS IAM], [Data Source: AWS STS], [Tactic: Persistence], [Tactic: Privilege Escalation], [Resources: Investigation Guide] |None |3 -|<> |An adversary with access to a set of compromised credentials may attempt to persist or escalate privileges by attaching additional permissions to user groups the compromised user account belongs to. This rule looks for use of the IAM `AttachGroupPolicy` API operation to attach the highly permissive `AdministratorAccess` AWS managed policy to an existing IAM user group. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS IAM], [Use Case: Identity and Access Audit], [Tactic: Privilege Escalation], [Tactic: Persistence], [Resources: Investigation Guide] |None |5 +|<> |An adversary with access to a set of compromised credentials may attempt to persist or escalate privileges by attaching additional permissions to user groups the compromised user account belongs to. This rule looks for use of the IAM `AttachGroupPolicy` API operation to attach the highly permissive `AdministratorAccess` AWS managed policy to an existing IAM user group. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS IAM], [Use Case: Identity and Access Audit], [Tactic: Privilege Escalation], [Tactic: Persistence], [Resources: Investigation Guide] |None |6 -|<> |An adversary with access to a set of compromised credentials may attempt to persist or escalate privileges by attaching additional permissions to compromised IAM roles. This rule looks for use of the IAM `AttachRolePolicy` API operation to attach the highly permissive `AdministratorAccess` AWS managed policy to an existing IAM role. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS IAM], [Use Case: Identity and Access Audit], [Tactic: Privilege Escalation], [Tactic: Persistence], [Resources: Investigation Guide] |None |5 +|<> |An adversary with access to a set of compromised credentials may attempt to persist or escalate privileges by attaching additional permissions to compromised IAM roles. This rule looks for use of the IAM `AttachRolePolicy` API operation to attach the highly permissive `AdministratorAccess` AWS managed policy to an existing IAM role. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS IAM], [Use Case: Identity and Access Audit], [Tactic: Privilege Escalation], [Tactic: Persistence], [Resources: Investigation Guide] |None |6 -|<> |An adversary with access to a set of compromised credentials may attempt to persist or escalate privileges by attaching additional permissions to compromised user accounts. This rule looks for use of the IAM `AttachUserPolicy` API operation to attach the highly permissive `AdministratorAccess` AWS managed policy to an existing IAM user. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS IAM], [Use Case: Identity and Access Audit], [Tactic: Privilege Escalation], [Tactic: Persistence], [Resources: Investigation Guide] |None |6 +|<> |An adversary with access to a set of compromised credentials may attempt to persist or escalate privileges by attaching additional permissions to compromised user accounts. This rule looks for use of the IAM `AttachUserPolicy` API operation to attach the highly permissive `AdministratorAccess` AWS managed policy to an existing IAM user. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS IAM], [Use Case: Identity and Access Audit], [Tactic: Privilege Escalation], [Tactic: Persistence], [Resources: Investigation Guide] |None |7 |<> |Identifies AWS CloudTrail events where an IAM role's trust policy has been updated by an IAM user or Assumed Role identity. The trust policy is a JSON document that defines which principals are allowed to assume the role. An attacker may attempt to modify this policy to gain the privileges of the role. This is a New Terms rule, which means it will only trigger once for each unique combination of the "cloud.account.id", "user.name" and "target.entity.id" fields, that have not been seen making this API request. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS IAM], [Use Case: Identity and Access Audit], [Resources: Investigation Guide], [Tactic: Privilege Escalation] |8.16.5 |214 @@ -132,7 +132,7 @@ and their rule type is `machine_learning`. |<> |Identifies the deletion of a specified AWS Identity and Access Management (IAM) resource group. Deleting a resource group does not delete resources that are members of the group; it only deletes the group structure. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS IAM], [Tactic: Impact], [Resources: Investigation Guide] |None |209 -|<> |Detects when an AWS IAM login profile is added to a root user account and is self-assigned. Adversaries, with temporary access to the root account, may add a login profile to the root user account to maintain access even if the original access key is rotated or disabled. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS IAM], [Use Case: Identity and Access Audit], [Tactic: Persistence], [Resources: Investigation Guide] |None |2 +|<> |Detects when an AWS IAM login profile is added to a root user account and is self-assigned. Adversaries, with temporary access to the root account, may add a login profile to the root user account to maintain access even if the original access key is rotated or disabled. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS IAM], [Use Case: Identity and Access Audit], [Tactic: Persistence], [Resources: Investigation Guide] |None |3 |<> |Identifies when an AWS IAM login profile is added to a user. Adversaries may add a login profile to an IAM user who typically does not have one and is used only for programmatic access. This can be used to maintain access to the account even if the original access key is rotated or disabled. This is a building block rule and does not generate alerts on its own. It is meant to be used for correlation with other rules to detect suspicious activity. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS IAM], [Use Case: Identity and Access Audit], [Tactic: Persistence], [Rule Type: BBR] |None |4 @@ -202,7 +202,7 @@ and their rule type is `machine_learning`. |<> |Identifies the deletion of various Amazon Simple Storage Service (S3) bucket configuration components. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Use Case: Asset Visibility], [Tactic: Defense Evasion], [Resources: Investigation Guide] |None |210 -|<> |Identifies a high number of failed S3 operations from a single source and account (or anonymous account) within a short timeframe. This activity can be indicative of attempting to cause an increase in billing to an account for excessive random operations, cause resource exhaustion, or enumerating bucket names for discovery. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS S3], [Resources: Investigation Guide], [Use Case: Log Auditing], [Tactic: Impact] |None |4 +|<> |Identifies a high number of failed S3 operations from a single source and account (or anonymous account) within a short timeframe. This activity can be indicative of attempting to cause an increase in billing to an account for excessive random operations, cause resource exhaustion, or enumerating bucket names for discovery. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS S3], [Resources: Investigation Guide], [Use Case: Log Auditing], [Tactic: Impact] |None |5 |<> |Identifies an expiration lifecycle configuration added to an S3 bucket. Lifecycle configurations can be used to manage objects in a bucket, including setting expiration policies. This rule detects when a lifecycle configuration is added to an S3 bucket, which could indicate that objects in the bucket will be automatically deleted after a specified period of time. This could be used to evade detection by deleting objects that contain evidence of malicious activity. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: Amazon S3], [Use Case: Asset Visibility], [Tactic: Defense Evasion], [Resources: Investigation Guide] |None |5 @@ -212,11 +212,11 @@ and their rule type is `machine_learning`. |<> |Identifies when server access logging is disabled for an Amazon S3 bucket. Server access logs provide a detailed record of requests made to an S3 bucket. When server access logging is disabled for a bucket, it could indicate an adversary's attempt to impair defenses by disabling logs that contain evidence of malicious activity. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: Amazon S3], [Use Case: Asset Visibility], [Tactic: Defense Evasion], [Resources: Investigation Guide] |None |4 -|<> |Identifies `CopyObject` events within an S3 bucket using an AWS KMS key from an external account for encryption. Adversaries with access to a misconfigured S3 bucket and the proper permissions may encrypt objects with an external KMS key to deny their victims access to their own data. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS S3], [Data Source: AWS KMS], [Use Case: Threat Detection], [Tactic: Impact], [Resources: Investigation Guide] |None |5 +|<> |Identifies `CopyObject` events within an S3 bucket using an AWS KMS key from an external account for encryption. Adversaries with access to a misconfigured S3 bucket and the proper permissions may encrypt objects with an external KMS key to deny their victims access to their own data. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS S3], [Data Source: AWS KMS], [Use Case: Threat Detection], [Tactic: Impact], [Resources: Investigation Guide] |None |6 |<> |Identifies when object versioning is suspended for an Amazon S3 bucket. Object versioning allows for multiple versions of an object to exist in the same bucket. This allows for easy recovery of deleted or overwritten objects. When object versioning is suspended for a bucket, it could indicate an adversary's attempt to inhibit system recovery following malicious activity. Additionally, when versioning is suspended, buckets can then be deleted. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS S3], [Use Case: Threat Detection], [Tactic: Impact], [Resources: Investigation Guide] |None |5 -|<> |This rule detects when a JavaScript file is uploaded or accessed in an S3 static site directory (`static/js/`) by an IAM user or assumed role. This can indicate suspicious modification of web content hosted on S3, such as injecting malicious scripts into a static website frontend. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS S3], [Tactic: Impact], [Use Case: Web Application Compromise], [Use Case: Cloud Threat Detection], [Resources: Investigation Guide] |None |1 +|<> |This rule detects when a JavaScript file is uploaded or accessed in an S3 static site directory (`static/js/`) by an IAM user or assumed role. This can indicate suspicious modification of web content hosted on S3, such as injecting malicious scripts into a static website frontend. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS S3], [Tactic: Impact], [Use Case: Web Application Compromise], [Use Case: Cloud Threat Detection], [Resources: Investigation Guide] |None |2 |<> |Identifies AWS CloudTrail events where an unauthenticated source is attempting to access an S3 bucket. This activity may indicate a misconfigured S3 bucket policy that allows public access to the bucket, potentially exposing sensitive data to unauthorized users. Adversaries can specify `--no-sign-request` in the AWS CLI to retrieve objects from an S3 bucket without authentication. This is a [New Terms](https://www.elastic.co/guide/en/security/current/rules-ui-create.html#create-new-terms-rule) rule, which means it will only trigger once for each unique value of the `source.address` field that has not been seen making this API request within the last 7 days. This field contains the IP address of the source making the request. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: Amazon S3], [Use Case: Asset Visibility], [Resources: Investigation Guide], [Tactic: Collection] |None |4 @@ -246,9 +246,9 @@ and their rule type is `machine_learning`. |<> |Identifies role chaining activity. Role chaining is when you use one assumed role to assume a second role through the AWS CLI or API. While this a recognized functionality in AWS, role chaining can be abused for privilege escalation if the subsequent assumed role provides additional privileges. Role chaining can also be used as a persistence mechanism as each AssumeRole action results in a refreshed session token with a 1 hour maximum duration. This rule looks for role chaining activity happening within a single account, to eliminate false positives produced by common cross-account behavior. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS STS], [Use Case: Threat Detection], [Tactic: Persistence], [Tactic: Privilege Escalation], [Tactic: Lateral Movement], [Resources: Investigation Guide] |None |2 -|<> |Identifies when a single AWS resource is making `GetServiceQuota` API calls for the EC2 service quota L-1216C47A in more than 10 regions within a 30-second window. Quota code L-1216C47A represents on-demand instances which are used by adversaries to deploy malware and mine cryptocurrency. This could indicate a potential threat actor attempting to discover the AWS infrastructure across multiple regions using compromised credentials or a compromised instance. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS Service Quotas], [Use Case: Threat Detection], [Tactic: Discovery], [Resources: Investigation Guide] |None |3 +|<> |Identifies when a single AWS resource is making `GetServiceQuota` API calls for the EC2 service quota L-1216C47A in more than 10 regions within a 30-second window. Quota code L-1216C47A represents on-demand instances which are used by adversaries to deploy malware and mine cryptocurrency. This could indicate a potential threat actor attempting to discover the AWS infrastructure across multiple regions using compromised credentials or a compromised instance. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS Service Quotas], [Use Case: Threat Detection], [Tactic: Discovery], [Resources: Investigation Guide] |None |4 -|<> |Identifies when a federated user logs into the AWS Management Console without using multi-factor authentication (MFA). Federated users are typically given temporary credentials to access AWS services. If a federated user logs into the AWS Management Console without using MFA, it may indicate a security risk, as MFA adds an additional layer of security to the authentication process. This could also indicate the abuse of STS tokens to bypass MFA requirements. |[Domain: Cloud], [Data Source: Amazon Web Services], [Data Source: AWS], [Data Source: AWS Sign-In], [Use Case: Threat Detection], [Tactic: Initial Access], [Resources: Investigation Guide] |None |3 +|<> |Identifies when a federated user logs into the AWS Management Console without using multi-factor authentication (MFA). Federated users are typically given temporary credentials to access AWS services. If a federated user logs into the AWS Management Console without using MFA, it may indicate a security risk, as MFA adds an additional layer of security to the authentication process. This could also indicate the abuse of STS tokens to bypass MFA requirements. |[Domain: Cloud], [Data Source: Amazon Web Services], [Data Source: AWS], [Data Source: AWS Sign-In], [Use Case: Threat Detection], [Tactic: Initial Access], [Resources: Investigation Guide] |None |4 |<> |Detects the first occurrence of a user identity accessing AWS Systems Manager (SSM) SecureString parameters using the GetParameter or GetParameters API actions with credentials in the request parameters. This could indicate that the user is accessing sensitive information. This rule detects when a user accesses a SecureString parameter with the withDecryption parameter set to true. This is a New Terms rule that detects the first occurrence of an AWS identity accessing SecureString parameters with decryption. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS Systems Manager], [Tactic: Credential Access], [Resources: Investigation Guide] |None |6 @@ -442,7 +442,7 @@ and their rule type is `machine_learning`. |<> |Identifies the deletion of a Network Watcher in Azure. Network Watchers are used to monitor, diagnose, view metrics, and enable or disable logs for resources in an Azure virtual network. An adversary may delete a Network Watcher in an attempt to evade defenses. |[Domain: Cloud], [Data Source: Azure], [Use Case: Network Security Monitoring], [Tactic: Defense Evasion], [Resources: Investigation Guide] |None |105 -|<> |Detects when Azure OpenAI requests result in zero response length, potentially indicating issues in output handling that might lead to security exploits such as data leaks or code execution. This can occur in cases where the API fails to handle outputs correctly under certain input conditions. |[Domain: LLM], [Data Source: Azure OpenAI], [Data Source: Azure Event Hubs], [Use Case: Insecure Output Handling], [Resources: Investigation Guide] |None |2 +|<> |Detects when Azure OpenAI requests result in zero response length, potentially indicating issues in output handling that might lead to security exploits such as data leaks or code execution. This can occur in cases where the API fails to handle outputs correctly under certain input conditions. |[Domain: LLM], [Data Source: Azure OpenAI], [Data Source: Azure Event Hubs], [Use Case: Insecure Output Handling], [Resources: Investigation Guide] |None |3 |<> |Azure Active Directory (AD) Privileged Identity Management (PIM) is a service that enables you to manage, control, and monitor access to important resources in an organization. PIM can be used to manage the built-in Azure resource roles such as Global Administrator and Application Administrator. An adversary may add a user to a PIM role in order to maintain persistence in their target's environment or modify a PIM role to weaken their target's security controls. |[Domain: Cloud], [Data Source: Azure], [Use Case: Identity and Access Audit], [Resources: Investigation Guide], [Tactic: Persistence] |None |107 @@ -588,8 +588,6 @@ and their rule type is `machine_learning`. |<> |Identifies use of the fsutil.exe to delete the volume USNJRNL. This technique is used by attackers to eliminate evidence of files created during post-exploitation activities. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: Elastic Endgame], [Resources: Investigation Guide], [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] |None |314 -|<> |Identifies potential brute-force attempts against Microsoft 365 user accounts by detecting a high number of failed interactive or non-interactive login attempts within a 30-minute window from a single source. Attackers may attempt to brute force user accounts to gain unauthorized access to Microsoft 365 services via different services such as Exchange, SharePoint, or Teams. |[Domain: Cloud], [Domain: SaaS], [Data Source: Azure], [Data Source: Entra ID], [Data Source: Entra ID Sign-in], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide] |None |4 - |<> |Indicates the creation or modification of a launch daemon, which adversaries may use to repeatedly execute malicious payloads as part of persistence. |[Domain: Endpoint], [OS: macOS], [Use Case: Threat Detection], [Tactic: Persistence], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |111 |<> |This rule identifies the creation of directories in the /bin directory. The /bin directory contains essential binary files that are required for the system to function properly. The creation of directories in this location could be an attempt to hide malicious files or executables, as these /bin directories usually just contain binaries. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Tactic: Persistence], [Data Source: Elastic Defend], [Data Source: Crowdstrike], [Data Source: SentinelOne], [Data Source: Elastic Endgame], [Resources: Investigation Guide] |None |105 @@ -626,7 +624,7 @@ and their rule type is `machine_learning`. |<> |Adversaries may dump the content of the keychain storage data from a system to acquire credentials. Keychains are the built-in way for macOS to keep track of users' passwords and credentials for many services and features, including Wi-Fi and website passwords, secure notes, certificates, and Kerberos. |[Domain: Endpoint], [OS: macOS], [Use Case: Threat Detection], [Tactic: Credential Access], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |112 -|<> |Identifies PowerShell scripts that reconstruct the IEX (Invoke-Expression) command by accessing and indexing the string representation of method references. This obfuscation technique uses constructs like ''.IndexOf.ToString() to expose method metadata as a string, then extracts specific characters through indexed access and joins them to form IEX, bypassing static keyword detection and evading defenses such as AMSI. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |3 +|<> |Identifies PowerShell scripts that reconstruct the IEX (Invoke-Expression) command by accessing and indexing the string representation of method references. This obfuscation technique uses constructs like ''.IndexOf.ToString() to expose method metadata as a string, then extracts specific characters through indexed access and joins them to form IEX, bypassing static keyword detection and evading defenses such as AMSI. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |4 |<> |This rule detects the creation of the dynamic linker (ld.so) file. The dynamic linker is used to load shared libraries needed by an executable. Attackers may attempt to replace the dynamic linker with a malicious version to execute arbitrary code. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Tactic: Execution], [Tactic: Persistence], [Data Source: Elastic Defend], [Data Source: SentinelOne], [Data Source: Elastic Endgame], [Resources: Investigation Guide] |None |104 @@ -646,7 +644,7 @@ and their rule type is `machine_learning`. |<> |Identifies the Elastic endpoint agent has stopped and is no longer running on the host. Adversaries may attempt to disable security monitoring tools in an attempt to evade detection or prevention capabilities during an intrusion. This may also indicate an issue with the agent itself and should be addressed to ensure defensive measures are back in a stable state. |[Domain: Endpoint], [OS: Linux], [OS: Windows], [OS: macOS], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |110 -|<> |Generates a detection alert for each Elastic Security alert written to the configured indices. Enabling this rule allows you to immediately begin investigating Elastic Security alerts in the app. |[Data Source: Elastic Security], [Use Case: Threat Detection], [Resources: Investigation Guide], [Promotion: External Alerts] |8.18.0 |1 +|<> |Generates a detection alert for each Elastic Security alert written to the configured indices. Enabling this rule allows you to immediately begin investigating Elastic Security alerts in the app. |[Data Source: Elastic Security], [Use Case: Threat Detection], [Resources: Investigation Guide], [Promotion: External Alerts] |8.18.0 |2 |<> |Identifies the creation or modification of the Event Monitor Daemon (emond) rules. Adversaries may abuse this service by writing a rule to execute commands when a defined event occurs, such as system start up or user authentication. |[Domain: Endpoint], [OS: macOS], [Use Case: Threat Detection], [Tactic: Persistence], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |112 @@ -688,7 +686,7 @@ and their rule type is `machine_learning`. |<> |Identifies an excessive number of Microsoft 365 mailbox items accessed by a user either via aggregated counts or throttling. Microsoft audits mailbox access via the MailItemsAccessed event, which is triggered when a user accesses mailbox items. If more than 1000 mailbox items are accessed within a 24-hour period, it is then throttled. Excessive mailbox access may indicate an adversary attempting to exfiltrate sensitive information or perform reconnaissance on a target's mailbox. This rule detects both the throttled and unthrottled events with a high threshold. |[Domain: Cloud], [Domain: Email], [Data Source: Microsoft 365], [Data Source: Microsoft 365 Audit Logs], [Use Case: Threat Detection], [Tactic: Collection], [Resources: Investigation Guide] |None |1 -|<> |Identifies excessive secret or key retrieval operations from Azure Key Vault. This rule detects when a user principal retrieves secrets or keys from Azure Key Vault multiple times within a short time frame, which may indicate potential abuse or unauthorized access attempts. The rule focuses on high-frequency retrieval operations that deviate from normal user behavior, suggesting possible credential harvesting or misuse of sensitive information. |[Domain: Cloud], [Domain: Storage], [Domain: Identity], [Data Source: Azure], [Data Source: Azure Platform Logs], [Data Source: Azure Key Vault], [Use Case: Threat Detection], [Use Case: Identity and Access Audit], [Tactic: Credential Access], [Resources: Investigation Guide] |None |1 +|<> |Identifies excessive secret or key retrieval operations from Azure Key Vault. This rule detects when a user principal retrieves secrets or keys from Azure Key Vault multiple times within a short time frame, which may indicate potential abuse or unauthorized access attempts. The rule focuses on high-frequency retrieval operations that deviate from normal user behavior, suggesting possible credential harvesting or misuse of sensitive information. |[Domain: Cloud], [Domain: Storage], [Domain: Identity], [Data Source: Azure], [Data Source: Azure Platform Logs], [Data Source: Azure Key Vault], [Use Case: Threat Detection], [Use Case: Identity and Access Audit], [Tactic: Credential Access], [Resources: Investigation Guide] |None |2 |<> |Identifies the use of the Exchange PowerShell cmdlet, New-MailBoxExportRequest, to export the contents of a primary mailbox or archive to a .pst file. Adversaries may target user email to collect sensitive information. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Collection], [Resources: Investigation Guide], [Data Source: PowerShell Logs] |None |212 @@ -958,9 +956,9 @@ and their rule type is `machine_learning`. |<> |Detects a high number of unique private repo clone events originating from a single personal access token within a short time period. |[Domain: Cloud], [Use Case: Threat Detection], [Use Case: UEBA], [Tactic: Execution], [Data Source: Github], [Resources: Investigation Guide] |None |207 -|<> |This rule detects a high number of egress network connections from an unusual executable on a Linux system. This could indicate a command and control (C2) communication attempt, a brute force attack via a malware infection, or other malicious activity. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Command and Control], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |4 +|<> |This rule detects a high number of egress network connections from an unusual executable on a Linux system. This could indicate a command and control (C2) communication attempt, a brute force attack via a malware infection, or other malicious activity. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Command and Control], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |5 -|<> |Detects when an Okta client address has a certain threshold of Okta user authentication events with multiple device token hashes generated for single user authentication. Adversaries may attempt to launch a credential stuffing or password spraying attack from the same device by using a list of known usernames and passwords to gain unauthorized access to user accounts. |[Use Case: Identity and Access Audit], [Data Source: Okta], [Tactic: Credential Access], [Resources: Investigation Guide] |None |205 +|<> |Detects when an Okta client address has a certain threshold of Okta user authentication events with multiple device token hashes generated for single user authentication. Adversaries may attempt to launch a credential stuffing or password spraying attack from the same device by using a list of known usernames and passwords to gain unauthorized access to user accounts. |[Use Case: Identity and Access Audit], [Data Source: Okta], [Tactic: Credential Access], [Resources: Investigation Guide] |None |206 |<> |Identifies a high number of Okta user password reset or account unlock attempts. An adversary may attempt to obtain unauthorized access to Okta user accounts using these methods and attempt to blend in with normal activity in their target's environment and evade detection. |[Use Case: Identity and Access Audit], [Data Source: Okta], [Tactic: Defense Evasion], [Resources: Investigation Guide] |None |415 @@ -1150,7 +1148,7 @@ and their rule type is `machine_learning`. |<> |This rule identifies successful logins by system users that are uncommon to authenticate. These users have `nologin` set by default, and must be modified to allow SSH access. Adversaries may backdoor these users to gain unauthorized access to the system. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Persistence], [Tactic: Defense Evasion], [Data Source: System], [Resources: Investigation Guide] |None |4 -|<> |Identifies when an excessive number of files are downloaded from OneDrive using OAuth authentication. Adversaries may conduct phishing campaigns to steal OAuth tokens and impersonate users. These access tokens can then be used to download files from OneDrive. |[Domain: Cloud], [Domain: SaaS], [Data Source: Microsoft 365], [Data Source: SharePoint], [Data Source: OneDrive], [Use Case: Threat Detection], [Tactic: Collection], [Tactic: Exfiltration], [Resources: Investigation Guide] |None |2 +|<> |Identifies when an excessive number of files are downloaded from OneDrive using OAuth authentication. Adversaries may conduct phishing campaigns to steal OAuth tokens and impersonate users. These access tokens can then be used to download files from OneDrive. |[Domain: Cloud], [Domain: SaaS], [Data Source: Microsoft 365], [Data Source: SharePoint], [Data Source: OneDrive], [Use Case: Threat Detection], [Tactic: Collection], [Tactic: Exfiltration], [Resources: Investigation Guide] |None |3 |<> |Detects multi-factor authentication (MFA) deactivation with no subsequent re-activation for an Okta user account. An adversary may deactivate MFA for an Okta user account in order to weaken the authentication requirements for the account. |[Tactic: Persistence], [Use Case: Identity and Access Audit], [Data Source: Okta], [Domain: Cloud], [Resources: Investigation Guide] |None |415 @@ -1196,7 +1194,7 @@ and their rule type is `machine_learning`. |<> |This rule detects the creation of potentially malicious files within the default MOTD file directories. Message of the day (MOTD) is the message that is presented to the user when a user connects to a Linux server via SSH or a serial connection. Linux systems contain several default MOTD files located in the "/etc/update-motd.d/" directory. These scripts run as the root user every time a user connects over SSH or a serial connection. Adversaries may create malicious MOTD files that grant them persistence onto the target every time a user connects to the system by executing a backdoor script or command. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Persistence], [Resources: Investigation Guide], [Data Source: Elastic Defend] |None |15 -|<> |Identifies potential brute-force attacks targeting Microsoft 365 user accounts by analyzing failed sign-in patterns in Microsoft Entra ID Sign-In Logs. This detection focuses on a high volume of failed interactive or non-interactive authentication attempts within a short time window, often indicative of password spraying, credential stuffing, or password guessing. Adversaries may use these techniques to gain unauthorized access to Microsoft 365 services such as Exchange Online, SharePoint, or Teams. |[Domain: Cloud], [Domain: SaaS], [Domain: Identity], [Data Source: Azure], [Data Source: Entra ID], [Data Source: Entra ID Sign-in Logs], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide] |None |105 +|<> |Identifies potential brute-force attacks targeting Microsoft 365 user accounts by analyzing failed sign-in patterns in Microsoft Entra ID Sign-In Logs. This detection focuses on a high volume of failed interactive or non-interactive authentication attempts within a short time window, often indicative of password spraying, credential stuffing, or password guessing. Adversaries may use these techniques to gain unauthorized access to Microsoft 365 services such as Exchange Online, SharePoint, or Teams. |[Domain: Cloud], [Domain: SaaS], [Domain: Identity], [Data Source: Azure], [Data Source: Entra ID], [Data Source: Entra ID Sign-in Logs], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide] |None |106 |<> |Identifies the deletion of an anti-phishing policy in Microsoft 365. By default, Microsoft 365 includes built-in features that help protect users from phishing attacks. Anti-phishing polices increase this protection by refining settings to better detect and prevent attacks. |[Domain: Cloud], [Data Source: Microsoft 365], [Use Case: Configuration Audit], [Tactic: Initial Access], [Resources: Investigation Guide] |None |209 @@ -1260,19 +1258,19 @@ and their rule type is `machine_learning`. |<> |An instance of MSBuild, the Microsoft Build Engine, was started after being renamed. This is uncommon behavior and may indicate an attempt to run unnoticed or undetected. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Tactic: Execution], [Data Source: Elastic Endgame], [Resources: Investigation Guide], [Data Source: Elastic Defend], [Data Source: Sysmon], [Data Source: Microsoft Defender for Endpoint] |None |217 -|<> |Identifies concurrent azure signin events for the same user and from multiple sources, and where one of the authentication event has some suspicious properties often associated to DeviceCode and OAuth phishing. Adversaries may steal Refresh Tokens (RTs) via phishing to bypass multi-factor authentication (MFA) and gain unauthorized access to Azure resources. |[Domain: Cloud], [Domain: SaaS], [Data Source: Azure], [Data Source: Entra ID], [Data Source: Entra ID Sign-in], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide] |None |1 +|<> |Identifies concurrent azure signin events for the same user and from multiple sources, and where one of the authentication event has some suspicious properties often associated to DeviceCode and OAuth phishing. Adversaries may steal Refresh Tokens (RTs) via phishing to bypass multi-factor authentication (MFA) and gain unauthorized access to Azure resources. |[Domain: Cloud], [Domain: SaaS], [Data Source: Azure], [Data Source: Entra ID], [Data Source: Entra ID Sign-in], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide] |None |2 |<> |Identifies a modification to a conditional access policy (CAP) in Microsoft Entra ID. Adversaries may modify existing CAPs to loosen access controls and maintain persistence in the environment with a compromised identity or entity. |[Domain: Cloud], [Data Source: Azure], [Data Source: Microsoft Entra ID], [Data Source: Microsoft Entra ID Audit Logs], [Use Case: Identity and Access Audit], [Use Case: Configuration Audit], [Tactic: Persistence], [Resources: Investigation Guide] |None |106 |<> |Identifies when a user has elevated their access to User Access Administrator for their Azure Resources. The User Access Administrator role allows users to manage user access to Azure resources, including the ability to assign roles and permissions. Adversaries may target an Entra ID Global Administrator or other privileged role to elevate their access to User Access Administrator, which can lead to further privilege escalation and unauthorized access to sensitive resources. This is a New Terms rule that only signals if the user principal name has not been seen doing this activity in the last 14 days. |[Domain: Cloud], [Data Source: Azure], [Data Source: Microsoft Entra ID], [Data Source: Microsoft Entra ID Audit Logs], [Use Case: Identity and Access Audit], [Tactic: Privilege Escalation], [Resources: Investigation Guide] |None |1 -|<> |Identifies a high count of failed Microsoft Entra ID sign-in attempts as the result of the target user account being locked out. Adversaries may attempt to brute-force user accounts by repeatedly trying to authenticate with incorrect credentials, leading to account lockouts by Entra ID Smart Lockout policies. |[Domain: Cloud], [Domain: Identity], [Data Source: Azure], [Data Source: Entra ID], [Data Source: Entra ID Sign-in Logs], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide] |None |1 +|<> |Identifies a high count of failed Microsoft Entra ID sign-in attempts as the result of the target user account being locked out. Adversaries may attempt to brute-force user accounts by repeatedly trying to authenticate with incorrect credentials, leading to account lockouts by Entra ID Smart Lockout policies. |[Domain: Cloud], [Domain: Identity], [Data Source: Azure], [Data Source: Entra ID], [Data Source: Entra ID Sign-in Logs], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide] |None |2 |<> |Identifies high risk Microsoft Entra ID sign-ins by leveraging Microsoft's Identity Protection machine learning and heuristics. Identity Protection categorizes risk into three tiers: low, medium, and high. While Microsoft does not provide specific details about how risk is calculated, each level brings higher confidence that the user or sign-in is compromised. |[Domain: Cloud], [Data Source: Azure], [Data Source: Microsoft Entra ID], [Data Source: Microsoft Entra ID Sign-in Logs], [Use Case: Identity and Access Audit], [Resources: Investigation Guide], [Tactic: Initial Access] |None |108 |<> |Identifies an illicit consent grant request on-behalf-of a registered Entra ID application. Adversaries may create and register an application in Microsoft Entra ID for the purpose of requesting user consent to access resources. This is accomplished by tricking a user into granting consent to the application, typically via a pre-made phishing URL. This establishes an OAuth grant that allows the malicious client applocation to access resources on-behalf-of the user. |[Domain: Cloud], [Data Source: Azure], [Data Source: Microsoft Entra ID], [Data Source: Microsoft Entra ID Audit Logs], [Use Case: Identity and Access Audit], [Resources: Investigation Guide], [Tactic: Initial Access], [Tactic: Credential Access] |None |216 -|<> |Identifies brute force attempts against Azure Entra multi-factor authentication (MFA) Time-based One-Time Password (TOTP) verification codes. This rule detects high frequency failed TOTP code attempts for a single user in a short time-span with a high number of distinct session IDs. Adversaries may programmatically attemopt to brute-force TOTP codes by generating several sessions and attempt to guess the correct code. |[Domain: Cloud], [Domain: Identity], [Data Source: Azure], [Data Source: Entra ID], [Data Source: Entra ID Sign-in logs], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide] |None |3 +|<> |Identifies brute force attempts against Azure Entra multi-factor authentication (MFA) Time-based One-Time Password (TOTP) verification codes. This rule detects high frequency failed TOTP code attempts for a single user in a short time-span with a high number of distinct session IDs. Adversaries may programmatically attemopt to brute-force TOTP codes by generating several sessions and attempt to guess the correct code. |[Domain: Cloud], [Domain: Identity], [Data Source: Azure], [Data Source: Entra ID], [Data Source: Entra ID Sign-in logs], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide] |None |4 |<> |Detects potentially suspicious OAuth authorization activity in Microsoft Entra ID where the Visual Studio Code first-party application (client_id = aebc6443-996d-45c2-90f0-388ff96faa56) is used to request access to Microsoft Graph resources. While this client ID is legitimately used by Visual Studio Code, threat actors have been observed abusing it in phishing campaigns to make OAuth requests appear trustworthy. These attacks rely on redirect URIs such as VSCode's Insiders redirect location, prompting victims to return an OAuth authorization code that can be exchanged for access tokens. This rule may help identify unauthorized use of the VS Code OAuth flow as part of social engineering or credential phishing activity. |[Domain: Cloud], [Data Source: Azure], [Data Source: Microsoft Entra ID], [Data Source: Microsoft Entra ID Sign-in Logs], [Use Case: Identity and Access Audit], [Resources: Investigation Guide], [Tactic: Initial Access] |None |3 @@ -1284,11 +1282,11 @@ and their rule type is `machine_learning`. |<> |Identifies when new Service Principal credentials have been added in Microsoft Entra ID. In most organizations, credentials will be added to service principals infrequently. Hijacking an application (by adding a rogue secret or certificate) with granted permissions will allow the attacker to access data that is normally protected by MFA requirements. |[Domain: Cloud], [Data Source: Azure], [Data Source: Microsoft Entra ID], [Data Source: Microsoft Entra ID Audit Logs], [Use Case: Identity and Access Audit], [Tactic: Persistence], [Resources: Investigation Guide] |None |107 -|<> |Identifies potential session hijacking or token replay in Microsoft Entra ID. This rule detects cases where a user signs in and subsequently accesses Microsoft Graph from a different IP address using the same session ID within a short time window. This may indicate the use of a stolen refresh/access token or session cookie to impersonate the user and interact with Microsoft services. |[Domain: Cloud], [Data Source: Azure], [Data Source: Microsoft Entra ID], [Data Source: Microsoft Entra ID Sign-In Logs], [Data Source: Microsoft Graph], [Data Source: Microsoft Graph Activity Logs], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Resources: Investigation Guide], [Tactic: Defense Evasion], [Tactic: Initial Access] |None |2 +|<> |Identifies potential session hijacking or token replay in Microsoft Entra ID. This rule detects cases where a user signs in and subsequently accesses Microsoft Graph from a different IP address using the same session ID within a short time window. This may indicate the use of a stolen refresh/access token or session cookie to impersonate the user and interact with Microsoft services. |[Domain: Cloud], [Data Source: Azure], [Data Source: Microsoft Entra ID], [Data Source: Microsoft Entra ID Sign-In Logs], [Data Source: Microsoft Graph], [Data Source: Microsoft Graph Activity Logs], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Resources: Investigation Guide], [Tactic: Defense Evasion], [Tactic: Initial Access] |None |3 |<> |This rule detects non-interactive authentication activity against SharePoint Online (`Office 365 SharePoint Online`) by a user principal via the `Microsoft Authentication Broker` application. The session leverages a refresh token or Primary Refresh Token (PRT) without interactive sign-in, often used in OAuth phishing or token replay scenarios. |[Domain: Cloud], [Use Case: Identity and Access Audit], [Tactic: Collection], [Data Source: Azure], [Data Source: Microsoft Entra ID], [Data Source: Microsoft Entra ID Sign-in Logs], [Resources: Investigation Guide] |None |2 -|<> |Identifies potential brute-force attacks targeting user accounts by analyzing failed sign-in patterns in Microsoft Entra ID Sign-In Logs. This detection focuses on a high volume of failed interactive or non-interactive authentication attempts within a short time window, often indicative of password spraying, credential stuffing, or password guessing. Adversaries may use these techniques to gain unauthorized access to applications integrated with Entra ID or to compromise valid user accounts. |[Domain: Cloud], [Domain: Identity], [Data Source: Azure], [Data Source: Entra ID], [Data Source: Entra ID Sign-in Logs], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide] |8.17.0 |3 +|<> |Identifies potential brute-force attacks targeting user accounts by analyzing failed sign-in patterns in Microsoft Entra ID Sign-In Logs. This detection focuses on a high volume of failed interactive or non-interactive authentication attempts within a short time window, often indicative of password spraying, credential stuffing, or password guessing. Adversaries may use these techniques to gain unauthorized access to applications integrated with Entra ID or to compromise valid user accounts. |[Domain: Cloud], [Domain: Identity], [Data Source: Azure], [Data Source: Entra ID], [Data Source: Entra ID Sign-in Logs], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide] |8.17.0 |4 |<> |Detects a sequence of events in Microsoft Entra ID indicative of a suspicious cloud-based device registration, potentially using ROADtools. This behavior involves adding a device via the Device Registration Service, followed by the assignment of registered users and owners β€” a pattern consistent with techniques used to establish persistence or acquire a Primary Refresh Token (PRT). ROADtools, a popular red team toolkit, often leaves distinct telemetry signatures such as the `Microsoft.OData.Client` user agent and specific OS version values. These sequences are uncommon in typical user behavior and may reflect abuse of device trust for session hijacking or silent token replay. |[Domain: Cloud], [Domain: Identity], [Data Source: Azure], [Data Source: Microsoft Entra ID], [Data Source: Microsoft Entra ID Audit Logs], [Use Case: Identity and Access Audit], [Tactic: Persistence], [Resources: Investigation Guide] |None |1 @@ -1354,13 +1352,13 @@ and their rule type is `machine_learning`. |<> |This rule uses alert data to determine when multiple alerts in different phases of an attack involving the same host are triggered. Analysts can use this to prioritize triage and response, as these hosts are more likely to be compromised. |[Use Case: Threat Detection], [Rule Type: Higher-Order Rule], [Resources: Investigation Guide] |None |6 -|<> |This rule detects when a specific Okta actor has multiple device token hashes for a single Okta session. This may indicate an authenticated session has been hijacked or is being used by multiple devices. Adversaries may hijack a session to gain unauthorized access to Okta admin console, applications, tenants, or other resources. |[Use Case: Identity and Access Audit], [Data Source: Okta], [Tactic: Credential Access], [Domain: SaaS], [Resources: Investigation Guide] |None |306 +|<> |This rule detects when a specific Okta actor has multiple device token hashes for a single Okta session. This may indicate an authenticated session has been hijacked or is being used by multiple devices. Adversaries may hijack a session to gain unauthorized access to Okta admin console, applications, tenants, or other resources. |[Use Case: Identity and Access Audit], [Data Source: Okta], [Tactic: Credential Access], [Domain: SaaS], [Resources: Investigation Guide] |None |307 |<> |Identifies multiple logon failures followed by a successful one from the same source address. Adversaries will often brute force login attempts across multiple users with a common or known password, in an attempt to gain access to accounts. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide], [Data Source: Windows Security Event Logs] |None |115 |<> |Identifies multiple consecutive logon failures from the same source address and within a short time interval. Adversaries will often brute force login attempts across multiple users with a common or known password, in an attempt to gain access to accounts. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide], [Data Source: Windows Security Event Logs] |None |114 -|<> |Detects a burst of Microsoft 365 user account lockouts within a short 5-minute window. A high number of IdsLocked login errors across multiple user accounts may indicate brute-force attempts for the same users resulting in lockouts. |[Domain: Cloud], [Domain: SaaS], [Data Source: Microsoft 365], [Data Source: Microsoft 365 Audit Logs], [Use Case: Threat Detection], [Use Case: Identity and Access Audit], [Tactic: Credential Access], [Resources: Investigation Guide] |None |2 +|<> |Detects a burst of Microsoft 365 user account lockouts within a short 5-minute window. A high number of IdsLocked login errors across multiple user accounts may indicate brute-force attempts for the same users resulting in lockouts. |[Domain: Cloud], [Domain: SaaS], [Data Source: Microsoft 365], [Data Source: Microsoft 365 Audit Logs], [Use Case: Threat Detection], [Use Case: Identity and Access Audit], [Tactic: Credential Access], [Resources: Investigation Guide] |None |3 |<> |Identifies more than two Microsoft Entra ID Protection alerts associated to the user principal in a short time period. Microsoft Entra ID Protection alerts are triggered by suspicious sign-in activity, such as anomalous IP addresses, risky sign-ins, or other risk detections. Multiple alerts in a short time frame may indicate an ongoing attack or compromised account. |[Domain: Cloud], [Data Source: Azure], [Data Source: Microsoft Entra ID], [Data Source: Microsoft Entra ID Protection Logs], [Use Case: Identity and Access Audit], [Resources: Investigation Guide], [Tactic: Initial Access] |None |1 @@ -1368,9 +1366,9 @@ and their rule type is `machine_learning`. |<> |Detects when Okta user authentication events are reported for multiple users with the same device token hash behind a proxy. |[Use Case: Identity and Access Audit], [Data Source: Okta], [Tactic: Credential Access], [Resources: Investigation Guide] |None |209 -|<> |Detects when a certain threshold of Okta user authentication events are reported for multiple users from the same client address. Adversaries may attempt to launch a credential stuffing or password spraying attack from the same device by using a list of known usernames and passwords to gain unauthorized access to user accounts. |[Use Case: Identity and Access Audit], [Data Source: Okta], [Tactic: Credential Access], [Resources: Investigation Guide] |None |205 +|<> |Detects when a certain threshold of Okta user authentication events are reported for multiple users from the same client address. Adversaries may attempt to launch a credential stuffing or password spraying attack from the same device by using a list of known usernames and passwords to gain unauthorized access to user accounts. |[Use Case: Identity and Access Audit], [Data Source: Okta], [Tactic: Credential Access], [Resources: Investigation Guide] |None |206 -|<> |Detects when a high number of Okta user authentication events are reported for multiple users in a short time frame. Adversaries may attempt to launch a credential stuffing or password spraying attack from the same device by using a list of known usernames and passwords to gain unauthorized access to user accounts. |[Use Case: Identity and Access Audit], [Data Source: Okta], [Tactic: Credential Access], [Resources: Investigation Guide] |None |205 +|<> |Detects when a high number of Okta user authentication events are reported for multiple users in a short time frame. Adversaries may attempt to launch a credential stuffing or password spraying attack from the same device by using a list of known usernames and passwords to gain unauthorized access to user accounts. |[Use Case: Identity and Access Audit], [Data Source: Okta], [Tactic: Credential Access], [Resources: Investigation Guide] |None |206 |<> |Windows Credential Manager allows you to create, view, or delete saved credentials for signing into websites, connected applications, and networks. An adversary may abuse this to list or dump credentials stored in the Credential Manager for saved usernames and passwords. This may also be performed in preparation of lateral movement. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Credential Access], [Data Source: Windows Security Event Logs], [Resources: Investigation Guide] |None |115 @@ -1446,7 +1444,7 @@ and their rule type is `machine_learning`. |<> |Detects the occurrence of mailbox audit bypass associations. The mailbox audit is responsible for logging specified mailbox events (like accessing a folder or a message or permanently deleting a message). However, actions taken by some authorized accounts, such as accounts used by third-party tools or accounts used for lawful monitoring, can create a large number of mailbox audit log entries and may not be of interest to your organization. Because of this, administrators can create bypass associations, allowing certain accounts to perform their tasks without being logged. Attackers can abuse this allowlist mechanism to conceal actions taken, as the mailbox audit will log no activity done by the account. |[Domain: Cloud], [Data Source: Microsoft 365], [Tactic: Initial Access], [Tactic: Defense Evasion], [Resources: Investigation Guide] |None |209 -|<> |Detects a change to the OpenID Connect (OIDC) discovery URL in the Entra ID Authentication Methods Policy. This behavior may indicate an attempt to federate Entra ID with an attacker-controlled identity provider, enabling bypass of multi-factor authentication (MFA) and unauthorized access through bring-your-own IdP (BYOIDP) methods. |[Domain: Cloud], [Domain: Identity], [Data Source: Azure], [Data Source: Microsoft Entra ID], [Data Source: Microsoft Entra ID Audit Logs], [Use Case: Identity and Access Audit], [Tactic: Persistence], [Resources: Investigation Guide] |None |2 +|<> |Detects a change to the OpenID Connect (OIDC) discovery URL in the Entra ID Authentication Methods Policy. This behavior may indicate an attempt to federate Entra ID with an attacker-controlled identity provider, enabling bypass of multi-factor authentication (MFA) and unauthorized access through bring-your-own IdP (BYOIDP) methods. |[Domain: Cloud], [Domain: Identity], [Data Source: Azure], [Data Source: Microsoft Entra ID], [Data Source: Microsoft Entra ID Audit Logs], [Use Case: Identity and Access Audit], [Tactic: Persistence], [Resources: Investigation Guide] |None |3 |<> |Identifies the modification of the Microsoft Office "Office Test" Registry key, a registry location that can be used to specify a DLL which will be executed every time an MS Office application is started. Attackers can abuse this to gain persistence on a compromised host. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Persistence], [Tactic: Defense Evasion], [Data Source: Elastic Defend], [Data Source: Elastic Endgame], [Data Source: Microsoft Defender for Endpoint], [Data Source: SentinelOne], [Resources: Investigation Guide] |None |106 @@ -1460,7 +1458,7 @@ and their rule type is `machine_learning`. |<> |A user has initiated a session impersonation granting them access to the environment with the permissions of the user they are impersonating. This would likely indicate Okta administrative access and should only ever occur if requested and expected. |[Use Case: Identity and Access Audit], [Tactic: Credential Access], [Data Source: Okta], [Resources: Investigation Guide] |None |414 -|<> |Detects when a specific Okta actor has multiple sessions started from different geolocations. Adversaries may attempt to launch an attack by using a list of known usernames and passwords to gain unauthorized access to user accounts from different locations. |[Use Case: Identity and Access Audit], [Data Source: Okta], [Tactic: Initial Access], [Resources: Investigation Guide] |None |306 +|<> |Detects when a specific Okta actor has multiple sessions started from different geolocations. Adversaries may attempt to launch an attack by using a list of known usernames and passwords to gain unauthorized access to user accounts from different locations. |[Use Case: Identity and Access Audit], [Data Source: Okta], [Tactic: Initial Access], [Resources: Investigation Guide] |None |307 |<> |Identifies the occurence of files uploaded to OneDrive being detected as Malware by the file scanning engine. Attackers can use File Sharing and Organization Repositories to spread laterally within the company and amplify their access. Users can inadvertently share these files without knowing their maliciousness, giving adversaries opportunity to gain initial access to other endpoints in the environment. |[Domain: Cloud], [Data Source: Microsoft 365], [Tactic: Lateral Movement], [Resources: Investigation Guide] |None |209 @@ -1534,9 +1532,9 @@ and their rule type is `machine_learning`. |<> |Active Directory Integrated DNS (ADIDNS) is one of the core components of AD DS, leveraging AD's access control and replication to maintain domain consistency. It stores DNS zones as AD objects, a feature that, while robust, introduces some security issues, such as wildcard records, mainly because of the default permission (Any authenticated users) to create DNS-named records. Attackers can create wildcard records to redirect traffic that doesn't explicitly match records contained in the zone, becoming the Man-in-the-Middle and being able to abuse DNS similarly to LLMNR/NBNS spoofing. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Credential Access], [Data Source: Active Directory], [Use Case: Active Directory Monitoring], [Data Source: Windows Security Event Logs], [Resources: Investigation Guide] |None |107 -|<> |Identifies potential ransomware note being uploaded to an AWS S3 bucket. This rule detects the `PutObject` S3 API call with a common ransomware note file extension such as `.ransom`, or `.lock`. Adversaries with access to a misconfigured S3 bucket may retrieve, delete, and replace objects with ransom notes to extort victims. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS S3], [Use Case: Threat Detection], [Tactic: Impact], [Resources: Investigation Guide] |None |5 +|<> |Identifies potential ransomware note being uploaded to an AWS S3 bucket. This rule detects the `PutObject` S3 API call with a common ransomware note file extension such as `.ransom`, or `.lock`. Adversaries with access to a misconfigured S3 bucket may retrieve, delete, and replace objects with ransom notes to extort victims. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS S3], [Use Case: Threat Detection], [Tactic: Impact], [Resources: Investigation Guide] |None |6 -|<> |Detects potential resource exhaustion or data breach attempts by monitoring for users who consistently generate high input token counts, submit numerous requests, and receive large responses. This behavior could indicate an attempt to overload the system or extract an unusually large amount of data, possibly revealing sensitive information or causing service disruptions. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: Amazon Web Services], [Data Source: AWS S3], [Use Case: Potential Overload], [Use Case: Resource Exhaustion], [Mitre Atlas: LLM04], [Resources: Investigation Guide] |None |4 +|<> |Detects potential resource exhaustion or data breach attempts by monitoring for users who consistently generate high input token counts, submit numerous requests, and receive large responses. This behavior could indicate an attempt to overload the system or extract an unusually large amount of data, possibly revealing sensitive information or causing service disruptions. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: Amazon Web Services], [Data Source: AWS S3], [Use Case: Potential Overload], [Use Case: Resource Exhaustion], [Mitre Atlas: LLM04], [Resources: Investigation Guide] |None |5 |<> |Identifies the modification of the nTSecurityDescriptor attribute in a domain object with rights related to DCSync to a user/computer account. Attackers can use this backdoor to re-obtain access to hashes of any user/computer. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Credential Access], [Data Source: Active Directory], [Use Case: Active Directory Monitoring], [Data Source: Windows Security Event Logs], [Resources: Investigation Guide] |None |108 @@ -1546,7 +1544,7 @@ and their rule type is `machine_learning`. |<> |The Application Shim was created to allow for backward compatibility of software as the operating system codebase changes over time. This Windows functionality has been abused by attackers to stealthily gain persistence and arbitrary code execution in legitimate Windows processes. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Persistence], [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], [Resources: Investigation Guide] |None |316 -|<> |Monitors for suspicious activities that may indicate theft or unauthorized duplication of machine learning (ML) models, such as unauthorized API calls, atypical access patterns, or large data transfers that are unusual during model interactions. |[Domain: LLM], [Data Source: Azure OpenAI], [Data Source: Azure Event Hubs], [Use Case: Model Theft], [Mitre Atlas: T0044], [Resources: Investigation Guide] |None |2 +|<> |Monitors for suspicious activities that may indicate theft or unauthorized duplication of machine learning (ML) models, such as unauthorized API calls, atypical access patterns, or large data transfers that are unusual during model interactions. |[Domain: LLM], [Data Source: Azure OpenAI], [Data Source: Azure Event Hubs], [Use Case: Model Theft], [Mitre Atlas: T0044], [Resources: Investigation Guide] |None |3 |<> |This rule detects SSH session ID change followed by a suspicious SSHD child process, this may indicate the successful execution of a potentially malicious process through the Pluggable Authentication Module (PAM) utility. PAM is a framework used by Linux systems to authenticate users. Adversaries may create malicious PAM modules that grant them persistence onto the target every time a user logs in by executing a backdoor script or command. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Credential Access], [Tactic: Persistence], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |2 @@ -1602,13 +1600,13 @@ and their rule type is `machine_learning`. |<> |Identifies the execution of the PRoot utility, an open-source tool for user-space implementation of chroot, mount --bind, and binfmt_misc. Adversaries can leverage an open-source tool PRoot to expand the scope of their operations to multiple Linux distributions and simplify their necessary efforts. In a normal threat scenario, the scope of an attack is limited by the varying configurations of each Linux distribution. With PRoot, it provides an attacker with a consistent operational environment across different Linux distributions, such as Ubuntu, Fedora, and Alpine. PRoot also provides emulation capabilities that allow for malware built on other architectures, such as ARM, to be run.The post-exploitation technique called bring your own filesystem (BYOF), can be used by the threat actors to execute malicious payload or elevate privileges or perform network scans or orchestrate another attack on the environment. Although PRoot was originally not developed with malicious intent it can be easily tuned to work for one. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: Elastic Defend], [Data Source: Elastic Endgame], [Data Source: Crowdstrike], [Data Source: SentinelOne], [Resources: Investigation Guide] |None |111 -|<> |Detects patterns indicative of Denial-of-Service (DoS) attacks on machine learning (ML) models, focusing on unusually high volume and frequency of requests or patterns of requests that are known to cause performance degradation or service disruption, such as large input sizes or rapid API calls. |[Domain: LLM], [Data Source: Azure OpenAI], [Data Source: Azure Event Hubs], [Use Case: Denial of Service], [Mitre Atlas: T0029], [Resources: Investigation Guide] |None |2 +|<> |Detects patterns indicative of Denial-of-Service (DoS) attacks on machine learning (ML) models, focusing on unusually high volume and frequency of requests or patterns of requests that are known to cause performance degradation or service disruption, such as large input sizes or rapid API calls. |[Domain: LLM], [Data Source: Azure OpenAI], [Data Source: Azure Event Hubs], [Use Case: Denial of Service], [Mitre Atlas: T0029], [Resources: Investigation Guide] |None |3 |<> |This rule monitors for potential attempts to disable AppArmor. AppArmor is a Linux security module that enforces fine-grained access control policies to restrict the actions and resources that specific applications and processes can access. Adversaries may disable security tools to avoid possible detection of their tools and activities. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: Elastic Defend], [Data Source: Elastic Endgame], [Data Source: Auditd Manager], [Data Source: Crowdstrike], [Data Source: SentinelOne], [Resources: Investigation Guide] |None |111 |<> |Identifies potential attempts to disable Security-Enhanced Linux (SELinux), which is a Linux kernel security feature to support access control policies. Adversaries may disable security tools to avoid possible detection of their tools and activities. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: Elastic Endgame], [Data Source: Elastic Defend], [Data Source: Auditd Manager], [Data Source: Crowdstrike], [Data Source: SentinelOne], [Resources: Investigation Guide] |None |214 -|<> |Identifies PowerShell scripts that reconstruct the IEX (Invoke-Expression) command at runtime using indexed slices of environment variables. This technique leverages character access and join operations to build execution logic dynamically, bypassing static keyword detection and evading defenses such as AMSI. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |2 +|<> |Identifies PowerShell scripts that reconstruct the IEX (Invoke-Expression) command at runtime using indexed slices of environment variables. This technique leverages character access and join operations to build execution logic dynamically, bypassing static keyword detection and evading defenses such as AMSI. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |3 |<> |Identifies processes loading Active Directory related modules followed by a network connection to the ADWS dedicated TCP port. Adversaries may abuse the ADWS Windows service that allows Active Directory to be queried via this web service. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Discovery], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |5 @@ -1686,9 +1684,9 @@ and their rule type is `machine_learning`. |<> |Identifies potential relay attacks against a machine account by identifying network share access events coming from a remote source.ip but using the target server computer account. This may indicate a successful SMB relay attack. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Credential Access], [Data Source: Elastic Defend], [Data Source: Active Directory], [Use Case: Active Directory Monitoring], [Data Source: Windows Security Event Logs], [Resources: Investigation Guide] |None |1 -|<> |Identifies PowerShell script blocks associated with multiple distinct detections, indicating likely malicious behavior. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Execution], [Rule Type: Higher-Order Rule], [Resources: Investigation Guide] |None |1 +|<> |Identifies PowerShell script blocks associated with multiple distinct detections, indicating likely malicious behavior. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Execution], [Rule Type: Higher-Order Rule], [Resources: Investigation Guide] |None |2 -|<> |This detection identifies a Linux host that has potentially been infected with malware and is being used to conduct brute-force attacks against external systems over SSH (port 22 and common alternative SSH ports). The detection looks for a high volume of outbound connection attempts to non-private IP addresses from a single process. A compromised host may be part of a botnet or controlled by an attacker, attempting to gain unauthorized access to remote systems. This behavior is commonly observed in SSH brute-force campaigns where malware hijacks vulnerable machines to expand its attack surface. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Impact], [Tactic: Execution], [Tactic: Command and Control], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |4 +|<> |This detection identifies a Linux host that has potentially been infected with malware and is being used to conduct brute-force attacks against external systems over SSH (port 22 and common alternative SSH ports). The detection looks for a high volume of outbound connection attempts to non-private IP addresses from a single process. A compromised host may be part of a botnet or controlled by an attacker, attempting to gain unauthorized access to remote systems. This behavior is commonly observed in SSH brute-force campaigns where malware hijacks vulnerable machines to expand its attack surface. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Impact], [Tactic: Execution], [Tactic: Command and Control], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |5 |<> |Identifies suspicious instances of browser processes, such as unsigned or signed with unusual certificates, that can indicate an attempt to conceal malicious activity, bypass security features such as allowlists, or trick users into executing malware. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Tactic: Persistence], [Rule Type: BBR], [Data Source: Elastic Defend] |None |9 @@ -1706,7 +1704,7 @@ and their rule type is `machine_learning`. |<> |This detection rule identifies a sample of suspicious Linux system file reads used for system fingerprinting, leveraged by the Metasploit Meterpreter shell to gather information about the target that it is executing its shell on. Detecting this pattern is indicative of a successful meterpreter shell connection. |[Data Source: Auditd Manager], [Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Execution], [Resources: Investigation Guide] |None |10 -|<> |Identifies brute-force authentication activity targeting Microsoft 365 user accounts using failed sign-in patterns that match password spraying, credential stuffing, or password guessing behavior. Adversaries may attempt brute-force authentication with credentials obtained from previous breaches, leaks, marketplaces or guessable passwords. |[Domain: Cloud], [Domain: SaaS], [Data Source: Microsoft 365], [Data Source: Microsoft 365 Audit Logs], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide] |None |413 +|<> |Identifies brute-force authentication activity targeting Microsoft 365 user accounts using failed sign-in patterns that match password spraying, credential stuffing, or password guessing behavior. Adversaries may attempt brute-force authentication with credentials obtained from previous breaches, leaks, marketplaces or guessable passwords. |[Domain: Cloud], [Domain: SaaS], [Data Source: Microsoft 365], [Data Source: Microsoft 365 Audit Logs], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide] |None |414 |<> |Identifies the creation of a suspicious zip file prepended with special characters. Sandboxed Microsoft Office applications on macOS are allowed to write files that start with special characters, which can be combined with an AutoStart location to achieve sandbox evasion. |[Domain: Endpoint], [OS: macOS], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |110 @@ -1746,7 +1744,7 @@ and their rule type is `machine_learning`. |<> |Identifies port monitor and print processor registry modifications. Adversaries may abuse port monitor and print processors to run malicious DLLs during system boot that will be executed as SYSTEM for privilege escalation and/or persistence, if permissions allow writing a fully-qualified pathname for that DLL. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Privilege Escalation], [Data Source: Elastic Endgame], [Data Source: Elastic Defend], [Data Source: Microsoft Defender for Endpoint], [Resources: Investigation Guide] |None |111 -|<> |This rule detects potential port scanning activity from a compromised host. Port scanning is a common reconnaissance technique used by attackers to identify open ports and services on a target system. A compromised host may exhibit port scanning behavior when an attacker is attempting to map out the network topology, identify vulnerable services, or prepare for further exploitation. This rule identifies potential port scanning activity by monitoring network connection attempts from a single host to a large number of ports within a short time frame. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Discovery], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |4 +|<> |This rule detects potential port scanning activity from a compromised host. Port scanning is a common reconnaissance technique used by attackers to identify open ports and services on a target system. A compromised host may exhibit port scanning behavior when an attacker is attempting to map out the network topology, identify vulnerable services, or prepare for further exploitation. This rule identifies potential port scanning activity by monitoring network connection attempts from a single host to a large number of ports within a short time frame. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Discovery], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |5 |<> |Detects known PowerShell offensive tooling author's name in PowerShell scripts. Attackers commonly use out-of-the-box offensive tools without modifying the code, which may still contain the author artifacts. This rule identifies common author handles found in popular PowerShell scripts used for red team exercises. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Execution], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |107 @@ -1754,25 +1752,25 @@ and their rule type is `machine_learning`. |<> |Identifies scripts that contain patterns and known methods that obfuscate PowerShell code. Attackers can use obfuscation techniques to bypass PowerShell security protections such as Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |107 -|<> |Identifies PowerShell scripts that use backtick-escaped characters inside ${} variable expansion as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |2 +|<> |Identifies PowerShell scripts that use backtick-escaped characters inside ${} variable expansion as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |3 -|<> |Identifies PowerShell scripts that use character arrays and runtime string reconstruction as a form of obfuscation. This technique breaks strings into individual characters, often using constructs like char[] with index-based access or joining logic. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |2 +|<> |Identifies PowerShell scripts that use character arrays and runtime string reconstruction as a form of obfuscation. This technique breaks strings into individual characters, often using constructs like char[] with index-based access or joining logic. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |3 -|<> |Identifies PowerShell scripts that use concatenated strings within dynamic command invocation (&() or .()) as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |2 +|<> |Identifies PowerShell scripts that use concatenated strings within dynamic command invocation (&() or .()) as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |3 -|<> |Identifies PowerShell scripts with a disproportionately high number of numeric characters, often indicating the presence of obfuscated or encoded payloads. This behavior is typical of obfuscation methods involving byte arrays, character code manipulation, or embedded encoded strings used to deliver and execute malicious content. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |3 +|<> |Identifies PowerShell scripts with a disproportionately high number of numeric characters, often indicating the presence of obfuscated or encoded payloads. This behavior is typical of obfuscation methods involving byte arrays, character code manipulation, or embedded encoded strings used to deliver and execute malicious content. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |4 -|<> |Identifies PowerShell scripts with an abnormally high proportion of non-alphanumeric characters, often resulting from encoding, string mangling, or dynamic code generation. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Rule Type: BBR] |None |1 +|<> |Identifies PowerShell scripts with an abnormally high proportion of non-alphanumeric characters, often resulting from encoding, string mangling, or dynamic code generation. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Rule Type: BBR] |None |2 -|<> |Identifies PowerShell scripts that use invalid escape sequences as a form of obfuscation. This technique introduces backticks (`) between characters in a way that does not correspond to valid PowerShell escape sequences, breaking up strings and bypassing pattern-based detections while preserving execution logic. This is designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |3 +|<> |Identifies PowerShell scripts that use invalid escape sequences as a form of obfuscation. This technique introduces backticks (`) between characters in a way that does not correspond to valid PowerShell escape sequences, breaking up strings and bypassing pattern-based detections while preserving execution logic. This is designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |4 -|<> |Identifies PowerShell scripts that use reversed strings as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |2 +|<> |Identifies PowerShell scripts that use reversed strings as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |3 -|<> |Identifies PowerShell scripts with an unusually high proportion of whitespace and special characters, often indicative of obfuscation. This behavior is commonly associated with techniques such as SecureString encoding, formatting obfuscation, or character-level manipulation designed to bypass static analysis and AMSI inspection. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |3 +|<> |Identifies PowerShell scripts with an unusually high proportion of whitespace and special characters, often indicative of obfuscation. This behavior is commonly associated with techniques such as SecureString encoding, formatting obfuscation, or character-level manipulation designed to bypass static analysis and AMSI inspection. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |4 -|<> |Identifies PowerShell scripts that use string concatenation as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |3 +|<> |Identifies PowerShell scripts that use string concatenation as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |4 -|<> |Identifies PowerShell scripts that use string reordering and runtime reconstruction techniques as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |4 +|<> |Identifies PowerShell scripts that use string reordering and runtime reconstruction techniques as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |5 |<> |Detects PowerShell scripts that can execute pass-the-hash (PtH) attacks, intercept and relay NTLM challenges, and carry out other man-in-the-middle (MitM) attacks. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide], [Data Source: PowerShell Logs] |None |107 @@ -1870,7 +1868,7 @@ and their rule type is `machine_learning`. |<> |This rule monitors for the execution of a set of linux binaries, that are potentially vulnerable to wildcard injection, with suspicious command line flags followed by a shell spawn event. Linux wildcard injection is a type of security vulnerability where attackers manipulate commands or input containing wildcards (e.g., *, ?, []) to execute unintended operations or access sensitive data by tricking the system into interpreting the wildcard characters in unexpected ways. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Privilege Escalation], [Tactic: Execution], [Data Source: Elastic Defend], [Data Source: SentinelOne], [Resources: Investigation Guide] |None |110 -|<> |This rule detects potential subnet scanning activity from a compromised host. Subnet scanning is a common reconnaissance technique used by attackers to identify live hosts within a network range. A compromised host may exhibit subnet scanning behavior when an attacker is attempting to map out the network topology, identify vulnerable hosts, or prepare for further exploitation. This rule identifies potential subnet scanning activity by monitoring network connection attempts from a single host to a large number of hosts within a short time frame. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Discovery], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |4 +|<> |This rule detects potential subnet scanning activity from a compromised host. Subnet scanning is a common reconnaissance technique used by attackers to identify live hosts within a network range. A compromised host may exhibit subnet scanning behavior when an attacker is attempting to map out the network topology, identify vulnerable hosts, or prepare for further exploitation. This rule identifies potential subnet scanning activity by monitoring network connection attempts from a single host to a large number of hosts within a short time frame. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Discovery], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |5 |<> |An FTP (file transfer protocol) brute force attack is a method where an attacker systematically tries different combinations of usernames and passwords to gain unauthorized access to an FTP server, and if successful, the impact can include unauthorized data access, manipulation, or theft, compromising the security and integrity of the server and potentially exposing sensitive information. This rule identifies multiple consecutive authentication failures targeting a specific user account from the same source address and within a short time interval, followed by a successful authentication. |[Data Source: Auditd Manager], [Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide] |None |10 @@ -1898,7 +1896,7 @@ and their rule type is `machine_learning`. |<> |Identifies a potential Windows Server Update Services (WSUS) abuse to execute psexec to enable for lateral movement. WSUS is limited to executing Microsoft signed binaries, which limits the executables that can be used to tools published by Microsoft. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Lateral Movement], [Data Source: Elastic Endgame], [Data Source: Elastic Defend], [Data Source: Sysmon], [Data Source: SentinelOne], [Data Source: Microsoft Defender for Endpoint], [Data Source: Windows Security Event Logs], [Data Source: Crowdstrike], [Resources: Investigation Guide] |None |210 -|<> |This rule uses alert data to determine when a malware signature is triggered in multiple hosts. Analysts can use this to prioritize triage and response, as this can potentially indicate a widespread malware infection. |[Domain: Endpoint], [Data Source: Elastic Defend], [Use Case: Threat Detection], [Tactic: Execution], [Rule Type: Higher-Order Rule], [Resources: Investigation Guide] |None |3 +|<> |This rule uses alert data to determine when a malware signature is triggered in multiple hosts. Analysts can use this to prioritize triage and response, as this can potentially indicate a widespread malware infection. |[Domain: Endpoint], [Data Source: Elastic Defend], [Use Case: Threat Detection], [Tactic: Execution], [Rule Type: Higher-Order Rule], [Resources: Investigation Guide] |None |4 |<> |Identifies suspicious instances of the Windows Error Reporting process (WerFault.exe or Wermgr.exe) with matching command-line and process executable values performing outgoing network connections. This may be indicative of a masquerading attempt to evade suspicious child process behavior detections. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Resources: Investigation Guide], [Data Source: Elastic Defend], [Data Source: Sysmon] |None |213 @@ -1926,7 +1924,7 @@ and their rule type is `machine_learning`. |<> |This rule detects PowerShell scripts capable of dumping process memory using WindowsErrorReporting or Dbghelp.dll MiniDumpWriteDump. Attackers can use this tooling to dump LSASS and get access to credentials. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Credential Access], [Resources: Investigation Guide], [Data Source: PowerShell Logs] |None |212 -|<> |Identifies PowerShell scripts that use negative index ranges to reverse the contents of a string or array at runtime as a form of obfuscation. This technique avoids direct use of reversal functions by iterating through array elements in reverse order. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |2 +|<> |Identifies PowerShell scripts that use negative index ranges to reverse the contents of a string or array at runtime as a form of obfuscation. This technique avoids direct use of reversal functions by iterating through array elements in reverse order. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI). |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: PowerShell Logs], [Resources: Investigation Guide] |None |3 |<> |Detects the use of PSReflect in PowerShell scripts. Attackers leverage PSReflect as a library that enables PowerShell to access win32 API functions. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Execution], [Resources: Investigation Guide], [Data Source: PowerShell Logs] |None |316 @@ -2068,7 +2066,7 @@ and their rule type is `machine_learning`. |<> |A machine learning job detected an unusual error in a CloudTrail message. These can be byproducts of attempted or successful persistence, privilege escalation, defense evasion, discovery, lateral movement, or collection. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Rule Type: ML], [Rule Type: Machine Learning], [Resources: Investigation Guide] |None |211 -|<> |Identifies rare connection attempts to a Web Distributed Authoring and Versioning (WebDAV) resource. Attackers may inject WebDAV paths in files or features opened by a victim user to leak their NTLM credentials via forced authentication. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Credential Access], [Data Source: Elastic Defend], [Data Source: Windows Security Event Logs], [Data Source: Microsoft Defender for Endpoint], [Data Source: Crowdstrike], [Resources: Investigation Guide] |None |1 +|<> |Identifies rare connection attempts to a Web Distributed Authoring and Versioning (WebDAV) resource. Attackers may inject WebDAV paths in files or features opened by a victim user to leak their NTLM credentials via forced authentication. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Credential Access], [Data Source: Elastic Defend], [Data Source: Windows Security Event Logs], [Data Source: Microsoft Defender for Endpoint], [Data Source: Crowdstrike], [Resources: Investigation Guide] |None |2 |<> |This rule detects rare internet network connections via the SMB protocol. SMB is commonly used to leak NTLM credentials via rogue UNC path injection. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Exfiltration], [Data Source: Elastic Endgame], [Data Source: Elastic Defend], [Data Source: Microsoft Defender for Endpoint], [Data Source: Sysmon], [Data Source: SentinelOne], [Resources: Investigation Guide] |None |211 @@ -2420,11 +2418,11 @@ and their rule type is `machine_learning`. |<> |Identifies suspicious Microsoft 365 mail access by ClientAppId. This rule detects when a user accesses their mailbox using a client application that is not typically used by the user, which may indicate potential compromise or unauthorized access attempts. Adversaries may use custom or third-party applications to access mailboxes, bypassing standard security controls. First-party Microsoft applications are also abused after OAuth tokens are compromised, allowing adversaries to access mailboxes without raising suspicion. |[Domain: Cloud], [Domain: Email], [Data Source: Microsoft 365], [Data Source: Microsoft 365 Audit Logs], [Use Case: Threat Detection], [Tactic: Collection], [Resources: Investigation Guide] |None |111 -|<> |Identifies sign-ins on behalf of a principal user to the Microsoft Graph API from multiple IPs using the Microsoft Authentication Broker or Visual Studio Code application. This behavior may indicate an adversary using a phished OAuth refresh token. |[Domain: Cloud], [Domain: Email], [Domain: Identity], [Data Source: Microsoft 365], [Data Source: Microsoft 365 Audit Logs], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Resources: Investigation Guide], [Tactic: Defense Evasion] |None |2 +|<> |Identifies sign-ins on behalf of a principal user to the Microsoft Graph API from multiple IPs using the Microsoft Authentication Broker or Visual Studio Code application. This behavior may indicate an adversary using a phished OAuth refresh token. |[Domain: Cloud], [Domain: Email], [Domain: Identity], [Data Source: Microsoft 365], [Data Source: Microsoft 365 Audit Logs], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Resources: Investigation Guide], [Tactic: Defense Evasion] |None |3 |<> |Identifies potential abuse of the Microsoft Diagnostics Troubleshooting Wizard (MSDT) to proxy malicious command or binary execution via malicious process arguments. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: Elastic Endgame], [Data Source: Elastic Defend], [Data Source: Microsoft Defender for Endpoint], [Data Source: Sysmon], [Resources: Investigation Guide] |None |213 -|<> |Identifies separate OAuth authorization flows in Microsoft Entra ID where the same user principal and session ID are observed across multiple IP addresses within a 5-minute window. These flows involve the Microsoft Authentication Broker (MAB) as the client application and the Device Registration Service (DRS) as the target resource. This pattern is highly indicative of OAuth phishing activity, where an adversary crafts a legitimate Microsoft login URL to trick a user into completing authentication and sharing the resulting authorization code, which is then exchanged for an access and refresh token by the attacker. |[Domain: Cloud], [Domain: Identity], [Data Source: Azure], [Data Source: Entra ID], [Data Source: Entra ID Sign-in Logs], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Resources: Investigation Guide], [Tactic: Initial Access] |None |2 +|<> |Identifies separate OAuth authorization flows in Microsoft Entra ID where the same user principal and session ID are observed across multiple IP addresses within a 5-minute window. These flows involve the Microsoft Authentication Broker (MAB) as the client application and the Device Registration Service (DRS) as the target resource. This pattern is highly indicative of OAuth phishing activity, where an adversary crafts a legitimate Microsoft login URL to trick a user into completing authentication and sharing the resulting authorization code, which is then exchanged for an access and refresh token by the attacker. |[Domain: Cloud], [Domain: Identity], [Data Source: Azure], [Data Source: Entra ID], [Data Source: Entra ID Sign-in Logs], [Use Case: Identity and Access Audit], [Use Case: Threat Detection], [Resources: Investigation Guide], [Tactic: Initial Access] |None |3 |<> |Identifies service creation events of common mining services, possibly indicating the infection of a system with a cryptominer. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Execution], [Data Source: Elastic Endgame], [Data Source: Elastic Defend], [Data Source: Crowdstrike], [Data Source: SentinelOne], [Resources: Investigation Guide] |None |110 @@ -2646,7 +2644,7 @@ and their rule type is `machine_learning`. |<> |Identifies when AWS S3 objects stored in a bucket are encrypted using Server-Side Encryption with Customer-Provided Keys (SSE-C). Adversaries with compromised AWS credentials can encrypt objects in an S3 bucket using their own encryption keys, rendering the objects unreadable or recoverable without the key. This can be used as a form of ransomware to extort the bucket owner for the decryption key. This is a New Terms rule that flags when this behavior is observed for the first time user and target bucket name. |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Data Source: AWS S3], [Resources: Investigation Guide], [Use Case: Threat Detection], [Tactic: Impact] |None |4 -|<> |This rule leverages ESQL to detect unusual base64 encoding/decoding activity on Linux systems. Attackers may use base64 encoding/decoding to obfuscate data, such as command and control traffic or payloads, to evade detection by host- or network-based security controls. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |4 +|<> |This rule leverages ESQL to detect unusual base64 encoding/decoding activity on Linux systems. Attackers may use base64 encoding/decoding to obfuscate data, such as command and control traffic or payloads, to evade detection by host- or network-based security controls. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |5 |<> |Identifies a suspicious child process of the Windows virtual system process, which could indicate code injection. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [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], [Resources: Investigation Guide] |None |316 @@ -2656,7 +2654,7 @@ and their rule type is `machine_learning`. |<> |A machine learning job detected AWS command activity that, while not inherently suspicious or abnormal, is sourcing from a geolocation (city) that is unusual for the command. This can be the result of compromised credentials or keys being used by a threat actor in a different geography than the authorized user(s). |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Rule Type: ML], [Rule Type: Machine Learning], [Resources: Investigation Guide] |None |211 -|<> |This rule detects potential command execution from a web server parent process on a Linux host. Adversaries may attempt to execute commands from a web server parent process to blend in with normal web server activity and evade detection. This behavior is commonly observed in web shell attacks where adversaries exploit web server vulnerabilities to execute arbitrary commands on the host. The detection rule identifies unusual command execution from web server parent processes, which may indicate a compromised host or an ongoing attack. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Persistence], [Tactic: Execution], [Tactic: Command and Control], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |4 +|<> |This rule detects potential command execution from a web server parent process on a Linux host. Adversaries may attempt to execute commands from a web server parent process to blend in with normal web server activity and evade detection. This behavior is commonly observed in web shell attacks where adversaries exploit web server vulnerabilities to execute arbitrary commands on the host. The detection rule identifies unusual command execution from web server parent processes, which may indicate a compromised host or an ongoing attack. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Persistence], [Tactic: Execution], [Tactic: Command and Control], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |5 |<> |A machine learning job detected AWS command activity that, while not inherently suspicious or abnormal, is sourcing from a geolocation (country) that is unusual for the command. This can be the result of compromised credentials or keys being used by a threat actor in a different geography than the authorized user(s). |[Domain: Cloud], [Data Source: AWS], [Data Source: Amazon Web Services], [Rule Type: ML], [Rule Type: Machine Learning], [Resources: Investigation Guide] |None |211 @@ -2682,21 +2680,21 @@ and their rule type is `machine_learning`. |<> |Identifies suspicious creation of Alternate Data Streams on highly targeted files. This is uncommon for legitimate files and sometimes done by adversaries to hide malware. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Defense Evasion], [Resources: Investigation Guide], [Data Source: Elastic Defend], [Data Source: Sysmon], [Data Source: Microsoft Defender for Endpoint], [Data Source: SentinelOne], [Data Source: Elastic Endgame] |None |320 -|<> |This rule detects unusual file creations from a web server parent process. Adversaries may attempt to create files from a web server parent process to establish persistence, execute malicious scripts, or exfiltrate data. ES|QL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Persistence], [Tactic: Execution], [Tactic: Command and Control], [Data Source: Elastic Defend], [Rule Type: BBR] |None |3 +|<> |This rule detects unusual file creations from a web server parent process. Adversaries may attempt to create files from a web server parent process to establish persistence, execute malicious scripts, or exfiltrate data. ES|QL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Persistence], [Tactic: Execution], [Tactic: Command and Control], [Data Source: Elastic Defend], [Rule Type: BBR] |None |4 |<> |Identifies an unexpected file being modified by dns.exe, the process responsible for Windows DNS Server services, which may indicate activity related to remote code execution or other forms of exploitation. |[Domain: Endpoint], [OS: Windows], [Use Case: Threat Detection], [Tactic: Lateral Movement], [Data Source: Elastic Endgame], [Use Case: Vulnerability], [Data Source: Elastic Defend], [Data Source: Sysmon], [Resources: Investigation Guide] |None |214 -|<> |This rule leverages ESQL to detect the execution of unusual file transfer utilities on Linux systems. Attackers may use these utilities to exfiltrate data from a compromised system. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Exfiltration], [Tactic: Execution], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |4 +|<> |This rule leverages ESQL to detect the execution of unusual file transfer utilities on Linux systems. Attackers may use these utilities to exfiltrate data from a compromised system. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Exfiltration], [Tactic: Execution], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |5 |<> |A machine learning job has detected a user accessing an uncommon group name for privileged operations, indicating potential privileged access activity. This indicates that a user has accessed a group name that is unusual for their typical operations, particularly for actions requiring elevated privileges. This could point to an attempt to manipulate group memberships or escalate privileges on a system. |[Use Case: Privileged Access Detection], [Rule Type: ML], [Rule Type: Machine Learning], [Tactic: Privilege Escalation], [Resources: Investigation Guide] |None |3 -|<> |Detects repeated high-confidence 'BLOCKED' actions coupled with specific 'Content Filter' policy violation having codes such as 'MISCONDUCT', 'HATE', 'SEXUAL', INSULTS', 'PROMPT_ATTACK', 'VIOLENCE' indicating persistent misuse or attempts to probe the model's ethical boundaries. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Use Case: Policy Violation], [Mitre Atlas: T0051], [Mitre Atlas: T0054], [Resources: Investigation Guide] |None |6 +|<> |Detects repeated high-confidence 'BLOCKED' actions coupled with specific 'Content Filter' policy violation having codes such as 'MISCONDUCT', 'HATE', 'SEXUAL', INSULTS', 'PROMPT_ATTACK', 'VIOLENCE' indicating persistent misuse or attempts to probe the model's ethical boundaries. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Use Case: Policy Violation], [Mitre Atlas: T0051], [Mitre Atlas: T0054], [Resources: Investigation Guide] |None |7 -|<> |Detects repeated compliance violation 'BLOCKED' actions coupled with specific policy name such as 'sensitive_information_policy', indicating persistent misuse or attempts to probe the model's denied topics. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Use Case: Policy Violation], [Mitre Atlas: T0051], [Mitre Atlas: T0054], [Resources: Investigation Guide] |None |2 +|<> |Detects repeated compliance violation 'BLOCKED' actions coupled with specific policy name such as 'sensitive_information_policy', indicating persistent misuse or attempts to probe the model's denied topics. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Use Case: Policy Violation], [Mitre Atlas: T0051], [Mitre Atlas: T0054], [Resources: Investigation Guide] |None |3 -|<> |Detects repeated compliance violation 'BLOCKED' actions coupled with specific policy name such as 'topic_policy', indicating persistent misuse or attempts to probe the model's denied topics. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Use Case: Policy Violation], [Mitre Atlas: T0051], [Mitre Atlas: T0054], [Resources: Investigation Guide] |None |2 +|<> |Detects repeated compliance violation 'BLOCKED' actions coupled with specific policy name such as 'topic_policy', indicating persistent misuse or attempts to probe the model's denied topics. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Use Case: Policy Violation], [Mitre Atlas: T0051], [Mitre Atlas: T0054], [Resources: Investigation Guide] |None |3 -|<> |Detects repeated compliance violation 'BLOCKED' actions coupled with specific policy name such as 'word_policy', indicating persistent misuse or attempts to probe the model's denied topics. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Use Case: Policy Violation], [Mitre Atlas: T0051], [Mitre Atlas: T0054], [Resources: Investigation Guide] |None |2 +|<> |Detects repeated compliance violation 'BLOCKED' actions coupled with specific policy name such as 'word_policy', indicating persistent misuse or attempts to probe the model's denied topics. |[Domain: LLM], [Data Source: AWS Bedrock], [Data Source: AWS S3], [Use Case: Policy Violation], [Mitre Atlas: T0051], [Mitre Atlas: T0054], [Resources: Investigation Guide] |None |3 |<> |A machine learning job has identified a user performing privileged operations in Okta from an uncommon device, indicating potential privileged access activity. This could signal a compromised account, an attacker using stolen credentials, or an insider threat leveraging an unauthorized device to escalate privileges. |[Use Case: Privileged Access Detection], [Rule Type: ML], [Rule Type: Machine Learning], [Tactic: Privilege Escalation], [Resources: Investigation Guide] |None |3 @@ -2784,7 +2782,7 @@ and their rule type is `machine_learning`. |<> |A machine learning job has detected a suspicious Windows process. This process has been classified as malicious in two ways. It was predicted to be malicious by the ProblemChild supervised ML model, and it was found to be suspicious given that its user context is unusual and does not commonly manifest malicious activity,by an unsupervised ML model. Such a process may be an instance of suspicious or malicious activity, possibly involving LOLbins, that may be resistant to detection using conventional search rules. |[Domain: Endpoint], [OS: Windows], [Use Case: Living off the Land Attack Detection], [Rule Type: ML], [Rule Type: Machine Learning], [Tactic: Defense Evasion], [Resources: Investigation Guide] |None |110 -|<> |This rule detects unusual processes spawned from a web server parent process by identifying low frequency counts of process spawning activity. Unusual process spawning activity may indicate an attacker attempting to establish persistence, execute malicious commands, or establish command and control channels on the host system. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Persistence], [Tactic: Execution], [Tactic: Command and Control], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |4 +|<> |This rule detects unusual processes spawned from a web server parent process by identifying low frequency counts of process spawning activity. Unusual process spawning activity may indicate an attacker attempting to establish persistence, execute malicious commands, or establish command and control channels on the host system. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert. |[Domain: Endpoint], [OS: Linux], [Use Case: Threat Detection], [Tactic: Persistence], [Tactic: Execution], [Tactic: Command and Control], [Data Source: Elastic Defend], [Resources: Investigation Guide] |None |5 |<> |A machine learning job has detected a rare process writing data to an external device. Malicious actors often use benign-looking processes to mask their data exfiltration activities. The discovery of such a process that has no legitimate reason to write data to external devices can indicate exfiltration. |[Use Case: Data Exfiltration Detection], [Rule Type: ML], [Rule Type: Machine Learning], [Tactic: Exfiltration], [Resources: Investigation Guide] |None |7 diff --git a/docs/detections/prebuilt-rules/rule-desc-index.asciidoc b/docs/detections/prebuilt-rules/rule-desc-index.asciidoc index 7d8836b301..2f40b5d7c5 100644 --- a/docs/detections/prebuilt-rules/rule-desc-index.asciidoc +++ b/docs/detections/prebuilt-rules/rule-desc-index.asciidoc @@ -285,7 +285,6 @@ include::rule-details/default-cobalt-strike-team-server-certificate.asciidoc[] include::rule-details/delayed-execution-via-ping.asciidoc[] include::rule-details/delegated-managed-service-account-modification-by-an-unusual-user.asciidoc[] include::rule-details/delete-volume-usn-journal-with-fsutil.asciidoc[] -include::rule-details/deprecated-azure-entra-sign-in-brute-force-microsoft-365-accounts-by-repeat-source.asciidoc[] include::rule-details/deprecated-launchdaemon-creation-or-modification-and-immediate-loading.asciidoc[] include::rule-details/directory-creation-in-bin-directory.asciidoc[] include::rule-details/disable-windows-event-and-security-logs-using-built-in-tools.asciidoc[] diff --git a/docs/detections/prebuilt-rules/rule-details/aws-access-token-used-from-multiple-addresses.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-access-token-used-from-multiple-addresses.asciidoc index a0aac87c9a..b036f387eb 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-access-token-used-from-multiple-addresses.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-access-token-used-from-multiple-addresses.asciidoc @@ -32,7 +32,7 @@ This rule identifies potentially suspicious activity by detecting instances wher * Use Case: Identity and Access Audit * Resources: Investigation Guide -*Version*: 101 +*Version*: 102 *Rule authors*: @@ -52,14 +52,14 @@ This rule identifies potentially suspicious activity by detecting instances wher *Investigating AWS Access Token Used from Multiple Addresses* -Access tokens are bound to a single user. Usage from multiple IP addresses may indicate the token was stolen and used elsewhere. By correlating this with additional detection criteria like multiple user agents, different cities, and different networks, we can improve the fidelity of the rule and help to eliminate false positives associated with expected behavior, like dual-stack IPV4/IPV6 usage. +Access tokens are bound to a single user. Usage from multiple IP addresses may indicate the token was stolen and used elsewhere. By correlating this with additional detection criteria like multiple user agents, different cities, and different networks, we can improve the fidelity of the rule and help to eliminate false positives associated with expected behavior, like dual-stack IPV4/IPV6 usage. *Possible Investigation Steps* - **Identify the IAM User**: Examine the `aws.cloudtrail.user_identity.arn` stored in `user_id` and correlate with the `source.ips` stored in `ip_list` and `unique_ips` count to determine how widely the token was used. -- **Correlate Additional Detection Context**: Examine `activity_type` and `fidelity_score` to determine additional cities, networks or user agents associated with the token usage. +- **Correlate Additional Detection Context**: Examine `activity_type` and `fidelity_score` to determine additional cities, networks or user agents associated with the token usage. - **Determine Access Key Type**: Examine the `access_key_id` to determine whether the token is short-term (beginning with ASIA) or long-term (beginning with AKIA). - **Check Recent MFA Events**: Determine whether the user recently enabled MFA, registered devices, or assumed a role using this token. - **Review Workload Context**: Confirm whether the user was expected to be active across multiple cities, networks or user agent environments. @@ -95,81 +95,97 @@ Access tokens are bound to a single user. Usage from multiple IP addresses may i [source, js] ---------------------------------- -FROM logs-aws.cloudtrail* metadata _id, _version, _index -| WHERE @timestamp > NOW() - 30 minutes - // filter on CloudTrail logs for STS temporary session tokens used by IAM users - - AND event.dataset == "aws.cloudtrail" - AND aws.cloudtrail.user_identity.arn IS NOT NULL - AND aws.cloudtrail.user_identity.type == "IAMUser" - AND source.ip IS NOT NULL - - // exclude known benign IaC tools and Amazon Network - AND NOT (user_agent.original LIKE "%Terraform%" OR user_agent.original LIKE "%Ansible%" OR user_agent.original LIKE "%Pulumni%") - AND `source.as.organization.name` != "AMAZON-AES" - - // exclude noisy service APIs less indicative of malicous behavior - AND event.provider NOT IN ("health.amazonaws.com", "monitoring.amazonaws.com", "notifications.amazonaws.com", "ce.amazonaws.com", "cost-optimization-hub.amazonaws.com", "servicecatalog-appregistry.amazonaws.com", "securityhub.amazonaws.com") - -| EVAL - // create a time window for aggregation - time_window = DATE_TRUNC(30 minutes, @timestamp), - // capture necessary fields for detection and investigation - user_id = aws.cloudtrail.user_identity.arn, - access_key_id = aws.cloudtrail.user_identity.access_key_id, - ip = source.ip, - user_agent = user_agent.original, - ip_string = TO_STRING(source.ip), // Convert IP to string - ip_user_agent_pair = CONCAT(ip_string, " - ", user_agent.original), // Combine IP and user agent - ip_city_pair = CONCAT(ip_string, " - ", source.geo.city_name), // Combine IP and city - city = source.geo.city_name, - event_time = @timestamp, - network_arn = `source.as.organization.name` - -| STATS - event_actions = VALUES(event.action), - event_providers = VALUES(event.provider), - access_key_id = VALUES(access_key_id), - user_id = VALUES(user_id), - ip_list = VALUES(ip), // Collect list of IPs - user_agent_list = VALUES(user_agent), // Collect list of user agents - ip_user_agent_pairs = VALUES(ip_user_agent_pair), // Collect list of IP - user agent pairs - cities_list = VALUES(city), // Collect list of cities - ip_city_pairs = VALUES(ip_city_pair), // Collect list of IP - city pairs - networks_list = VALUES(network_arn), // Collect list of networks - unique_ips = COUNT_DISTINCT(ip), - unique_user_agents = COUNT_DISTINCT(user_agent), - unique_cities = COUNT_DISTINCT(city), - unique_networks = COUNT_DISTINCT(network_arn), - first_seen = MIN(event_time), - last_seen = MAX(event_time), - total_events = COUNT() - BY time_window, access_key_id - -| EVAL - // activity type based on combinations of detection criteria - activity_type = CASE( - unique_ips >= 2 AND unique_networks >= 2 AND unique_cities >= 2 AND unique_user_agents >= 2, "multiple_ip_network_city_user_agent", // high severity - unique_ips >= 2 AND unique_networks >= 2 AND unique_cities >= 2, "multiple_ip_network_city", // high severity - unique_ips >= 2 AND unique_cities >= 2, "multiple_ip_and_city", // medium severity - unique_ips >= 2 AND unique_networks >= 2, "multiple_ip_and_network", // medium severity - unique_ips >= 2 AND unique_user_agents >= 2, "multiple_ip_and_user_agent", // low severity - "normal_activity" - ), - // likelihood of malicious activity based on activity type - fidelity_score = CASE( - activity_type == "multiple_ip_network_city_user_agent", "high", - activity_type == "multiple_ip_network_city", "high", - activity_type == "multiple_ip_and_city", "medium", - activity_type == "multiple_ip_and_network", "medium", - activity_type == "multiple_ip_and_user_agent", "low" - ) - -| KEEP - time_window, activity_type, fidelity_score, total_events, first_seen, last_seen, - user_id, access_key_id, event_actions, event_providers, ip_list, user_agent_list, ip_user_agent_pairs, cities_list, ip_city_pairs, networks_list, unique_ips, unique_user_agents, unique_cities, unique_networks - -| WHERE activity_type != "normal_activity" +from logs-aws.cloudtrail* metadata _id, _version, _index +| where @timestamp > now() - 30 minutes + and event.dataset == "aws.cloudtrail" + and aws.cloudtrail.user_identity.arn is not null + and aws.cloudtrail.user_identity.type == "IAMUser" + and source.ip is not null + and not ( + user_agent.original like "%Terraform%" or + user_agent.original like "%Ansible%" or + user_agent.original like "%Pulumni%" + ) + and `source.as.organization.name` != "AMAZON-AES" + and event.provider not in ( + "health.amazonaws.com", "monitoring.amazonaws.com", "notifications.amazonaws.com", + "ce.amazonaws.com", "cost-optimization-hub.amazonaws.com", + "servicecatalog-appregistry.amazonaws.com", "securityhub.amazonaws.com" + ) + +| eval + Esql.time_window_date_trunc = date_trunc(30 minutes, @timestamp), + Esql.aws_cloudtrail_user_identity_arn = aws.cloudtrail.user_identity.arn, + Esql.aws_cloudtrail_user_identity_access_key_id = aws.cloudtrail.user_identity.access_key_id, + Esql.source_ip = source.ip, + Esql.user_agent_original = user_agent.original, + Esql.source_ip_string = to_string(source.ip), + Esql.source_ip_user_agent_pair = concat(Esql.source_ip_string, " - ", user_agent.original), + Esql.source_ip_city_pair = concat(Esql.source_ip_string, " - ", source.geo.city_name), + Esql.source_geo_city_name = source.geo.city_name, + Esql.event_timestamp = @timestamp, + Esql.source_network_org_name = `source.as.organization.name` + +| stats + Esql.event_action_values = values(event.action), + Esql.event_provider_values = values(event.provider), + Esql.aws_cloudtrail_user_identity_access_key_id_values = values(Esql.aws_cloudtrail_user_identity_access_key_id), + Esql.aws_cloudtrail_user_identity_arn_values = values(Esql.aws_cloudtrail_user_identity_arn), + Esql.source_ip_values = values(Esql.source_ip), + Esql.user_agent_original_values = values(Esql.user_agent_original), + Esql.source_ip_user_agent_pair_values = values(Esql.source_ip_user_agent_pair), + Esql.source_geo_city_name_values = values(Esql.source_geo_city_name), + Esql.source_ip_city_pair_values = values(Esql.source_ip_city_pair), + Esql.source_network_org_name_values = values(Esql.source_network_org_name), + Esql.source_ip_count_distinct = count_distinct(Esql.source_ip), + Esql.user_agent_original_count_distinct = count_distinct(Esql.user_agent_original), + Esql.source_geo_city_name_count_distinct = count_distinct(Esql.source_geo_city_name), + Esql.source_network_org_name_count_distinct = count_distinct(Esql.source_network_org_name), + Esql.timestamp_first_seen = min(Esql.event_timestamp), + Esql.timestamp_last_seen = max(Esql.event_timestamp), + Esql.event_count = count() + by Esql.time_window_date_trunc, Esql.aws_cloudtrail_user_identity_access_key_id + +| eval + Esql.activity_type = case( + Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2 and Esql.user_agent_original_count_distinct >= 2, "multiple_ip_network_city_user_agent", + Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2, "multiple_ip_network_city", + Esql.source_ip_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2, "multiple_ip_and_city", + Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2, "multiple_ip_and_network", + Esql.source_ip_count_distinct >= 2 and Esql.user_agent_original_count_distinct >= 2, "multiple_ip_and_user_agent", + "normal_activity" + ), + Esql.activity_fidelity_score = case( + Esql.activity_type == "multiple_ip_network_city_user_agent", "high", + Esql.activity_type == "multiple_ip_network_city", "high", + Esql.activity_type == "multiple_ip_and_city", "medium", + Esql.activity_type == "multiple_ip_and_network", "medium", + Esql.activity_type == "multiple_ip_and_user_agent", "low" + ) + +| keep + Esql.time_window_date_trunc, + Esql.activity_type, + Esql.activity_fidelity_score, + Esql.event_count, + Esql.timestamp_first_seen, + Esql.timestamp_last_seen, + Esql.aws_cloudtrail_user_identity_arn_values, + Esql.aws_cloudtrail_user_identity_access_key_id_values, + Esql.event_action_values, + Esql.event_provider_values, + Esql.source_ip_values, + Esql.user_agent_original_values, + Esql.source_ip_user_agent_pair_values, + Esql.source_geo_city_name_values, + Esql.source_ip_city_pair_values, + Esql.source_network_org_name_values, + Esql.source_ip_count_distinct, + Esql.user_agent_original_count_distinct, + Esql.source_geo_city_name_count_distinct, + Esql.source_network_org_name_count_distinct + +| where Esql.activity_type != "normal_activity" ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/aws-bedrock-detected-multiple-attempts-to-use-denied-models-by-a-single-user.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-bedrock-detected-multiple-attempts-to-use-denied-models-by-a-single-user.asciidoc index 3ae143c50c..9bb2e32e76 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-bedrock-detected-multiple-attempts-to-use-denied-models-by-a-single-user.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-bedrock-detected-multiple-attempts-to-use-denied-models-by-a-single-user.asciidoc @@ -34,7 +34,7 @@ Identifies multiple successive failed attempts to use denied model resources wit * Mitre Atlas: T0015 * Mitre Atlas: T0034 -*Version*: 4 +*Version*: 5 *Rule authors*: @@ -107,10 +107,29 @@ https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html [source, js] ---------------------------------- from logs-aws_bedrock.invocation-* + +// Filter for access denied errors from GenAI responses | where gen_ai.response.error_code == "AccessDeniedException" -| keep user.id, gen_ai.request.model.id, cloud.account.id, gen_ai.response.error_code -| stats total_denials = count(*) by user.id, gen_ai.request.model.id, cloud.account.id -| where total_denials > 3 -| sort total_denials desc + +// keep ECS and response fields +| keep + user.id, + gen_ai.request.model.id, + cloud.account.id, + gen_ai.response.error_code + +// count total denials per user/model/account +| stats + Esql.ml_response_access_denied_count = count(*) + by + user.id, + gen_ai.request.model.id, + cloud.account.id + +// Filter for users with repeated denials +| where Esql.ml_response_access_denied_count > 3 + +// sort by volume of denials +| sort Esql.ml_response_access_denied_count desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/aws-bedrock-detected-multiple-validation-exception-errors-by-a-single-user.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-bedrock-detected-multiple-validation-exception-errors-by-a-single-user.asciidoc index 8a4da3db51..96fd343b94 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-bedrock-detected-multiple-validation-exception-errors-by-a-single-user.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-bedrock-detected-multiple-validation-exception-errors-by-a-single-user.asciidoc @@ -36,7 +36,7 @@ Identifies multiple validation exeception errors within AWS Bedrock. Validation * Mitre Atlas: T0046 * Resources: Investigation Guide -*Version*: 4 +*Version*: 5 *Rule authors*: @@ -110,12 +110,30 @@ https://www.elastic.co/docs/current/integrations/aws_bedrock [source, js] ---------------------------------- from logs-aws_bedrock.invocation-* -// truncate the timestamp to a 1-minute window -| eval target_time_window = DATE_TRUNC(1 minutes, @timestamp) + +// Truncate timestamp to 1-minute window +| eval Esql.time_window_date_trunc = date_trunc(1 minutes, @timestamp) + +// Filter for validation exceptions in responses | where gen_ai.response.error_code == "ValidationException" -| keep user.id, gen_ai.request.model.id, cloud.account.id, gen_ai.response.error_code, target_time_window -// count the number of users causing validation errors within a 1 minute window -| stats total_denials = count(*) by target_time_window, user.id, cloud.account.id -| where total_denials > 3 + +// keep relevant ECS and derived fields +| keep + user.id, + gen_ai.request.model.id, + cloud.account.id, + gen_ai.response.error_code, + Esql.time_window_date_trunc + +// count number of denials by user/account/time window +| stats + Esql.ml_response_validation_error_count = count(*) + by + Esql.time_window_date_trunc, + user.id, + cloud.account.id + +// Filter for excessive errors +| where Esql.ml_response_validation_error_count > 3 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/aws-bedrock-guardrails-detected-multiple-policy-violations-within-a-single-blocked-request.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-bedrock-guardrails-detected-multiple-policy-violations-within-a-single-blocked-request.asciidoc index 3a5fb75422..3b1f43925b 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-bedrock-guardrails-detected-multiple-policy-violations-within-a-single-blocked-request.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-bedrock-guardrails-detected-multiple-policy-violations-within-a-single-blocked-request.asciidoc @@ -34,7 +34,7 @@ Identifies multiple violations of AWS Bedrock guardrails within a single request * Mitre Atlas: T0051 * Mitre Atlas: T0054 -*Version*: 4 +*Version*: 5 *Rule authors*: @@ -111,11 +111,34 @@ https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html [source, js] ---------------------------------- from logs-aws_bedrock.invocation-* + +// Filter for policy-blocked requests | where gen_ai.policy.action == "BLOCKED" -| eval policy_violations = mv_count(gen_ai.policy.name) -| where policy_violations > 1 -| keep gen_ai.policy.action, policy_violations, user.id, gen_ai.request.model.id, cloud.account.id, user.id -| stats total_unique_request_violations = count(*) by policy_violations, user.id, gen_ai.request.model.id, cloud.account.id -| sort total_unique_request_violations desc + +// count number of policy matches per request (multi-valued) +| eval Esql.ml_policy_violations_mv_count = mv_count(gen_ai.policy.name) + +// Filter for requests with more than one policy match +| where Esql.ml_policy_violations_mv_count > 1 + +// keep relevant fields +| keep + gen_ai.policy.action, + Esql.ml_policy_violations_mv_count, + user.id, + gen_ai.request.model.id, + cloud.account.id + +// Aggregate requests with multiple violations +| stats + Esql.ml_policy_violations_total_unique_requests_count = count(*) + by + Esql.ml_policy_violations_mv_count, + user.id, + gen_ai.request.model.id, + cloud.account.id + +// sort by number of unique requests +| sort Esql.ml_policy_violations_total_unique_requests_count desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/aws-bedrock-guardrails-detected-multiple-violations-by-a-single-user-over-a-session.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-bedrock-guardrails-detected-multiple-violations-by-a-single-user-over-a-session.asciidoc index 166abafd02..9bc247c5a6 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-bedrock-guardrails-detected-multiple-violations-by-a-single-user-over-a-session.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-bedrock-guardrails-detected-multiple-violations-by-a-single-user-over-a-session.asciidoc @@ -34,7 +34,7 @@ Identifies multiple violations of AWS Bedrock guardrails by the same user in the * Mitre Atlas: T0051 * Mitre Atlas: T0054 -*Version*: 5 +*Version*: 6 *Rule authors*: @@ -111,10 +111,28 @@ https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html [source, js] ---------------------------------- from logs-aws_bedrock.invocation-* + +// Filter for compliance violations detected | where gen_ai.compliance.violation_detected -| keep user.id, gen_ai.request.model.id, cloud.account.id -| stats violations = count(*) by user.id, gen_ai.request.model.id, cloud.account.id -| where violations > 1 -| sort violations desc + +// keep relevant ECS + model fields +| keep + user.id, + gen_ai.request.model.id, + cloud.account.id + +// count violations by user, model, and account +| stats + Esql.ml_violations_count = count(*) + by + user.id, + gen_ai.request.model.id, + cloud.account.id + +// Filter for repeated violations +| where Esql.ml_violations_count > 1 + +// sort descending by violation volume +| sort Esql.ml_violations_count desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/aws-bedrock-invocations-without-guardrails-detected-by-a-single-user-over-a-session.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-bedrock-invocations-without-guardrails-detected-by-a-single-user-over-a-session.asciidoc index fcdca98b63..86dcc6634d 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-bedrock-invocations-without-guardrails-detected-by-a-single-user-over-a-session.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-bedrock-invocations-without-guardrails-detected-by-a-single-user-over-a-session.asciidoc @@ -34,7 +34,7 @@ Identifies multiple AWS Bedrock executions in a one minute time window without g * Mitre Atlas: T0051 * Mitre Atlas: T0054 -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -107,12 +107,29 @@ https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html [source, js] ---------------------------------- from logs-aws_bedrock.invocation-* -// create time window buckets of 1 minute -| eval time_window = date_trunc(1 minute, @timestamp) -| where gen_ai.guardrail_id is NULL -| KEEP @timestamp, time_window, gen_ai.guardrail_id , user.id -| stats model_invocation_without_guardrails = count() by user.id -| where model_invocation_without_guardrails > 5 -| sort model_invocation_without_guardrails desc + +// Create 1-minute time buckets +| eval Esql.time_window_date_trunc = date_trunc(1 minute, @timestamp) + +// Filter for invocations without guardrails +| where gen_ai.guardrail_id is null and user.id is not null + +// keep only relevant fields +| keep + @timestamp, + Esql.time_window_date_trunc, + gen_ai.guardrail_id, + user.id + +// count number of unsafe invocations per user +| stats + Esql.ml_invocations_no_guardrails_count = count() + by user.id + +// Filter for suspicious volume +| where Esql.ml_invocations_no_guardrails_count > 5 + +// sort descending +| sort Esql.ml_invocations_no_guardrails_count desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/aws-discovery-api-calls-via-cli-from-a-single-resource.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-discovery-api-calls-via-cli-from-a-single-resource.asciidoc index cd9ad7bc21..a061188922 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-discovery-api-calls-via-cli-from-a-single-resource.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-discovery-api-calls-via-cli-from-a-single-resource.asciidoc @@ -32,7 +32,7 @@ Detects when a single AWS resource is running multiple `Describe` and `List` API * Tactic: Discovery * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -105,11 +105,11 @@ For further guidance on AWS infrastructure discovery and best practices, refer t from logs-aws.cloudtrail* // create time window buckets of 10 seconds -| eval time_window = date_trunc(10 seconds, @timestamp) +| eval Esql.time_window_date_trunc = date_trunc(10 seconds, @timestamp) | where event.dataset == "aws.cloudtrail" - // filter on CloudTrail audit logs for IAM, EC2, and S3 events only + // filter on CloudTrail audit logs for IAM, EC2, S3, etc. and event.provider in ( "iam.amazonaws.com", "ec2.amazonaws.com", @@ -119,8 +119,7 @@ from logs-aws.cloudtrail* "dynamodb.amazonaws.com", "kms.amazonaws.com", "cloudfront.amazonaws.com", - "elasticloadbalancing.amazonaws.com", - "cloudfront.amazonaws.com" + "elasticloadbalancing.amazonaws.com" ) // ignore AWS service actions @@ -139,19 +138,24 @@ from logs-aws.cloudtrail* starts_with(event.action, "List"), starts_with(event.action, "Generate") ) + // extract owner, identity type, and actor from the ARN -| dissect aws.cloudtrail.user_identity.arn "%{}::%{owner}:%{identity_type}/%{actor}" -| where starts_with(actor, "AWSServiceRoleForConfig") != true -| keep @timestamp, time_window, event.action, aws.cloudtrail.user_identity.arn +| dissect aws.cloudtrail.user_identity.arn "%{}::%{Esql_priv.aws_cloudtrail_user_identity_arn_owner}:%{Esql.aws_cloudtrail_user_identity_arn_type}/%{Esql.aws_cloudtrail_user_identity_arn_roles}" +| where starts_with(Esql.aws_cloudtrail_user_identity_arn_roles, "AWSServiceRoleForConfig") != true + +// keep relevant fields (preserving ECS fields and computed time window) +| keep @timestamp, Esql.time_window_date_trunc, event.action, aws.cloudtrail.user_identity.arn + +// count the number of unique API calls per time window and actor | stats - // count the number of unique API calls per time window and actor - unique_api_count = count_distinct(event.action) by time_window, aws.cloudtrail.user_identity.arn + Esql.event_action_count_distinct = count_distinct(event.action) + by Esql.time_window_date_trunc, aws.cloudtrail.user_identity.arn -// filter for more than 5 unique API calls per time window -| where unique_api_count > 5 +// filter for more than 5 unique API calls per 10s window +| where Esql.event_action_count_distinct > 5 // sort the results by the number of unique API calls in descending order -| sort unique_api_count desc +| sort Esql.event_action_count_distinct desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/aws-ec2-ebs-snapshot-access-removed.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-ec2-ebs-snapshot-access-removed.asciidoc index f531c4695a..a6828ba1f6 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-ec2-ebs-snapshot-access-removed.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-ec2-ebs-snapshot-access-removed.asciidoc @@ -32,7 +32,7 @@ Identifies the removal of access permissions from a shared AWS EC2 EBS snapshot. * Tactic: Impact * Resources: Investigation Guide -*Version*: 1 +*Version*: 2 *Rule authors*: @@ -64,7 +64,7 @@ Restricting snapshot access may help adversaries cover their tracks by making it - **Analyze the Source of the Request**: Investigate the `source.ip` and `source.geo` fields to determine the geographical origin of the request. An external or unexpected location might indicate compromised credentials or unauthorized access. - **Contextualize with Timestamp**: Use the `@timestamp` field to check when the change occurred. Modifications during non-business hours or outside regular maintenance windows might require further scrutiny. - **Correlate with Other Activities**: Search for related CloudTrail events before and after this change to see if the same actor or IP address engaged in other potentially suspicious activities. In particular, use the `snapshotId` to see if this snapshot was shared with an unauthorized account. -- **Review UserID**: Check the `userId` field to identify which user's permissions were removed. Verify if this account should be authorized to access the data or if the access removal is expected. +- **Review UserID**: Check the `userId` field to identify which user's permissions were removed. Verify if this account should be authorized to access the data or if the access removal is expected. *False Positive Analysis:* @@ -98,10 +98,31 @@ For further guidance on managing EBS snapshots and securing AWS environments, re [source, js] ---------------------------------- from logs-aws.cloudtrail-* metadata _id, _version, _index -| where event.provider == "ec2.amazonaws.com" and event.action == "ModifySnapshotAttribute" and event.outcome == "success" -| dissect aws.cloudtrail.request_parameters "{%{?snapshotId}=%{snapshotId},%{?attributeType}=%{attributeType},%{?createVolumePermission}={%{operationType}={%{?items}=[{%{?userId}=%{userId}}]}}}" -| where operationType == "remove" -| keep @timestamp, aws.cloudtrail.user_identity.arn, cloud.account.id, event.action, snapshotId, attributeType, operationType, userId, source.address + +// Filter for successful snapshot modifications +| where + event.provider == "ec2.amazonaws.com" + and event.action == "ModifySnapshotAttribute" + and event.outcome == "success" + +// dissect parameters to extract key fields +| dissect aws.cloudtrail.request_parameters + "{%{?snapshotId}=%{Esql.aws_cloudtrail_request_parameters_snapshot_id},%{?attributeType}=%{Esql.aws_cloudtrail_request_parameters_attribute_type},%{?createVolumePermission}={%{Esql.aws_cloudtrail_request_parameters_operation_type}={%{?items}=[{%{?userId}=%{Esql_priv.aws_cloudtrail_request_parameters_user_id}}]}}}" + +// Match on snapshot permission **removal** +| where Esql.aws_cloudtrail_request_parameters_operation_type == "remove" + +// keep ECS and derived fields +| keep + @timestamp, + aws.cloudtrail.user_identity.arn, + cloud.account.id, + event.action, + Esql.aws_cloudtrail_request_parameters_snapshot_id, + Esql.aws_cloudtrail_request_parameters_attribute_type, + Esql.aws_cloudtrail_request_parameters_operation_type, + Esql_priv.aws_cloudtrail_request_parameters_user_id, + source.address ---------------------------------- @@ -112,10 +133,10 @@ from logs-aws.cloudtrail-* metadata _id, _version, _index ** ID: TA0040 ** Reference URL: https://attack.mitre.org/tactics/TA0040/ * Technique: -** Name: Inhibit System Recovery -** ID: T1490 -** Reference URL: https://attack.mitre.org/techniques/T1490/ -* Technique: ** Name: Data Destruction ** ID: T1485 ** Reference URL: https://attack.mitre.org/techniques/T1485/ +* Technique: +** Name: Inhibit System Recovery +** ID: T1490 +** Reference URL: https://attack.mitre.org/techniques/T1490/ diff --git a/docs/detections/prebuilt-rules/rule-details/aws-ec2-ebs-snapshot-shared-or-made-public.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-ec2-ebs-snapshot-shared-or-made-public.asciidoc index e8fd50462c..9749f3ee31 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-ec2-ebs-snapshot-shared-or-made-public.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-ec2-ebs-snapshot-shared-or-made-public.asciidoc @@ -34,7 +34,7 @@ Identifies AWS EC2 EBS snaphots being shared with another AWS account or made pu * Tactic: Exfiltration * Resources: Investigation Guide -*Version*: 6 +*Version*: 7 *Rule authors*: @@ -101,10 +101,31 @@ For further guidance on managing EBS snapshots and securing AWS environments, re [source, js] ---------------------------------- from logs-aws.cloudtrail-* metadata _id, _version, _index -| where event.provider == "ec2.amazonaws.com" and event.action == "ModifySnapshotAttribute" and event.outcome == "success" -| dissect aws.cloudtrail.request_parameters "{%{?snapshotId}=%{snapshotId},%{?attributeType}=%{attributeType},%{?createVolumePermission}={%{operationType}={%{?items}=[{%{?userId}=%{userId}}]}}}" -| where operationType == "add" and cloud.account.id != userId -| keep @timestamp, aws.cloudtrail.user_identity.arn, cloud.account.id, event.action, snapshotId, attributeType, operationType, userId, source.address +| where + event.provider == "ec2.amazonaws.com" + and event.action == "ModifySnapshotAttribute" + and event.outcome == "success" + +// Extract snapshotId, attribute type, operation type, and userId +| dissect aws.cloudtrail.request_parameters + "{%{?snapshotId}=%{Esql.aws_cloudtrail_request_parameters_snapshot_id},%{?attributeType}=%{Esql.aws_cloudtrail_request_parameters_attribute_type},%{?createVolumePermission}={%{Esql.aws_cloudtrail_request_parameters_operation_type}={%{?items}=[{%{?userId}=%{Esql_priv.aws_cloudtrail_request_parameters_user_id}}]}}}" + +// Check for snapshot permission added for another AWS account +| where + Esql.aws_cloudtrail_request_parameters_operation_type == "add" + and cloud.account.id != Esql_priv.aws_cloudtrail_request_parameters_user_id + +// keep ECS and derived fields +| keep + @timestamp, + aws.cloudtrail.user_identity.arn, + cloud.account.id, + event.action, + Esql.aws_cloudtrail_request_parameters_snapshot_id, + Esql.aws_cloudtrail_request_parameters_attribute_type, + Esql.aws_cloudtrail_request_parameters_operation_type, + Esql_priv.aws_cloudtrail_request_parameters_user_id, + source.ip ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/aws-ec2-multi-region-describeinstances-api-calls.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-ec2-multi-region-describeinstances-api-calls.asciidoc index 05729b3b41..9944b618db 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-ec2-multi-region-describeinstances-api-calls.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-ec2-multi-region-describeinstances-api-calls.asciidoc @@ -31,7 +31,7 @@ Identifies when a single AWS resource is making `DescribeInstances` API calls in * Use Case: Threat Detection * Tactic: Discovery -*Version*: 4 +*Version*: 5 *Rule authors*: @@ -108,22 +108,27 @@ For further information on AWS `DescribeInstances` permissions and best practice from logs-aws.cloudtrail-* // filter for DescribeInstances API calls -| where event.dataset == "aws.cloudtrail" and event.provider == "ec2.amazonaws.com" and event.action == "DescribeInstances" +| where event.dataset == "aws.cloudtrail" + and event.provider == "ec2.amazonaws.com" + and event.action == "DescribeInstances" // truncate the timestamp to a 30-second window -| eval target_time_window = DATE_TRUNC(30 seconds, @timestamp) +| eval Esql.time_window_date_trunc = date_trunc(30 seconds, @timestamp) -// keep only the relevant fields -| keep target_time_window, aws.cloudtrail.user_identity.arn, cloud.region +// keep only the relevant raw fields +| keep Esql.time_window_date_trunc, aws.cloudtrail.user_identity.arn, cloud.region // count the number of unique regions and total API calls within the 30-second window -| stats region_count = count_distinct(cloud.region), window_count = count(*) by target_time_window, aws.cloudtrail.user_identity.arn +| stats + Esql.cloud_region_count_distinct = count_distinct(cloud.region), + Esql.event_count = count(*) + by Esql.time_window_date_trunc, aws.cloudtrail.user_identity.arn // filter for resources making DescribeInstances API calls in more than 10 regions within the 30-second window -| where region_count >= 10 and window_count >= 10 +| where Esql.cloud_region_count_distinct >= 10 and Esql.event_count >= 10 -// sort the results by time windows in descending order -| sort target_time_window desc +// sort the results by time window in descending order +| sort Esql.time_window_date_trunc desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/aws-iam-administratoraccess-policy-attached-to-group.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-iam-administratoraccess-policy-attached-to-group.asciidoc index 4a4d428346..48ec6b69cd 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-iam-administratoraccess-policy-attached-to-group.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-iam-administratoraccess-policy-attached-to-group.asciidoc @@ -34,7 +34,7 @@ An adversary with access to a set of compromised credentials may attempt to pers * Tactic: Persistence * Resources: Investigation Guide -*Version*: 5 +*Version*: 6 *Rule authors*: @@ -116,10 +116,27 @@ to look for use of the `AttachGroupPolicy` operation along with request_paramete [source, js] ---------------------------------- from logs-aws.cloudtrail-* metadata _id, _version, _index -| where event.provider == "iam.amazonaws.com" and event.action == "AttachGroupPolicy" and event.outcome == "success" -| dissect aws.cloudtrail.request_parameters "{%{?policyArn}=%{?arn}:%{?aws}:%{?iam}::%{?aws}:%{?policy}/%{policyName},%{?groupName}=%{group.name}}" -| where policyName == "AdministratorAccess" -| keep @timestamp, event.provider, event.action, event.outcome, policyName, group.name + +| where + event.provider == "iam.amazonaws.com" + and event.action == "AttachGroupPolicy" + and event.outcome == "success" + +// Extract policy and group details from request parameters +| dissect aws.cloudtrail.request_parameters + "{%{?policyArn}=%{?arn}:%{?aws}:%{?iam}::%{?aws}:%{?policy}/%{Esql.aws_cloudtrail_request_parameters_policy_name},%{?groupName}=%{Esql.aws_cloudtrail_request_parameters_group_name}}" + +// Filter for attachment of AdministratorAccess policy +| where Esql.aws_cloudtrail_request_parameters_policy_name == "AdministratorAccess" + +// keep ECS and derived fields +| keep + @timestamp, + event.provider, + event.action, + event.outcome, + Esql.aws_cloudtrail_request_parameters_policy_name, + Esql.aws_cloudtrail_request_parameters_group_name ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/aws-iam-administratoraccess-policy-attached-to-role.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-iam-administratoraccess-policy-attached-to-role.asciidoc index 6e4bef4764..2760e8451c 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-iam-administratoraccess-policy-attached-to-role.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-iam-administratoraccess-policy-attached-to-role.asciidoc @@ -34,7 +34,7 @@ An adversary with access to a set of compromised credentials may attempt to pers * Tactic: Persistence * Resources: Investigation Guide -*Version*: 5 +*Version*: 6 *Rule authors*: @@ -116,10 +116,27 @@ to look for use of the `AttachRolePolicy` operation along with request_parameter [source, js] ---------------------------------- from logs-aws.cloudtrail-* metadata _id, _version, _index -| where event.provider == "iam.amazonaws.com" and event.action == "AttachRolePolicy" and event.outcome == "success" -| dissect aws.cloudtrail.request_parameters "{%{?policyArn}=%{?arn}:%{?aws}:%{?iam}::%{?aws}:%{?policy}/%{policyName},%{?roleName}=%{role.name}}" -| where policyName == "AdministratorAccess" -| keep @timestamp, event.provider, event.action, event.outcome, policyName, role.name + +| where + event.provider == "iam.amazonaws.com" + and event.action == "AttachRolePolicy" + and event.outcome == "success" + +// Extract policy name and role name from request parameters +| dissect aws.cloudtrail.request_parameters + "{%{?policyArn}=%{?arn}:%{?aws}:%{?iam}::%{?aws}:%{?policy}/%{Esql.aws_cloudtrail_request_parameters_policy_name},%{?roleName}=%{Esql.aws_cloudtrail_request_parameters_role_name}}" + +// Filter for AdministratorAccess policy attachment +| where Esql.aws_cloudtrail_request_parameters_policy_name == "AdministratorAccess" + +// keep relevant ECS and dynamic fields +| keep + @timestamp, + event.provider, + event.action, + event.outcome, + Esql.aws_cloudtrail_request_parameters_policy_name, + Esql.aws_cloudtrail_request_parameters_role_name ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/aws-iam-administratoraccess-policy-attached-to-user.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-iam-administratoraccess-policy-attached-to-user.asciidoc index 4ebcc82b30..b6359e2f2b 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-iam-administratoraccess-policy-attached-to-user.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-iam-administratoraccess-policy-attached-to-user.asciidoc @@ -34,7 +34,7 @@ An adversary with access to a set of compromised credentials may attempt to pers * Tactic: Persistence * Resources: Investigation Guide -*Version*: 6 +*Version*: 7 *Rule authors*: @@ -116,17 +116,28 @@ to look for use of the `AttachUserPolicy` operation along with request_parameter [source, js] ---------------------------------- from logs-aws.cloudtrail-* metadata _id, _version, _index -| where event.provider == "iam.amazonaws.com" and event.action == "AttachUserPolicy" and event.outcome == "success" -| dissect aws.cloudtrail.request_parameters "{%{?policyArn}=%{?arn}:%{?aws}:%{?iam}::%{?aws}:%{?policy}/%{policyName},%{?userName}=%{target.userName}}" -| where policyName == "AdministratorAccess" + +| where + event.provider == "iam.amazonaws.com" + and event.action == "AttachUserPolicy" + and event.outcome == "success" + +// Extract policy name and user name from request parameters +| dissect aws.cloudtrail.request_parameters + "{%{?policyArn}=%{?arn}:%{?aws}:%{?iam}::%{?aws}:%{?policy}/%{Esql.aws_cloudtrail_request_parameters_policy_name},%{?userName}=%{Esql_priv.aws_cloudtrail_request_parameters_target_user_name}}" + +// Filter for AdministratorAccess policy +| where Esql.aws_cloudtrail_request_parameters_policy_name == "AdministratorAccess" + +// keep ECS and parsed fields | keep @timestamp, cloud.region, event.provider, event.action, event.outcome, - policyName, - target.userName, + Esql.aws_cloudtrail_request_parameters_policy_name, + Esql_priv.aws_cloudtrail_request_parameters_target_user_name, aws.cloudtrail.request_parameters, aws.cloudtrail.user_identity.arn, related.user, diff --git a/docs/detections/prebuilt-rules/rule-details/aws-iam-login-profile-added-for-root.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-iam-login-profile-added-for-root.asciidoc index 3e3d0f1fa9..812ba3f04e 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-iam-login-profile-added-for-root.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-iam-login-profile-added-for-root.asciidoc @@ -29,7 +29,7 @@ Detects when an AWS IAM login profile is added to a root user account and is sel * Tactic: Persistence * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -177,10 +177,10 @@ from logs-aws.cloudtrail* metadata _id, _version, _index and aws.cloudtrail.user_identity.type == "Root" // filter for an access key existing which sources from AssumeRoot - and aws.cloudtrail.user_identity.access_key_id IS NOT NULL + and aws.cloudtrail.user_identity.access_key_id is not null // filter on the request parameters not including UserName which assumes self-assignment - and NOT TO_LOWER(aws.cloudtrail.request_parameters) LIKE "*username*" + and not to_lower(aws.cloudtrail.request_parameters) like "*username*" | keep @timestamp, aws.cloudtrail.request_parameters, diff --git a/docs/detections/prebuilt-rules/rule-details/aws-s3-bucket-enumeration-or-brute-force.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-s3-bucket-enumeration-or-brute-force.asciidoc index 8bc465180f..ab98c16c40 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-s3-bucket-enumeration-or-brute-force.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-s3-bucket-enumeration-or-brute-force.asciidoc @@ -32,7 +32,7 @@ Identifies a high number of failed S3 operations from a single source and accoun * Use Case: Log Auditing * Tactic: Impact -*Version*: 4 +*Version*: 5 *Rule authors*: @@ -111,13 +111,29 @@ Attackers may attempt to enumerate names until a valid bucket is discovered and [source, js] ---------------------------------- from logs-aws.cloudtrail* -| where event.provider == "s3.amazonaws.com" and aws.cloudtrail.error_code == "AccessDenied" -// keep only relevant fields -| keep tls.client.server_name, source.address, cloud.account.id -| stats failed_requests = count(*) by tls.client.server_name, source.address, cloud.account.id - // can modify the failed request count or tweak time window to fit environment - // can add `not cloud.account.id in (KNOWN)` or specify in exceptions -| where failed_requests > 40 + +| where + event.provider == "s3.amazonaws.com" + and aws.cloudtrail.error_code == "AccessDenied" + and tls.client.server_name is not null + and cloud.account.id is not null + +// keep only relevant ECS fields +| keep + tls.client.server_name, + source.address, + cloud.account.id + +// count access denied requests per server_name, source, and account +| stats + Esql.event_count = count(*) + by + tls.client.server_name, + source.address, + cloud.account.id + +// Threshold: more than 40 denied requests +| where Esql.event_count > 40 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/aws-s3-object-encryption-using-external-kms-key.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-s3-object-encryption-using-external-kms-key.asciidoc index 3e544b4fe4..d1ce290cd2 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-s3-object-encryption-using-external-kms-key.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-s3-object-encryption-using-external-kms-key.asciidoc @@ -35,7 +35,7 @@ Identifies `CopyObject` events within an S3 bucket using an AWS KMS key from an * Tactic: Impact * Resources: Investigation Guide -*Version*: 5 +*Version*: 6 *Rule authors*: @@ -108,21 +108,30 @@ AWS S3 data event types need to be enabled in the CloudTrail trail configuration ---------------------------------- from logs-aws.cloudtrail-* metadata _id, _version, _index -// any successful copy event -| where event.dataset == "aws.cloudtrail" - and event.provider == "s3.amazonaws.com" - and event.action == "CopyObject" - and event.outcome == "success" - -// abstract key account id, key id, encrypted object bucket name and object name -| dissect aws.cloudtrail.request_parameters "{%{?bucketName}=%{target.bucketName},%{?x-amz-server-side-encryption-aws-kms-key-id}=%{?arn}:%{?aws}:%{?kms}:%{?region}:%{key.account.id}:%{?key}/%{keyId},%{?Host}=%{?tls.client.server_name},%{?x-amz-server-side-encryption}=%{?server-side-encryption},%{?x-amz-copy-source}=%{?bucket.objectName},%{?key}=%{target.objectName}}" - -// filter for s3 objects whose account id is different from the encryption key's account id -// add exceptions based on key.account.id or keyId for known external accounts or encryption keys -| where cloud.account.id != key.account.id - -// keep relevant fields -| keep @timestamp, aws.cloudtrail.user_identity.arn, cloud.account.id, event.action, target.bucketName, key.account.id, keyId, target.objectName +// any successful S3 copy event +| where + event.dataset == "aws.cloudtrail" + and event.provider == "s3.amazonaws.com" + and event.action == "CopyObject" + and event.outcome == "success" + +// dissect request parameters to extract KMS key info and target object info +| dissect aws.cloudtrail.request_parameters + "{%{?bucketName}=%{Esql.aws_cloudtrail_request_parameters_target_bucket_name},%{?x-amz-server-side-encryption-aws-kms-key-id}=%{?arn}:%{?aws}:%{?kms}:%{?region}:%{Esql.aws_cloudtrail_request_parameters_kms_key_account_id}:%{?key}/%{Esql.aws_cloudtrail_request_parameters_kms_key_id},%{?Host}=%{?tls.client.server.name},%{?x-amz-server-side-encryption}=%{?server_side_encryption},%{?x-amz-copy-source}=%{?bucket.object.name},%{?key}=%{Esql.aws_cloudtrail_request_parameters_target_object_key}}" + +// detect cross-account key usage +| where cloud.account.id != Esql.aws_cloudtrail_request_parameters_kms_key_account_id + +// keep ECS and dissected fields +| keep + @timestamp, + aws.cloudtrail.user_identity.arn, + cloud.account.id, + event.action, + Esql.aws_cloudtrail_request_parameters_target_bucket_name, + Esql.aws_cloudtrail_request_parameters_kms_key_account_id, + Esql.aws_cloudtrail_request_parameters_kms_key_id, + Esql.aws_cloudtrail_request_parameters_target_object_key ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/aws-s3-static-site-javascript-file-uploaded.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-s3-static-site-javascript-file-uploaded.asciidoc index 0fd00fc7da..646e012586 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-s3-static-site-javascript-file-uploaded.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-s3-static-site-javascript-file-uploaded.asciidoc @@ -34,7 +34,7 @@ This rule detects when a JavaScript file is uploaded or accessed in an S3 static * Use Case: Cloud Threat Detection * Resources: Investigation Guide -*Version*: 1 +*Version*: 2 *Rule authors*: @@ -90,41 +90,44 @@ An S3 `PutObject` action that targets a path like `static/js/` and uploads a `.j [source, js] ---------------------------------- from logs-aws.cloudtrail* metadata _id, _version, _index -| where - // filter on CloudTrail logs for S3 PutObject actions +| where + // S3 object read/write activity event.dataset == "aws.cloudtrail" and event.provider == "s3.amazonaws.com" - and event.action in ("GetObject","PutObject") + and event.action in ("GetObject", "PutObject") - // filter for IAM users, not federated identities + // IAM users or assumed roles only and aws.cloudtrail.user_identity.type in ("IAMUser", "AssumedRole") - // filter for S3 static site bucket paths from webpack or similar - and aws.cloudtrail.request_parameters LIKE "*static/js/*.js*" + // Requests for static site bundles + and aws.cloudtrail.request_parameters like "*static/js/*.js*" - // exclude common IaC tools and automation scripts + // Exclude IaC and automation tools and not ( - user_agent.original LIKE "*Terraform*" - or user_agent.original LIKE "*Ansible*" - or user_agent.original LIKE "*Pulumni*" + user_agent.original like "*Terraform*" + or user_agent.original like "*Ansible*" + or user_agent.original like "*Pulumni*" ) -// extract bucket and object details from request parameters -| dissect aws.cloudtrail.request_parameters "%{{?bucket.name.key}=%{bucket.name}, %{?host.key}=%{bucket.host}, %{?bucket.object.location.key}=%{bucket.object.location}}" +// Extract fields from request parameters +| dissect aws.cloudtrail.request_parameters + "%{{?bucket.name.key}=%{Esql.aws_cloudtrail_request_parameters_bucket_name}, %{?host.key}=%{Esql_priv.aws_cloudtrail_request_parameters_host}, %{?bucket.object.location.key}=%{Esql.aws_cloudtrail_request_parameters_bucket_object_location}}" + +// Extract file name portion from full object path +| dissect Esql.aws_cloudtrail_request_parameters_object_location "%{}static/js/%{Esql.aws_cloudtrail_request_parameters_object_key}" -// filter for specific bucket and object structure -| dissect bucket.object.location "%{}static/js/%{bucket.object}" +// Match on JavaScript files +| where ends_with(Esql.aws_cloudtrail_request_parameters_object_key, ".js") -// filter for JavaScript files -| where ENDS_WITH(bucket.object, ".js") +// Retain relevant ECS and dissected fields | keep aws.cloudtrail.user_identity.arn, aws.cloudtrail.user_identity.access_key_id, aws.cloudtrail.user_identity.type, aws.cloudtrail.request_parameters, - bucket.name, - bucket.object, + Esql.aws_cloudtrail_request_parameters_bucket_name, + Esql.aws_cloudtrail_request_parameters_object_key, user_agent.original, source.ip, event.action, diff --git a/docs/detections/prebuilt-rules/rule-details/aws-service-quotas-multi-region-getservicequota-requests.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-service-quotas-multi-region-getservicequota-requests.asciidoc index b869b0fcfc..06e63650a8 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-service-quotas-multi-region-getservicequota-requests.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-service-quotas-multi-region-getservicequota-requests.asciidoc @@ -32,7 +32,7 @@ Identifies when a single AWS resource is making `GetServiceQuota` API calls for * Tactic: Discovery * Resources: Investigation Guide -*Version*: 3 +*Version*: 4 *Rule authors*: @@ -97,28 +97,41 @@ AWS Service Quotas manage resource limits across AWS services, crucial for maint from logs-aws.cloudtrail-* // filter for GetServiceQuota API calls -| where event.dataset == "aws.cloudtrail" and event.provider == "servicequotas.amazonaws.com" and event.action == "GetServiceQuota" +| where + event.dataset == "aws.cloudtrail" + and event.provider == "servicequotas.amazonaws.com" + and event.action == "GetServiceQuota" // truncate the timestamp to a 30-second window -| eval target_time_window = DATE_TRUNC(30 seconds, @timestamp) +| eval Esql.time_window_date_trunc = date_trunc(30 seconds, @timestamp) -// pre-process the request parameters to extract the service code and quota code -| dissect aws.cloudtrail.request_parameters "{%{?service_code_key}=%{service_code}, %{?quota_code_key}=%{quota_code}}" +// dissect request parameters to extract service and quota code +| dissect aws.cloudtrail.request_parameters "{%{?Esql.aws_cloudtrail_request_parameters_service_code_key}=%{Esql.aws_cloudtrail_request_parameters_service_code}, %{?quota_code_key}=%{Esql.aws_cloudtrail_request_parameters_quota_code}}" // filter for EC2 service quota L-1216C47A (vCPU on-demand instances) -| where service_code == "ec2" and quota_code == "L-1216C47A" +| where Esql.aws_cloudtrail_request_parameters_service_code == "ec2" and Esql.aws_cloudtrail_request_parameters_quota_code == "L-1216C47A" // keep only the relevant fields -| keep target_time_window, aws.cloudtrail.user_identity.arn, cloud.region, service_code, quota_code - -// count the number of unique regions and total API calls within the 30-second window -| stats region_count = count_distinct(cloud.region), window_count = count(*) by target_time_window, aws.cloudtrail.user_identity.arn - -// filter for resources making DescribeInstances API calls in more than 10 regions within the 30-second window -| where region_count >= 10 and window_count >= 10 - -// sort the results by time windows in descending order -| sort target_time_window desc +| keep + Esql.time_window_date_trunc, + aws.cloudtrail.user_identity.arn, + cloud.region, + Esql.aws_cloudtrail_request_parameters_service_code, + Esql.aws_cloudtrail_request_parameters_quota_code + +// count the number of unique regions and total API calls within the time window +| stats + Esql.cloud_region_count_distinct = count_distinct(cloud.region), + Esql.event_count = count(*) + by Esql.time_window_date_trunc, aws.cloudtrail.user_identity.arn + +// filter for API calls in more than 10 regions within the 30-second window +| where + Esql.cloud_region_count_distinct >= 10 + and Esql.event_count >= 10 + +// sort by time window descending +| sort Esql.time_window_date_trunc desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/aws-signin-single-factor-console-login-with-federated-user.asciidoc b/docs/detections/prebuilt-rules/rule-details/aws-signin-single-factor-console-login-with-federated-user.asciidoc index 5c0ebf140a..f5c76c6a37 100644 --- a/docs/detections/prebuilt-rules/rule-details/aws-signin-single-factor-console-login-with-federated-user.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/aws-signin-single-factor-console-login-with-federated-user.asciidoc @@ -31,7 +31,7 @@ Identifies when a federated user logs into the AWS Management Console without us * Tactic: Initial Access * Resources: Investigation Guide -*Version*: 3 +*Version*: 4 *Rule authors*: @@ -95,14 +95,28 @@ Federated users in AWS are granted temporary credentials to access resources, of [source, js] ---------------------------------- from logs-aws.cloudtrail-* metadata _id, _version, _index + | where event.provider == "signin.amazonaws.com" and event.action == "GetSigninToken" and aws.cloudtrail.event_type == "AwsConsoleSignIn" and aws.cloudtrail.user_identity.type == "FederatedUser" -| dissect aws.cloudtrail.additional_eventdata "{%{?mobile_version_key}=%{mobile_version}, %{?mfa_used_key}=%{mfa_used}}" -| where mfa_used == "No" -| keep @timestamp, event.action, aws.cloudtrail.event_type, aws.cloudtrail.user_identity.type + +// Extract mobile version and MFA usage +| dissect aws.cloudtrail.additional_eventdata + "{%{?mobile_version_key}=%{Esql.aws_cloudtrail_additional_eventdata_device_version}, %{?mfa_used_key}=%{Esql.aws_cloudtrail_additional_eventdata_auth_mfa_used}}" + +// Only keep events where MFA was not used +| where Esql.aws_cloudtrail_additional_eventdata_auth_mfa_used == "No" + +// keep relevant ECS and dissected fields +| keep + @timestamp, + event.action, + aws.cloudtrail.event_type, + aws.cloudtrail.user_identity.type, + Esql.aws_cloudtrail_additional_eventdata_device_version, + Esql.aws_cloudtrail_additional_eventdata_auth_mfa_used ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/azure-openai-insecure-output-handling.asciidoc b/docs/detections/prebuilt-rules/rule-details/azure-openai-insecure-output-handling.asciidoc index ed92d42ad3..f0113c20d3 100644 --- a/docs/detections/prebuilt-rules/rule-details/azure-openai-insecure-output-handling.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/azure-openai-insecure-output-handling.asciidoc @@ -29,7 +29,7 @@ Detects when Azure OpenAI requests result in zero response length, potentially i * Use Case: Insecure Output Handling * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -104,10 +104,22 @@ https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/stream-monitori [source, js] ---------------------------------- from logs-azure_openai.logs-* -| where azure.open_ai.properties.response_length == 0 and azure.open_ai.result_signature == "200" and azure.open_ai.operation_name == "ChatCompletions_Create" -| keep azure.open_ai.properties.request_length, azure.open_ai.result_signature, cloud.account.id, azure.resource.name -| stats count = count() by azure.resource.name -| where count >= 10 -| sort count desc +| where + azure.open_ai.properties.response_length == 0 and + azure.open_ai.result_signature == "200" and + azure.open_ai.operation_name == "ChatCompletions_Create" +| keep + azure.open_ai.properties.request_length, + azure.open_ai.result_signature, + cloud.account.id, + azure.resource.name +| stats + Esql.event_count = count(*) + by + azure.resource.name +| where + Esql.event_count >= 10 +| sort + Esql.event_count desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/dynamic-iex-reconstruction-via-method-string-access.asciidoc b/docs/detections/prebuilt-rules/rule-details/dynamic-iex-reconstruction-via-method-string-access.asciidoc index 249be6ac77..2fcadeed98 100644 --- a/docs/detections/prebuilt-rules/rule-details/dynamic-iex-reconstruction-via-method-string-access.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/dynamic-iex-reconstruction-via-method-string-access.asciidoc @@ -28,7 +28,7 @@ Identifies PowerShell scripts that reconstruct the IEX (Invoke-Expression) comma * Data Source: PowerShell Logs * Resources: Investigation Guide -*Version*: 3 +*Version*: 4 *Rule authors*: @@ -113,23 +113,42 @@ reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" [source, js] ---------------------------------- -FROM logs-windows.powershell_operational* metadata _id, _version, _index -| WHERE event.code == "4104" +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" -// Look for scripts with more than 500 chars that contain a related keyword -| EVAL script_len = LENGTH(powershell.file.script_block_text) -| WHERE script_len > 500 +// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for +| eval Esql.script_block_length = length(powershell.file.script_block_text) +| where Esql.script_block_length > 500 -// Replace string format expressions with πŸ”₯ to enable counting the occurrence of the patterns we are looking for +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them // The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 -| EVAL replaced_with_fire = REPLACE(powershell.file.script_block_text, """(?i)['"]['"].(Insert|Normalize|Chars|SubString|Remove|LastIndexOfAny|LastIndexOf|IsNormalized|IndexOfAny|IndexOf)[^\[]+\[\d+,\d+,\d+\]""", "πŸ”₯") - -// Count how many patterns were detected by calculating the number of πŸ”₯ characters inserted -| EVAL count = LENGTH(replaced_with_fire) - LENGTH(REPLACE(replaced_with_fire, "πŸ”₯", "")) - -// Keep the fields relevant to the query, although this is not needed as the alert is populated using _id -| KEEP count, replaced_with_fire, powershell.file.script_block_text, powershell.file.script_block_id, file.path, powershell.sequence, powershell.total, _id, _index, host.name, agent.id, user.id -| WHERE count >= 1 +| eval Esql.script_block_tmp = replace( + powershell.file.script_block_text, + """(?i)['"]['"].(Insert|Normalize|Chars|substring|Remove|LastIndexOfAny|LastIndexOf|IsNormalized|IndexOfAny|IndexOf)[^\[]+\[\d+,\d+,\d+\]""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_length, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least once +| where Esql.script_block_pattern_count >= 1 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/elastic-security-external-alerts.asciidoc b/docs/detections/prebuilt-rules/rule-details/elastic-security-external-alerts.asciidoc index d283a15f12..7161cbf671 100644 --- a/docs/detections/prebuilt-rules/rule-details/elastic-security-external-alerts.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/elastic-security-external-alerts.asciidoc @@ -30,7 +30,7 @@ Generates a detection alert for each Elastic Security alert written to the confi * Resources: Investigation Guide * Promotion: External Alerts -*Version*: 1 +*Version*: 2 *Rule authors*: diff --git a/docs/detections/prebuilt-rules/rule-details/excessive-secret-or-key-retrieval-from-azure-key-vault.asciidoc b/docs/detections/prebuilt-rules/rule-details/excessive-secret-or-key-retrieval-from-azure-key-vault.asciidoc index f54e66a6b9..da67390214 100644 --- a/docs/detections/prebuilt-rules/rule-details/excessive-secret-or-key-retrieval-from-azure-key-vault.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/excessive-secret-or-key-retrieval-from-azure-key-vault.asciidoc @@ -34,7 +34,7 @@ Identifies excessive secret or key retrieval operations from Azure Key Vault. Th * Tactic: Credential Access * Resources: Investigation Guide -*Version*: 1 +*Version*: 2 *Rule authors*: @@ -103,11 +103,11 @@ To ensure this rule functions correctly, the following diagnostic logs must be e [source, js] ---------------------------------- -FROM logs-azure.platformlogs-* METADATA _id, _index +from logs-azure.platformlogs-* metadata _id, _index // Filter for Azure Key Vault read operations -| WHERE event.dataset == "azure.platformlogs" - AND event.action IN ( +| where event.dataset == "azure.platformlogs" + and event.action in ( "VaultGet", "KeyGet", "KeyList", @@ -131,64 +131,64 @@ FROM logs-azure.platformlogs-* METADATA _id, _index ) // Truncate timestamps into 1-minute windows -| EVAL Esql.time_window.date_trunc = DATE_TRUNC(1 minute, @timestamp) +| eval Esql.time_window_date_trunc = date_trunc(1 minute, @timestamp) // Aggregate identity, geo, resource, and activity info -| STATS - Esql.azure.platformlogs.identity.claim.upn.values = VALUES(azure.platformlogs.identity.claim.upn), - Esql.azure.platformlogs.identity.claim.upn.count_unique = COUNT_DISTINCT(azure.platformlogs.identity.claim.upn), - Esql.azure.platformlogs.identity.claim.appid.values = VALUES(azure.platformlogs.identity.claim.appid), - Esql.azure.platformlogs.identity.claim.objectid.values = VALUES(azure.platformlogs.identity.claim.objectid), - - Esql.source.ip.values = VALUES(source.ip), - Esql.geo.city.values = VALUES(geo.city_name), - Esql.geo.region.values = VALUES(geo.region_name), - Esql.geo.country.values = VALUES(geo.country_name), - Esql.network.as_org.values = VALUES(source.as.organization.name), - - Esql.event.actions.values = VALUES(event.action), - Esql.event.count = COUNT(*), - Esql.event.action.count_distinct = COUNT_DISTINCT(event.action), - Esql.azure.resource.name.count_distinct = COUNT_DISTINCT(azure.resource.name), - Esql.azure.resource.name.values = VALUES(azure.resource.name), - Esql.azure.platformlogs.result_type.values = VALUES(azure.platformlogs.result_type), - Esql.cloud.region.values = VALUES(cloud.region), - - Esql.agent.name.values = VALUES(agent.name), - Esql.azure.subscription_id.values = VALUES(azure.subscription_id), - Esql.azure.resource_group.values = VALUES(azure.resource.group), - Esql.azure.resource_id.values = VALUES(azure.resource.id) - -BY Esql.time_window.date_trunc, azure.platformlogs.identity.claim.upn - -// Keep relevant fields -| KEEP - Esql.time_window.date_trunc, - Esql.azure.platformlogs.identity.claim.upn.values, - Esql.azure.platformlogs.identity.claim.upn.count_unique, - Esql.azure.platformlogs.identity.claim.appid.values, - Esql.azure.platformlogs.identity.claim.objectid.values, - Esql.source.ip.values, - Esql.geo.city.values, - Esql.geo.region.values, - Esql.geo.country.values, - Esql.network.as_org.values, - Esql.event.actions.values, - Esql.event.count, - Esql.event.action.count_distinct, - Esql.azure.resource.name.count_distinct, - Esql.azure.resource.name.values, - Esql.azure.platformlogs.result_type.values, - Esql.cloud.region.values, - Esql.agent.name.values, - Esql.azure.subscription_id.values, - Esql.azure.resource_group.values, - Esql.azure.resource_id.values +| stats + Esql_priv.azure_platformlogs_identity_claim_upn_values = values(azure.platformlogs.identity.claim.upn), + Esql.azure_platformlogs_identity_claim_upn_count_distinct = count_distinct(azure.platformlogs.identity.claim.upn), + Esql.azure_platformlogs_identity_claim_appid_values = values(azure.platformlogs.identity.claim.appid), + Esql.azure_platformlogs_identity_claim_objectid_values = values(azure.platformlogs.identity.claim.objectid), + + Esql.source_ip_values = values(source.ip), + Esql.geo_city_values = values(geo.city_name), + Esql.geo_region_values = values(geo.region_name), + Esql.geo_country_values = values(geo.country_name), + Esql.source_as_organization_name_values = values(source.as.organization.name), + + Esql.event_action_values = values(event.action), + Esql.event_count = count(*), + Esql.event_action_count_distinct = count_distinct(event.action), + Esql.azure_resource_name_count_distinct = count_distinct(azure.resource.name), + Esql.azure_resource_name_values = values(azure.resource.name), + Esql.azure_platformlogs_result_type_values = values(azure.platformlogs.result_type), + Esql.cloud_region_values = values(cloud.region), + + Esql.agent_name_values = values(agent.name), + Esql.azure_subscription_id_values = values(azure.subscription_id), + Esql.azure_resource_group_values = values(azure.resource.group), + Esql.azure_resource_id_values = values(azure.resource.id) + +by Esql.time_window_date_trunc, azure.platformlogs.identity.claim.upn + +// keep relevant fields +| keep + Esql.time_window_date_trunc, + Esql_priv.azure_platformlogs_identity_claim_upn_values, + Esql.azure_platformlogs_identity_claim_upn_count_distinct, + Esql.azure_platformlogs_identity_claim_appid_values, + Esql.azure_platformlogs_identity_claim_objectid_values, + Esql.source_ip_values, + Esql.geo_city_values, + Esql.geo_region_values, + Esql.geo_country_values, + Esql.source_as_organization_name_values, + Esql.event_action_values, + Esql.event_count, + Esql.event_action_count_distinct, + Esql.azure_resource_name_count_distinct, + Esql.azure_resource_name_values, + Esql.azure_platformlogs_result_type_values, + Esql.cloud_region_values, + Esql.agent_name_values, + Esql.azure_subscription_id_values, + Esql.azure_resource_group_values, + Esql.azure_resource_id_values // Filter for suspiciously high volume of distinct Key Vault reads by a single actor -| WHERE Esql.azure.platformlogs.identity.claim.upn.count_unique == 1 AND Esql.event.count >= 10 AND Esql.event.action.count_distinct >= 2 +| where Esql.azure_platformlogs_identity_claim_upn_count_distinct == 1 and Esql.event_count >= 10 and Esql.event_action_count_distinct >= 2 -| SORT Esql.time_window.date_trunc DESC +| sort Esql.time_window_date_trunc desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/high-number-of-egress-network-connections-from-unusual-executable.asciidoc b/docs/detections/prebuilt-rules/rule-details/high-number-of-egress-network-connections-from-unusual-executable.asciidoc index 6f181dd36c..5dd38e5981 100644 --- a/docs/detections/prebuilt-rules/rule-details/high-number-of-egress-network-connections-from-unusual-executable.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/high-number-of-egress-network-connections-from-unusual-executable.asciidoc @@ -28,7 +28,7 @@ This rule detects a high number of egress network connections from an unusual ex * Data Source: Elastic Defend * Resources: Investigation Guide -*Version*: 4 +*Version*: 5 *Rule authors*: @@ -130,30 +130,50 @@ For more details on Elastic Defend refer to the https://www.elastic.co/guide/en/ [source, js] ---------------------------------- from logs-endpoint.events.network-* -| keep @timestamp, host.os.type, event.type, event.action, process.name, process.executable, destination.ip, agent.id, host.name -| where @timestamp > now() - 1 hours -| where host.os.type == "linux" and event.type == "start" and event.action == "connection_attempted" and ( - ( - process.executable like "/tmp/*" or - process.executable like "/var/tmp/*" or - process.executable like "/dev/shm/*" - ) or - (process.name like ".*") -) and not ( - CIDR_MATCH( - destination.ip, "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24", "192.0.0.0/29", "192.0.0.8/32", "192.0.0.9/32", - "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24", "192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", - "224.0.0.0/4", "100.64.0.0/10", "192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "224.0.0.0/4", "240.0.0.0/4", "::1", - "FE80::/10", "FF00::/8" - ) or - process.executable like "/nix/store/*" or - process.executable like "/tmp/newroot/*" or - process.executable like "/tmp/.mount*" or - process.executable like "/tmp/go-build*" - ) -| stats cc = count(), agent_count = count_distinct(agent.id), host.name = VALUES(host.name), agent.id = VALUES(agent.id) by process.executable -| where agent_count == 1 and cc > 15 -| sort cc asc +| where + @timestamp > now() - 1h and + host.os.type == "linux" and + event.type == "start" and + event.action == "connection_attempted" and + ( + process.executable like "/tmp/*" or + process.executable like "/var/tmp/*" or + process.executable like "/dev/shm/*" or + process.name rlike ".*" + ) and not ( + cidr_match(destination.ip, + "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", + "192.0.0.0/24", "192.0.0.29/32", "192.0.0.8/32", "192.0.0.9/32", + "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24", + "192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", + "224.0.0.0/4", "100.64.0.0/10", "192.175.48.0/24", "198.18.0.0/15", + "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1", "FE80::/10", "FF00::/8" + ) or + process.executable like "/nix/store/*" or + process.executable like "/tmp/newroot/*" or + process.executable like "/tmp/.mount*" or + process.executable like "/tmp/go-build*" + ) +| keep + @timestamp, + host.os.type, + event.type, + event.action, + process.name, + process.executable, + destination.ip, + agent.id, + host.name +| stats + Esql.event_count = count(), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.executable +| where + Esql.agent_id_count_distinct == 1 and + Esql.event_count > 15 +| sort Esql.event_count asc | limit 100 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/high-number-of-okta-device-token-cookies-generated-for-authentication.asciidoc b/docs/detections/prebuilt-rules/rule-details/high-number-of-okta-device-token-cookies-generated-for-authentication.asciidoc index 3cf1c70914..01ef7bdf7e 100644 --- a/docs/detections/prebuilt-rules/rule-details/high-number-of-okta-device-token-cookies-generated-for-authentication.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/high-number-of-okta-device-token-cookies-generated-for-authentication.asciidoc @@ -34,7 +34,7 @@ Detects when an Okta client address has a certain threshold of Okta user authent * Tactic: Credential Access * Resources: Investigation Guide -*Version*: 205 +*Version*: 206 *Rule authors*: @@ -115,20 +115,28 @@ The Okta Fleet integration, Filebeat module, or similarly structured data is req [source, js] ---------------------------------- -FROM logs-okta* -| WHERE - event.dataset == "okta.system" - AND (event.action RLIKE "user\\.authentication(.*)" OR event.action == "user.session.start") - AND okta.debug_context.debug_data.request_uri == "/api/v1/authn" - AND okta.outcome.reason == "INVALID_CREDENTIALS" -| KEEP event.action, okta.debug_context.debug_data.dt_hash, okta.client.ip, okta.actor.alternate_id, okta.debug_context.debug_data.request_uri, okta.outcome.reason -| STATS - source_auth_count = COUNT_DISTINCT(okta.debug_context.debug_data.dt_hash) - BY okta.client.ip, okta.actor.alternate_id -| WHERE - source_auth_count >= 30 -| SORT - source_auth_count DESC +from logs-okta* +| where + event.dataset == "okta.system" and + (event.action rlike "user\.authentication(.*)" or event.action == "user.session.start") and + okta.debug_context.debug_data.request_uri == "/api/v1/authn" and + okta.outcome.reason == "INVALID_CREDENTIALS" +| keep + event.action, + okta.debug_context.debug_data.dt_hash, + okta.client.ip, + okta.actor.alternate_id, + okta.debug_context.debug_data.request_uri, + okta.outcome.reason +| stats + Esql.okta_debug_context_debug_data_dt_hash_count_distinct = count_distinct(okta.debug_context.debug_data.dt_hash) + by + okta.client.ip, + okta.actor.alternate_id +| where + Esql.okta_debug_context_debug_data_dt_hash_count_distinct >= 30 +| sort + Esql.okta_debug_context_debug_data_dt_hash_count_distinct desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/m365-onedrive-excessive-file-downloads-with-oauth-token.asciidoc b/docs/detections/prebuilt-rules/rule-details/m365-onedrive-excessive-file-downloads-with-oauth-token.asciidoc index 230a5f4935..67c8055763 100644 --- a/docs/detections/prebuilt-rules/rule-details/m365-onedrive-excessive-file-downloads-with-oauth-token.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/m365-onedrive-excessive-file-downloads-with-oauth-token.asciidoc @@ -33,7 +33,7 @@ Identifies when an excessive number of files are downloaded from OneDrive using * Tactic: Exfiltration * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -99,27 +99,30 @@ This rule leverages ESQL aggregations which limit the field values available in [source, js] ---------------------------------- -FROM logs-o365.audit-* -| WHERE @timestamp > now() - 14 day -| WHERE +from logs-o365.audit-* +| where + @timestamp > now() - 14d and event.dataset == "o365.audit" and - - // filter on files downloaded from OneDrive event.provider == "OneDrive" and event.action == "FileDownloaded" and - - // filter on OAuth authentication which encompasses device code workflow - o365.audit.AuthenticationType == "OAuth" - and event.outcome == "success" -// bucket authentication attempts by 1 minute -| EVAL target_time_window = DATE_TRUNC(1 minutes, @timestamp) -| KEEP target_time_window, o365.audit.UserId, file.name, source.ip - -// aggregate on unique file names and download attempts -| STATS unique_file_count = count_distinct(file.name), download_attempt_count = count(*) BY target_time_window, o365.audit.UserId, source.ip - -// adjustable range for "excessive" unique files that were downloaded -| WHERE unique_file_count >= 25 + o365.audit.AuthenticationType == "OAuth" and + event.outcome == "success" +| eval + Esql.time_window_date_trunc = date_trunc(1 minutes, @timestamp) +| keep + Esql.time_window_date_trunc, + o365.audit.UserId, + file.name, + source.ip +| stats + Esql.file_name_count_distinct = count_distinct(file.name), + Esql.event_count = count(*) + by + Esql.time_window_date_trunc, + o365.audit.UserId, + source.ip +| where + Esql.file_name_count_distinct >= 25 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/microsoft-365-brute-force-via-entra-id-sign-ins.asciidoc b/docs/detections/prebuilt-rules/rule-details/microsoft-365-brute-force-via-entra-id-sign-ins.asciidoc index 143aa5a200..277dcfd6af 100644 --- a/docs/detections/prebuilt-rules/rule-details/microsoft-365-brute-force-via-entra-id-sign-ins.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/microsoft-365-brute-force-via-entra-id-sign-ins.asciidoc @@ -40,7 +40,7 @@ Identifies potential brute-force attacks targeting Microsoft 365 user accounts b * Tactic: Credential Access * Resources: Investigation Guide -*Version*: 105 +*Version*: 106 *Rule authors*: @@ -104,28 +104,22 @@ Identifies brute-force authentication activity against Microsoft 365 services us [source, js] ---------------------------------- -FROM logs-azure.signinlogs* - -| EVAL - time_window = DATE_TRUNC(15 minutes, @timestamp), - user_id = TO_LOWER(azure.signinlogs.properties.user_principal_name), - ip = source.ip, - login_error = azure.signinlogs.result_description, - error_code = azure.signinlogs.properties.status.error_code, - request_type = TO_LOWER(azure.signinlogs.properties.incoming_token_type), - app_name = TO_LOWER(azure.signinlogs.properties.app_display_name), - asn_org = source.`as`.organization.name, - country = source.geo.country_name, - user_agent = user_agent.original, - event_time = @timestamp - -| WHERE event.dataset == "azure.signinlogs" - AND event.category == "authentication" - AND azure.signinlogs.category IN ("NonInteractiveUserSignInLogs", "SignInLogs") - AND azure.signinlogs.properties.resource_display_name RLIKE "(.*)365|SharePoint|Exchange|Teams|Office(.*)" - AND event.outcome == "failure" - AND error_code != 50053 - AND azure.signinlogs.properties.status.error_code IN ( +from logs-azure.signinlogs* + +| eval + Esql.time_window_date_trunc = date_trunc(15 minutes, @timestamp), + Esql_priv.azure_signinlogs_properties_user_principal_name_lower = to_lower(azure.signinlogs.properties.user_principal_name), + Esql.azure_signinlogs_properties_incoming_token_type_lower = to_lower(azure.signinlogs.properties.incoming_token_type), + Esql.azure_signinlogs_properties_app_display_name_lower = to_lower(azure.signinlogs.properties.app_display_name), + Esql.user_agent_original = user_agent.original + +| where event.dataset == "azure.signinlogs" + and event.category == "authentication" + and azure.signinlogs.category in ("NonInteractiveUserSignInLogs", "SignInLogs") + and azure.signinlogs.properties.resource_display_name rlike "(.*)365|SharePoint|Exchange|Teams|Office(.*)" + and event.outcome == "failure" + and azure.signinlogs.properties.status.error_code != 50053 + and azure.signinlogs.properties.status.error_code in ( 50034, // UserAccountNotFound 50126, // InvalidUsernameOrPassword 50055, // PasswordExpired @@ -147,84 +141,113 @@ FROM logs-azure.signinlogs* 120002, // PasswordChangeInvalidNewPasswordWeak 120020 // PasswordChangeFailure ) - AND user_id IS NOT NULL AND user_id != "" - AND user_agent != "Mozilla/5.0 (compatible; MSAL 1.0) PKeyAuth/1.0" - -| STATS - authentication_requirement = VALUES(azure.signinlogs.properties.authentication_requirement), - client_app_id = VALUES(azure.signinlogs.properties.app_id), - client_app_display_name = VALUES(azure.signinlogs.properties.app_display_name), - target_resource_id = VALUES(azure.signinlogs.properties.resource_id), - target_resource_display_name = VALUES(azure.signinlogs.properties.resource_display_name), - conditional_access_status = VALUES(azure.signinlogs.properties.conditional_access_status), - device_detail_browser = VALUES(azure.signinlogs.properties.device_detail.browser), - device_detail_device_id = VALUES(azure.signinlogs.properties.device_detail.device_id), - device_detail_operating_system = VALUES(azure.signinlogs.properties.device_detail.operating_system), - incoming_token_type = VALUES(azure.signinlogs.properties.incoming_token_type), - risk_state = VALUES(azure.signinlogs.properties.risk_state), - session_id = VALUES(azure.signinlogs.properties.session_id), - user_id = VALUES(azure.signinlogs.properties.user_id), - user_principal_name = VALUES(azure.signinlogs.properties.user_principal_name), - result_description = VALUES(azure.signinlogs.result_description), - result_signature = VALUES(azure.signinlogs.result_signature), - result_type = VALUES(azure.signinlogs.result_type), - - unique_users = COUNT_DISTINCT(user_id), - user_id_list = VALUES(user_id), - login_errors = VALUES(login_error), - unique_login_errors = COUNT_DISTINCT(login_error), - error_codes = VALUES(error_code), - unique_error_codes = COUNT_DISTINCT(error_code), - request_types = VALUES(request_type), - app_names = VALUES(app_name), - ip_list = VALUES(ip), - unique_ips = COUNT_DISTINCT(ip), - source_orgs = VALUES(asn_org), - countries = VALUES(country), - unique_country_count = COUNT_DISTINCT(country), - unique_asn_orgs = COUNT_DISTINCT(asn_org), - first_seen = MIN(event_time), - last_seen = MAX(event_time), - total_attempts = COUNT() -BY time_window - -| EVAL - duration_seconds = DATE_DIFF("seconds", first_seen, last_seen), - bf_type = CASE( - // Many users, relatively few distinct login errors, distributed over multiple IPs (but not too many), - // and happens quickly. Often bots using leaked credentials. - unique_users >= 10 AND total_attempts >= 30 AND unique_login_errors <= 3 - AND unique_ips >= 5 - AND duration_seconds <= 600 - AND unique_users > unique_ips, + and azure.signinlogs.properties.user_principal_name is not null + and azure.signinlogs.properties.user_principal_name != "" + and user_agent.original != "Mozilla/5.0 (compatible; MSAL 1.0) PKeyAuth/1.0" + +| stats + Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement), + Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id), + Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name), + Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id), + Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name), + Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status), + Esql.azure_signinlogs_properties_device_detail_browser_values = values(azure.signinlogs.properties.device_detail.browser), + Esql.azure_signinlogs_properties_device_detail_device_id_values = values(azure.signinlogs.properties.device_detail.device_id), + Esql.azure_signinlogs_properties_device_detail_operating_system_values = values(azure.signinlogs.properties.device_detail.operating_system), + Esql.azure_signinlogs_properties_incoming_token_type_values = values(azure.signinlogs.properties.incoming_token_type), + Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state), + Esql.azure_signinlogs_properties_session_id_values = values(azure.signinlogs.properties.session_id), + Esql.azure_signinlogs_properties_user_id_values = values(azure.signinlogs.properties.user_id), + Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name), + Esql.azure_signinlogs_result_description_values = values(azure.signinlogs.result_description), + Esql.azure_signinlogs_result_signature_values = values(azure.signinlogs.result_signature), + Esql.azure_signinlogs_result_type_values = values(azure.signinlogs.result_type), + + Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct = count_distinct(Esql_priv.azure_signinlogs_properties_user_principal_name_lower), + Esql_priv.azure_signinlogs_properties_user_principal_name_lower_values = values(Esql_priv.azure_signinlogs_properties_user_principal_name_lower), + Esql.azure_signinlogs_result_description_count_distinct = count_distinct(azure.signinlogs.result_description), + Esql.azure_signinlogs_result_description_values = values(azure.signinlogs.result_description), + Esql.azure_signinlogs_properties_status_error_code_count_distinct = count_distinct(azure.signinlogs.properties.status.error_code), + Esql.azure_signinlogs_properties_status_error_code_values = values(azure.signinlogs.properties.status.error_code), + Esql.azure_signinlogs_properties_incoming_token_type_lower_values = values(Esql.azure_signinlogs_properties_incoming_token_type_lower), + Esql.azure_signinlogs_properties_app_display_name_lower_values = values(Esql.azure_signinlogs_properties_app_display_name_lower), + Esql.source_ip_values = values(source.ip), + Esql.source_ip_count_distinct = count_distinct(source.ip), + Esql.source_as_organization_name_values = values(source.`as`.organization.name), + Esql.source_as_organization_name_count_distinct = count_distinct(source.`as`.organization.name), + Esql.source_geo_country_name_values = values(source.geo.country_name), + Esql.source_geo_country_name_count_distinct = count_distinct(source.geo.country_name), + Esql.@timestamp.min = min(@timestamp), + Esql.@timestamp.max = max(@timestamp), + Esql.event_count = count() +by Esql.time_window_date_trunc + +| eval + Esql.event_duration_seconds = date_diff("seconds", Esql.@timestamp.min, Esql.@timestamp.max), + Esql.event_bf_type = case( + Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct >= 10 + and Esql.event_count >= 30 + and Esql.azure_signinlogs_result_description_count_distinct <= 3 + and Esql.source_ip_count_distinct >= 5 + and Esql.event_duration_seconds <= 600 + and Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct > Esql.source_ip_count_distinct, "credential_stuffing", - // One password against many users. Single error (e.g., "InvalidPassword"), not necessarily fast. - unique_users >= 15 AND unique_login_errors == 1 AND total_attempts >= 15 AND duration_seconds <= 1800, + Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct >= 15 + and Esql.azure_signinlogs_result_description_count_distinct == 1 + and Esql.event_count >= 15 + and Esql.event_duration_seconds <= 1800, "password_spraying", - // One user targeted repeatedly (same error), OR extremely noisy pattern from many IPs. - (unique_users == 1 AND unique_login_errors == 1 AND total_attempts >= 30 AND duration_seconds <= 300) - OR (unique_users <= 3 AND unique_ips > 30 AND total_attempts >= 100), + (Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct == 1 + and Esql.azure_signinlogs_result_description_count_distinct == 1 + and Esql.event_count >= 30 + and Esql.event_duration_seconds <= 300) + or (Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct <= 3 + and Esql.source_ip_count_distinct > 30 + and Esql.event_count >= 100), "password_guessing", - // everything else "other" ) -| KEEP - time_window, bf_type, duration_seconds, total_attempts, first_seen, last_seen, - unique_users, user_id_list, login_errors, unique_login_errors, - unique_error_codes, error_codes, request_types, app_names, - ip_list, unique_ips, source_orgs, countries, - unique_country_count, unique_asn_orgs, - authentication_requirement, client_app_id, client_app_display_name, - target_resource_id, target_resource_display_name, conditional_access_status, - device_detail_browser, device_detail_device_id, device_detail_operating_system, - incoming_token_type, risk_state, session_id, user_id, - user_principal_name, result_description, result_signature, result_type - -| WHERE bf_type != "other" +| where Esql.event_bf_type != "other" + +| keep + Esql.time_window_date_trunc, + Esql.event_bf_type, + Esql.event_duration_seconds, + Esql.event_count, + Esql.@timestamp.min, + Esql.@timestamp.max, + Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct, + Esql_priv.azure_signinlogs_properties_user_principal_name_lower_values, + Esql.azure_signinlogs_result_description_count_distinct, + Esql.azure_signinlogs_result_description_values, + Esql.azure_signinlogs_properties_status_error_code_count_distinct, + Esql.azure_signinlogs_properties_status_error_code_values, + Esql.azure_signinlogs_properties_incoming_token_type_lower_values, + Esql.azure_signinlogs_properties_app_display_name_lower_values, + Esql.source_ip_values, + Esql.source_ip_count_distinct, + Esql.source_as_organization_name_values, + Esql.source_as_organization_name_count_distinct, + Esql.source_geo_country_name_values, + Esql.source_geo_country_name_count_distinct, + Esql.azure_signinlogs_properties_authentication_requirement_values, + Esql.azure_signinlogs_properties_app_id_values, + Esql.azure_signinlogs_properties_app_display_name_values, + Esql.azure_signinlogs_properties_resource_id_values, + Esql.azure_signinlogs_properties_resource_display_name_values, + Esql.azure_signinlogs_properties_conditional_access_status_values, + Esql.azure_signinlogs_properties_device_detail_browser_values, + Esql.azure_signinlogs_properties_device_detail_device_id_values, + Esql.azure_signinlogs_properties_device_detail_operating_system_values, + Esql.azure_signinlogs_properties_incoming_token_type_values, + Esql.azure_signinlogs_properties_risk_state_values, + Esql.azure_signinlogs_properties_session_id_values, + Esql.azure_signinlogs_properties_user_id_values ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-concurrent-sign-ins-with-suspicious-properties.asciidoc b/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-concurrent-sign-ins-with-suspicious-properties.asciidoc index 390002711d..7f8014cc57 100644 --- a/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-concurrent-sign-ins-with-suspicious-properties.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-concurrent-sign-ins-with-suspicious-properties.asciidoc @@ -36,7 +36,7 @@ Identifies concurrent azure signin events for the same user and from multiple so * Tactic: Credential Access * Resources: Investigation Guide -*Version*: 1 +*Version*: 2 *Rule authors*: @@ -92,20 +92,67 @@ This rule requires the Azure logs integration be enabled and configured to colle [source, js] ---------------------------------- -FROM logs-azure.signinlogs* metadata _id, _version, _index -// the rule is scheduled to run every hour and looks for events occured during last 1 hour. -| where @timestamp > NOW() - 1 hours -| where event.dataset == "azure.signinlogs" and source.ip is not null and azure.signinlogs.identity is not null and to_lower(event.outcome) == "success" -| keep @timestamp, azure.signinlogs.identity, source.ip, azure.signinlogs.properties.authentication_requirement, azure.signinlogs.properties.app_id, azure.signinlogs.properties.resource_display_name, azure.signinlogs.properties.authentication_protocol, azure.signinlogs.properties.app_display_name -// devicecode authentication no MFA -| eval device_code = case(azure.signinlogs.properties.authentication_protocol == "deviceCode" and azure.signinlogs.properties.authentication_requirement != "multiFactorAuthentication", azure.signinlogs.identity, null), -// potential Visual Studio Code OAuth code phish - sign-in events with client set to Visual Studio Code - visual_studio = case(azure.signinlogs.properties.app_id == "aebc6443-996d-45c2-90f0-388ff96faa56" and azure.signinlogs.properties.resource_display_name == "Microsoft Graph", azure.signinlogs.identity, null), -// Other sign-in events - other = case(azure.signinlogs.properties.authentication_protocol != "deviceCode" and azure.signinlogs.properties.app_id != "aebc6443-996d-45c2-90f0-388ff96faa56", azure.signinlogs.identity, null) -| stats total = COUNT(*), device_code_count = COUNT_DISTINCT(device_code), vsc = count_distinct(visual_studio), other_count = COUNT_DISTINCT(other), src_ip = COUNT_DISTINCT(source.ip), ips = values(source.ip), clients = values(azure.signinlogs.properties.app_display_name), resources = VALUES(azure.signinlogs.properties.resource_display_name), auth_requirement = VALUES(azure.signinlogs.properties.authentication_requirement) by azure.signinlogs.identity -// 2 unique source.ip for same account - which may indicate the presence 2 sign-ins one by the adversary and the other by the victim -| where src_ip >= 2 and (device_code_count > 0 or vsc >0) +from logs-azure.signinlogs* metadata _id, _version, _index + +// Scheduled to run every hour, reviewing events from past hour +| where + @timestamp > now() - 1 hours + and event.dataset == "azure.signinlogs" + and source.ip is not null + and azure.signinlogs.identity is not null + and to_lower(event.outcome) == "success" + +// keep relevant raw fields +| keep + @timestamp, + azure.signinlogs.identity, + source.ip, + azure.signinlogs.properties.authentication_requirement, + azure.signinlogs.properties.app_id, + azure.signinlogs.properties.resource_display_name, + azure.signinlogs.properties.authentication_protocol, + azure.signinlogs.properties.app_display_name + +// case classifications for identity usage +| eval + Esql.azure_signinlogs_properties_authentication_device_code_case = case( + azure.signinlogs.properties.authentication_protocol == "deviceCode" + and azure.signinlogs.properties.authentication_requirement != "multiFactorAuthentication", + azure.signinlogs.identity, + null), + + Esql.azure_signinlogs_auth_visual_studio_case = case( + azure.signinlogs.properties.app_id == "aebc6443-996d-45c2-90f0-388ff96faa56" + and azure.signinlogs.properties.resource_display_name == "Microsoft Graph", + azure.signinlogs.identity, + null), + + Esql.azure_signinlogs_auth_other_case = case( + azure.signinlogs.properties.authentication_protocol != "deviceCode" + and azure.signinlogs.properties.app_id != "aebc6443-996d-45c2-90f0-388ff96faa56", + azure.signinlogs.identity, + null) + +// Aggregate metrics by user identity +| stats + Esql.event_count = count(*), + Esql.azure_signinlogs_properties_authentication_device_code_case_count_distinct = count_distinct(Esql.azure_signinlogs_properties_authentication_device_code_case), + Esql.azure_signinlogs_properties_auth_visual_studio_count_distinct = count_distinct(Esql.azure_signinlogs_auth_visual_studio_case), + Esql.azure_signinlogs_properties_auth_other_count_distinct = count_distinct(Esql.azure_signinlogs_auth_other_case), + Esql.azure_signinlogs_properties_source_ip_count_distinct = count_distinct(source.ip), + Esql.azure_signinlogs_properties_source_ip_values = values(source.ip), + Esql.azure_signinlogs_properties_client_app_values = values(azure.signinlogs.properties.app_display_name), + Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name), + Esql.azure_signinlogs_properties_auth_requirement_values = values(azure.signinlogs.properties.authentication_requirement) + by azure.signinlogs.identity + +// Detect multiple unique IPs for one user with signs of deviceCode or VSC OAuth usage +| where + Esql.azure_signinlogs_properties_source_ip_count_distinct >= 2 + and ( + Esql.azure_signinlogs_properties_authentication_device_code_case_count_distinct > 0 + or Esql.azure_signinlogs_properties_auth_visual_studio_count_distinct > 0 + ) ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-exccessive-account-lockouts-detected.asciidoc b/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-exccessive-account-lockouts-detected.asciidoc index a6f5f4d37a..72f6963644 100644 --- a/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-exccessive-account-lockouts-detected.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-exccessive-account-lockouts-detected.asciidoc @@ -40,7 +40,7 @@ Identifies a high count of failed Microsoft Entra ID sign-in attempts as the res * Tactic: Credential Access * Resources: Investigation Guide -*Version*: 1 +*Version*: 2 *Rule authors*: @@ -102,79 +102,99 @@ This rule detects a high number of sign-in failures due to account lockouts (err [source, js] ---------------------------------- -FROM logs-azure.signinlogs* - -| EVAL - time_window = DATE_TRUNC(30 minutes, @timestamp), - user_id = TO_LOWER(azure.signinlogs.properties.user_principal_name), - ip = source.ip, - login_error = azure.signinlogs.result_description, - error_code = azure.signinlogs.properties.status.error_code, - request_type = TO_LOWER(azure.signinlogs.properties.incoming_token_type), - app_name = TO_LOWER(azure.signinlogs.properties.app_display_name), - asn_org = source.`as`.organization.name, - country = source.geo.country_name, - user_agent = user_agent.original, - event_time = @timestamp - -| WHERE event.dataset == "azure.signinlogs" - AND event.category == "authentication" - AND azure.signinlogs.category IN ("NonInteractiveUserSignInLogs", "SignInLogs") - AND event.outcome == "failure" - AND azure.signinlogs.properties.authentication_requirement == "singleFactorAuthentication" - AND error_code == 50053 - AND user_id IS NOT NULL AND user_id != "" - AND asn_org != "MICROSOFT-CORP-MSN-AS-BLOCK" - -| STATS - authentication_requirement = VALUES(azure.signinlogs.properties.authentication_requirement), - client_app_id = VALUES(azure.signinlogs.properties.app_id), - client_app_display_name = VALUES(azure.signinlogs.properties.app_display_name), - target_resource_id = VALUES(azure.signinlogs.properties.resource_id), - target_resource_display_name = VALUES(azure.signinlogs.properties.resource_display_name), - conditional_access_status = VALUES(azure.signinlogs.properties.conditional_access_status), - device_detail_browser = VALUES(azure.signinlogs.properties.device_detail.browser), - device_detail_device_id = VALUES(azure.signinlogs.properties.device_detail.device_id), - device_detail_operating_system = VALUES(azure.signinlogs.properties.device_detail.operating_system), - incoming_token_type = VALUES(azure.signinlogs.properties.incoming_token_type), - risk_state = VALUES(azure.signinlogs.properties.risk_state), - session_id = VALUES(azure.signinlogs.properties.session_id), - user_id = VALUES(azure.signinlogs.properties.user_id), - user_principal_name = VALUES(azure.signinlogs.properties.user_principal_name), - result_description = VALUES(azure.signinlogs.result_description), - result_signature = VALUES(azure.signinlogs.result_signature), - result_type = VALUES(azure.signinlogs.result_type), - - unique_users = COUNT_DISTINCT(user_id), - user_id_list = VALUES(user_id), - login_errors = VALUES(login_error), - unique_login_errors = COUNT_DISTINCT(login_error), - error_codes = VALUES(error_code), - unique_error_codes = COUNT_DISTINCT(error_code), - request_types = VALUES(request_type), - app_names = VALUES(app_name), - ip_list = VALUES(ip), - unique_ips = COUNT_DISTINCT(ip), - source_orgs = VALUES(asn_org), - countries = VALUES(country), - unique_country_count = COUNT_DISTINCT(country), - unique_asn_orgs = COUNT_DISTINCT(asn_org), - first_seen = MIN(event_time), - last_seen = MAX(event_time), - total_attempts = COUNT() -BY time_window -| WHERE unique_users >= 15 AND total_attempts >= 20 -| KEEP - time_window, total_attempts, first_seen, last_seen, - unique_users, user_id_list, login_errors, unique_login_errors, - unique_error_codes, error_codes, request_types, app_names, - ip_list, unique_ips, source_orgs, countries, - unique_country_count, unique_asn_orgs, - authentication_requirement, client_app_id, client_app_display_name, - target_resource_id, target_resource_display_name, conditional_access_status, - device_detail_browser, device_detail_device_id, device_detail_operating_system, - incoming_token_type, risk_state, session_id, user_id, - user_principal_name, result_description, result_signature, result_type +from logs-azure.signinlogs* + +| eval + Esql.time_window_date_trunc = date_trunc(30 minutes, @timestamp), + Esql_priv.azure_signinlogs_properties_user_principal_name_lower = to_lower(azure.signinlogs.properties.user_principal_name), + Esql.azure_signinlogs_properties_incoming_token_type_lower = to_lower(azure.signinlogs.properties.incoming_token_type), + Esql.azure_signinlogs_properties_app_display_name_lower = to_lower(azure.signinlogs.properties.app_display_name) + +| where event.dataset == "azure.signinlogs" + and event.category == "authentication" + and azure.signinlogs.category in ("NonInteractiveUserSignInLogs", "SignInLogs") + and event.outcome == "failure" + and azure.signinlogs.properties.authentication_requirement == "singleFactorAuthentication" + and azure.signinlogs.properties.status.error_code == 50053 + and azure.signinlogs.properties.user_principal_name is not null + and azure.signinlogs.properties.user_principal_name != "" + and source.`as`.organization.name != "MICROSOFT-CORP-MSN-as-BLOCK" + +| stats + Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement), + Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id), + Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name), + Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id), + Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name), + Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status), + Esql.azure_signinlogs_properties_device_detail_browser_values = values(azure.signinlogs.properties.device_detail.browser), + Esql.azure_signinlogs_properties_device_detail_device_id_values = values(azure.signinlogs.properties.device_detail.device_id), + Esql.azure_signinlogs_properties_device_detail_operating_system_values = values(azure.signinlogs.properties.device_detail.operating_system), + Esql.azure_signinlogs_properties_incoming_token_type_values = values(azure.signinlogs.properties.incoming_token_type), + Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state), + Esql.azure_signinlogs_properties_session_id_values = values(azure.signinlogs.properties.session_id), + Esql.azure_signinlogs_properties_user_id_values = values(azure.signinlogs.properties.user_id), + Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name), + Esql.azure_signinlogs_result_description_values = values(azure.signinlogs.result_description), + Esql.azure_signinlogs_result_signature_values = values(azure.signinlogs.result_signature), + Esql.azure_signinlogs_result_type_values = values(azure.signinlogs.result_type), + + Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct = count_distinct(Esql_priv.azure_signinlogs_properties_user_principal_name_lower), + Esql_priv.azure_signinlogs_properties_user_principal_name_lower_values = values(Esql_priv.azure_signinlogs_properties_user_principal_name_lower), + Esql.azure_signinlogs_result_description_count_distinct = count_distinct(azure.signinlogs.result_description), + Esql.azure_signinlogs_properties_status_error_code_count_distinct = count_distinct(azure.signinlogs.properties.status.error_code), + Esql.azure_signinlogs_properties_status_error_code_values = values(azure.signinlogs.properties.status.error_code), + Esql.azure_signinlogs_properties_incoming_token_type_lower_values = values(Esql.azure_signinlogs_properties_incoming_token_type_lower), + Esql.azure_signinlogs_properties_app_display_name_lower_values = values(Esql.azure_signinlogs_properties_app_display_name_lower), + Esql.source_ip_values = values(source.ip), + Esql.source_ip_count_distinct = count_distinct(source.ip), + Esql.source_as_organization_name_values = values(source.`as`.organization.name), + Esql.source_as_organization_name_count_distinct = count_distinct(source.`as`.organization.name), + Esql.source_geo_country_name_values = values(source.geo.country_name), + Esql.source_geo_country_name_count_distinct = count_distinct(source.geo.country_name), + Esql.@timestamp.min = min(@timestamp), + Esql.@timestamp.max = max(@timestamp), + Esql.event_count = count() +by Esql.time_window_date_trunc + +| where Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct >= 15 and Esql.event_count >= 20 + +| keep + Esql.time_window_date_trunc, + Esql.event_count, + Esql.@timestamp.min, + Esql.@timestamp.max, + Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct, + Esql_priv.azure_signinlogs_properties_user_principal_name_lower_values, + Esql.azure_signinlogs_result_description_count_distinct, + Esql.azure_signinlogs_result_description_values, + Esql.azure_signinlogs_properties_status_error_code_count_distinct, + Esql.azure_signinlogs_properties_status_error_code_values, + Esql.azure_signinlogs_properties_incoming_token_type_lower_values, + Esql.azure_signinlogs_properties_app_display_name_lower_values, + Esql.source_ip_values, + Esql.source_ip_count_distinct, + Esql.source_as_organization_name_values, + Esql.source_as_organization_name_count_distinct, + Esql.source_geo_country_name_values, + Esql.source_geo_country_name_count_distinct, + Esql.azure_signinlogs_properties_authentication_requirement_values, + Esql.azure_signinlogs_properties_app_id_values, + Esql.azure_signinlogs_properties_app_display_name_values, + Esql.azure_signinlogs_properties_resource_id_values, + Esql.azure_signinlogs_properties_resource_display_name_values, + Esql.azure_signinlogs_properties_conditional_access_status_values, + Esql.azure_signinlogs_properties_device_detail_browser_values, + Esql.azure_signinlogs_properties_device_detail_device_id_values, + Esql.azure_signinlogs_properties_device_detail_operating_system_values, + Esql.azure_signinlogs_properties_incoming_token_type_values, + Esql.azure_signinlogs_properties_risk_state_values, + Esql.azure_signinlogs_properties_session_id_values, + Esql.azure_signinlogs_properties_user_id_values, + Esql_priv.azure_signinlogs_properties_user_principal_name_values, + Esql.azure_signinlogs_result_description_values, + Esql.azure_signinlogs_result_signature_values, + Esql.azure_signinlogs_result_type_values ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-mfa-totp-brute-force-attempts.asciidoc b/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-mfa-totp-brute-force-attempts.asciidoc index 823652cc27..a83076a872 100644 --- a/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-mfa-totp-brute-force-attempts.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-mfa-totp-brute-force-attempts.asciidoc @@ -35,7 +35,7 @@ Identifies brute force attempts against Azure Entra multi-factor authentication * Tactic: Credential Access * Resources: Investigation Guide -*Version*: 3 +*Version*: 4 *Rule authors*: @@ -112,7 +112,7 @@ This rule requires the Entra ID sign-in logs via the Azure integration be enable from logs-azure.signinlogs* metadata _id, _version, _index | where - // filter for Entra Sign-In Logs + // filter for Entra Sign-in Logs event.dataset == "azure.signinlogs" and azure.signinlogs.operation_name == "Sign-in activity" and azure.signinlogs.properties.user_type == "Member" @@ -129,36 +129,36 @@ from logs-azure.signinlogs* metadata _id, _version, _index ) | stats - Esql.event_count = COUNT(*), - Esql.azure_signinlogs_properties.session_id_count_distinct = COUNT_DISTINCT(azure.signinlogs.properties.session_id), - Esql.source_address_values = VALUES(source.address), - Esql.azure_tenant_id_valuues = VALUES(azure.tenant_id), - Esql_priv.azure_identity_values = VALUES(azure.signinlogs.identity), - Esql_priv.azure_signinlogs_properties_user_principal_name_values = VALUES(azure.signinlogs.properties.user_principal_name), - Esql.azure_signinlogs_properties_app_id_values = VALUES(azure.signinlogs.properties.app_id), - Esql.azure_signinlogs_properties_app_display_name_values = VALUES(azure.signinlogs.properties.app_display_name), - Esql.azure_signinlogs_properties_authentication_requirement_values = VALUES(azure.signinlogs.properties.authentication_requirement), - Esql.azure_signinlogs_properties_authentication_protocol_values = VALUES(azure.signinlogs.properties.authentication_protocol), - Esql.azure_signinlogs_properties_client_app_used_values = VALUES(azure.signinlogs.properties.client_app_used), - Esql.azure_signinlogs_properties_client_credential_type_values = VALUES(azure.signinlogs.properties.client_credential_type), - Esql.azure_signinlogs_properties_conditional_access_status_values = VALUES(azure.signinlogs.properties.conditional_access_status), - Esql.azure_signinlogs_properties_correlation_id_values = VALUES(azure.signinlogs.properties.correlation_id), - Esql.azure_signinlogs_properties_is_interactive_values = VALUES(azure.signinlogs.properties.is_interactive), - Esql.azure_signinlogs_properties_mfa_detail_auth_method_values = VALUES(azure.signinlogs.properties.mfa_detail.auth_method), - Esql.azure_signinlogs_properties_resource_display_name_values = VALUES(azure.signinlogs.properties.resource_display_name), - Esql.azure_signinlogs_properties_resource_id_values = VALUES(azure.signinlogs.properties.resource_id), - Esql.azure_signinlogs_properties_risk_state_values = VALUES(azure.signinlogs.properties.risk_state), - Esql.azure_signinlogs_properties_risk_detail_values = VALUES(azure.signinlogs.properties.risk_detail), - Esql.azure_signinlogs_properties_status.error_code_values = VALUES(azure.signinlogs.properties.status.error_code), - Esql.azure_signinlogs_properties_original_request_id_values = VALUES(azure.signinlogs.properties.original_request_id), - Esql.user_id_values = VALUES(user.id) + Esql.event_count = count(*), + Esql.azure_signinlogs_properties_session_id_count_distinct = count_distinct(azure.signinlogs.properties.session_id), + Esql.source_address_values = values(source.address), + Esql.azure_tenant_id_valuues = values(azure.tenant_id), + Esql_priv.azure_identity_values = values(azure.signinlogs.identity), + Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name), + Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id), + Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name), + Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement), + Esql.azure_signinlogs_properties_authentication_protocol_values = values(azure.signinlogs.properties.authentication_protocol), + Esql.azure_signinlogs_properties_client_app_used_values = values(azure.signinlogs.properties.client_app_used), + Esql.azure_signinlogs_properties_client_credential_type_values = values(azure.signinlogs.properties.client_credential_type), + Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status), + Esql.azure_signinlogs_properties_correlation_id_values = values(azure.signinlogs.properties.correlation_id), + Esql.azure_signinlogs_properties_is_interactive_values = values(azure.signinlogs.properties.is_interactive), + Esql.azure_signinlogs_properties_mfa_detail_auth_method_values = values(azure.signinlogs.properties.mfa_detail.auth_method), + Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name), + Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id), + Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state), + Esql.azure_signinlogs_properties_risk_detail_values = values(azure.signinlogs.properties.risk_detail), + Esql.azure_signinlogs_properties_status_error_code_values = values(azure.signinlogs.properties.status.error_code), + Esql.azure_signinlogs_properties_original_request_id_values = values(azure.signinlogs.properties.original_request_id), + Esql.user_id_values = values(user.id) by user.id -| where Esql.event_count >= 20 and Esql.azure_signinlogs_properties.session_id_count_distinct >= 10 +| where Esql.event_count >= 20 and Esql.azure_signinlogs_properties_session_id_count_distinct >= 10 | keep Esql.event_count, - Esql.azure_signinlogs_properties.session_id_count_distinct, + Esql.azure_signinlogs_properties_session_id_count_distinct, Esql.source_address_values, Esql.azure_tenant_id_valuues, Esql_priv.azure_identity_values, @@ -177,7 +177,7 @@ from logs-azure.signinlogs* metadata _id, _version, _index Esql.azure_signinlogs_properties_resource_id_values, Esql.azure_signinlogs_properties_risk_state_values, Esql.azure_signinlogs_properties_risk_detail_values, - Esql.azure_signinlogs_properties_status.error_code_values, + Esql.azure_signinlogs_properties_status_error_code_values, Esql.azure_signinlogs_properties_original_request_id_values, Esql.user_id_values diff --git a/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-session-reuse-with-suspicious-graph-access.asciidoc b/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-session-reuse-with-suspicious-graph-access.asciidoc index b06d306a70..d8a0136afe 100644 --- a/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-session-reuse-with-suspicious-graph-access.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-session-reuse-with-suspicious-graph-access.asciidoc @@ -37,7 +37,7 @@ Identifies potential session hijacking or token replay in Microsoft Entra ID. Th * Tactic: Defense Evasion * Tactic: Initial Access -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -110,49 +110,65 @@ This rule requires the Microsoft Entra ID Sign-In Logs and Microsoft Graph Activ [source, js] ---------------------------------- -FROM logs-azure.* -| WHERE - (event.dataset == "azure.signinlogs" AND source.`as`.organization.name != "MICROSOFT-CORP-MSN-AS-BLOCK" AND azure.signinlogs.properties.session_id IS NOT NULL) - OR - (event.dataset == "azure.graphactivitylogs" AND source.`as`.organization.name != "MICROSOFT-CORP-MSN-AS-BLOCK" AND azure.graphactivitylogs.properties.c_sid IS NOT NULL) -| EVAL - session_id = COALESCE(azure.signinlogs.properties.session_id, azure.graphactivitylogs.properties.c_sid), - user_id = COALESCE(azure.signinlogs.properties.user_id, azure.graphactivitylogs.properties.user_principal_object_id), - client_id = COALESCE(azure.signinlogs.properties.app_id, azure.graphactivitylogs.properties.app_id), - source_ip = source.ip, - event_time = @timestamp, - event_type = CASE( +from logs-azure.* +| where + (event.dataset == "azure.signinlogs" + and source.`as`.organization.name != "MICROSOFT-CORP-MSN-as-BLOCK" + and azure.signinlogs.properties.session_id is not null) + or + (event.dataset == "azure.graphactivitylogs" + and source.`as`.organization.name != "MICROSOFT-CORP-MSN-as-BLOCK" + and azure.graphactivitylogs.properties.c_sid is not null) + +| eval + Esql.azure_signinlogs_properties_session_id_coalesce = coalesce(azure.signinlogs.properties.session_id, azure.graphactivitylogs.properties.c_sid), + Esql.azure_signinlogs_properties_user_id_coalesce = coalesce(azure.signinlogs.properties.user_id, azure.graphactivitylogs.properties.user_principal_object_id), + Esql.azure_signinlogs_properties_app_id_coalesce = coalesce(azure.signinlogs.properties.app_id, azure.graphactivitylogs.properties.app_id), + Esql.source_ip = source.ip, + Esql.@timestamp = @timestamp, + Esql.event_type_case = case( event.dataset == "azure.signinlogs", "signin", event.dataset == "azure.graphactivitylogs", "graph", "other" ), - time_window = DATE_TRUNC(5 minutes, @timestamp) -| KEEP session_id, source_ip, event_time, event_type, time_window, user_id, client_id -| STATS - user_id = VALUES(user_id), - session_id = VALUES(session_id), - source_ip_list = VALUES(source_ip), - source_ip_count = COUNT_DISTINCT(source_ip), - client_id_list = VALUES(client_id), - application_count = COUNT_DISTINCT(client_id), - event_type_list = VALUES(event_type), - event_type_count = COUNT_DISTINCT(event_type), - event_start = MIN(event_time), - event_end = MAX(event_time), - signin_time = MIN(CASE(event_type == "signin", event_time, NULL)), - graph_time = MIN(CASE(event_type == "graph", event_time, NULL)), - document_count = COUNT() - BY session_id, time_window -| EVAL - duration_minutes = DATE_DIFF("minutes", event_start, event_end), - signin_to_graph_delay_minutes = DATE_DIFF("minutes", signin_time, graph_time) -| WHERE - event_type_count > 1 AND - source_ip_count > 1 AND - duration_minutes <= 5 AND - signin_time IS NOT NULL AND - graph_time IS NOT NULL AND - signin_to_graph_delay_minutes >= 0 + Esql.time_window_date_trunc = date_trunc(5 minutes, @timestamp) + +| keep + Esql.azure_signinlogs_properties_session_id_coalesce, + Esql.source_ip, + Esql.@timestamp, + Esql.event_type_case, + Esql.time_window_date_trunc, + Esql.azure_signinlogs_properties_user_id_coalesce, + Esql.azure_signinlogs_properties_app_id_coalesce + +| stats + Esql.azure_signinlogs_properties_user_id_coalesce_values = values(Esql.azure_signinlogs_properties_user_id_coalesce), + Esql.azure_signinlogs_properties_session_id_coalesce_values = values(Esql.azure_signinlogs_properties_session_id_coalesce), + Esql.source_ip_values = values(Esql.source_ip), + Esql.source_ip_count_distinct = count_distinct(Esql.source_ip), + Esql.azure_signinlogs_properties_app_id_coalesce_values = values(Esql.azure_signinlogs_properties_app_id_coalesce), + Esql.azure_signinlogs_properties_app_id_coalesce_count_distinct = count_distinct(Esql.azure_signinlogs_properties_app_id_coalesce), + Esql.event_type_case_values = values(Esql.event_type_case), + Esql.event_type_case_count_distinct = count_distinct(Esql.event_type_case), + Esql.@timestamp.min = min(Esql.@timestamp), + Esql.@timestamp.max = max(Esql.@timestamp), + Esql.signin_time_min = min(case(Esql.event_type_case == "signin", Esql.@timestamp, null)), + Esql.graph_time_min = min(case(Esql.event_type_case == "graph", Esql.@timestamp, null)), + Esql.event_count = count() + by Esql.azure_signinlogs_properties_session_id_coalesce, Esql.time_window_date_trunc + +| eval + Esql.event_duration_minutes_date_diff = date_diff("minutes", Esql.@timestamp.min, Esql.@timestamp.max), + Esql.event_signin_to_graph_delay_minutes_date_diff = date_diff("minutes", Esql.signin_time_min, Esql.graph_time_min) + +| where + Esql.event_type_case_count_distinct > 1 and + Esql.source_ip_count_distinct > 1 and + Esql.event_duration_minutes_date_diff <= 5 and + Esql.signin_time_min is not null and + Esql.graph_time_min is not null and + Esql.event_signin_to_graph_delay_minutes_date_diff >= 0 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-sign-in-brute-force-activity.asciidoc b/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-sign-in-brute-force-activity.asciidoc index a245ed5c51..fa8d471576 100644 --- a/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-sign-in-brute-force-activity.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/microsoft-entra-id-sign-in-brute-force-activity.asciidoc @@ -41,7 +41,7 @@ Identifies potential brute-force attacks targeting user accounts by analyzing fa * Tactic: Credential Access * Resources: Investigation Guide -*Version*: 3 +*Version*: 4 *Rule authors*: @@ -104,20 +104,18 @@ This rule detects brute-force authentication activity in Entra ID sign-in logs. [source, js] ---------------------------------- -FROM logs-azure.signinlogs* +from logs-azure.signinlogs* // Define a time window for grouping and maintain the original event timestamp -| EVAL - time_window = DATE_TRUNC(15 minutes, @timestamp), - event_time = @timestamp +| eval Esql.time_window_date_trunc = date_trunc(15 minutes, @timestamp) // Filter relevant failed authentication events with specific error codes -| WHERE event.dataset == "azure.signinlogs" - AND event.category == "authentication" - AND azure.signinlogs.category IN ("NonInteractiveUserSignInLogs", "SignInLogs") - AND event.outcome == "failure" - AND azure.signinlogs.properties.authentication_requirement == "singleFactorAuthentication" - AND azure.signinlogs.properties.status.error_code IN ( +| where event.dataset == "azure.signinlogs" + and event.category == "authentication" + and azure.signinlogs.category in ("NonInteractiveUserSignInLogs", "SignInLogs") + and event.outcome == "failure" + and azure.signinlogs.properties.authentication_requirement == "singleFactorAuthentication" + and azure.signinlogs.properties.status.error_code in ( 50034, // UserAccountNotFound 50126, // InvalidUsernameOrPassword 50055, // PasswordExpired @@ -139,89 +137,107 @@ FROM logs-azure.signinlogs* 120002, // PasswordChangeInvalidNewPasswordWeak 120020 // PasswordChangeFailure ) - AND azure.signinlogs.properties.user_principal_name IS NOT NULL AND azure.signinlogs.properties.user_principal_name != "" - AND user_agent.original != "Mozilla/5.0 (compatible; MSAL 1.0) PKeyAuth/1.0" - AND source.`as`.organization.name != "MICROSOFT-CORP-MSN-AS-BLOCK" - -// Aggregate statistics for behavioral pattern analysis -| STATS - authentication_requirement = VALUES(azure.signinlogs.properties.authentication_requirement), - client_app_id = VALUES(azure.signinlogs.properties.app_id), - client_app_display_name = VALUES(azure.signinlogs.properties.app_display_name), - target_resource_id = VALUES(azure.signinlogs.properties.resource_id), - target_resource_display_name = VALUES(azure.signinlogs.properties.resource_display_name), - conditional_access_status = VALUES(azure.signinlogs.properties.conditional_access_status), - device_detail_browser = VALUES(azure.signinlogs.properties.device_detail.browser), - device_detail_device_id = VALUES(azure.signinlogs.properties.device_detail.device_id), - device_detail_operating_system = VALUES(azure.signinlogs.properties.device_detail.operating_system), - incoming_token_type = VALUES(azure.signinlogs.properties.incoming_token_type), - risk_state = VALUES(azure.signinlogs.properties.risk_state), - session_id = VALUES(azure.signinlogs.properties.session_id), - user_id = VALUES(azure.signinlogs.properties.user_id), - user_principal_name = VALUES(azure.signinlogs.properties.user_principal_name), - result_description = VALUES(azure.signinlogs.result_description), - result_signature = VALUES(azure.signinlogs.result_signature), - result_type = VALUES(azure.signinlogs.result_type), - - unique_users = COUNT_DISTINCT(azure.signinlogs.properties.user_id), - user_id_list = VALUES(azure.signinlogs.properties.user_id), - login_errors = VALUES(azure.signinlogs.result_description), - unique_login_errors = COUNT_DISTINCT(azure.signinlogs.result_description), - error_codes = VALUES(azure.signinlogs.properties.status.error_code), - unique_error_codes = COUNT_DISTINCT(azure.signinlogs.properties.status.error_code), - request_types = VALUES(azure.signinlogs.properties.incoming_token_type), - app_names = VALUES(azure.signinlogs.properties.app_display_name), - ip_list = VALUES(source.ip), - unique_ips = COUNT_DISTINCT(source.ip), - source_orgs = VALUES(source.`as`.organization.name), - countries = VALUES(source.geo.country_name), - unique_country_count = COUNT_DISTINCT(source.geo.country_name), - unique_asn_orgs = COUNT_DISTINCT(source.`as`.organization.name), - first_seen = MIN(@timestamp), - last_seen = MAX(@timestamp), - total_attempts = COUNT() -BY time_window - -// Determine brute force behavior type based on statistical thresholds -| EVAL - duration_seconds = DATE_DIFF("seconds", first_seen, last_seen), - bf_type = CASE( - // Many users, relatively few distinct login errors, distributed over multiple IPs (but not too many), - // and happens quickly. Often bots using leaked credentials. - unique_users >= 10 AND total_attempts >= 30 AND unique_login_errors <= 3 - AND unique_ips >= 5 - AND duration_seconds <= 600 - AND unique_users > unique_ips, + and azure.signinlogs.properties.user_principal_name is not null and azure.signinlogs.properties.user_principal_name != "" + and user_agent.original != "Mozilla/5.0 (compatible; MSAL 1.0) PKeyAuth/1.0" + and source.`as`.organization.name != "MICROSOFT-CORP-MSN-as-BLOCK" + +| stats + Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement), + Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id), + Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name), + Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id), + Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name), + Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status), + Esql.azure_signinlogs_properties_device_detail_browser_values = values(azure.signinlogs.properties.device_detail.browser), + Esql.azure_signinlogs_properties_device_detail_device_id_values = values(azure.signinlogs.properties.device_detail.device_id), + Esql.azure_signinlogs_properties_device_detail_operating_system_values = values(azure.signinlogs.properties.device_detail.operating_system), + Esql.azure_signinlogs_properties_incoming_token_type_values = values(azure.signinlogs.properties.incoming_token_type), + Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state), + Esql.azure_signinlogs_properties_session_id_values = values(azure.signinlogs.properties.session_id), + Esql.azure_signinlogs_properties_user_id_values = values(azure.signinlogs.properties.user_id), + Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name), + Esql.azure_signinlogs_result_description_values = values(azure.signinlogs.result_description), + Esql.azure_signinlogs_result_signature_values = values(azure.signinlogs.result_signature), + Esql.azure_signinlogs_result_type_values = values(azure.signinlogs.result_type), + + Esql.azure_signinlogs_properties_user_id_count_distinct = count_distinct(azure.signinlogs.properties.user_id), + Esql.azure_signinlogs_properties_user_id_list = values(azure.signinlogs.properties.user_id), + Esql.azure_signinlogs_result_description_values_all = values(azure.signinlogs.result_description), + Esql.azure_signinlogs_result_description_count_distinct = count_distinct(azure.signinlogs.result_description), + Esql.azure_signinlogs_properties_status_error_code_values = values(azure.signinlogs.properties.status.error_code), + Esql.azure_signinlogs_properties_status_error_code_count_distinct = count_distinct(azure.signinlogs.properties.status.error_code), + Esql.azure_signinlogs_properties_incoming_token_type_values_all = values(azure.signinlogs.properties.incoming_token_type), + Esql.azure_signinlogs_properties_app_display_name_values_all = values(azure.signinlogs.properties.app_display_name), + Esql.source_ip_values = values(source.ip), + Esql.source_ip_count_distinct = count_distinct(source.ip), + Esql.source_as_organization_name_values = values(source.`as`.organization.name), + Esql.source_geo_country_name_values = values(source.geo.country_name), + Esql.source_geo_country_name_count_distinct = count_distinct(source.geo.country_name), + Esql.source_as_organization_name_count_distinct = count_distinct(source.`as`.organization.name), + Esql.timestamp_first_seen = min(@timestamp), + Esql.timestamp_last_seen = max(@timestamp), + Esql.event_count = count() +by Esql.time_window_date_trunc + +| eval + Esql.duration_seconds = date_diff("seconds", Esql.timestamp_first_seen, Esql.timestamp_last_seen), + Esql.brute_force_type = case( + Esql.azure_signinlogs_properties_user_id_count_distinct >= 10 and Esql.event_count >= 30 and Esql.azure_signinlogs_result_description_count_distinct <= 3 + and Esql.source_ip_count_distinct >= 5 + and Esql.duration_seconds <= 600 + and Esql.azure_signinlogs_properties_user_id_count_distinct > Esql.source_ip_count_distinct, "credential_stuffing", - // One password against many users. Single error (e.g., "InvalidPassword"), not necessarily fast. - unique_users >= 15 AND unique_login_errors == 1 AND total_attempts >= 15 AND duration_seconds <= 1800, + Esql.azure_signinlogs_properties_user_id_count_distinct >= 15 and Esql.azure_signinlogs_result_description_count_distinct == 1 and Esql.event_count >= 15 and Esql.duration_seconds <= 1800, "password_spraying", - // One user targeted repeatedly (same error), OR extremely noisy pattern from many IPs. - (unique_users == 1 AND unique_login_errors == 1 AND total_attempts >= 30 AND duration_seconds <= 300) - OR (unique_users <= 3 AND unique_ips > 30 AND total_attempts >= 100), + (Esql.azure_signinlogs_properties_user_id_count_distinct == 1 and Esql.azure_signinlogs_result_description_count_distinct == 1 and Esql.event_count >= 30 and Esql.duration_seconds <= 300) + or (Esql.azure_signinlogs_properties_user_id_count_distinct <= 3 and Esql.source_ip_count_distinct > 30 and Esql.event_count >= 100), "password_guessing", - // everything else "other" ) -// Only keep columns necessary for detection output/reporting -| KEEP - time_window, bf_type, duration_seconds, total_attempts, first_seen, last_seen, - unique_users, user_id_list, login_errors, unique_login_errors, - unique_error_codes, error_codes, request_types, app_names, - ip_list, unique_ips, source_orgs, countries, - unique_country_count, unique_asn_orgs, - authentication_requirement, client_app_id, client_app_display_name, - target_resource_id, target_resource_display_name, conditional_access_status, - device_detail_browser, device_detail_device_id, device_detail_operating_system, - incoming_token_type, risk_state, session_id, user_id, - user_principal_name, result_description, result_signature, result_type - -// Remove anything not classified as credential attack activity -| WHERE bf_type != "other" +| keep + Esql.time_window_date_trunc, + Esql.brute_force_type, + Esql.duration_seconds, + Esql.event_count, + Esql.timestamp_first_seen, + Esql.timestamp_last_seen, + Esql.azure_signinlogs_properties_user_id_count_distinct, + Esql.azure_signinlogs_properties_user_id_list, + Esql.azure_signinlogs_result_description_values_all, + Esql.azure_signinlogs_result_description_count_distinct, + Esql.azure_signinlogs_properties_status_error_code_count_distinct, + Esql.azure_signinlogs_properties_status_error_code_values, + Esql.azure_signinlogs_properties_incoming_token_type_values_all, + Esql.azure_signinlogs_properties_app_display_name_values_all, + Esql.source_ip_values, + Esql.source_ip_count_distinct, + Esql.source_as_organization_name_values, + Esql.source_geo_country_name_values, + Esql.source_geo_country_name_count_distinct, + Esql.source_as_organization_name_count_distinct, + Esql.azure_signinlogs_properties_authentication_requirement_values, + Esql.azure_signinlogs_properties_app_id_values, + Esql.azure_signinlogs_properties_app_display_name_values, + Esql.azure_signinlogs_properties_resource_id_values, + Esql.azure_signinlogs_properties_resource_display_name_values, + Esql.azure_signinlogs_properties_conditional_access_status_values, + Esql.azure_signinlogs_properties_device_detail_browser_values, + Esql.azure_signinlogs_properties_device_detail_device_id_values, + Esql.azure_signinlogs_properties_device_detail_operating_system_values, + Esql.azure_signinlogs_properties_incoming_token_type_values, + Esql.azure_signinlogs_properties_risk_state_values, + Esql.azure_signinlogs_properties_session_id_values, + Esql.azure_signinlogs_properties_user_id_values, + Esql_priv.azure_signinlogs_properties_user_principal_name_values, + Esql.azure_signinlogs_result_description_values, + Esql.azure_signinlogs_result_signature_values, + Esql.azure_signinlogs_result_type_values + +| where Esql.brute_force_type != "other" ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/multiple-device-token-hashes-for-single-okta-session.asciidoc b/docs/detections/prebuilt-rules/rule-details/multiple-device-token-hashes-for-single-okta-session.asciidoc index 6fdb979b35..9911ef4e2a 100644 --- a/docs/detections/prebuilt-rules/rule-details/multiple-device-token-hashes-for-single-okta-session.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/multiple-device-token-hashes-for-single-okta-session.asciidoc @@ -35,7 +35,7 @@ This rule detects when a specific Okta actor has multiple device token hashes fo * Domain: SaaS * Resources: Investigation Guide -*Version*: 306 +*Version*: 307 *Rule authors*: @@ -108,30 +108,31 @@ The Okta Fleet integration, Filebeat module, or similarly structured data is req [source, js] ---------------------------------- -FROM logs-okta* -| WHERE - event.dataset == "okta.system" - // ignore authentication events where session and device token hash change often - AND NOT event.action IN ( +from logs-okta* +| where + event.dataset == "okta.system" and + not event.action in ( "policy.evaluate_sign_on", "user.session.start", "user.authentication.sso" - ) - // ignore Okta system events and only allow registered users - AND ( - okta.actor.alternate_id != "system@okta.com" - AND okta.actor.alternate_id RLIKE "[^@\\s]+\\@[^@\\s]+" - ) - AND okta.authentication_context.external_session_id != "unknown" -| KEEP event.action, okta.actor.alternate_id, okta.authentication_context.external_session_id, okta.debug_context.debug_data.dt_hash -| STATS - dt_hash_counts = COUNT_DISTINCT(okta.debug_context.debug_data.dt_hash) BY - okta.actor.alternate_id, - okta.authentication_context.external_session_id -| WHERE - dt_hash_counts >= 2 -| SORT - dt_hash_counts DESC + ) and + okta.actor.alternate_id != "system@okta.com" and + okta.actor.alternate_id rlike "[^@\s]+\@[^@\s]+" and + okta.authentication_context.external_session_id != "unknown" +| keep + event.action, + okta.actor.alternate_id, + okta.authentication_context.external_session_id, + okta.debug_context.debug_data.dt_hash +| stats + Esql.okta_debug_context_debug_data_dt_hash_count_distinct = count_distinct(okta.debug_context.debug_data.dt_hash) + by + okta.actor.alternate_id, + okta.authentication_context.external_session_id +| where + Esql.okta_debug_context_debug_data_dt_hash_count_distinct >= 2 +| sort + Esql.okta_debug_context_debug_data_dt_hash_count_distinct desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/multiple-microsoft-365-user-account-lockouts-in-short-time-window.asciidoc b/docs/detections/prebuilt-rules/rule-details/multiple-microsoft-365-user-account-lockouts-in-short-time-window.asciidoc index af49d417d9..045e9b120a 100644 --- a/docs/detections/prebuilt-rules/rule-details/multiple-microsoft-365-user-account-lockouts-in-short-time-window.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/multiple-microsoft-365-user-account-lockouts-in-short-time-window.asciidoc @@ -36,7 +36,7 @@ Detects a burst of Microsoft 365 user account lockouts within a short 5-minute w * Tactic: Credential Access * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -98,57 +98,55 @@ This rule uses ESQL aggregations and thus has dynamically generated fields. Corr [source, js] ---------------------------------- -FROM logs-o365.audit-* - -| MV_EXPAND event.category -| EVAL - time_window = DATE_TRUNC(5 minutes, @timestamp), - user_id = TO_LOWER(o365.audit.UserId), - ip = source.ip, - login_error = o365.audit.LogonError, - request_type = TO_LOWER(o365.audit.ExtendedProperties.RequestType), - asn_org = source.`as`.organization.name, - country = source.geo.country_name, - event_time = @timestamp - -| WHERE event.dataset == "o365.audit" - AND event.category == "authentication" - AND event.provider IN ("AzureActiveDirectory", "Exchange") - AND event.action IN ("UserLoginFailed", "PasswordLogonInitialAuthUsingPassword") - AND request_type RLIKE "(oauth.*||.*login.*)" - AND login_error == "IdsLocked" - AND user_id != "not available" - AND o365.audit.Target.Type IN ("0", "2", "6", "10") - AND asn_org != "MICROSOFT-CORP-MSN-AS-BLOCK" - -| STATS - unique_users = COUNT_DISTINCT(user_id), - user_id_list = VALUES(user_id), - ip_list = VALUES(ip), - unique_ips = COUNT_DISTINCT(ip), - source_orgs = VALUES(asn_org), - countries = VALUES(country), - unique_country_count = COUNT_DISTINCT(country), - unique_asn_orgs = COUNT_DISTINCT(asn_org), - request_types = VALUES(request_type), - first_seen = MIN(event_time), - last_seen = MAX(event_time), - total_lockout_responses = COUNT() - BY time_window - -| EVAL - duration_seconds = DATE_DIFF("seconds", first_seen, last_seen) - -| KEEP - time_window, unique_users, user_id_list, ip_list, - unique_ips, source_orgs, countries, unique_country_count, - unique_asn_orgs, request_types, first_seen, last_seen, - total_lockout_responses, duration_seconds - -| WHERE - unique_users >= 10 AND - total_lockout_responses >= 10 AND - duration_seconds <= 300 +from logs-o365.audit-* +| mv_expand event.category +| eval + Esql.time_window_date_trunc = date_trunc(5 minutes, @timestamp) +| where + event.dataset == "o365.audit" and + event.category == "authentication" and + event.provider in ("AzureActiveDirectory", "Exchange") and + event.action in ("UserLoginFailed", "PasswordLogonInitialAuthUsingPassword") and + to_lower(o365.audit.ExtendedProperties.RequestType) rlike "(oauth.*||.*login.*)" and + o365.audit.LogonError == "IdsLocked" and + to_lower(o365.audit.UserId) != "not available" and + o365.audit.Target.Type in ("0", "2", "6", "10") and + source.`as`.organization.name != "MICROSOFT-CORP-MSN-as-BLOCK" +| stats + Esql_priv.o365_audit_UserId_count_distinct = count_distinct(to_lower(o365.audit.UserId)), + Esql_priv.o365_audit_UserId_values = values(to_lower(o365.audit.UserId)), + Esql.source_ip_values = values(source.ip), + Esql.source_ip_count_distinct = count_distinct(source.ip), + Esql.source_as_organization_name_values = values(source.`as`.organization.name), + Esql.source_as_organization_name_count_distinct = count_distinct(source.`as`.organization.name), + Esql.source_geo_country_name_values = values(source.geo.country_name), + Esql.source_geo_country_name_count_distinct = count_distinct(source.geo.country_name), + Esql.o365_audit_ExtendedProperties_RequestType_values = values(to_lower(o365.audit.ExtendedProperties.RequestType)), + Esql.timestamp_first_seen = min(@timestamp), + Esql.timestamp_last_seen = max(@timestamp), + Esql.event_count = count(*) + by Esql.time_window_date_trunc +| eval + Esql.event_duration_seconds = date_diff("seconds", Esql.timestamp_first_seen, Esql.timestamp_last_seen) +| keep + Esql.time_window_date_trunc, + Esql_priv.o365_audit_UserId_count_distinct, + Esql_priv.o365_audit_UserId_values, + Esql.source_ip_values, + Esql.source_ip_count_distinct, + Esql.source_as_organization_name_values, + Esql.source_as_organization_name_count_distinct, + Esql.source_geo_country_name_values, + Esql.source_geo_country_name_count_distinct, + Esql.o365_audit_ExtendedProperties_RequestType_values, + Esql.timestamp_first_seen, + Esql.timestamp_last_seen, + Esql.event_count, + Esql.event_duration_seconds +| where + Esql_priv.o365_audit_UserId_count_distinct >= 10 and + Esql.event_count >= 10 and + Esql.event_duration_seconds <= 300 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/multiple-okta-user-authentication-events-with-client-address.asciidoc b/docs/detections/prebuilt-rules/rule-details/multiple-okta-user-authentication-events-with-client-address.asciidoc index 4f26f8d46c..879bb06b5b 100644 --- a/docs/detections/prebuilt-rules/rule-details/multiple-okta-user-authentication-events-with-client-address.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/multiple-okta-user-authentication-events-with-client-address.asciidoc @@ -34,7 +34,7 @@ Detects when a certain threshold of Okta user authentication events are reported * Tactic: Credential Access * Resources: Investigation Guide -*Version*: 205 +*Version*: 206 *Rule authors*: @@ -115,19 +115,26 @@ The Okta Fleet integration, Filebeat module, or similarly structured data is req [source, js] ---------------------------------- -FROM logs-okta* -| WHERE - event.dataset == "okta.system" - AND (event.action == "user.session.start" OR event.action RLIKE "user\\.authentication(.*)") - AND okta.outcome.reason == "INVALID_CREDENTIALS" -| KEEP okta.client.ip, okta.actor.alternate_id, okta.actor.id, event.action, okta.outcome.reason -| STATS - source_auth_count = COUNT_DISTINCT(okta.actor.id) - BY okta.client.ip, okta.actor.alternate_id -| WHERE - source_auth_count > 5 -| SORT - source_auth_count DESC +from logs-okta* +| where + event.dataset == "okta.system" and + (event.action == "user.session.start" or event.action rlike "user\.authentication(.*)") and + okta.outcome.reason == "INVALID_CREDENTIALS" +| keep + okta.client.ip, + okta.actor.alternate_id, + okta.actor.id, + event.action, + okta.outcome.reason +| stats + Esql.okta_actor_id_count_distinct = count_distinct(okta.actor.id) + by + okta.client.ip, + okta.actor.alternate_id +| where + Esql.okta_actor_id_count_distinct > 5 +| sort + Esql.okta_actor_id_count_distinct desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/multiple-okta-user-authentication-events-with-same-device-token-hash.asciidoc b/docs/detections/prebuilt-rules/rule-details/multiple-okta-user-authentication-events-with-same-device-token-hash.asciidoc index f504a68eab..e5feeb913c 100644 --- a/docs/detections/prebuilt-rules/rule-details/multiple-okta-user-authentication-events-with-same-device-token-hash.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/multiple-okta-user-authentication-events-with-same-device-token-hash.asciidoc @@ -34,7 +34,7 @@ Detects when a high number of Okta user authentication events are reported for m * Tactic: Credential Access * Resources: Investigation Guide -*Version*: 205 +*Version*: 206 *Rule authors*: @@ -112,20 +112,27 @@ The Okta Fleet integration, Filebeat module, or similarly structured data is req [source, js] ---------------------------------- -FROM logs-okta* -| WHERE - event.dataset == "okta.system" - AND (event.action RLIKE "user\\.authentication(.*)" OR event.action == "user.session.start") - AND okta.debug_context.debug_data.dt_hash != "-" - AND okta.outcome.reason == "INVALID_CREDENTIALS" -| KEEP event.action, okta.debug_context.debug_data.dt_hash, okta.actor.id, okta.actor.alternate_id, okta.outcome.reason -| STATS - target_auth_count = COUNT_DISTINCT(okta.actor.id) - BY okta.debug_context.debug_data.dt_hash, okta.actor.alternate_id -| WHERE - target_auth_count > 20 -| SORT - target_auth_count DESC +from logs-okta* +| where + event.dataset == "okta.system" and + (event.action rlike "user\.authentication(.*)" or event.action == "user.session.start") and + okta.debug_context.debug_data.dt_hash != "-" and + okta.outcome.reason == "INVALID_CREDENTIALS" +| keep + event.action, + okta.debug_context.debug_data.dt_hash, + okta.actor.id, + okta.actor.alternate_id, + okta.outcome.reason +| stats + Esql.okta_actor_id_count_distinct = count_distinct(okta.actor.id) + by + okta.debug_context.debug_data.dt_hash, + okta.actor.alternate_id +| where + Esql.okta_actor_id_count_distinct > 20 +| sort + Esql.okta_actor_id_count_distinct desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/oidc-discovery-url-changed-in-entra-id.asciidoc b/docs/detections/prebuilt-rules/rule-details/oidc-discovery-url-changed-in-entra-id.asciidoc index ffbe168ba3..0e5d4d3a47 100644 --- a/docs/detections/prebuilt-rules/rule-details/oidc-discovery-url-changed-in-entra-id.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/oidc-discovery-url-changed-in-entra-id.asciidoc @@ -32,7 +32,7 @@ Detects a change to the OpenID Connect (OIDC) discovery URL in the Entra ID Auth * Tactic: Persistence * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -84,15 +84,15 @@ This rule detects when the OIDC `discoveryUrl` is changed within the Entra ID Au [source, js] ---------------------------------- -FROM logs-azure.auditlogs-* metadata _id, _version, _index -| WHERE event.action == "Authentication Methods Policy Update" -| EVAL Esql.azure.auditlogs.properties.target_resources.modified_properties.new_value.replace = REPLACE(`azure.auditlogs.properties.target_resources.0.modified_properties.0.new_value`, "\\\\", "") -| EVAL Esql.azure.auditlogs.properties.target_resources.modified_properties.old_value.replace = REPLACE(`azure.auditlogs.properties.target_resources.0.modified_properties.0.old_value`, "\\\\", "") -| DISSECT Esql.azure.auditlogs.properties.target_resources.modified_properties.new_value.replace "%{}discoveryUrl\":\"%{Esql.azure.auditlogs.properties.auth.oidc.discovery.url.new}\"}%{}" -| DISSECT Esql.azure.auditlogs.properties.target_resources.modified_properties.old_value.replace "%{}discoveryUrl\":\"%{Esql.azure.auditlogs.properties.auth.oidc.discovery.url.old}\"}%{}" -| WHERE Esql.azure.auditlogs.properties.auth.oidc.discovery.url.new IS NOT NULL and Esql.azure.auditlogs.properties.auth.oidc.discovery.url.old IS NOT NULL -| WHERE Esql.azure.auditlogs.properties.auth.oidc.discovery.url.new != Esql.azure.auditlogs.properties.auth.oidc.discovery.url.old -| KEEP +from logs-azure.auditlogs-* metadata _id, _version, _index +| where event.action == "Authentication Methods Policy Update" +| eval Esql.azure_auditlogs_properties_target_resources_modified_properties_new_value_replace = replace(`azure.auditlogs.properties.target_resources.0.modified_properties.0.new_value`, "\\\\", "") +| eval Esql.azure_auditlogs_properties_target_resources_modified_properties_old_value_replace = replace(`azure.auditlogs.properties.target_resources.0.modified_properties.0.old_value`, "\\\\", "") +| dissect Esql.azure_auditlogs_properties_target_resources_modified_properties_new_value_replace "%{}discoveryUrl\":\"%{Esql.azure_auditlogs_properties_auth_oidc_discovery_url_new}\"}%{}" +| dissect Esql.azure_auditlogs_properties_target_resources_modified_properties_old_value_replace "%{}discoveryUrl\":\"%{Esql.azure_auditlogs_properties_auth_oidc_discovery_url_old}\"}%{}" +| where Esql.azure_auditlogs_properties_auth_oidc_discovery_url_new is not null and Esql.azure_auditlogs_properties_auth_oidc_discovery_url_old is not null +| where Esql.azure_auditlogs_properties_auth_oidc_discovery_url_new != Esql.azure_auditlogs_properties_auth_oidc_discovery_url_old +| keep @timestamp, event.action, event.outcome, @@ -106,8 +106,8 @@ FROM logs-azure.auditlogs-* metadata _id, _version, _index source.geo.city_name, source.geo.region_name, source.geo.country_name, - Esql.azure.auditlogs.properties.auth.oidc.discovery.url.new, - Esql.azure.auditlogs.properties.auth.oidc.discovery.url.old + Esql.azure_auditlogs_properties_auth_oidc_discovery_url_new, + Esql.azure_auditlogs_properties_auth_oidc_discovery_url_old ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/okta-user-sessions-started-from-different-geolocations.asciidoc b/docs/detections/prebuilt-rules/rule-details/okta-user-sessions-started-from-different-geolocations.asciidoc index f47e21ea35..c0b09ee704 100644 --- a/docs/detections/prebuilt-rules/rule-details/okta-user-sessions-started-from-different-geolocations.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/okta-user-sessions-started-from-different-geolocations.asciidoc @@ -34,7 +34,7 @@ Detects when a specific Okta actor has multiple sessions started from different * Tactic: Initial Access * Resources: Investigation Guide -*Version*: 306 +*Version*: 307 *Rule authors*: @@ -106,18 +106,27 @@ The Okta Fleet integration, Filebeat module, or similarly structured data is req [source, js] ---------------------------------- -FROM logs-okta* -| WHERE - event.dataset == "okta.system" - AND (event.action RLIKE "user\\.authentication(.*)" OR event.action == "user.session.start") - AND okta.security_context.is_proxy != true and okta.actor.id != "unknown" - AND event.outcome == "success" -| KEEP event.action, okta.security_context.is_proxy, okta.actor.id, event.outcome, client.geo.country_name, okta.actor.alternate_id -| STATS - geo_auth_counts = COUNT_DISTINCT(client.geo.country_name) - BY okta.actor.id, okta.actor.alternate_id -| WHERE - geo_auth_counts >= 2 +from logs-okta* +| where + event.dataset == "okta.system" and + (event.action rlike "user\.authentication(.*)" or event.action == "user.session.start") and + okta.security_context.is_proxy != true and + okta.actor.id != "unknown" and + event.outcome == "success" +| keep + event.action, + okta.security_context.is_proxy, + okta.actor.id, + okta.actor.alternate_id, + event.outcome, + client.geo.country_name +| stats + Esql.client_geo_country_name_count_distinct = count_distinct(client.geo.country_name) + by okta.actor.id, okta.actor.alternate_id +| where + Esql.client_geo_country_name_count_distinct >= 2 +| sort + Esql.client_geo_country_name_count_distinct desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-abuse-of-resources-by-high-token-count-and-large-response-sizes.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-abuse-of-resources-by-high-token-count-and-large-response-sizes.asciidoc index 2c929a8845..d21397010e 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-abuse-of-resources-by-high-token-count-and-large-response-sizes.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-abuse-of-resources-by-high-token-count-and-large-response-sizes.asciidoc @@ -34,7 +34,7 @@ Detects potential resource exhaustion or data breach attempts by monitoring for * Mitre Atlas: LLM04 * Resources: Investigation Guide -*Version*: 4 +*Version*: 5 *Rule authors*: @@ -109,15 +109,37 @@ https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html [source, js] ---------------------------------- from logs-aws_bedrock.invocation-* -| keep user.id, gen_ai.usage.prompt_tokens, gen_ai.usage.completion_tokens -| stats max_tokens = max(gen_ai.usage.prompt_tokens), - total_requests = count(*), - avg_response_size = avg(gen_ai.usage.completion_tokens) - by user.id -// tokens count depends on specific LLM, as is related to how embeddings are generated. -| where max_tokens > 5000 and total_requests > 10 and avg_response_size > 500 -| eval risk_factor = (max_tokens / 1000) * total_requests * (avg_response_size / 500) -| where risk_factor > 10 -| sort risk_factor desc + +// keep token usage data +| keep + user.id, + gen_ai.usage.prompt_tokens, + gen_ai.usage.completion_tokens + +// Aggregate usage metrics +| stats + Esql.ml_usage_prompt_tokens_max = max(gen_ai.usage.prompt_tokens), + Esql.ml_invocations_total_count = count(*), + Esql.ml_usage_completion_tokens_avg = avg(gen_ai.usage.completion_tokens) + by + user.id + +// Filter for suspicious usage patterns +| where + Esql.ml_usage_prompt_tokens_max > 5000 + and Esql.ml_invocations_total_count > 10 + and Esql.ml_usage_completion_tokens_avg > 500 + +// Calculate a custom risk factor +| eval Esql.ml_risk_score = + (Esql.ml_usage_prompt_tokens_max / 1000) * + Esql.ml_invocations_total_count * + (Esql.ml_usage_completion_tokens_avg / 500) + +// Filter on risk score +| where Esql.ml_risk_score > 10 + +// sort high risk users to top +| sort Esql.ml_risk_score desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-aws-s3-bucket-ransomware-note-uploaded.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-aws-s3-bucket-ransomware-note-uploaded.asciidoc index ec98f512aa..761a96214c 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-aws-s3-bucket-ransomware-note-uploaded.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-aws-s3-bucket-ransomware-note-uploaded.asciidoc @@ -33,7 +33,7 @@ Identifies potential ransomware note being uploaded to an AWS S3 bucket. This ru * Tactic: Impact * Resources: Investigation Guide -*Version*: 5 +*Version*: 6 *Rule authors*: @@ -108,26 +108,36 @@ AWS S3 data types need to be enabled in the CloudTrail trail configuration. from logs-aws.cloudtrail-* // any successful uploads via S3 API requests -| where event.dataset == "aws.cloudtrail" - and event.provider == "s3.amazonaws.com" - and event.action == "PutObject" - and event.outcome == "success" - -// abstract object name from API request parameters -| dissect aws.cloudtrail.request_parameters "%{?ignore_values}key=%{object_name}}" - -// regex on common ransomware note extensions -| where object_name rlike "(.*)(ransom|lock|crypt|enc|readme|how_to_decrypt|decrypt_instructions|recovery|datarescue)(.*)" - and not object_name rlike "(.*)(AWSLogs|CloudTrail|access-logs)(.*)" - -// keep relevant fields -| keep tls.client.server_name, aws.cloudtrail.user_identity.arn, object_name - -// aggregate by S3 bucket, resource and object name -| stats note_upload_count = count(*) by tls.client.server_name, aws.cloudtrail.user_identity.arn, object_name - -// filter for single occurrence to eliminate common upload operations -| where note_upload_count == 1 +| where + event.dataset == "aws.cloudtrail" + and event.provider == "s3.amazonaws.com" + and event.action == "PutObject" + and event.outcome == "success" + +// extract object key from API request parameters +| dissect aws.cloudtrail.request_parameters "%{?ignore_values}key=%{Esql.aws_cloudtrail_request_parameters_object_key}}" + +// regex match against common ransomware naming patterns +| where + Esql.aws_cloudtrail_request_parameters_object_key rlike "(.*)(ransom|lock|crypt|enc|readme|how_to_decrypt|decrypt_instructions|recovery|datarescue)(.*)" + and not Esql.aws_cloudtrail_request_parameters_object_key rlike "(.*)(AWSLogs|CloudTrail|access-logs)(.*)" + +// keep relevant ECS and derived fields +| keep + tls.client.server_name, + aws.cloudtrail.user_identity.arn, + Esql.aws_cloudtrail_request_parameters_object_key + +// aggregate by server name, actor, and object key +| stats + Esql.event_count = count(*) + by + tls.client.server_name, + aws.cloudtrail.user_identity.arn, + Esql.aws_cloudtrail_request_parameters_object_key + +// filter for rare single uploads (likely test/detonation) +| where Esql.event_count == 1 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-azure-openai-model-theft.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-azure-openai-model-theft.asciidoc index c0a11ea5a6..a2e05333e3 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-azure-openai-model-theft.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-azure-openai-model-theft.asciidoc @@ -31,7 +31,7 @@ Monitors for suspicious activities that may indicate theft or unauthorized dupli * Mitre Atlas: T0044 * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -107,10 +107,26 @@ https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/stream-monitori [source, js] ---------------------------------- from logs-azure_openai.logs-* -| where azure.open_ai.operation_name == "ListKey" and azure.open_ai.category == "Audit" -| KEEP @timestamp, azure.open_ai.operation_name , azure.open_ai.category, azure.resource.group, azure.resource.name, azure.open_ai.properties.response_length -| stats count = count(), max_data_transferred = max(azure.open_ai.properties.response_length) by azure.resource.group , azure.resource.name -| where count >= 100 or max_data_transferred >= 1000000 -| sort count desc +| where + azure.open_ai.operation_name == "ListKey" and + azure.open_ai.category == "Audit" +| keep + @timestamp, + azure.open_ai.operation_name, + azure.open_ai.category, + azure.resource.group, + azure.resource.name, + azure.open_ai.properties.response_length +| stats + Esql.event_count = count(*), + Esql.azure_open_ai_properties_response_length_max = max(azure.open_ai.properties.response_length) + by + azure.resource.group, + azure.resource.name +| where + Esql.event_count >= 100 or + Esql.azure_open_ai_properties_response_length_max >= 1000000 +| sort + Esql.event_count desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-denial-of-azure-openai-ml-service.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-denial-of-azure-openai-ml-service.asciidoc index f958ce58e9..5fb9ec3f28 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-denial-of-azure-openai-ml-service.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-denial-of-azure-openai-ml-service.asciidoc @@ -31,7 +31,7 @@ Detects patterns indicative of Denial-of-Service (DoS) attacks on machine learni * Mitre Atlas: T0029 * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -107,12 +107,23 @@ https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/stream-monitori [source, js] ---------------------------------- from logs-azure_openai.logs-* -// truncate the timestamp to a 1-minute window -| eval target_time_window = DATE_TRUNC(1 minutes, @timestamp) +| eval + Esql.time_window_date_trunc = date_trunc(1 minutes, @timestamp) | where azure.open_ai.operation_name == "ChatCompletions_Create" -| keep azure.open_ai.properties.request_length, azure.resource.name, cloud.account.id,target_time_window -| stats count = count(), avg_request_size = avg(azure.open_ai.properties.request_length) by target_time_window, azure.resource.name -| where count >= 10 and avg_request_size >= 5000 -| sort count desc +| keep + azure.open_ai.properties.request_length, + azure.resource.name, + cloud.account.id, + Esql.time_window_date_trunc +| stats + Esql.event_count = count(*), + Esql.azure_open_ai_properties_request_length_avg = avg(azure.open_ai.properties.request_length) + by + Esql.time_window_date_trunc, + azure.resource.name +| where + Esql.event_count >= 10 and + Esql.azure_open_ai_properties_request_length_avg >= 5000 +| sort Esql.event_count desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-dynamic-iex-reconstruction-via-environment-variables.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-dynamic-iex-reconstruction-via-environment-variables.asciidoc index 406bbb9caf..7294c64842 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-dynamic-iex-reconstruction-via-environment-variables.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-dynamic-iex-reconstruction-via-environment-variables.asciidoc @@ -28,7 +28,7 @@ Identifies PowerShell scripts that reconstruct the IEX (Invoke-Expression) comma * Data Source: PowerShell Logs * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -113,23 +113,42 @@ reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" [source, js] ---------------------------------- -FROM logs-windows.powershell_operational* metadata _id, _version, _index -| WHERE event.code == "4104" +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" -// Look for scripts with more than 500 chars that contain a related keyword -| EVAL script_len = LENGTH(powershell.file.script_block_text) -| WHERE script_len > 500 +// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for +| eval Esql.script_block_length = length(powershell.file.script_block_text) +| where Esql.script_block_length > 500 -// Replace string format expressions with πŸ”₯ to enable counting the occurrence of the patterns we are looking for +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them // The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 -| EVAL replaced_with_fire = REPLACE(powershell.file.script_block_text, """(?i)(\$(?:\w+|\w+\:\w+)\[\d++\]\+\$(?:\w+|\w+\:\w+)\[\d++\]\+['"]x['"]|\$(?:\w+\:\w+)\[\d++,\d++,\d++\]|\.name\[\d++,\d++,\d++\])""", "πŸ”₯") - -// Count how many patterns were detected by calculating the number of πŸ”₯ characters inserted -| EVAL count = LENGTH(replaced_with_fire) - LENGTH(REPLACE(replaced_with_fire, "πŸ”₯", "")) - -// Keep the fields relevant to the query, although this is not needed as the alert is populated using _id -| KEEP count, replaced_with_fire, powershell.file.script_block_text, powershell.file.script_block_id, file.path, powershell.sequence, powershell.total, _id, _index, host.name, agent.id, user.id -| WHERE count >= 1 +| eval Esql.script_block_tmp = replace( + powershell.file.script_block_text, + """(?i)(\$(?:\w+|\w+\:\w+)\[\d++\]\+\$(?:\w+|\w+\:\w+)\[\d++\]\+['"]x['"]|\$(?:\w+\:\w+)\[\d++,\d++,\d++\]|\.name\[\d++,\d++,\d++\])""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_length, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least once +| where Esql.script_block_pattern_count >= 1 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-malicious-powershell-based-on-alert-correlation.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-malicious-powershell-based-on-alert-correlation.asciidoc index 1edefff05b..94fbbf6af1 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-malicious-powershell-based-on-alert-correlation.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-malicious-powershell-based-on-alert-correlation.asciidoc @@ -28,7 +28,7 @@ Identifies PowerShell script blocks associated with multiple distinct detections * Rule Type: Higher-Order Rule * Resources: Investigation Guide -*Version*: 1 +*Version*: 2 *Rule authors*: @@ -111,20 +111,27 @@ This detection rule aggregates alert data to identify PowerShell Scripts that ha [source, js] ---------------------------------- -FROM .alerts-security.* metadata _id +from .alerts-security.* metadata _id // Filter for PowerShell related alerts -| WHERE kibana.alert.rule.name LIKE "*PowerShell*" +| where kibana.alert.rule.name like "*PowerShell*" -// As alerts don't have non-ECS fields, parse the script block ID using GROK -| GROK message "ScriptBlock ID: (?.+)" -| WHERE powershell.file.script_block_id IS NOT NULL +// as alerts don't have non-ECS fields, parse the script block ID using grok +| grok message "ScriptBlock ID: (?.+)" +| where Esql.script_block_id is not null -| KEEP kibana.alert.rule.name, powershell.file.script_block_id, _id +// keep relevant fields for further processing +| keep kibana.alert.rule.name, Esql.script_block_id, _id -// Count distinct alerts and filter for matches above the threshold -| STATS distinct_alerts = COUNT_DISTINCT(kibana.alert.rule.name), rules_triggered = VALUES(kibana.alert.rule.name), alert_ids = VALUES(_id) BY powershell.file.script_block_id -| WHERE distinct_alerts >= 5 +// count distinct alerts and filter for matches above the threshold +| stats + Esql.kibana_alert_rule_name_count_distinct = count_distinct(kibana.alert.rule.name), + Esql.kibana_alert_rule_name_values = values(kibana.alert.rule.name), + Esql._id_values = values(_id) + by Esql.script_block_id + +// Apply detection threshold +| where Esql.kibana_alert_rule_name_count_distinct >= 5 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-malware-driven-ssh-brute-force-attempt.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-malware-driven-ssh-brute-force-attempt.asciidoc index 72778bb53a..091f86af70 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-malware-driven-ssh-brute-force-attempt.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-malware-driven-ssh-brute-force-attempt.asciidoc @@ -30,7 +30,7 @@ This detection identifies a Linux host that has potentially been infected with m * Data Source: Elastic Defend * Resources: Investigation Guide -*Version*: 4 +*Version*: 5 *Rule authors*: @@ -130,18 +130,31 @@ For more details on Elastic Defend refer to the https://www.elastic.co/guide/en/ ---------------------------------- from logs-endpoint.events.network-* | keep @timestamp, host.os.type, event.type, event.action, destination.port, process.executable, destination.ip, agent.id, host.name -| where @timestamp > now() - 1 hours -| where host.os.type == "linux" and event.type == "start" and event.action == "connection_attempted" and - destination.port in (22, 222, 2222, 10022, 2022, 2200, 62612, 8022) and not - CIDR_MATCH( - destination.ip, "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24", "192.0.0.0/29", "192.0.0.8/32", "192.0.0.9/32", - "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24", "192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", - "224.0.0.0/4", "100.64.0.0/10", "192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "224.0.0.0/4", "240.0.0.0/4", "::1", - "FE80::/10", "FF00::/8" - ) -| stats cc = count(), agent_count = count_distinct(agent.id), host.name = VALUES(host.name), agent.id = VALUES(agent.id) by process.executable, destination.port -| where agent_count == 1 and cc > 15 -| sort cc asc +| where + @timestamp > now() - 1 hours and + host.os.type == "linux" and + event.type == "start" and + event.action == "connection_attempted" and + destination.port in (22, 222, 2222, 10022, 2022, 2200, 62612, 8022) and + not cidr_match( + destination.ip, + "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", + "192.0.0.0/24", "192.0.0.0/29", "192.0.0.8/32", "192.0.0.9/32", + "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24", + "192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", + "224.0.0.0/4", "100.64.0.0/10", "192.175.48.0/24", "198.18.0.0/15", + "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1", "FE80::/10", "FF00::/8" + ) +| stats + Esql.event_count = count(), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.executable, destination.port +| where + Esql.agent_id_count_distinct == 1 and + Esql.event_count > 15 +| sort Esql.event_count asc | limit 100 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-microsoft-365-user-account-brute-force.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-microsoft-365-user-account-brute-force.asciidoc index 554a406cac..1c761b4883 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-microsoft-365-user-account-brute-force.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-microsoft-365-user-account-brute-force.asciidoc @@ -36,7 +36,7 @@ Identifies brute-force authentication activity targeting Microsoft 365 user acco * Tactic: Credential Access * Resources: Investigation Guide -*Version*: 413 +*Version*: 414 *Rule authors*: @@ -98,67 +98,76 @@ Identifies brute-force authentication activity targeting Microsoft 365 user acco [source, js] ---------------------------------- -FROM logs-o365.audit-* - -| MV_EXPAND event.category -| EVAL - time_window = DATE_TRUNC(5 minutes, @timestamp), - user_id = TO_LOWER(o365.audit.UserId), - ip = source.ip, - login_error = o365.audit.LogonError, - request_type = TO_LOWER(o365.audit.ExtendedProperties.RequestType), - asn_org = source.`as`.organization.name, - country = source.geo.country_name, - event_time = @timestamp - -| WHERE event.dataset == "o365.audit" - AND event.category == "authentication" - AND event.provider IN ("AzureActiveDirectory", "Exchange") - AND event.action IN ("UserLoginFailed", "PasswordLogonInitialAuthUsingPassword") - AND request_type RLIKE "(oauth.*||.*login.*)" - AND login_error != "IdsLocked" - AND login_error NOT IN ( - "EntitlementGrantsNotFound", "UserStrongAuthEnrollmentRequired", "UserStrongAuthClientAuthNRequired", - "InvalidReplyTo", "SsoArtifactExpiredDueToConditionalAccess", "PasswordResetRegistrationRequiredInterrupt", - "SsoUserAccountNotFoundInResourceTenant", "UserStrongAuthExpired", "CmsiInterrupt" - ) - AND user_id != "not available" - AND o365.audit.Target.Type IN ("0", "2", "6", "10") - -| STATS - unique_users = COUNT_DISTINCT(user_id), - user_id_list = VALUES(user_id), - login_errors = VALUES(login_error), - unique_login_errors = COUNT_DISTINCT(login_error), - request_types = VALUES(request_type), - ip_list = VALUES(ip), - unique_ips = COUNT_DISTINCT(ip), - source_orgs = VALUES(asn_org), - countries = VALUES(country), - unique_country_count = COUNT_DISTINCT(country), - unique_asn_orgs = COUNT_DISTINCT(asn_org), - first_seen = MIN(event_time), - last_seen = MAX(event_time), - total_attempts = COUNT() - BY time_window - -| EVAL - duration_seconds = DATE_DIFF("seconds", first_seen, last_seen), - bf_type = CASE( - unique_users >= 15 AND unique_login_errors == 1 AND total_attempts >= 10 AND duration_seconds <= 1800, "password_spraying", - unique_users >= 8 AND total_attempts >= 15 AND unique_login_errors <= 3 AND unique_ips <= 5 AND duration_seconds <= 600, "credential_stuffing", - unique_users == 1 AND unique_login_errors == 1 AND total_attempts >= 20 AND duration_seconds <= 300, "password_guessing", +from logs-o365.audit-* +| mv_expand event.category +| eval + Esql.time_window_date_trunc = date_trunc(5 minutes, @timestamp), + Esql_priv.o365_audit_UserId_lower = to_lower(o365.audit.UserId), + Esql.o365_audit_LogonError = o365.audit.LogonError, + Esql.o365_audit_ExtendedProperties_RequestType_lower = to_lower(o365.audit.ExtendedProperties.RequestType) +| where + event.dataset == "o365.audit" and + event.category == "authentication" and + event.provider in ("AzureActiveDirectory", "Exchange") and + event.action in ("UserLoginFailed", "PasswordLogonInitialAuthUsingPassword") and + Esql.o365_audit_ExtendedProperties_RequestType_lower rlike "(oauth.*||.*login.*)" and + Esql.o365_audit_LogonError != "IdsLocked" and + Esql.o365_audit_LogonError not in ( + "EntitlementGrantsNotFound", + "UserStrongAuthEnrollmentRequired", + "UserStrongAuthClientAuthNRequired", + "InvalidReplyTo", + "SsoArtifactExpiredDueToConditionalAccess", + "PasswordResetRegistrationRequiredInterrupt", + "SsoUserAccountNotFoundInResourceTenant", + "UserStrongAuthExpired", + "CmsiInterrupt" + ) and + Esql_priv.o365_audit_UserId_lower != "not available" and + o365.audit.Target.Type in ("0", "2", "6", "10") +| stats + Esql.o365_audit_UserId_lower_count_distinct = count_distinct(Esql_priv.o365_audit_UserId_lower), + Esql_priv.o365_audit_UserId_lower_values = values(Esql_priv.o365_audit_UserId_lower), + Esql.o365_audit_LogonError_values = values(Esql.o365_audit_LogonError), + Esql.o365_audit_LogonError_count_distinct = count_distinct(Esql.o365_audit_LogonError), + Esql.o365_audit_ExtendedProperties_RequestType_values = values(Esql.o365_audit_ExtendedProperties_RequestType_lower), + Esql.source_ip_values = values(source.ip), + Esql.source_ip_count_distinct = count_distinct(source.ip), + Esql.source_as_organization_name_values = values(source.`as`.organization.name), + Esql.source_geo_country_name_values = values(source.geo.country_name), + Esql.source_geo_country_name_count_distinct = count_distinct(source.geo.country_name), + Esql.source_as_organization_name_count_distinct = count_distinct(source.`as`.organization.name), + Esql.timestamp_first_seen = min(@timestamp), + Esql.timestamp_last_seen = max(@timestamp), + Esql.event_count = count(*) + by Esql.time_window_date_trunc +| eval + Esql.event_duration_seconds = date_diff("seconds", Esql.timestamp_first_seen, Esql.timestamp_last_seen), + Esql.brute_force_type = case( + Esql.o365_audit_UserId_lower_count_distinct >= 15 and Esql.o365_audit_LogonError_count_distinct == 1 and Esql.event_count >= 10 and Esql.event_duration_seconds <= 1800, "password_spraying", + Esql.o365_audit_UserId_lower_count_distinct >= 8 and Esql.event_count >= 15 and Esql.o365_audit_LogonError_count_distinct <= 3 and Esql.source_ip_count_distinct <= 5 and Esql.event_duration_seconds <= 600, "credential_stuffing", + Esql.o365_audit_UserId_lower_count_distinct == 1 and Esql.o365_audit_LogonError_count_distinct == 1 and Esql.event_count >= 20 and Esql.event_duration_seconds <= 300, "password_guessing", "other" ) - -| KEEP - time_window, unique_users, user_id_list, login_errors, unique_login_errors, - request_types, ip_list, unique_ips, source_orgs, countries, - unique_country_count, unique_asn_orgs, first_seen, last_seen, - duration_seconds, total_attempts, bf_type - -| WHERE - bf_type != "other" +| keep + Esql.time_window_date_trunc, + Esql.o365_audit_UserId_lower_count_distinct, + Esql_priv.o365_audit_UserId_lower_values, + Esql.o365_audit_LogonError_values, + Esql.o365_audit_LogonError_count_distinct, + Esql.o365_audit_ExtendedProperties_RequestType_values, + Esql.source_ip_values, + Esql.source_ip_count_distinct, + Esql.source_as_organization_name_values, + Esql.source_geo_country_name_values, + Esql.source_geo_country_name_count_distinct, + Esql.source_as_organization_name_count_distinct, + Esql.timestamp_first_seen, + Esql.timestamp_last_seen, + Esql.event_duration_seconds, + Esql.event_count, + Esql.brute_force_type +| where Esql.brute_force_type != "other" ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-port-scanning-activity-from-compromised-host.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-port-scanning-activity-from-compromised-host.asciidoc index cf0823fee2..dd64256e03 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-port-scanning-activity-from-compromised-host.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-port-scanning-activity-from-compromised-host.asciidoc @@ -28,7 +28,7 @@ This rule detects potential port scanning activity from a compromised host. Port * Data Source: Elastic Defend * Resources: Investigation Guide -*Version*: 4 +*Version*: 5 *Rule authors*: @@ -128,12 +128,32 @@ For more details on Elastic Defend refer to the https://www.elastic.co/guide/en/ [source, js] ---------------------------------- from logs-endpoint.events.network-* -| keep @timestamp, host.os.type, event.type, event.action, destination.port, process.executable, destination.ip, agent.id, host.name -| where @timestamp > now() - 1 hours -| where host.os.type == "linux" and event.type == "start" and event.action == "connection_attempted" -| stats cc = count(), port_count = count_distinct(destination.port), agent_count = count_distinct(agent.id), host.name = VALUES(host.name), agent.id = VALUES(agent.id) by process.executable, destination.ip -| where agent_count == 1 and port_count > 100 -| sort cc asc +| where + @timestamp > now() - 1h and + host.os.type == "linux" and + event.type == "start" and + event.action == "connection_attempted" +| keep + @timestamp, + host.os.type, + event.type, + event.action, + destination.port, + process.executable, + destination.ip, + agent.id, + host.name +| stats + Esql.event_count = count(), + Esql.destination_port_count_distinct = count_distinct(destination.port), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.executable, destination.ip +| where + Esql.agent_id_count_distinct == 1 and + Esql.destination_port_count_distinct > 100 +| sort Esql.event_count asc | limit 100 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-backtick-escaped-variable-expansion.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-backtick-escaped-variable-expansion.asciidoc index d3a47642fb..018e7b021c 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-backtick-escaped-variable-expansion.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-backtick-escaped-variable-expansion.asciidoc @@ -28,7 +28,7 @@ Identifies PowerShell scripts that use backtick-escaped characters inside ${} va * Data Source: PowerShell Logs * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -114,23 +114,39 @@ reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" [source, js] ---------------------------------- -FROM logs-windows.powershell_operational* metadata _id, _version, _index -| WHERE event.code == "4104" +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" -// Look for scripts with more than 500 chars that contain a related keyword -| EVAL script_len = LENGTH(powershell.file.script_block_text) -| WHERE script_len > 500 +// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for +| eval Esql.script_block_length = length(powershell.file.script_block_text) +| where Esql.script_block_length > 500 -// Replace string format expressions with πŸ”₯ to enable counting the occurrence of the patterns we are looking for +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them // The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 -| EVAL replaced_with_fire = REPLACE(powershell.file.script_block_text, """\$\{(\w++`){2,}\w++\}""", "πŸ”₯") - -// Count how many patterns were detected by calculating the number of πŸ”₯ characters inserted -| EVAL count = LENGTH(replaced_with_fire) - LENGTH(REPLACE(replaced_with_fire, "πŸ”₯", "")) - -// Keep the fields relevant to the query, although this is not needed as the alert is populated using _id -| KEEP count, replaced_with_fire, powershell.file.script_block_text, powershell.file.script_block_id, file.path, file.name, powershell.sequence, powershell.total, _id, _index, host.name, agent.id, user.id -| WHERE count >= 1 +| eval Esql.script_block_tmp = replace(powershell.file.script_block_text, """\$\{(\w++`){2,}\w++\}""", "πŸ”₯") + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_length, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + file.name, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least once +| where Esql.script_block_pattern_count >= 1 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-character-array-reconstruction.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-character-array-reconstruction.asciidoc index fc6e1cdff2..094976a37c 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-character-array-reconstruction.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-character-array-reconstruction.asciidoc @@ -28,7 +28,7 @@ Identifies PowerShell scripts that use character arrays and runtime string recon * Data Source: PowerShell Logs * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -113,22 +113,40 @@ reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" [source, js] ---------------------------------- -FROM logs-windows.powershell_operational* metadata _id, _version, _index -| WHERE event.code == "4104" +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" // Filter for scripts that contain the "char" keyword using MATCH, boosts the query performance -| WHERE powershell.file.script_block_text : "char" +| where powershell.file.script_block_text : "char" -// Replace string format expressions with πŸ”₯ to enable counting the occurrence of the patterns we are looking for +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them // The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 -| EVAL replaced_with_fire = REPLACE(powershell.file.script_block_text, """(char\[\]\]\(\d+,\d+[^)]+|(\s?\(\[char\]\d+\s?\)\+){2,})""", "πŸ”₯") - -// Count how many patterns were detected by calculating the number of πŸ”₯ characters inserted -| EVAL count = LENGTH(replaced_with_fire) - LENGTH(REPLACE(replaced_with_fire, "πŸ”₯", "")) - -// Keep the fields relevant to the query, although this is not needed as the alert is populated using _id -| KEEP count, replaced_with_fire, powershell.file.script_block_text, powershell.file.script_block_id, file.path, powershell.sequence, powershell.total, _id, _index, host.name, agent.id, user.id -| WHERE count >= 1 +| eval Esql.script_block_tmp = replace( + powershell.file.script_block_text, + """(char\[\]\]\(\d+,\d+[^)]+|(\s?\(\[char\]\d+\s?\)\+){2,})""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least once +| where Esql.script_block_pattern_count >= 1 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-concatenated-dynamic-command-invocation.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-concatenated-dynamic-command-invocation.asciidoc index 8490c91fe8..ca1a5cb43d 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-concatenated-dynamic-command-invocation.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-concatenated-dynamic-command-invocation.asciidoc @@ -28,7 +28,7 @@ Identifies PowerShell scripts that use concatenated strings within dynamic comma * Data Source: PowerShell Logs * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -113,19 +113,37 @@ reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" [source, js] ---------------------------------- -FROM logs-windows.powershell_operational* metadata _id, _version, _index -| WHERE event.code == "4104" and powershell.file.script_block_text LIKE "*+*" +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" and powershell.file.script_block_text like "*+*" -// Replace string format expressions with πŸ”₯ to enable counting the occurrence of the patterns we are looking for +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them // The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 -| EVAL replaced_with_fire = REPLACE(powershell.file.script_block_text, """[.&]\(\s*(['"][A-Za-z0-9.-]+['"]\s*\+\s*)+['"][A-Za-z0-9.-]+['"]\s*\)""", "πŸ”₯") - -// Count how many patterns were detected by calculating the number of πŸ”₯ characters inserted -| EVAL count = LENGTH(replaced_with_fire) - LENGTH(REPLACE(replaced_with_fire, "πŸ”₯", "")) - -// Keep the fields relevant to the query, although this is not needed as the alert is populated using _id -| KEEP count, replaced_with_fire, powershell.file.script_block_text, powershell.file.script_block_id, file.path, powershell.sequence, powershell.total, _id, _index, host.name, agent.id, user.id -| WHERE count >= 1 +| eval Esql.script_block_tmp = replace( + powershell.file.script_block_text, + """[.&]\(\s*(['"][A-Za-z0-9.-]+['"]\s*\+\s*)+['"][A-Za-z0-9.-]+['"]\s*\)""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least once +| where Esql.script_block_pattern_count >= 1 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-high-numeric-character-proportion.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-high-numeric-character-proportion.asciidoc index 574275aacd..5356bf66d1 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-high-numeric-character-proportion.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-high-numeric-character-proportion.asciidoc @@ -28,7 +28,7 @@ Identifies PowerShell scripts with a disproportionately high number of numeric c * Data Source: PowerShell Logs * Resources: Investigation Guide -*Version*: 3 +*Version*: 4 *Rule authors*: @@ -113,30 +113,45 @@ reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" [source, js] ---------------------------------- -FROM logs-windows.powershell_operational* metadata _id, _version, _index -| WHERE event.code == "4104" +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" -// Look for scripts with more than 1000 chars that contain a related keyword -| EVAL script_len = LENGTH(powershell.file.script_block_text) -| WHERE script_len > 1000 +// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for +| eval Esql.script_block_length = length(powershell.file.script_block_text) +| where Esql.script_block_length > 1000 -// Replace string format expressions with πŸ”₯ to enable counting the occurrence of the patterns we are looking for +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them // The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 -| EVAL replaced_with_fire = REPLACE(powershell.file.script_block_text, """[0-9]""", "πŸ”₯") - -// Count the occurrence of numbers and their proportion to the total chars in the script -| EVAL special_count = script_len - LENGTH(REPLACE(replaced_with_fire, "πŸ”₯", "")) -| EVAL proportion = special_count::double / script_len::double - -// Keep the fields relevant to the query, although this is not needed as the alert is populated using _id -| KEEP special_count, script_len, proportion, replaced_with_fire, powershell.file.script_block_text, powershell.file.script_block_id, file.path, powershell.sequence, powershell.total, _id, _index, host.name, agent.id, user.id - -// Filter for scripts with a 30%+ proportion of numbers -| WHERE proportion > 0.30 - -// Exclude noisy patterns -| WHERE - NOT powershell.file.script_block_text RLIKE """.*\"[a-fA-F0-9]{64}\"\,.*""" +| eval Esql.script_block_tmp = replace(powershell.file.script_block_text, """[0-9]""", "πŸ”₯") + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = Esql.script_block_length - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// Calculate the ratio of special characters to total length +| eval Esql.script_block_ratio = Esql.script_block_pattern_count::double / Esql.script_block_length::double + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_ratio, + Esql.script_block_length, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts with high numeric character ratio +| where Esql.script_block_ratio > 0.30 + +// Exclude noisy patterns such as 64-character hash lists +| where not powershell.file.script_block_text rlike """.*\"[a-fA-F0-9]{64}\"\,.*""" ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-high-special-character-proportion.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-high-special-character-proportion.asciidoc index fc3711aa29..6e3016a591 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-high-special-character-proportion.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-high-special-character-proportion.asciidoc @@ -28,7 +28,7 @@ Identifies PowerShell scripts with an abnormally high proportion of non-alphanum * Data Source: PowerShell Logs * Rule Type: BBR -*Version*: 1 +*Version*: 2 *Rule authors*: @@ -66,27 +66,43 @@ reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" [source, js] ---------------------------------- -FROM logs-windows.powershell_operational* metadata _id, _version, _index -| WHERE event.code == "4104" +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" -// Look for scripts with more than 1000 chars that contain a related keyword -| EVAL script_len = LENGTH(powershell.file.script_block_text) -| WHERE script_len > 1000 +// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for +| eval Esql.script_block_length = length(powershell.file.script_block_text) +| where Esql.script_block_length > 1000 -// Replace string format expressions with πŸ”₯ to enable counting the occurrence of the patterns we are looking for +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them // The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 // Excludes spaces, #, = and - as they are heavily used in scripts for formatting -| EVAL replaced_with_fire = REPLACE(powershell.file.script_block_text, """[^0-9A-Za-z\s#=-]""", "πŸ”₯") - -// Count the occurrence of special chars and their proportion to the total chars in the script -| EVAL special_count = script_len - LENGTH(REPLACE(replaced_with_fire, "πŸ”₯", "")) -| EVAL proportion = special_count::double / script_len::double - -// Keep the fields relevant to the query, although this is not needed as the alert is populated using _id -| KEEP special_count, script_len, proportion, replaced_with_fire, powershell.file.script_block_text, powershell.file.script_block_id, file.path, powershell.sequence, powershell.total, _id, _index, host.name, agent.id, user.id - -// Filter for scripts with a 25%+ proportion of special chars -| WHERE proportion > 0.25 +| eval Esql.script_block_tmp = replace(powershell.file.script_block_text, """[^0-9A-Za-z\s#=-]""", "πŸ”₯") + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = Esql.script_block_length - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// Calculate the ratio of special characters to total length +| eval Esql.script_block_ratio = Esql.script_block_pattern_count::double / Esql.script_block_length::double + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_length, + Esql.script_block_ratio, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts with high special character ratio +| where Esql.script_block_ratio > 0.25 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-invalid-escape-sequences.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-invalid-escape-sequences.asciidoc index 4c79d89362..b3a2845e96 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-invalid-escape-sequences.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-invalid-escape-sequences.asciidoc @@ -28,7 +28,7 @@ Identifies PowerShell scripts that use invalid escape sequences as a form of obf * Data Source: PowerShell Logs * Resources: Investigation Guide -*Version*: 3 +*Version*: 4 *Rule authors*: @@ -119,26 +119,40 @@ reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" [source, js] ---------------------------------- -FROM logs-windows.powershell_operational* metadata _id, _version, _index -| WHERE event.code == "4104" and powershell.file.script_block_text LIKE "*`*" +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" and powershell.file.script_block_text like "*`*" -// Replace string format expressions with πŸ”₯ to enable counting the occurrence of the patterns we are looking for +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them // The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 -| EVAL replaced_with_fire = REPLACE(powershell.file.script_block_text, """[A-Za-z0-9_-]`(?![rntb]|\r|\n|\d)[A-Za-z0-9_-]""", "πŸ”₯") - -// Count how many patterns were detected by calculating the number of πŸ”₯ characters inserted -| EVAL count = LENGTH(replaced_with_fire) - LENGTH(REPLACE(replaced_with_fire, "πŸ”₯", "")) - -// Keep the fields relevant to the query, although this is not needed as the alert is populated using _id -| KEEP count, replaced_with_fire, powershell.file.script_block_text, powershell.file.script_block_id, file.name, file.path, powershell.sequence, powershell.total, _id, _index, host.name, agent.id, user.id -| WHERE count >= 10 - -// Filter FPs, and due to the behavior of the LIKE operator, allow null values -| WHERE (file.name NOT LIKE "TSS_*.psm1" or file.name IS NULL) - -| WHERE - // VSCode Shell integration - NOT powershell.file.script_block_text LIKE "*$([char]0x1b)]633*" +| eval Esql.script_block_tmp = replace(powershell.file.script_block_text, """[A-Za-z0-9_-]`(?![rntb]|\r|\n|\d)[A-Za-z0-9_-]""", "πŸ”₯") + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.name, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least 10 times +| where Esql.script_block_pattern_count >= 10 + +// Filter FPs, and due to the behavior of the like operator, allow null values +| where (file.name not like "TSS_*.psm1" or file.name is null) + +// VSCode Shell integration +| where not powershell.file.script_block_text like "*$([char]0x1b)]633*" ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-reverse-keywords.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-reverse-keywords.asciidoc index 5fbbcb30dd..af5636812e 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-reverse-keywords.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-reverse-keywords.asciidoc @@ -28,7 +28,7 @@ Identifies PowerShell scripts that use reversed strings as a form of obfuscation * Data Source: PowerShell Logs * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -113,22 +113,39 @@ reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" [source, js] ---------------------------------- -FROM logs-windows.powershell_operational* metadata _id, _version, _index -| WHERE event.code == "4104" +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" -// Filter for scripts that contains these keywords using MATCH, boosts the query performance, match will ignore the | and look for the individual words -| WHERE powershell.file.script_block_text : "rahc|metsys|stekcos|tcejboimw|ecalper|ecnerferpe|noitcennoc|nioj|eman|vne|gnirts|tcejbo-wen|_23niw|noisserpxe|ekovni|daolnwod" +// Filter for scripts that contains these keywords using MATCH, boosts the query performance, +// match will ignore the | and look for the individual words +| where powershell.file.script_block_text : "rahc|metsys|stekcos|tcejboimw|ecalper|ecnerferpe|noitcennoc|nioj|eman|vne|gnirts|tcejbo-wen|_23niw|noisserpxe|ekovni|daolnwod" -// Replace string format expressions with πŸ”₯ to enable counting the occurrence of the patterns we are looking for +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them // The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 -| EVAL replaced_with_fire = REPLACE(powershell.file.script_block_text, """(?i)(rahc|metsys|stekcos|tcejboimw|ecalper|ecnerferpe|noitcennoc|nioj|eman\.|:vne|gnirts|tcejbo-wen|_23niw|noisserpxe|ekovni|daolnwod)""", "πŸ”₯") - -// Count how many patterns were detected by calculating the number of πŸ”₯ characters inserted -| EVAL count = LENGTH(replaced_with_fire) - LENGTH(REPLACE(replaced_with_fire, "πŸ”₯", "")) - -// Keep the fields relevant to the query, although this is not needed as the alert is populated using _id -| KEEP count, replaced_with_fire, powershell.file.script_block_text, powershell.file.script_block_id, file.path, powershell.sequence, powershell.total, _id, _index, agent.id -| WHERE count >= 2 +| eval Esql.script_block_tmp = replace( + powershell.file.script_block_text, + """(?i)(rahc|metsys|stekcos|tcejboimw|ecalper|ecnerferpe|noitcennoc|nioj|eman\.|:vne|gnirts|tcejbo-wen|_23niw|noisserpxe|ekovni|daolnwod)""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + agent.id + +// Filter for scripts that match the pattern at least twice +| where Esql.script_block_pattern_count >= 2 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-special-character-overuse.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-special-character-overuse.asciidoc index 3bd7458649..626e1542c2 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-special-character-overuse.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-special-character-overuse.asciidoc @@ -28,7 +28,7 @@ Identifies PowerShell scripts with an unusually high proportion of whitespace an * Data Source: PowerShell Logs * Resources: Investigation Guide -*Version*: 3 +*Version*: 4 *Rule authors*: @@ -113,29 +113,49 @@ reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" [source, js] ---------------------------------- -FROM logs-windows.powershell_operational* metadata _id, _version, _index -| WHERE event.code == "4104" +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" -// Replace repeated spaces used for formatting after a new line with a single space to reduce FPs -| EVAL dedup_space_script_block = REPLACE(powershell.file.script_block_text, """\n\s+""", "\n ") +// replace repeated spaces used for formatting after a new line with a single space to reduce FPs +| eval Esql.script_block_tmp = replace(powershell.file.script_block_text, """\n\s+""", "\n ") -// Look for scripts with more than 1000 chars that contain a related keyword -| EVAL script_len = LENGTH(dedup_space_script_block) -| WHERE script_len > 1000 +// Look for scripts with more than 1000 chars +| eval Esql.script_block_length = length(Esql.script_block_tmp) +| where Esql.script_block_length > 1000 -// Replace string format expressions with πŸ”₯ to enable counting the occurrence of the patterns we are looking for +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them // The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 -| EVAL replaced_with_fire = REPLACE(dedup_space_script_block, """[\s\$\{\}\+\@\=\(\)\^\\\"~\[\]\?\.]""", "πŸ”₯") - -// Count the occurrence of numbers and their proportion to the total chars in the script -| EVAL special_count = script_len - LENGTH(REPLACE(replaced_with_fire, "πŸ”₯", "")) -| EVAL proportion = special_count::double / script_len::double - -// Keep the fields relevant to the query, although this is not needed as the alert is populated using _id -| KEEP special_count, script_len, proportion, dedup_space_script_block, replaced_with_fire, powershell.file.script_block_text, powershell.file.script_block_id, file.path, powershell.sequence, powershell.total, _id, _index, host.name, agent.id, user.id - -// Filter for scripts with a 75%+ proportion of numbers -| WHERE proportion > 0.75 +| eval Esql.script_block_tmp = replace( + Esql.script_block_tmp, + """[\s\$\{\}\+\@\=\(\)\^\\\"~\[\]\?\.]""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_count = Esql.script_block_length - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// Calculate the ratio of special characters to total length +| eval Esql.script_block_ratio = Esql.script_block_count::double / Esql.script_block_length::double + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_count, + Esql.script_block_length, + Esql.script_block_ratio, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts with high whitespace and special character ratio +| where Esql.script_block_ratio > 0.75 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-string-concatenation.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-string-concatenation.asciidoc index 87059c1af2..13da416521 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-string-concatenation.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-string-concatenation.asciidoc @@ -28,7 +28,7 @@ Identifies PowerShell scripts that use string concatenation as a form of obfusca * Data Source: PowerShell Logs * Resources: Investigation Guide -*Version*: 3 +*Version*: 4 *Rule authors*: @@ -114,23 +114,42 @@ reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" [source, js] ---------------------------------- -FROM logs-windows.powershell_operational* metadata _id, _version, _index -| WHERE event.code == "4104" +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" -// Look for scripts with more than 500 chars that contain a related keyword -| EVAL script_len = LENGTH(powershell.file.script_block_text) -| WHERE script_len > 500 +// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for +| eval Esql.script_block_length = length(powershell.file.script_block_text) +| where Esql.script_block_length > 500 -// Replace string format expressions with πŸ”₯ to enable counting the occurrence of the patterns we are looking for +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them // The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 -| EVAL replaced_with_fire = REPLACE(powershell.file.script_block_text, """['"][A-Za-z0-9.]+['"](\s?\+\s?['"][A-Za-z0-9.,\-\s]+['"]){2,}""", "πŸ”₯") - -// Count how many patterns were detected by calculating the number of πŸ”₯ characters inserted -| EVAL count = LENGTH(replaced_with_fire) - LENGTH(REPLACE(replaced_with_fire, "πŸ”₯", "")) - -// Keep the fields relevant to the query, although this is not needed as the alert is populated using _id -| KEEP count, replaced_with_fire, powershell.file.script_block_text, powershell.file.script_block_id, file.path, powershell.sequence, powershell.total, _id, _index, host.name, agent.id, user.id -| WHERE count >= 2 +| eval Esql.script_block_tmp = replace( + powershell.file.script_block_text, + """['"][A-Za-z0-9.]+['"](\s?\+\s?['"][A-Za-z0-9.,\-\s]+['"]){2,}""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_length, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least twice +| where Esql.script_block_pattern_count >= 2 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-string-reordering.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-string-reordering.asciidoc index 347f995589..7e33e902da 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-string-reordering.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-powershell-obfuscation-via-string-reordering.asciidoc @@ -28,7 +28,7 @@ Identifies PowerShell scripts that use string reordering and runtime reconstruct * Data Source: PowerShell Logs * Resources: Investigation Guide -*Version*: 4 +*Version*: 5 *Rule authors*: @@ -112,37 +112,57 @@ reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" [source, js] ---------------------------------- -FROM logs-windows.powershell_operational* metadata _id, _version, _index -| WHERE event.code == "4104" +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" and powershell.file.script_block_text like "*{0}*" -// Look for scripts with more than 500 chars that contain a related keyword -| EVAL script_len = LENGTH(powershell.file.script_block_text) -| WHERE script_len > 500 -| WHERE powershell.file.script_block_text LIKE "*{0}*" +// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for +| eval Esql.script_block_length = length(powershell.file.script_block_text) +| where Esql.script_block_length > 500 -// Replace string format expressions with πŸ”₯ to enable counting the occurrence of the patterns we are looking for +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them // The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 -| EVAL replaced_with_fire = REPLACE(powershell.file.script_block_text, """((\{\d+\}){2,}["']\s?-f|::Format[^\{]+(\{\d+\}){2,})""", "πŸ”₯") - -// Count how many patterns were detected by calculating the number of πŸ”₯ characters inserted -| EVAL count = LENGTH(replaced_with_fire) - LENGTH(REPLACE(replaced_with_fire, "πŸ”₯", "")) - -// Keep the fields relevant to the query, although this is not needed as the alert is populated using _id -| KEEP count, replaced_with_fire, powershell.file.script_block_text, powershell.file.script_block_id, file.path, powershell.sequence, powershell.total, _id, _index, host.name, agent.id, user.id -| WHERE count > 3 +| eval Esql.script_block_tmp = replace( + powershell.file.script_block_text, + """((\{\d+\}){2,}["']\s?-f|::Format[^\{]+(\{\d+\}){2,})""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_length, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + file.name, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least four times +| where Esql.script_block_pattern_count >= 4 // Exclude Noisy Patterns // Icinga Framework -| WHERE (file.name NOT LIKE "framework_cache.psm1" or file.name IS NULL) -| WHERE NOT +| where (file.name not like "framework_cache.psm1" or file.name is null) + +| where not // https://wtfbins.wtf/17 ( - (powershell.file.script_block_text LIKE "*sentinelbreakpoints*" OR - powershell.file.script_block_text LIKE "*:::::\\\\windows\\\\sentinel*") - AND - (powershell.file.script_block_text LIKE "*$local:Bypassed*" OR - powershell.file.script_block_text LIKE "*origPSExecutionPolicyPreference*") + (powershell.file.script_block_text like "*sentinelbreakpoints*" or + powershell.file.script_block_text like "*:::::\\\\windows\\\\sentinel*") + and + (powershell.file.script_block_text like "*$local:Bypassed*" or + powershell.file.script_block_text like "*origPSExecutionPolicyPreference*") ) ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-subnet-scanning-activity-from-compromised-host.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-subnet-scanning-activity-from-compromised-host.asciidoc index a60263093e..1408df4603 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-subnet-scanning-activity-from-compromised-host.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-subnet-scanning-activity-from-compromised-host.asciidoc @@ -28,7 +28,7 @@ This rule detects potential subnet scanning activity from a compromised host. Su * Data Source: Elastic Defend * Resources: Investigation Guide -*Version*: 4 +*Version*: 5 *Rule authors*: @@ -128,11 +128,22 @@ For more details on Elastic Defend refer to the https://www.elastic.co/guide/en/ ---------------------------------- from logs-endpoint.events.network-* | keep @timestamp, host.os.type, event.type, event.action, process.executable, destination.ip, agent.id, host.name -| where @timestamp > now() - 1 hours -| where host.os.type == "linux" and event.type == "start" and event.action == "connection_attempted" -| stats cc = count(), dest_count = count_distinct(destination.ip), agent_count = count_distinct(agent.id), host.name = VALUES(host.name), agent.id = VALUES(agent.id) by process.executable -| where agent_count == 1 and dest_count > 250 -| sort cc asc +| where + @timestamp > now() - 1 hours and + host.os.type == "linux" and + event.type == "start" and + event.action == "connection_attempted" +| stats + Esql.event_count = count(), + Esql.destination_ip_count_distinct = count_distinct(destination.ip), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.executable +| where + Esql.agent_id_count_distinct == 1 and + Esql.destination_ip_count_distinct > 250 +| sort Esql.event_count asc | limit 100 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/potential-widespread-malware-infection-across-multiple-hosts.asciidoc b/docs/detections/prebuilt-rules/rule-details/potential-widespread-malware-infection-across-multiple-hosts.asciidoc index ed77cd131f..3e8987f316 100644 --- a/docs/detections/prebuilt-rules/rule-details/potential-widespread-malware-infection-across-multiple-hosts.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/potential-widespread-malware-infection-across-multiple-hosts.asciidoc @@ -30,7 +30,7 @@ This rule uses alert data to determine when a malware signature is triggered in * Rule Type: Higher-Order Rule * Resources: Investigation Guide -*Version*: 3 +*Version*: 4 *Rule authors*: @@ -96,8 +96,8 @@ Endpoint security technologies monitor and analyze activities on devices to dete from logs-endpoint.alerts-* | where event.code in ("malicious_file", "memory_signature", "shellcode_thread") and rule.name is not null | keep host.id, rule.name, event.code -| stats hosts = count_distinct(host.id) by rule.name, event.code -| where hosts >= 3 +| stats Esql.host_id_count_distinct = count_distinct(host.id) by rule.name, event.code +| where Esql.host_id_count_distinct >= 3 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/powershell-obfuscation-via-negative-index-string-reversal.asciidoc b/docs/detections/prebuilt-rules/rule-details/powershell-obfuscation-via-negative-index-string-reversal.asciidoc index a8f1030678..a7671128b7 100644 --- a/docs/detections/prebuilt-rules/rule-details/powershell-obfuscation-via-negative-index-string-reversal.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/powershell-obfuscation-via-negative-index-string-reversal.asciidoc @@ -28,7 +28,7 @@ Identifies PowerShell scripts that use negative index ranges to reverse the cont * Data Source: PowerShell Logs * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -114,26 +114,45 @@ reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" [source, js] ---------------------------------- -FROM logs-windows.powershell_operational* metadata _id, _version, _index -| WHERE event.code == "4104" +from logs-windows.powershell_operational* metadata _id, _version, _index +| where event.code == "4104" -// Look for scripts with more than 500 chars that contain a related keyword -| EVAL script_len = LENGTH(powershell.file.script_block_text) -| WHERE script_len > 500 +// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for +| eval Esql.script_block_length = length(powershell.file.script_block_text) +| where Esql.script_block_length > 500 -// Replace string format expressions with πŸ”₯ to enable counting the occurrence of the patterns we are looking for +// replace the patterns we are looking for with the πŸ”₯ emoji to enable counting them // The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 -| EVAL replaced_with_fire = REPLACE(powershell.file.script_block_text, """\$\w+\[\-\s?1\.\.""", "πŸ”₯") - -// Count how many patterns were detected by calculating the number of πŸ”₯ characters inserted -| EVAL count = LENGTH(replaced_with_fire) - LENGTH(REPLACE(replaced_with_fire, "πŸ”₯", "")) - -// Keep the fields relevant to the query, although this is not needed as the alert is populated using _id -| KEEP count, replaced_with_fire, powershell.file.script_block_text, powershell.file.script_block_id, file.path, powershell.sequence, powershell.total, _id, _index, host.name, agent.id, user.id -| WHERE count >= 1 +| eval Esql.script_block_tmp = replace( + powershell.file.script_block_text, + """\$\w+\[\-\s?1\.\.""", + "πŸ”₯" +) + +// count how many patterns were detected by calculating the number of πŸ”₯ characters inserted +| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "πŸ”₯", "")) + +// keep the fields relevant to the query, although this is not needed as the alert is populated using _id +| keep + Esql.script_block_pattern_count, + Esql.script_block_length, + Esql.script_block_tmp, + powershell.file.script_block_text, + powershell.file.script_block_id, + file.path, + powershell.sequence, + powershell.total, + _id, + _index, + host.name, + agent.id, + user.id + +// Filter for scripts that match the pattern at least once +| where Esql.script_block_pattern_count >= 1 // FP Patterns -| WHERE NOT powershell.file.script_block_text LIKE "*GENESIS-5654*" +| where not powershell.file.script_block_text like "*GENESIS-5654*" ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/rare-connection-to-webdav-target.asciidoc b/docs/detections/prebuilt-rules/rule-details/rare-connection-to-webdav-target.asciidoc index f865ae7bec..6c4eff1fc8 100644 --- a/docs/detections/prebuilt-rules/rule-details/rare-connection-to-webdav-target.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/rare-connection-to-webdav-target.asciidoc @@ -33,7 +33,7 @@ Identifies rare connection attempts to a Web Distributed Authoring and Versionin * Data Source: Crowdstrike * Resources: Investigation Guide -*Version*: 1 +*Version*: 2 *Rule authors*: @@ -81,15 +81,32 @@ Identifies rare connection attempts to a Web Distributed Authoring and Versionin [source, js] ---------------------------------- -FROM logs-* -| where @timestamp > NOW() - 8 hours -| WHERE event.category == "process" and event.type == "start" and process.name == "rundll32.exe" and process.command_line like "*DavSetCookie*" +from logs-* +| where + @timestamp > now() - 8 hours and + event.category == "process" and + event.type == "start" and + process.name == "rundll32.exe" and + process.command_line like "*DavSetCookie*" | keep host.id, process.command_line, user.name -| grok process.command_line """(?DavSetCookie .* http)""" -| eval webdav_target = REPLACE(target, "(DavSetCookie | http)", "") -| where webdav_target is not null and webdav_target rlike """(([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,3}(@SSL.*)*|(\d{1,3}\.){3}\d{1,3})""" and not webdav_target in ("www.google.com@SSL", "www.elastic.co@SSL") and not webdav_target rlike """(10\.(\d{1,3}\.){2}\d{1,3}|172\.(1[6-9]|2\d|3[0-1])\.(\d{1,3}\.)\d{1,3}|192\.168\.(\d{1,3}\.)\d{1,3})""" -| stats total = count(*), unique_count_host = count_distinct(host.id), hosts = VALUES(host.id), users = VALUES(user.name) by webdav_target -| where unique_count_host == 1 and total <= 3 +| grok + process.command_line """(?DavSetCookie .* http)""" +| eval + Esql.server_webdav_cookie_replace = replace(Esql.server_webdav_cookie, "(DavSetCookie | http)", "") +| where + Esql.server_webdav_cookie_replace is not null and + Esql.server_webdav_cookie_replace rlike """(([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,3}(@SSL.*)*|(\d{1,3}\.){3}\d{1,3})""" and + not Esql.server_webdav_cookie_replace in ("www.google.com@SSL", "www.elastic.co@SSL") and + not Esql.server_webdav_cookie_replace rlike """(10\.(\d{1,3}\.){2}\d{1,3}|172\.(1[6-9]|2\d|3[0-1])\.(\d{1,3}\.)\d{1,3}|192\.168\.(\d{1,3}\.)\d{1,3})""" +| stats + Esql.event_count = count(*), + Esql.host_id_count_distinct = count_distinct(host.id), + Esql.host_id_values = values(host.id), + Esql.user_name_values = values(user.name) + by Esql.server_webdav_cookie_replace +| where + Esql.host_id_count_distinct == 1 and + Esql.event_count <= 3 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/suspicious-microsoft-365-userloggedin-via-oauth-code.asciidoc b/docs/detections/prebuilt-rules/rule-details/suspicious-microsoft-365-userloggedin-via-oauth-code.asciidoc index aafdaf2d74..f601dbd53a 100644 --- a/docs/detections/prebuilt-rules/rule-details/suspicious-microsoft-365-userloggedin-via-oauth-code.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/suspicious-microsoft-365-userloggedin-via-oauth-code.asciidoc @@ -35,7 +35,7 @@ Identifies sign-ins on behalf of a principal user to the Microsoft Graph API fro * Resources: Investigation Guide * Tactic: Defense Evasion -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -99,43 +99,51 @@ The Office 365 Logs Fleet integration, Filebeat module, or similarly structured [source, js] ---------------------------------- from logs-o365.audit-* -| WHERE event.dataset == "o365.audit" and event.action == "UserLoggedIn" and - - // ensure source, application and user are not null - source.ip is not null and - o365.audit.UserId is not null and - o365.audit.ApplicationId is not null and - - // filter for user principals that are not service accounts - o365.audit.UserType in ("0", "2", "3", "10") and - - // filter for successful logon to Microsoft Graph and from the Microsoft Authentication Broker or Visual Studio Code - o365.audit.ApplicationId in ("aebc6443-996d-45c2-90f0-388ff96faa56", "29d9ed98-a469-4536-ade2-f981bc1d605e") and - o365.audit.ObjectId in ("00000003-0000-0000-c000-000000000000") - -// keep relevant fields only -| keep @timestamp, o365.audit.UserId, source.ip, o365.audit.ApplicationId, o365.audit.ObjectId, o365.audit.ExtendedProperties.RequestType, source.as.organization.name, o365.audit.ExtendedProperties.ResultStatusDetail - -// case statements to track which are OAuth2 authorization request via redirect and which are related to OAuth2 code to token conversion +| where + event.dataset == "o365.audit" and + event.action == "UserLoggedIn" and + source.ip is not null and + o365.audit.UserId is not null and + o365.audit.ApplicationId is not null and + o365.audit.UserType in ("0", "2", "3", "10") and + o365.audit.ApplicationId in ("aebc6443-996d-45c2-90f0-388ff96faa56", "29d9ed98-a469-4536-ade2-f981bc1d605e") and + o365.audit.ObjectId in ("00000003-0000-0000-c000-000000000000") | eval - oauth_authorize = case(o365.audit.ExtendedProperties.RequestType == "OAuth2:Authorize" and o365.audit.ExtendedProperties.ResultStatusDetail == "Redirect", o365.audit.UserId, null), - oauth_token = case(o365.audit.ExtendedProperties.RequestType == "OAuth2:Token", o365.audit.UserId, null) - -// split time to 30 minutes intervals -| eval target_time_window = DATE_TRUNC(30 minutes, @timestamp) - -// aggregate by principal, applicationId, objectId and time window + Esql.time_window_date_trunc = date_trunc(30 minutes, @timestamp), + Esql.oauth_authorize_user_id_case = case( + o365.audit.ExtendedProperties.RequestType == "OAuth2:Authorize" and o365.audit.ExtendedProperties.ResultStatusDetail == "Redirect", + o365.audit.UserId, + null + ), + Esql.oauth_token_user_id_case = case( + o365.audit.ExtendedProperties.RequestType == "OAuth2:Token", + o365.audit.UserId, + null + ) | stats - unique_ips = COUNT_DISTINCT(source.ip), - source_ips = VALUES(source.ip), - appIds = VALUES(o365.audit.ApplicationId), - asn = values(`source.as.organization.name`), - is_oauth_token = COUNT_DISTINCT(oauth_token), - is_oauth_authorize = COUNT_DISTINCT(oauth_authorize) -by o365.audit.UserId, target_time_window, o365.audit.ApplicationId, o365.audit.ObjectId - -// filter for cases where the same appId is used by the same principal user to access the same object and from multiple addresses via OAuth2 token -| where unique_ips >= 2 and is_oauth_authorize > 0 and is_oauth_token > 0 + Esql.source_ip_count_distinct = count_distinct(source.ip), + Esql.source_ip_values = values(source.ip), + Esql.o365_audit_ApplicationId_values = values(o365.audit.ApplicationId), + Esql.source_as_organization_name_values = values(source.`as`.organization.name), + Esql.oauth_token_count_distinct = count_distinct(Esql.oauth_token_user_id_case), + Esql.oauth_authorize_count_distinct = count_distinct(Esql.oauth_authorize_user_id_case) + by + o365.audit.UserId, + Esql.time_window_date_trunc, + o365.audit.ApplicationId, + o365.audit.ObjectId +| keep + Esql.time_window_date_trunc, + Esql.source_ip_values, + Esql.source_ip_count_distinct, + Esql.o365_audit_ApplicationId_values, + Esql.source_as_organization_name_values, + Esql.oauth_token_count_distinct, + Esql.oauth_authorize_count_distinct +| where + Esql.source_ip_count_distinct >= 2 and + Esql.oauth_token_count_distinct > 0 and + Esql.oauth_authorize_count_distinct > 0 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/suspicious-microsoft-oauth-flow-via-auth-broker-to-drs.asciidoc b/docs/detections/prebuilt-rules/rule-details/suspicious-microsoft-oauth-flow-via-auth-broker-to-drs.asciidoc index 5030bea37d..88ecfaff5f 100644 --- a/docs/detections/prebuilt-rules/rule-details/suspicious-microsoft-oauth-flow-via-auth-broker-to-drs.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/suspicious-microsoft-oauth-flow-via-auth-broker-to-drs.asciidoc @@ -35,7 +35,7 @@ Identifies separate OAuth authorization flows in Microsoft Entra ID where the sa * Resources: Investigation Guide * Tactic: Initial Access -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -109,95 +109,105 @@ This rule requires the Microsoft Entra ID Sign-In Logs integration be enabled an [source, js] ---------------------------------- -FROM logs-azure.signinlogs* metadata _id, _version, _index - -// Filter for Microsoft Entra ID sign-in logs -| WHERE event.dataset == "azure.signinlogs" - AND event.outcome == "success" - AND azure.signinlogs.properties.user_type == "Member" - AND azure.signinlogs.identity IS NOT NULL - AND azure.signinlogs.properties.user_principal_name IS NOT NULL - AND source.address IS NOT NULL - - // Filter for MAB as client (app_id) and DRS as resource (resource_id) - AND azure.signinlogs.properties.app_id == "29d9ed98-a469-4536-ade2-f981bc1d605e" // MAB - AND azure.signinlogs.properties.resource_id == "01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9" // DRS - -// Normalize timestamps into 30-minute detection windows -| EVAL target_time_window = DATE_TRUNC(30 minutes, @timestamp) - -// Tag browser-based requests and extract session ID -| EVAL - session_id = azure.signinlogs.properties.session_id, - is_browser = CASE( - TO_LOWER(azure.signinlogs.properties.device_detail.browser) RLIKE "(chrome|firefox|edge|safari).*", 1, 0 +from logs-azure.signinlogs* metadata _id, _version, _index +| where + event.dataset == "azure.signinlogs" and + event.outcome == "success" and + azure.signinlogs.properties.user_type == "Member" and + azure.signinlogs.identity is not null and + azure.signinlogs.properties.user_principal_name is not null and + source.address is not null and + azure.signinlogs.properties.app_id == "29d9ed98-a469-4536-ade2-f981bc1d605e" and // MAB + azure.signinlogs.properties.resource_id == "01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9" // DRS + +| eval + Esql.time_window_date_trunc = date_trunc(30 minutes, @timestamp), + Esql.azure_signinlogs_properties_session_id = azure.signinlogs.properties.session_id, + Esql.is_browser_case = case( + to_lower(azure.signinlogs.properties.device_detail.browser) rlike "(chrome|firefox|edge|safari).*", 1, 0 ) -| STATS - // user & session identity - user_display_name = VALUES(azure.signinlogs.properties.user_display_name), - user_principal_name = VALUES(azure.signinlogs.properties.user_principal_name), - session_id = VALUES(azure.signinlogs.properties.session_id), - unique_token_id = VALUES(azure.signinlogs.properties.unique_token_identifier), - - // geolocation - city_name = VALUES(source.geo.city_name), - country_name = VALUES(source.geo.country_name), - region_name = VALUES(source.geo.region_name), - source_ip = VALUES(source.address), - ip_count = COUNT_DISTINCT(source.address), - autonomous_system = VALUES(source.`as`.organization.name), - - // authentication context - auth_protocol = VALUES(azure.signinlogs.properties.authentication_protocol), - auth_requirement = VALUES(azure.signinlogs.properties.authentication_requirement), - is_interactive = VALUES(azure.signinlogs.properties.is_interactive), - - // token & app context - token_type = VALUES(azure.signinlogs.properties.incoming_token_type), - token_session_status = VALUES(azure.signinlogs.properties.token_protection_status_details.sign_in_session_status), - session_id_count = COUNT_DISTINCT(session_id), - client_app_display_name = VALUES(azure.signinlogs.properties.app_display_name), - client_app_ids = VALUES(azure.signinlogs.properties.app_id), - target_resource_ids = VALUES(azure.signinlogs.properties.resource_id), - target_resource_display_name = VALUES(azure.signinlogs.properties.resource_display_name), - - // tenant details - app_owner_tenant_id = VALUES(azure.signinlogs.properties.app_owner_tenant_id), - resource_owner_tenant_id = VALUES(azure.signinlogs.properties.resource_owner_tenant_id), - - // conditional access & risk signals - conditional_access_status = VALUES(azure.signinlogs.properties.conditional_access_status), - risk_state = VALUES(azure.signinlogs.properties.risk_state), - risk_level_aggregated = VALUES(azure.signinlogs.properties.risk_level_aggregated), - - // user agent & device - browser = VALUES(azure.signinlogs.properties.device_detail.browser), - os = VALUES(azure.signinlogs.properties.device_detail.operating_system), - user_agent = VALUES(user_agent.original), - has_browser = MAX(is_browser), - - auth_count = COUNT(*) -BY - target_time_window, +| stats + Esql_priv.azure_signinlogs_properties_user_display_name_values = values(azure.signinlogs.properties.user_display_name), + Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name), + Esql.azure_signinlogs_properties_session_id_values = values(azure.signinlogs.properties.session_id), + Esql.azure_signinlogs_properties_unique_token_identifier_values = values(azure.signinlogs.properties.unique_token_identifier), + + Esql.source_geo_city_name_values = values(source.geo.city_name), + Esql.source_geo_country_name_values = values(source.geo.country_name), + Esql.source_geo_region_name_values = values(source.geo.region_name), + Esql.source_address_values = values(source.address), + Esql.source_address_count_distinct = count_distinct(source.address), + Esql.source_as_organization_name_values = values(source.`as`.organization.name), + + Esql.azure_signinlogs_properties_authentication_protocol_values = values(azure.signinlogs.properties.authentication_protocol), + Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement), + Esql.azure_signinlogs_properties_is_interactive_values = values(azure.signinlogs.properties.is_interactive), + + Esql.azure_signinlogs_properties_incoming_token_type_values = values(azure.signinlogs.properties.incoming_token_type), + Esql.azure_signinlogs_properties_token_protection_status_details_sign_in_session_status_values = values(azure.signinlogs.properties.token_protection_status_details.sign_in_session_status), + Esql.azure_signinlogs_properties_session_id_count_distinct = count_distinct(azure.signinlogs.properties.session_id), + Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name), + Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id), + Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id), + Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name), + + Esql.azure_signinlogs_properties_app_owner_tenant_id_values = values(azure.signinlogs.properties.app_owner_tenant_id), + Esql.azure_signinlogs_properties_resource_owner_tenant_id_values = values(azure.signinlogs.properties.resource_owner_tenant_id), + + Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status), + Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state), + Esql.azure_signinlogs_properties_risk_level_aggregated_values = values(azure.signinlogs.properties.risk_level_aggregated), + + Esql.azure_signinlogs_properties_device_detail_browser_values = values(azure.signinlogs.properties.device_detail.browser), + Esql.azure_signinlogs_properties_device_detail_operating_system_values = values(azure.signinlogs.properties.device_detail.operating_system), + Esql.user_agent_original_values = values(user_agent.original), + Esql.is_browser_case_max = max(Esql.is_browser_case), + + Esql.event_count = count(*) + by + Esql.time_window_date_trunc, azure.signinlogs.properties.user_principal_name, - session_id - -| KEEP - target_time_window, user_display_name, user_principal_name, session_id, unique_token_id, - city_name, country_name, region_name, source_ip, ip_count, autonomous_system, - auth_protocol, auth_requirement, is_interactive, - token_type, token_session_status, session_id_count, client_app_display_name, - client_app_ids, target_resource_ids, target_resource_display_name, - app_owner_tenant_id, resource_owner_tenant_id, - conditional_access_status, risk_state, risk_level_aggregated, - browser, os, user_agent, has_browser, auth_count - -| WHERE - ip_count >= 2 AND - session_id_count == 1 AND - has_browser >= 1 AND - auth_count >= 2 + azure.signinlogs.properties.session_id + +| keep + Esql.time_window_date_trunc, + Esql_priv.azure_signinlogs_properties_user_display_name_values, + Esql_priv.azure_signinlogs_properties_user_principal_name_values, + Esql.azure_signinlogs_properties_session_id_values, + Esql.azure_signinlogs_properties_unique_token_identifier_values, + Esql.source_geo_city_name_values, + Esql.source_geo_country_name_values, + Esql.source_geo_region_name_values, + Esql.source_address_values, + Esql.source_address_count_distinct, + Esql.source_as_organization_name_values, + Esql.azure_signinlogs_properties_authentication_protocol_values, + Esql.azure_signinlogs_properties_authentication_requirement_values, + Esql.azure_signinlogs_properties_is_interactive_values, + Esql.azure_signinlogs_properties_incoming_token_type_values, + Esql.azure_signinlogs_properties_token_protection_status_details_sign_in_session_status_values, + Esql.azure_signinlogs_properties_session_id_count_distinct, + Esql.azure_signinlogs_properties_app_display_name_values, + Esql.azure_signinlogs_properties_app_id_values, + Esql.azure_signinlogs_properties_resource_id_values, + Esql.azure_signinlogs_properties_resource_display_name_values, + Esql.azure_signinlogs_properties_app_owner_tenant_id_values, + Esql.azure_signinlogs_properties_resource_owner_tenant_id_values, + Esql.azure_signinlogs_properties_conditional_access_status_values, + Esql.azure_signinlogs_properties_risk_state_values, + Esql.azure_signinlogs_properties_risk_level_aggregated_values, + Esql.azure_signinlogs_properties_device_detail_browser_values, + Esql.azure_signinlogs_properties_device_detail_operating_system_values, + Esql.user_agent_original_values, + Esql.is_browser_case_max, + Esql.event_count + +| where + Esql.source_address_count_distinct >= 2 and + Esql.azure_signinlogs_properties_session_id_count_distinct == 1 and + Esql.is_browser_case_max >= 1 and + Esql.event_count >= 2 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/unusual-base64-encoding-decoding-activity.asciidoc b/docs/detections/prebuilt-rules/rule-details/unusual-base64-encoding-decoding-activity.asciidoc index 86b1f9e594..8f92c0afea 100644 --- a/docs/detections/prebuilt-rules/rule-details/unusual-base64-encoding-decoding-activity.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/unusual-base64-encoding-decoding-activity.asciidoc @@ -28,7 +28,7 @@ This rule leverages ESQL to detect unusual base64 encoding/decoding activity on * Data Source: Elastic Defend * Resources: Investigation Guide -*Version*: 4 +*Version*: 5 *Rule authors*: @@ -131,21 +131,63 @@ For more details on Elastic Defend refer to the https://www.elastic.co/guide/en/ [source, js] ---------------------------------- from logs-endpoint.events.process-* -| keep @timestamp, host.os.type, event.type, event.action, process.name, process.args, process.command_line, agent.id, host.name -| where @timestamp > now() - 1 hours -| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and ( - (process.name in ("base64", "base64plain", "base64url", "base64mime", "base64pem", "base32", "base16") and process.command_line like "*-*d*") or - (process.name == "openssl" and process.args == "enc" and process.args in ("-d", "-base64", "-a")) or - (process.name like "python*" and - (process.args == "base64" and process.args in ("-d", "-u", "-t")) or - (process.args == "-c" and process.command_line like "*base64*" and process.command_line like "*b64decode*") - ) or - (process.name like "perl*" and process.command_line like "*decode_base64*") or - (process.name like "ruby*" and process.args == "-e" and process.command_line like "*Base64.decode64*") -) -| stats cc = count(), agent_count = count_distinct(agent.id), host.name = VALUES(host.name), agent.id = VALUES(agent.id) by process.name, process.command_line -| where agent_count == 1 and cc < 15 -| sort cc asc +| where + @timestamp > now() - 1h and + host.os.type == "linux" and + event.type == "start" and + event.action == "exec" and ( + ( + process.name in ("base64", "base64plain", "base64url", "base64mime", "base64pem", "base32", "base16") and + process.command_line like "*-*d*" + ) or + ( + process.name == "openssl" and + process.args == "enc" and + process.args in ("-d", "-base64", "-a") + ) or + ( + process.name like "python*" and ( + ( + process.args == "base64" and + process.args in ("-d", "-u", "-t") + ) or + ( + process.args == "-c" and + process.command_line like "*base64*" and + process.command_line like "*b64decode*" + ) + ) + ) or + ( + process.name like "perl*" and + process.command_line like "*decode_base64*" + ) or + ( + process.name like "ruby*" and + process.args == "-e" and + process.command_line like "*Base64.decode64*" + ) + ) +| keep + @timestamp, + host.os.type, + event.type, + event.action, + process.name, + process.args, + process.command_line, + agent.id, + host.name +| stats + Esql.event_count = count(), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.name, process.command_line +| where + Esql.agent_id_count_distinct == 1 and + Esql.event_count < 15 +| sort Esql.event_count asc | limit 100 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/unusual-command-execution-from-web-server-parent.asciidoc b/docs/detections/prebuilt-rules/rule-details/unusual-command-execution-from-web-server-parent.asciidoc index 273b376ce6..16ce762a69 100644 --- a/docs/detections/prebuilt-rules/rule-details/unusual-command-execution-from-web-server-parent.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/unusual-command-execution-from-web-server-parent.asciidoc @@ -30,7 +30,7 @@ This rule detects potential command execution from a web server parent process o * Data Source: Elastic Defend * Resources: Investigation Guide -*Version*: 4 +*Version*: 5 *Rule authors*: @@ -136,35 +136,58 @@ For more details on Elastic Defend refer to the https://www.elastic.co/guide/en/ [source, js] ---------------------------------- from logs-endpoint.events.process-* -| keep @timestamp, host.os.type, event.type, event.action, process.parent.name, user.name, user.id, process.working_directory, process.name, process.command_line, process.parent.executable, agent.id, host.name -| where @timestamp > now() - 1 hours -| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and ( - process.parent.name in ( - "apache", "nginx", "apache2", "httpd", "lighttpd", "caddy", "node", "mongrel_rails", "java", "gunicorn", - "uwsgi", "openresty", "cherokee", "h2o", "resin", "puma", "unicorn", "traefik", "tornado", "hypercorn", - "daphne", "twistd", "yaws", "webfsd", "httpd.worker", "flask", "rails", "mongrel" - ) or - process.parent.name like "php-*" or - process.parent.name like "python*" or - process.parent.name like "ruby*" or - process.parent.name like "perl*" or - user.name in ( - "apache", "www-data", "httpd", "nginx", "lighttpd", "tomcat", "tomcat8", "tomcat9", "ftp", "ftpuser", "ftpd" - ) or - user.id in ("99", "33", "498", "48") or - process.working_directory like "/var/www/*" -) and - process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and process.command_line like "* -c *" and - not ( - process.working_directory like "/home/*" or - process.working_directory like "/" or - process.working_directory like "/vscode/vscode-server/*" or - process.parent.executable like "/vscode/vscode-server/*" or - process.parent.executable == "/usr/bin/xfce4-terminal" -) -| stats cc = count(), agent_count = count_distinct(agent.id), host.name = VALUES(host.name), agent.id = VALUES(agent.id) by process.command_line, process.working_directory, process.parent.executable -| where agent_count == 1 and cc < 5 -| sort cc asc +| keep + @timestamp, + host.os.type, + event.type, + event.action, + process.parent.name, + user.name, + user.id, + process.working_directory, + process.name, + process.command_line, + process.parent.executable, + agent.id, + host.name +| where + @timestamp > now() - 1 hours and + host.os.type == "linux" and + event.type == "start" and + event.action == "exec" and ( + process.parent.name in ( + "apache", "nginx", "apache2", "httpd", "lighttpd", "caddy", "node", "mongrel_rails", "java", "gunicorn", + "uwsgi", "openresty", "cherokee", "h2o", "resin", "puma", "unicorn", "traefik", "tornado", "hypercorn", + "daphne", "twistd", "yaws", "webfsd", "httpd.worker", "flask", "rails", "mongrel" + ) or + process.parent.name like "php-*" or + process.parent.name like "python*" or + process.parent.name like "ruby*" or + process.parent.name like "perl*" or + user.name in ( + "apache", "www-data", "httpd", "nginx", "lighttpd", "tomcat", "tomcat8", "tomcat9", "ftp", "ftpuser", "ftpd" + ) or + user.id in ("99", "33", "498", "48") or + process.working_directory like "/var/www/*" + ) and + process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and + process.command_line like "* -c *" and not ( + process.working_directory like "/home/*" or + process.working_directory == "/" or + process.working_directory like "/vscode/vscode-server/*" or + process.parent.executable like "/vscode/vscode-server/*" or + process.parent.executable == "/usr/bin/xfce4-terminal" + ) +| stats + Esql.event_count = count(), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.command_line, process.working_directory, process.parent.executable +| where + Esql.agent_id_count_distinct == 1 and + Esql.event_count < 5 +| sort Esql.event_count asc | limit 100 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/unusual-file-creation-by-web-server.asciidoc b/docs/detections/prebuilt-rules/rule-details/unusual-file-creation-by-web-server.asciidoc index 019b521415..0699a8ca75 100644 --- a/docs/detections/prebuilt-rules/rule-details/unusual-file-creation-by-web-server.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/unusual-file-creation-by-web-server.asciidoc @@ -30,7 +30,7 @@ This rule detects unusual file creations from a web server parent process. Adver * Data Source: Elastic Defend * Rule Type: BBR -*Version*: 3 +*Version*: 4 *Rule authors*: @@ -82,27 +82,48 @@ For more details on Elastic Defend refer to the https://www.elastic.co/guide/en/ [source, js] ---------------------------------- from logs-endpoint.events.file-* -| keep @timestamp, host.os.type, event.type, event.action, user.name, user.id, process.name, process.executable, file.path, agent.id, host.name -| where @timestamp > now() - 1 hours -| where host.os.type == "linux" and event.type == "change" and event.action in ("rename", "creation") and ( - user.name in ( - "apache", "www-data", "httpd", "nginx", "lighttpd", "tomcat", "tomcat8", "tomcat9", "ftp", "ftpuser", "ftpd" - ) or - user.id in ("99", "33", "498", "48") - ) and ( - process.name in ( - "apache", "nginx", "apache2", "httpd", "lighttpd", "caddy", "node", "mongrel_rails", "java", "gunicorn", - "uwsgi", "openresty", "cherokee", "h2o", "resin", "puma", "unicorn", "traefik", "tornado", "hypercorn", - "daphne", "twistd", "yaws", "webfsd", "httpd.worker", "flask", "rails", "mongrel" - ) or - process.name like "php-*" or - process.name like "python*" or - process.name like "ruby*" or - process.name like "perl*" - ) -| stats cc = count(), agent_count = count_distinct(agent.id), host.name = VALUES(host.name), agent.id = VALUES(agent.id) by process.executable, file.path -| where agent_count == 1 and cc < 5 -| sort cc asc +| keep + @timestamp, + host.os.type, + event.type, + event.action, + user.name, + user.id, + process.name, + process.executable, + file.path, + agent.id, + host.name +| where + @timestamp > now() - 1 hours and + host.os.type == "linux" and + event.type == "change" and + event.action in ("rename", "creation") and ( + user.name in ( + "apache", "www-data", "httpd", "nginx", "lighttpd", "tomcat", "tomcat8", "tomcat9", "ftp", "ftpuser", "ftpd" + ) or + user.id in ("99", "33", "498", "48") + ) and ( + process.name in ( + "apache", "nginx", "apache2", "httpd", "lighttpd", "caddy", "node", "mongrel_rails", "java", "gunicorn", + "uwsgi", "openresty", "cherokee", "h2o", "resin", "puma", "unicorn", "traefik", "tornado", "hypercorn", + "daphne", "twistd", "yaws", "webfsd", "httpd.worker", "flask", "rails", "mongrel" + ) or + process.name like "php-*" or + process.name like "python*" or + process.name like "ruby*" or + process.name like "perl*" + ) +| stats + Esql.event_count = count(), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.executable, file.path +| where + Esql.agent_id_count_distinct == 1 and + Esql.event_count < 5 +| sort Esql.event_count asc | limit 100 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/unusual-file-transfer-utility-launched.asciidoc b/docs/detections/prebuilt-rules/rule-details/unusual-file-transfer-utility-launched.asciidoc index 5e51cd6dc7..41d2bff6ca 100644 --- a/docs/detections/prebuilt-rules/rule-details/unusual-file-transfer-utility-launched.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/unusual-file-transfer-utility-launched.asciidoc @@ -29,7 +29,7 @@ This rule leverages ESQL to detect the execution of unusual file transfer utilit * Data Source: Elastic Defend * Resources: Investigation Guide -*Version*: 4 +*Version*: 5 *Rule authors*: @@ -130,12 +130,22 @@ For more details on Elastic Defend refer to the https://www.elastic.co/guide/en/ ---------------------------------- from logs-endpoint.events.process-* | keep @timestamp, host.os.type, event.type, event.action, process.name, process.executable, process.parent.executable, process.command_line, agent.id, host.name -| where @timestamp > now() - 1 hours -| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and - process.name in ("scp", "ftp", "sftp", "vsftpd", "sftp-server", "rsync") -| stats cc = count(), agent_count = count_distinct(agent.id), host.name = VALUES(host.name), agent.id = VALUES(agent.id) by process.executable, process.parent.executable, process.command_line -| where agent_count == 1 and cc < 5 -| sort cc asc +| where + @timestamp > now() - 1 hours and + host.os.type == "linux" and + event.type == "start" and + event.action == "exec" and + process.name in ("scp", "ftp", "sftp", "vsftpd", "sftp-server", "rsync") +| stats + Esql.event_count = count(), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.executable, process.parent.executable, process.command_line +| where + Esql.agent_id_count_distinct == 1 and + Esql.event_count < 5 +| sort Esql.event_count asc | limit 100 ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/unusual-high-confidence-content-filter-blocks-detected.asciidoc b/docs/detections/prebuilt-rules/rule-details/unusual-high-confidence-content-filter-blocks-detected.asciidoc index 5a383ea328..bb88cf2b80 100644 --- a/docs/detections/prebuilt-rules/rule-details/unusual-high-confidence-content-filter-blocks-detected.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/unusual-high-confidence-content-filter-blocks-detected.asciidoc @@ -34,7 +34,7 @@ Detects repeated high-confidence 'BLOCKED' actions coupled with specific 'Conten * Mitre Atlas: T0054 * Resources: Investigation Guide -*Version*: 6 +*Version*: 7 *Rule authors*: @@ -110,16 +110,41 @@ https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html [source, js] ---------------------------------- from logs-aws_bedrock.invocation-* -| MV_EXPAND gen_ai.compliance.violation_code -| MV_EXPAND gen_ai.policy.confidence -| MV_EXPAND gen_ai.policy.name -| where gen_ai.policy.action == "BLOCKED" and gen_ai.policy.name == "content_policy" and gen_ai.policy.confidence LIKE "HIGH" and gen_ai.compliance.violation_code IN ("HATE", "MISCONDUCT", "SEXUAL", "INSULTS", "PROMPT_ATTACK", "VIOLENCE") -| keep user.id, gen_ai.compliance.violation_code -| stats block_count_per_violation = count() by user.id, gen_ai.compliance.violation_code -| SORT block_count_per_violation DESC -| keep user.id, gen_ai.compliance.violation_code, block_count_per_violation -| STATS violation_count = SUM(block_count_per_violation) by user.id -| WHERE violation_count > 5 -| SORT violation_count DESC + +// Expand multi-value fields +| mv_expand gen_ai.compliance.violation_code +| mv_expand gen_ai.policy.confidence +| mv_expand gen_ai.policy.name + +// Filter for high-confidence content policy blocks with targeted violations +| where + gen_ai.policy.action == "BLOCKED" + and gen_ai.policy.name == "content_policy" + and gen_ai.policy.confidence like "HIGH" + and gen_ai.compliance.violation_code in ("HATE", "MISCONDUCT", "SEXUAL", "INSULTS", "PROMPT_ATTACK", "VIOLENCE") + +// keep ECS + compliance fields +| keep + user.id, + gen_ai.compliance.violation_code + +// count blocked violations per user per violation type +| stats + Esql.ml_policy_blocked_violation_count = count() + by + user.id, + gen_ai.compliance.violation_code + +// Aggregate all violation types per user +| stats + Esql.ml_policy_blocked_violation_total_count = sum(Esql.ml_policy_blocked_violation_count) + by + user.id + +// Filter for users with more than 5 total violations +| where Esql.ml_policy_blocked_violation_total_count > 5 + +// sort by violation volume +| sort Esql.ml_policy_blocked_violation_total_count desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/unusual-high-denied-sensitive-information-policy-blocks-detected.asciidoc b/docs/detections/prebuilt-rules/rule-details/unusual-high-denied-sensitive-information-policy-blocks-detected.asciidoc index ae765e32a7..e5efdba886 100644 --- a/docs/detections/prebuilt-rules/rule-details/unusual-high-denied-sensitive-information-policy-blocks-detected.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/unusual-high-denied-sensitive-information-policy-blocks-detected.asciidoc @@ -34,7 +34,7 @@ Detects repeated compliance violation 'BLOCKED' actions coupled with specific po * Mitre Atlas: T0054 * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -110,11 +110,28 @@ https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html [source, js] ---------------------------------- from logs-aws_bedrock.invocation-* -| MV_EXPAND gen_ai.policy.name -| where gen_ai.policy.action == "BLOCKED" and gen_ai.compliance.violation_detected == "true" and gen_ai.policy.name == "sensitive_information_policy" + +// Expand multi-valued policy name field +| mv_expand gen_ai.policy.name + +// Filter for blocked actions related to sensitive info policy +| where + gen_ai.policy.action == "BLOCKED" + and gen_ai.compliance.violation_detected == "true" + and gen_ai.policy.name == "sensitive_information_policy" + +// keep only relevant fields | keep user.id -| stats sensitive_information_block = count() by user.id -| where sensitive_information_block > 5 -| sort sensitive_information_block desc + +// count how many times each user triggered a sensitive info block +| stats + Esql.ml_policy_blocked_sensitive_info_count = count() + by user.id + +// Filter for users with more than 5 violations +| where Esql.ml_policy_blocked_sensitive_info_count > 5 + +// sort highest to lowest +| sort Esql.ml_policy_blocked_sensitive_info_count desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/unusual-high-denied-topic-blocks-detected.asciidoc b/docs/detections/prebuilt-rules/rule-details/unusual-high-denied-topic-blocks-detected.asciidoc index 632082aef6..9dd854dd29 100644 --- a/docs/detections/prebuilt-rules/rule-details/unusual-high-denied-topic-blocks-detected.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/unusual-high-denied-topic-blocks-detected.asciidoc @@ -34,7 +34,7 @@ Detects repeated compliance violation 'BLOCKED' actions coupled with specific po * Mitre Atlas: T0054 * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -110,11 +110,28 @@ https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html [source, js] ---------------------------------- from logs-aws_bedrock.invocation-* -| MV_EXPAND gen_ai.policy.name -| where gen_ai.policy.action == "BLOCKED" and gen_ai.compliance.violation_detected == "true" and gen_ai.policy.name == "topic_policy" + +// Expand multi-value policy name field +| mv_expand gen_ai.policy.name + +// Filter for blocked topic policy violations +| where + gen_ai.policy.action == "BLOCKED" + and gen_ai.compliance.violation_detected == "true" + and gen_ai.policy.name == "topic_policy" + +// keep only user info | keep user.id -| stats denied_topics = count() by user.id -| where denied_topics > 5 -| sort denied_topics desc + +// count how many times each user triggered a blocked topic policy +| stats + Esql.ml_policy_blocked_topic_count = count() + by user.id + +// Filter for excessive violations +| where Esql.ml_policy_blocked_topic_count > 5 + +// sort highest to lowest +| sort Esql.ml_policy_blocked_topic_count desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/unusual-high-word-policy-blocks-detected.asciidoc b/docs/detections/prebuilt-rules/rule-details/unusual-high-word-policy-blocks-detected.asciidoc index 93e06e8873..97aa00aba8 100644 --- a/docs/detections/prebuilt-rules/rule-details/unusual-high-word-policy-blocks-detected.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/unusual-high-word-policy-blocks-detected.asciidoc @@ -34,7 +34,7 @@ Detects repeated compliance violation 'BLOCKED' actions coupled with specific po * Mitre Atlas: T0054 * Resources: Investigation Guide -*Version*: 2 +*Version*: 3 *Rule authors*: @@ -110,11 +110,28 @@ https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html [source, js] ---------------------------------- from logs-aws_bedrock.invocation-* -| MV_EXPAND gen_ai.policy.name -| where gen_ai.policy.action == "BLOCKED" and gen_ai.compliance.violation_detected == "true" and gen_ai.policy.name == "word_policy" + +// Expand multivalued policy names +| mv_expand gen_ai.policy.name + +// Filter for blocked profanity-related policy violations +| where + gen_ai.policy.action == "BLOCKED" + and gen_ai.compliance.violation_detected == "true" + and gen_ai.policy.name == "word_policy" + +// keep relevant user field | keep user.id -| stats profanity_words= count() by user.id -| where profanity_words > 5 -| sort profanity_words desc + +// count blocked profanity attempts per user +| stats + Esql.ml_policy_blocked_profanity_count = count() + by user.id + +// Filter for excessive policy violations +| where Esql.ml_policy_blocked_profanity_count > 5 + +// sort by violation volume +| sort Esql.ml_policy_blocked_profanity_count desc ---------------------------------- diff --git a/docs/detections/prebuilt-rules/rule-details/unusual-process-spawned-from-web-server-parent.asciidoc b/docs/detections/prebuilt-rules/rule-details/unusual-process-spawned-from-web-server-parent.asciidoc index e740efd689..cc92e3dd5f 100644 --- a/docs/detections/prebuilt-rules/rule-details/unusual-process-spawned-from-web-server-parent.asciidoc +++ b/docs/detections/prebuilt-rules/rule-details/unusual-process-spawned-from-web-server-parent.asciidoc @@ -30,7 +30,7 @@ This rule detects unusual processes spawned from a web server parent process by * Data Source: Elastic Defend * Resources: Investigation Guide -*Version*: 4 +*Version*: 5 *Rule authors*: @@ -130,32 +130,55 @@ For more details on Elastic Defend refer to the https://www.elastic.co/guide/en/ [source, js] ---------------------------------- from logs-endpoint.events.process-* -| keep @timestamp, host.os.type, event.type, event.action, process.parent.name, user.name, user.id, process.working_directory, process.name, process.executable, process.command_line, process.parent.executable, agent.id, host.name -| where @timestamp > now() - 1 hours -| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and ( - process.parent.name in ( - "apache", "nginx", "apache2", "httpd", "lighttpd", "caddy", "node", "mongrel_rails", "java", "gunicorn", - "uwsgi", "openresty", "cherokee", "h2o", "resin", "puma", "unicorn", "traefik", "tornado", "hypercorn", - "daphne", "twistd", "yaws", "webfsd", "httpd.worker", "flask", "rails", "mongrel" - ) or - process.parent.name like "php-*" or - process.parent.name like "python*" or - process.parent.name like "ruby*" or - process.parent.name like "perl*" or - user.name in ( - "apache", "www-data", "httpd", "nginx", "lighttpd", "tomcat", "tomcat8", "tomcat9", "ftp", "ftpuser", "ftpd" - ) or - user.id in ("99", "33", "498", "48") or - process.working_directory like "/var/www/*" -) and -not ( - process.working_directory like "/home/*" or - process.working_directory like "/" or - process.parent.executable like "/vscode/vscode-server/*" -) -| stats cc = count(), agent_count = count_distinct(agent.id), host.name = VALUES(host.name), agent.id = VALUES(agent.id) by process.executable, process.working_directory, process.parent.executable -| where agent_count == 1 and cc < 5 -| sort cc asc +| keep + @timestamp, + host.os.type, + event.type, + event.action, + process.parent.name, + user.name, + user.id, + process.working_directory, + process.name, + process.executable, + process.command_line, + process.parent.executable, + agent.id, + host.name +| where + @timestamp > now() - 1 hours and + host.os.type == "linux" and + event.type == "start" and + event.action == "exec" and ( + process.parent.name in ( + "apache", "nginx", "apache2", "httpd", "lighttpd", "caddy", "node", "mongrel_rails", "java", "gunicorn", + "uwsgi", "openresty", "cherokee", "h2o", "resin", "puma", "unicorn", "traefik", "tornado", "hypercorn", + "daphne", "twistd", "yaws", "webfsd", "httpd.worker", "flask", "rails", "mongrel" + ) or + process.parent.name like "php-*" or + process.parent.name like "python*" or + process.parent.name like "ruby*" or + process.parent.name like "perl*" or + user.name in ( + "apache", "www-data", "httpd", "nginx", "lighttpd", "tomcat", "tomcat8", "tomcat9", "ftp", "ftpuser", "ftpd" + ) or + user.id in ("99", "33", "498", "48") or + process.working_directory like "/var/www/*" + ) and not ( + process.working_directory like "/home/*" or + process.working_directory == "/" or + process.parent.executable like "/vscode/vscode-server/*" + ) +| stats + Esql.event_count = count(), + Esql.agent_id_count_distinct = count_distinct(agent.id), + Esql.host_name_values = values(host.name), + Esql.agent_id_values = values(agent.id) + by process.executable, process.working_directory, process.parent.executable +| where + Esql.agent_id_count_distinct == 1 and + Esql.event_count < 5 +| sort Esql.event_count asc | limit 100 ---------------------------------- diff --git a/docs/index.asciidoc b/docs/index.asciidoc index 000916e7c3..cd2143106c 100644 --- a/docs/index.asciidoc +++ b/docs/index.asciidoc @@ -89,3 +89,5 @@ include::detections/prebuilt-rules/downloadable-packages/8-19-1/prebuilt-rules-8 include::detections/prebuilt-rules/downloadable-packages/8-19-2/prebuilt-rules-8-19-2-appendix.asciidoc[] include::detections/prebuilt-rules/downloadable-packages/8-19-3/prebuilt-rules-8-19-3-appendix.asciidoc[] + +include::detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-appendix.asciidoc[] From 8da604d505daabe598860fc8e1dba2c58d9bb4df Mon Sep 17 00:00:00 2001 From: Shashank K S Date: Wed, 6 Aug 2025 13:32:13 +0530 Subject: [PATCH 2/2] Remove deprecated rule references --- .../8-19-4/prebuilt-rules-8-19-4-appendix.asciidoc | 1 - .../8-19-4/prebuilt-rules-8-19-4-summary.asciidoc | 2 -- 2 files changed, 3 deletions(-) diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-appendix.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-appendix.asciidoc index 6ee37529bc..b2aaa92782 100644 --- a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-appendix.asciidoc +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-appendix.asciidoc @@ -74,4 +74,3 @@ include::prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-string-concat include::prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-string-reordering.asciidoc[] include::prebuilt-rule-8-19-4-potential-powershell-obfuscation-via-special-character-overuse.asciidoc[] include::prebuilt-rule-8-19-4-potential-malicious-powershell-based-on-alert-correlation.asciidoc[] -include::prebuilt-rule-8-19-4-deprecated-azure-entra-sign-in-brute-force-microsoft-365-accounts-by-repeat-source.asciidoc[] diff --git a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-summary.asciidoc b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-summary.asciidoc index 06b31f7ed5..2641a61eb0 100644 --- a/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-summary.asciidoc +++ b/docs/detections/prebuilt-rules/downloadable-packages/8-19-4/prebuilt-rules-8-19-4-summary.asciidoc @@ -149,6 +149,4 @@ This section lists all updates associated with version 8.19.4 of the Fleet integ |<> | Identifies PowerShell script blocks associated with multiple distinct detections, indicating likely malicious behavior. | update | 2 -|<> | Identifies potential brute-force attempts against Microsoft 365 user accounts by detecting a high number of failed interactive or non-interactive login attempts within a 30-minute window from a single source. Attackers may attempt to brute force user accounts to gain unauthorized access to Microsoft 365 services via different services such as Exchange, SharePoint, or Teams. | deprecated | 4 - |==============================================