AWS IAM Sensitive Operations via Lambda Execution Role

Detects successful IAM API calls that create or empower IAM users and roles, attach or embed policies, or wire roles to instance profiles when the caller is an assumed role session associated with AWS Lambda. Serverless execution roles are often over-permissioned; an adversary who can run or compromise function code can abuse these APIs for privilege escalation and persistence—for example creating users or roles, issuing keys, attaching managed or inline policies, or preparing EC2 instance profiles for lateral movement.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2026/04/04"
  3integration = ["aws"]
  4maturity = "production"
  5updated_date = "2026/04/04"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Detects successful IAM API calls that create or empower IAM users and roles, attach or embed policies, or wire roles to
 11instance profiles when the caller is an assumed role session associated with AWS Lambda. Serverless execution roles are
 12often over-permissioned; an adversary who can run or compromise function code can abuse these APIs for privilege
 13escalation and persistence—for example creating users or roles, issuing keys, attaching managed or inline policies, or
 14preparing EC2 instance profiles for lateral movement.
 15"""
 16false_positives = [
 17    """
 18    Some organizations intentionally use Lambda functions to provision IAM principals, bootstrap accounts, or run
 19    identity automation (including roles and instance profiles). Confirm the function name in `user_identity.arn`,
 20    deployment pipelines, and change records. Exclude known automation roles or specific
 21    `session_context.session_issuer.arn` values after validation.
 22    """,
 23]
 24from = "now-6m"
 25index = ["filebeat-*", "logs-aws.cloudtrail-*"]
 26interval = "5m"
 27language = "kuery"
 28license = "Elastic License v2"
 29name = "AWS IAM Sensitive Operations via Lambda Execution Role"
 30note = """## Triage and analysis
 31
 32### Investigating AWS IAM Sensitive Operations via Lambda Execution Role
 33
 34Lambda functions run under an **execution role**. When that role calls sensitive IAM control-plane APIs—user and group
 35changes (`CreateUser`, `AddUserToGroup`, …), user or role policies (`AttachUserPolicy`, `PutUserPolicy`,
 36`AttachRolePolicy`, `PutRolePolicy`), role and instance-profile wiring (`CreateRole`, `CreateInstanceProfile`,
 37`AddRoleToInstanceProfile`), or `CreateAccessKey`—CloudTrail typically records `user_identity.type` as `AssumedRole` and
 38may set `user_identity.invoked_by` to `lambda.amazonaws.com`. The session issuer ARN often references the Lambda service
 39or the execution role.
 40
 41#### Possible investigation steps
 42
 43- Parse `aws.cloudtrail.user_identity.arn` for the assumed-role session (function name or request id) and map it to the
 44  Lambda function and deployment path in the same account.
 45- Review `aws.cloudtrail.request_parameters` for targets such as `userName`, `groupName`, `roleName`, `policyArn`,
 46  `instanceProfileName`, or access key subject.
 47- Compare `user_agent.original` and `source.ip` to expected Lambda service patterns; correlate with CloudWatch Logs for
 48  the function around `@timestamp`.
 49- Hunt ±30 minutes for follow-on IAM, `sts:AssumeRole`, or data-plane access using any new credentials.
 50
 51### False positive analysis
 52
 53- Approved infrastructure-as-code or onboarding Lambdas may perform these calls. Tune on execution role ARN or tags.
 54
 55### Response and remediation
 56
 57- If unauthorized: disable the function, revoke or rotate the execution role credentials, remove rogue IAM users, roles,
 58  instance profiles, or keys, detach or delete unintended policies, and review permission boundaries on the role.
 59
 60### Additional information
 61
 62- [IAM API reference](https://docs.aws.amazon.com/IAM/latest/APIReference/)
 63- [Lambda execution role](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)
 64"""
 65references = [
 66    "https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html",
 67    "https://hackingthe.cloud/aws/exploitation/iam_privilege_escalation/",
 68    "https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateUser.html",
 69]
 70risk_score = 73
 71rule_id = "a8f3c2e1-4d5b-4e6f-8a9b-0c1d2e3f4a5b"
 72severity = "high"
 73tags = [
 74    "Domain: Cloud",
 75    "Domain: Identity",
 76    "Data Source: AWS",
 77    "Data Source: Amazon Web Services",
 78    "Data Source: AWS IAM",
 79    "Data Source: AWS Lambda",
 80    "Use Case: Threat Detection",
 81    "Tactic: Privilege Escalation",
 82    "Tactic: Persistence",
 83    "Resources: Investigation Guide",
 84]
 85timestamp_override = "event.ingested"
 86type = "query"
 87
 88query = '''
 89event.dataset: "aws.cloudtrail"
 90    and event.provider: "iam.amazonaws.com"
 91    and event.outcome: "success"
 92    and aws.cloudtrail.user_identity.type: "AssumedRole"
 93    and (
 94        aws.cloudtrail.user_identity.invoked_by: "lambda.amazonaws.com"
 95        or user_agent.original : *AWS_Lambda*
 96    )
 97    and event.action: (
 98        "AddRoleToInstanceProfile" or
 99        "AddUserToGroup" or 
100        "AttachGroupPolicy" or 
101        "AttachRolePolicy" or
102        "AttachUserPolicy" or
103        "CreateAccessKey" or
104        "CreateInstanceProfile" or
105        "CreateRole" or
106        "CreateUser" or
107        "PutRolePolicy" or
108        "PutUserPolicy"
109    )
110'''
111
112[rule.investigation_fields]
113field_names = [
114    "@timestamp",
115    "user.name",
116    "user_agent.original",
117    "source.ip",
118    "aws.cloudtrail.user_identity.arn",
119    "aws.cloudtrail.user_identity.type",
120    "aws.cloudtrail.user_identity.invoked_by",
121    "aws.cloudtrail.user_identity.access_key_id",
122    "aws.cloudtrail.request_parameters",
123    "aws.cloudtrail.response_elements",
124    "event.action",
125    "event.outcome",
126    "cloud.account.id",
127    "cloud.region",
128]
129
130[[rule.threat]]
131framework = "MITRE ATT&CK"
132[[rule.threat.technique]]
133id = "T1078"
134name = "Valid Accounts"
135reference = "https://attack.mitre.org/techniques/T1078/"
136[[rule.threat.technique.subtechnique]]
137id = "T1078.004"
138name = "Cloud Accounts"
139reference = "https://attack.mitre.org/techniques/T1078/004/"
140[rule.threat.tactic]
141id = "TA0004"
142name = "Privilege Escalation"
143reference = "https://attack.mitre.org/tactics/TA0004/"
144
145
146
147[[rule.threat]]
148framework = "MITRE ATT&CK"
149[[rule.threat.technique]]
150id = "T1136"
151name = "Create Account"
152reference = "https://attack.mitre.org/techniques/T1136/"
153[[rule.threat.technique.subtechnique]]
154id = "T1136.003"
155name = "Cloud Account"
156reference = "https://attack.mitre.org/techniques/T1136/003/"
157[[rule.threat.technique]]
158id = "T1098"
159name = "Account Manipulation"
160reference = "https://attack.mitre.org/techniques/T1098/"
161
162[rule.threat.tactic]
163id = "TA0003"
164name = "Persistence"
165reference = "https://attack.mitre.org/tactics/TA0003/"

Triage and analysis

Investigating AWS IAM Sensitive Operations via Lambda Execution Role

Lambda functions run under an execution role. When that role calls sensitive IAM control-plane APIs—user and group changes (CreateUser, AddUserToGroup, …), user or role policies (AttachUserPolicy, PutUserPolicy, AttachRolePolicy, PutRolePolicy), role and instance-profile wiring (CreateRole, CreateInstanceProfile, AddRoleToInstanceProfile), or CreateAccessKey—CloudTrail typically records user_identity.type as AssumedRole and may set user_identity.invoked_by to lambda.amazonaws.com. The session issuer ARN often references the Lambda service or the execution role.

Possible investigation steps

  • Parse aws.cloudtrail.user_identity.arn for the assumed-role session (function name or request id) and map it to the Lambda function and deployment path in the same account.
  • Review aws.cloudtrail.request_parameters for targets such as userName, groupName, roleName, policyArn, instanceProfileName, or access key subject.
  • Compare user_agent.original and source.ip to expected Lambda service patterns; correlate with CloudWatch Logs for the function around @timestamp.
  • Hunt ±30 minutes for follow-on IAM, sts:AssumeRole, or data-plane access using any new credentials.

False positive analysis

  • Approved infrastructure-as-code or onboarding Lambdas may perform these calls. Tune on execution role ARN or tags.

Response and remediation

  • If unauthorized: disable the function, revoke or rotate the execution role credentials, remove rogue IAM users, roles, instance profiles, or keys, detach or delete unintended policies, and review permission boundaries on the role.

Additional information

References

Related rules

to-top