Back to Security Cards
    AWS Control Tower

    AWS Control Tower Security

    MANAGEMENT

    AWS Control Tower orchestrates multi-account governance by deploying a landing zone with guardrails (preventive, detective, proactive), Account Factory, and centralized logging. Compromising the management account or disabling controls grants unrestricted access across the entire organization.

    CRITICAL
    Risk Level
    Prev/Det/Pro
    Control Types
    Landing Zone
    Governance
    Mgmt Acct
    Top Target

    📋Service Overview

    Landing Zone

    A pre-configured, secure multi-account environment based on AWS best practices. Deploys a Security OU (with Log Archive and Audit accounts) and a user-named additional OU. Managed via the aws controltower API (28 subcommands covering controls, landing zones, baselines, and tagging).

    Critical: The management account is exempt from all preventive controls (SCPs and RCPs). Any identity in this account can bypass every guardrail.

    Controls (Guardrails)

    Three behavioral types enforce governance: Preventive (SCPs/RCPs), Detective (AWS Config rules), and Proactive (CloudFormation Hooks). Three guidance categories: Mandatory (always on), Strongly Recommended, and Elective.

    Attack note: Disabling a detective control does not remediate existing non-compliant resources -- it simply stops detecting them.

    Account Factory

    Standardized account provisioning via AWS Service Catalog. Creates new accounts with the AWSControlTowerExecution role pre-installed. Account Factory for Terraform (AFT) extends this with IaC-based customization pipelines.

    Attack note: The AWSControlTowerExecution role in every member account has AdministratorAccess and trusts the management account root principal with no conditions by default.

    Key IAM Roles

    AWSControlTowerExecution -- Every member account, full admin access

    AWSControlTowerAdmin -- Management account, creates Config aggregators

    AWSControlTowerCloudTrailRole -- Management account, centralized CloudTrail

    AWSControlTowerStackSetRole -- Management account, deploys StackSets

    AuditAdministratorRole -- Audit account, Lambda-only cross-account admin

    AuditReadOnlyRole -- Audit account, Lambda-only cross-account read-only

    Security Risk Assessment

    LowMediumHighCritical
    9.5
    Risk Score

    AWS Control Tower is the governance layer for the entire organization. Compromise of the management account means full admin access to every enrolled member account via the AWSControlTowerExecution role. Disabling controls removes guardrails organization-wide. Drift introduced by an attacker can disable security detection without triggering obvious alerts.

    ⚔️Attack Vectors

    Management Account Compromise

    • Steal credentials with sts:AssumeRole on AWSControlTowerExecution to pivot to any member account
    • Exploit weakly-scoped IAM policies (Resource: "*") to assume AWSControlTowerExecution
    • Compromise AWSControlTowerAdmin role to modify landing zone configuration
    • Social-engineer org administrators with Control Tower console access
    • Target Account Factory / AFT pipeline credentials (Terraform tokens, git tokens)

    Control and Landing Zone Manipulation

    • Disable preventive controls (SCPs) to remove security restrictions from OUs
    • Disable detective controls to stop compliance monitoring silently
    • Introduce landing zone drift by modifying SCPs or moving accounts
    • Delete or modify AWSControlTowerCloudTrailRole to disrupt logging
    • Abuse delegated administrator privileges to escalate access

    ⚠️Misconfigurations

    Dangerous Defaults

    • AWSControlTowerExecution trusts management account root with no conditions
    • No Permissions Boundaries on management account identities
    • Only mandatory controls enabled; strongly recommended left disabled
    • Account Factory provisions accounts without additional SCPs
    • Audit account Lambda roles have cross-account admin access via role chaining

    Governance Gaps

    • No alerting configured for control disable/enable operations
    • Landing zone drift not monitored or auto-remediated
    • AFT pipeline credentials stored without rotation policy
    • No SCP protecting Control Tower roles from modification
    • Management account used for daily workloads instead of isolated administration

    🔍Enumeration

    List Landing Zones
    aws controltower list-landing-zones
    Get Landing Zone Details
    aws controltower get-landing-zone \
      --landing-zone-identifier arn:aws:controltower:us-east-1:123456789012:landingzone/LANDING_ZONE_ID
    List Enabled Controls on an OU
    aws controltower list-enabled-controls \
      --target-identifier arn:aws:organizations::123456789012:ou/o-abc1234xyz/ou-abc-xyz
    List Controls Filtered by Drift Status
    aws controltower list-enabled-controls \
      --target-identifier arn:aws:organizations::123456789012:ou/o-abc1234xyz/ou-abc-xyz \
      --filter '{"driftStatuses":["DRIFTED"]}'
    List All Baselines
    aws controltower list-baselines
    List Enabled Baselines
    aws controltower list-enabled-baselines
    Enumerate Organization Accounts
    aws organizations list-accounts \
      --query 'Accounts[*].[Id,Name,Status]' \
      --output table
    List SCPs Applied to an OU
    aws organizations list-policies-for-target \
      --target-id ou-xxxx-xxxxxxxx \
      --filter SERVICE_CONTROL_POLICY

    📈Privilege Escalation

    From Member Account to Full Org Access

    • Identify management account ID from aws organizations describe-organization
    • Check if AWSControlTowerExecution role exists and its trust policy
    • Compromise any identity in mgmt account with sts:AssumeRole to pivot to any member
    • Abuse Audit account AuditAdministratorRole chain to AdministratorExecutionRole
    • Exploit delegated administrator registration to escalate access

    From Management Account

    • Assume AWSControlTowerExecution in any member account for AdministratorAccess
    • Disable preventive controls to remove SCP restrictions
    • Disable detective controls to blind compliance monitoring
    • Modify landing zone manifest to weaken security configuration
    • Create new accounts via Account Factory with attacker-controlled settings

    Key insight: AWSControlTowerExecution in every member account has AdministratorAccess and trusts the management account root with no conditions by default.

    🔗Persistence

    Persistence Mechanisms

    • Add backup key administrator to management account
    • Register compromised account as delegated admin for sensitive services
    • Create new accounts via Account Factory with attacker-controlled settings
    • Inject malicious customizations via AFT pipeline
    • Modify AWSControlTowerExecution trust to include attacker principal

    Stealth Techniques

    • Introduce drift by modifying SCPs outside Control Tower
    • Disable detective controls to stop compliance monitoring
    • Delete or modify CloudTrail role to disrupt centralized logging
    • Move accounts between OUs to change applied controls
    • Disable baselines to remove security configuration

    🛡️Detection

    CloudTrail Events

    • DisableControl / EnableControl -- control changes
    • UpdateLandingZone / ResetLandingZone -- landing zone modifications
    • DisableBaseline -- baseline removal
    • CreateAccount or CreateManagedAccount -- new account creation
    • AssumeRole on AWSControlTowerExecution -- pivot to member accounts

    Indicators of Compromise

    • Unexpected DisableControl events on production OUs
    • AWSControlTowerExecution assumption from unknown principals
    • Landing zone drift detected without authorized changes
    • New accounts created outside normal provisioning workflow
    • Modifications to Control Tower IAM roles in member accounts

    💻Exploitation Commands

    Assume AWSControlTowerExecution in a Member Account
    aws sts assume-role \
      --role-arn arn:aws:iam::MEMBER_ACCOUNT_ID:role/AWSControlTowerExecution \
      --role-session-name ct-pivot
    Disable a Control on an OU
    aws controltower disable-control \
      --control-identifier arn:aws:controltower:us-east-1::control/CONTROL_ID \
      --target-identifier arn:aws:organizations::123456789012:ou/o-abc1234xyz/ou-abc-xyz
    Get Enabled Control Details
    aws controltower get-enabled-control \
      --enabled-control-identifier arn:aws:controltower:us-east-1:123456789012:enabledcontrol/CONTROL_ID
    List Enabled Baselines
    aws controltower list-enabled-baselines

    📜Policy Examples

    Dangerous - AWSControlTowerExecution Default Trust (No Conditions)
    {
      "Version": "2012-10-17",
      "Statement": [{
        "Effect": "Allow",
        "Principal": {
          "AWS": "arn:aws:iam::MANAGEMENT_ACCOUNT_ID:root"
        },
        "Action": "sts:AssumeRole"
      }]
    }

    Any identity in the management account with sts:AssumeRole and a wildcard resource policy can assume this role. No MFA, no IP restriction, no principal tag condition.

    Secure - AWSControlTowerExecution with Restrictive Conditions
    {
      "Version": "2012-10-17",
      "Statement": [{
        "Effect": "Allow",
        "Principal": {
          "AWS": "arn:aws:iam::MANAGEMENT_ACCOUNT_ID:root"
        },
        "Action": "sts:AssumeRole",
        "Condition": {
          "StringEquals": {
            "aws:PrincipalTag/team": "platform-engineering"
          },
          "IpAddress": {
            "aws:SourceIp": "203.0.113.0/24"
          }
        }
      }]
    }

    Restricts role assumption to principals tagged as platform-engineering from a known IP range. Reduces blast radius of compromised management account credentials.

    Dangerous - Wildcard AssumeRole in Management Account
    {
      "Version": "2012-10-17",
      "Statement": [{
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "*"
      }]
    }

    Allows assumption of AWSControlTowerExecution in every member account. This is the exact pattern that enables pivoting attacks.

    Secure - Permissions Boundary Blocking AWSControlTowerExecution
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "*",
          "Resource": "*"
        },
        {
          "Effect": "Deny",
          "Action": "sts:AssumeRole",
          "Resource": "arn:aws:iam::*:role/AWSControlTowerExecution"
        }
      ]
    }

    Applied as a Permissions Boundary to all IAM users, roles, and Identity Center Permission Sets in the management account. Prevents unauthorized pivoting to member accounts.

    Secure - SCP Protecting Control Tower Roles
    {
      "Version": "2012-10-17",
      "Statement": [{
        "Sid": "ProtectControlTowerRoles",
        "Effect": "Deny",
        "Action": [
          "iam:AttachRolePolicy",
          "iam:DeleteRole",
          "iam:DeleteRolePolicy",
          "iam:DetachRolePolicy",
          "iam:PutRolePolicy",
          "iam:UpdateAssumeRolePolicy"
        ],
        "Resource": [
          "arn:aws:iam::*:role/AWSControlTowerExecution",
          "arn:aws:iam::*:role/aws-controltower-*"
        ],
        "Condition": {
          "ArnNotLike": {
            "aws:PrincipalArn": "arn:aws:iam::*:role/AWSControlTowerExecution"
          }
        }
      }]
    }

    Prevents member account identities from modifying or deleting Control Tower roles. Only AWSControlTowerExecution itself can modify these roles.

    🛡️Defense Recommendations

    🏢

    Isolate the Management Account

    Run zero production workloads in the management account. Restrict it to Control Tower administration, Organizations management, and billing only. Apply strict identity controls: hardware MFA on root, minimal IAM users, and short-lived sessions via Identity Center.

    🔒

    Apply Permissions Boundaries in Management Account

    Attach Permissions Boundaries to all IAM users, roles, and Identity Center Permission Sets that deny sts:AssumeRole against AWSControlTowerExecution.

    "Effect": "Deny",
    "Action": "sts:AssumeRole",
    "Resource": "arn:aws:iam::*:role/AWSControlTowerExecution"
    🔐

    Add Conditions to AWSControlTowerExecution Trust Policies

    Modify the trust policy on AWSControlTowerExecution in every member account to require specific principal tags, source IP ranges, or named principal ARNs. Must be reapplied after enrollment.

    Enable All Strongly Recommended Controls

    Do not rely only on mandatory controls. Enable all strongly recommended preventive and detective controls. Evaluate elective controls for your threat model.

    📝

    Monitor Control Tower API Calls

    Configure CloudTrail alerts via EventBridge for DisableControl, EnableControl, UpdateLandingZone, ResetLandingZone, DisableBaseline, and AWSControlTowerExecution role assumptions.

    🛡️

    Protect Control Tower Roles via SCP

    Deploy an SCP that denies modification or deletion of AWSControlTowerExecution and aws-controltower-* roles by member account identities.

    🔄

    Monitor and Remediate Drift

    Check landing zone drift status regularly. Enable auto-enrollment to remediate inheritance drift when accounts move between OUs. Alert on drift detection via SNS notifications.

    aws controltower get-landing-zone --landing-zone-identifier LANDING_ZONE_ARN

    AWS Control Tower Security Card • Toc Consulting

    Always obtain proper authorization before testing