From 0f98238bcee92389d794f0b81261bcf03f3f312e Mon Sep 17 00:00:00 2001 From: bryans3c Date: Mon, 6 Jul 2026 12:04:07 +0200 Subject: [PATCH 1/2] [New Rule] AWS IAM Credentials Added to a Bedrock API Key Phantom User --- ...edrock_phantom_user_credentials_added.toml | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 rules/integrations/aws/privilege_escalation_bedrock_phantom_user_credentials_added.toml diff --git a/rules/integrations/aws/privilege_escalation_bedrock_phantom_user_credentials_added.toml b/rules/integrations/aws/privilege_escalation_bedrock_phantom_user_credentials_added.toml new file mode 100644 index 00000000000..38650e96ce4 --- /dev/null +++ b/rules/integrations/aws/privilege_escalation_bedrock_phantom_user_credentials_added.toml @@ -0,0 +1,118 @@ +[metadata] +creation_date = "2026/07/06" +integration = ["aws"] +maturity = "production" +updated_date = "2026/07/06" + +[rule] +author = ["Elastic"] +description = """ +Identifies standard IAM credentials being added to an Amazon Bedrock API key phantom user, whose user name starts with +"BedrockAPIKey-": either a long-term access key (CreateAccessKey) or a console password / login profile +(CreateLoginProfile, UpdateLoginProfile). When a long-term Bedrock API key is generated through the AWS Console, AWS +silently provisions a "BedrockAPIKey-" IAM user with the AmazonBedrockLimitedAccess managed policy. That user is +intended only to back a Bedrock bearer token and should never hold standard programmatic keys or interactive console +access. Adding either converts a Bedrock-scoped identity into general-purpose IAM credentials that inherit the policy's +Bedrock control-plane and IAM, VPC, and KMS reconnaissance permissions and that persist after the Bedrock API key is +revoked. This is the privilege-escalation and persistence pivot documented for Bedrock API key phantom users, and there +is no legitimate workflow that produces it. +""" +false_positives = [ + """ + There is no known legitimate workflow that adds IAM access keys or console login profiles to a Bedrock API key phantom + user. Any match should be investigated. Confirm the actor in "aws.cloudtrail.user_identity.arn" and the target user in + "aws.cloudtrail.request_parameters", and remove the credential if it was not expected. + """, +] +from = "now-30m" +language = "esql" +license = "Elastic License v2" +name = "AWS IAM Credentials Added to a Bedrock API Key Phantom User" +note = """## Triage and analysis + +### Investigating AWS IAM Credentials Added to a Bedrock API Key Phantom User + +Amazon Bedrock API keys authenticate with a bearer token. When a long-term key is created through the AWS Console, AWS provisions an IAM user named "BedrockAPIKey-" and attaches the AmazonBedrockLimitedAccess managed policy. That policy is broader than its name suggests: it grants Bedrock control-plane actions (including deletion of guardrails, custom models, and provisioned throughput) as well as IAM, VPC, and KMS reconnaissance. The phantom user is meant only to back the bearer token and should never hold standard access keys or an interactive console login. + +Adding an IAM access key (CreateAccessKey) or a console password (CreateLoginProfile/UpdateLoginProfile) to the phantom user escalates a Bedrock-scoped identity into general-purpose IAM credentials or interactive access that inherit the full policy scope and continue to work after the originating Bedrock API key is revoked. This is a deliberate privilege-escalation and persistence step. + +### Possible investigation steps + +- Identify the actor in "aws.cloudtrail.user_identity.arn" and "aws.cloudtrail.user_identity.type", and review "source.ip" and "user_agent.original" for whether this is an expected administrator. +- Confirm the target phantom user and the credential type in "event.action" and "aws.cloudtrail.request_parameters", and enumerate the user's remaining credentials (service-specific credentials, access keys, login profile). +- Review the phantom user's subsequent activity for use of the new credential outside Bedrock (IAM, VPC, KMS, STS calls, or console logins). +- Correlate with the key-creation events (CreateUser and CreateServiceSpecificCredential for the same user) to reconstruct the timeline. + +### False positive analysis + +- This should be near-zero. There is no standard workflow that adds access keys or login profiles to a "BedrockAPIKey-*" user. Treat any hit as suspicious until proven otherwise. + +### Response and remediation + +- Remove the access key or login profile on the phantom user and, if compromise is suspected, deactivate or delete the associated Bedrock service-specific credential. +- Review the actor's recent activity and rotate or restrict its credentials. +- Deploy a Service Control Policy that denies "iam:CreateAccessKey" and "iam:CreateLoginProfile" on "arn:aws:iam::*:user/BedrockAPIKey-*" to block this pivot organization-wide. +""" +references = [ + "https://www.beyondtrust.com/blog/entry/aws-bedrock-security-guide-api-keys-detection-response", + "https://www.beyondtrust.com/blog/entry/aws-bedrock-security-api-keys", + "https://docs.aws.amazon.com/bedrock/latest/userguide/api-keys.html", +] +risk_score = 99 +rule_id = "71159cad-f8b3-4b3c-ac6e-9cab05594670" +setup = "This rule requires AWS CloudTrail logs ingested via the Elastic AWS integration. See https://docs.elastic.co/integrations/aws/cloudtrail for setup details." +severity = "critical" +tags = [ + "Domain: Cloud", + "Data Source: AWS", + "Data Source: Amazon Web Services", + "Data Source: AWS IAM", + "Data Source: Amazon Bedrock", + "Use Case: Threat Detection", + "Tactic: Privilege Escalation", + "Tactic: Persistence", + "Resources: Investigation Guide", +] +type = "esql" + +query = ''' +FROM logs-aws.cloudtrail-* METADATA _id, _version, _index +| WHERE event.provider == "iam.amazonaws.com" + AND event.action IN ("CreateAccessKey", "CreateLoginProfile", "UpdateLoginProfile") + AND event.outcome == "success" + AND aws.cloudtrail.request_parameters RLIKE """.*userName=BedrockAPIKey-.*""" +| KEEP _id, _version, _index, @timestamp, aws.*, cloud.*, event.*, source.*, user.*, user_agent.* +''' + + +[[rule.threat]] +framework = "MITRE ATT&CK" +[[rule.threat.technique]] +id = "T1098" +name = "Account Manipulation" +reference = "https://attack.mitre.org/techniques/T1098/" +[[rule.threat.technique.subtechnique]] +id = "T1098.001" +name = "Additional Cloud Credentials" +reference = "https://attack.mitre.org/techniques/T1098/001/" + +[rule.threat.tactic] +id = "TA0004" +name = "Privilege Escalation" +reference = "https://attack.mitre.org/tactics/TA0004/" + +[[rule.threat]] +framework = "MITRE ATT&CK" +[[rule.threat.technique]] +id = "T1098" +name = "Account Manipulation" +reference = "https://attack.mitre.org/techniques/T1098/" +[[rule.threat.technique.subtechnique]] +id = "T1098.001" +name = "Additional Cloud Credentials" +reference = "https://attack.mitre.org/techniques/T1098/001/" + +[rule.threat.tactic] +id = "TA0003" +name = "Persistence" +reference = "https://attack.mitre.org/tactics/TA0003/" From 1968b621c69880a5219e734bccd454c322914a44 Mon Sep 17 00:00:00 2001 From: Bryan Porras Date: Mon, 6 Jul 2026 12:30:27 +0200 Subject: [PATCH 2/2] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- ...vilege_escalation_bedrock_phantom_user_credentials_added.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/rules/integrations/aws/privilege_escalation_bedrock_phantom_user_credentials_added.toml b/rules/integrations/aws/privilege_escalation_bedrock_phantom_user_credentials_added.toml index 38650e96ce4..a0f6b6c3c1e 100644 --- a/rules/integrations/aws/privilege_escalation_bedrock_phantom_user_credentials_added.toml +++ b/rules/integrations/aws/privilege_escalation_bedrock_phantom_user_credentials_added.toml @@ -73,6 +73,7 @@ tags = [ "Tactic: Persistence", "Resources: Investigation Guide", ] +timestamp_override = "event.ingested" type = "esql" query = '''