Create a backdoored IAM Role
Platform: AWS
MITRE ATT&CK Tactics
- Persistence
Description
Establishes persistence by creating a new backdoor role with a trust policy allowing it to be assumed from an external, fictitious attack AWS account.
Warm-up: None.
Detonation:
- Create a new IAM role with the following trust policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::193672423079:root"
},
"Action": "sts:AssumeRole"
}
]
}
- Attach the 'AdministratorAccess' managed IAM policy to it.
Note: For safety reasons, the detonation code makes sure that this role has no real effective permissions, by attaching a permissions boundary denying all actions. This could also be achieved with an inline role policy, but using a permissions boundary allows us to use a single API call (CreateRole).
References:
Instructions
Detection
-
Through IAM Access Analyzer, which generates a finding when a role can be assumed from a new AWS account or publicly.
-
Identify a call to
CreateRole
closely followed byAttachRolePolicy
with an administrator policy. -
Identify a call to
CreateRole
that contains an assumeRolePolicyDocument in the requestParameters that allows access from an external AWS account. Sample event:
{
"eventSource": "iam.amazonaws.com",
"eventName": "CreateRole",
"requestParameters": {
"roleName": "malicious-iam-role",
"assumeRolePolicyDocument": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"Service\": \"ec2.amazonaws.com\"\n },\n \"Action\": \"sts:AssumeRole\"\n },\n {\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::193672423079:root\"\n },\n \"Action\": \"sts:AssumeRole\"\n }\n ]\n}"
}
}