AWS ECS Defense: Task Definition Hardening Guide
Overview & Defensive Context: Mitigating Control Plane Hijacking in AWS ECS#
Harden AWS ECS against task overrides: enforce strict RunTask IAM condition keys, disable ECS Exec, and block container metadata exfiltration.
In our morning offensive architecture analysis, we demonstrated how low-privileged IAM identities exploit AWS Elastic Container Service (ECS) task definition command overrides (mapped to MITRE ATT&CK T1078.004: Valid Accounts: Cloud Accounts, T1552.005: Unsecured Credentials: Cloud Instance Metadata API, T1059.004: Command and Scripting Interpreter: Unix Shell, and T1611: Escape to Host). We showed that granting ecs:RunTask on existing task definitions allows an attacker to bypass iam:PassRole checks on the Amazon EC2 launch type. By injecting arbitrary commands into the containerOverrides parameter, the newly spawned container queries the link-local task metadata service (169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI) and exfiltrates temporary AWS Security Token Service (STS) credentials for high-privilege taskRoleArn identities. Furthermore, we analyzed how interactive debugging features like ECS Exec (ecs:ExecuteCommand) provide direct interactive root shells inside production containers, completely evading traditional perimeter network defenses.
For cloud security architects, principal DevSecOps engineers, and enterprise blue teams, defending containerized orchestration platforms against control plane abuse reveals several critical architectural pitfalls:
The Inadequacy of Standard Network Firewalls: Traditional perimeter security controls, such as Security Groups and Network Access Control Lists (NACLs), operate at the network layer (L3/L4). However, task command overriding is an AWS API control plane operation executed via TLS to ecs.amazonaws.com. Network firewalls cannot inspect or block the malicious payload embedded within the AWS API request; by the time the container boots and connects to the network, the command has already executed.
The Peril of Wildcard IAM Resource Definitions: Organizations commonly author IAM policies using wildcard patterns such as arn:aws:ecs:us-east-1:123456789012:task-definition/data-app:* or grant ecs:RunTask on * resources. Because AWS evaluates task definition families dynamically across revisions, a user permitted to run a low-privilege batch job can pivot to run an active administrative task definition within the same account.
The Necessity of Organizational Service Control Policies (SCPs): Local IAM policies configured within individual AWS accounts are prone to configuration drift, developer overrides, and permissive modifications. Enforcing immutable guardrails against task overrides requires top-down governance via AWS Organizations Service Control Policies (SCPs), ensuring that no principal—even a local account administrator—can dispatch unvetted container overrides in production.
The Five-Tier Defense Blueprint: Neutralizing ECS privilege escalation demands layered controls across five operational planes: scoping IAM policies with strict condition keys (ecs:TaskDefinition, ecs:cluster), enforcing organizational SCPs to disallow overrides, disabling interactive ECS Exec across production clusters, restricting network egress via AWS PrivateLink and metadata packet filtering, and implementing continuous eBPF and CloudTrail detection streams.
Permitting ecs:RunTask without explicit condition keys effectively grants the calling identity the cumulative privileges of every taskRoleArn associated with accessible task definitions.
⚔️ Exploitation Mechanics: For root-cause memory corruption analysis and attack flow, see our deep-dive: Deconstructing Breakdown.
Architecture Hardening: Five-Tier Defense-in-Depth for AWS ECS#
Securing Amazon ECS against command override exploitation, interactive shell injection, and metadata credential harvesting requires enforcing defense-in-depth across the IAM policy engine, organizational guardrails, container runtime, network routing, and continuous event telemetry.
Defensive Architecture Flowchart#
flowchart TD
classDef client fill:#1e293b,stroke:#ef4444,stroke-width:2px,color:#f8fafc
classDef gate fill:#0f172a,stroke:#3b82f6,stroke-width:2px,color:#93c5fd
classDef secure fill:#064e3b,stroke:#10b981,stroke-width:2px,color:#6ee7b7
classDef audit fill:#4c1d95,stroke:#8b5cf6,stroke-width:2px,color:#ddd6fe
classDef drop fill:#450a0a,stroke:#dc2626,stroke-width:2px,color:#fca5a5
classDef pass fill:#065f46,stroke:#34d399,stroke-width:2px,color:#a7f3d0
Caller[Caller Invocations: aws ecs run-task / start-task]:::client --> SCPGate{Tier 1: AWS Organizations SCP Evaluation}:::gate
SCPGate -- Contains Disallowed containerOverrides on Prod Cluster --> DropSCP[Action: Deny by SCP Guardrail]:::drop
DropSCP --> SIEMAlert1[Log SCP Authorization Failure to SIEM]:::audit
SCPGate -- Clean Request or Approved Task Launch --> IAMGate{Tier 2: IAM Principal Policy Evaluation}:::gate
IAMGate -- TaskDefinition Revision Mismatch or Wrong Cluster --> DropIAM[Action: Deny by ecs:TaskDefinition Condition]:::drop
DropIAM --> SIEMAlert2[Log Unauthorized Task Launch Attempt]:::audit
IAMGate -- Exact Match: Approved Task Definition & Cluster --> ExecGate{Tier 3: ECS Exec Policy Check}:::gate
ExecGate -- enableExecuteCommand=true on Production Task --> BlockExec[Action: Deny ecs:ExecuteCommand via SCP]:::drop
ExecGate -- Non-Interactive Standard Deployment --> HostDispatch[Dispatch Container Placement to Host]:::pass
HostDispatch --> NetGate{Tier 4: Network & Metadata Isolation: 169.254.170.2}:::gate
NetGate -- Outbound to Unknown Internet IP / C2 Listener --> DropNet[Action: Drop Egress at Private Subnet Boundary]:::drop
DropNet --> SIEMAlert3[Log Outbound C2 Connection Block]:::audit
NetGate -- Container Queries 169.254.170.2 via Approved Route --> AgentProxy[ECS Container Agent Serves Scoped STS Token]:::secure
AgentProxy --> RuntimeTelemetry{Tier 5: EventBridge & GuardDuty ECS Telemetry}:::gate
RuntimeTelemetry -- Anomalous Shell Spawn or Metadata Exfil Pattern --> SOCAlert[Action: Trigger GuardDuty Alert & Quarantine Host]:::audit
RuntimeTelemetry -- Standard Application Workload Execution --> NormalOps[Permit Workload Completion & Log Metrics]:::secureTier 1 & Tier 2: IAM Policy Scoping and Organizational Service Control Policies (SCPs) The most effective line of defense against ECS task definition abuse is strict policy authoring within the AWS IAM control plane. Security engineers must enforce least-privilege principles by eliminating wildcards and binding execution permissions directly to validated cluster and task definition ARNs. Scoping IAM Policies with ecs:TaskDefinition and ecs:cluster Condition Keys When developers or continuous integration pipelines require the ability to run tasks, their IAM policies must explicitly mandate:
Exact Task Definition ARN and Revision: Do not permit wildcards (*) in the revision suffix. Specify the exact numerical revision (e.g., :4) or enforce dynamic tag matching.
Explicit Cluster Scoping: Use the ecs:cluster condition key to restrict task placement exclusively to designated non-production or staging clusters.
Mandatory Launch Type Enforcement: Restrict whether the task can run on EC2 or Fargate using the ecs:launch-type condition key.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowScopedRunTaskWithConditionKeys",
"Effect": "Allow",
"Action": [
"ecs:RunTask"
],
"Resource": "arn:aws:ecs:us-east-1:123456789012:task-definition/enterprise-data-pipeline:4",
"Condition": {
"ArnEquals": {
"ecs:cluster": "arn:aws:ecs:us-east-1:123456789012:cluster/staging-batch-cluster"
},
"StringEquals": {
"ecs:launch-type": "FARGATE"
}
}
},
{
"Sid": "AllowTaskMonitoringOnly",
"Effect": "Allow",
"Action": [
"ecs:DescribeTasks",
"ecs:ListTasks"
],
"Resource": "*"
}
]
}
Top-Down Guardrail: Service Control Policy (SCP) to Block Overrides Within AWS Organizations, platform security architects can deploy a Service Control Policy to prevent unapproved principals from submitting containerOverrides or altering environment variables on production workloads.
The following SCP denies ecs:RunTask and ecs:StartTask across member accounts unless the request is originated by an authorized continuous deployment role or excludes runtime overrides:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyUnauthorizedECSContainerOverrides",
"Effect": "Deny",
"Action": [
"ecs:RunTask",
"ecs:StartTask"
],
"Resource": "",
"Condition": {
"Null": {
"ecs:containerOverrides": "false"
},
"StringNotLike": {
"aws:PrincipalArn": [
"arn:aws:iam:::role/EnterpriseProductionDeploymentPipelineRole",
"arn:aws:iam:::role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS"
]
}
}
},
{
"Sid": "DenyProductionECSExec",
"Effect": "Deny",
"Action": [
"ecs:ExecuteCommand"
],
"Resource": "arn:aws:ecs:::cluster/production-",
"Condition": {
"StringNotLike": {
"aws:PrincipalArn": [
"arn:aws:iam::*:role/EmergencyIncidentResponseAdminRole"
]
}
}
}
]
}
Tier 3: Hardening ECS Exec and Session Manager Boundaries#
AWS Systems Manager (SSM) Session Manager powers ECS Exec (ecs:ExecuteCommand), providing interactive shell connectivity directly into container namespaces without requiring open inbound SSH ports or bastion hosts. However, when misconfigured, ECS Exec bypasses network controls and grants interactive shell access to any container holding a high-privilege taskRoleArn. Disabling ECS Exec across Production Services By default, ECS Exec is disabled unless explicitly enabled during service creation or task launch via the --enable-execute-command flag. Security teams must ensure this setting remains disabled across production services.
To audit and remediate existing services:
# 1. Enumerate all services with ECS Exec enabled
aws ecs list-services --cluster production-core-cluster --region us-east-1
| jq -r '.serviceArns[]'
| while read service; do
enabled=$(aws ecs describe-services --cluster production-core-cluster --services "$service" --region us-east-1
--query "services[0].enableExecuteCommand" --output text)
if [ "$enabled" == "true" ]; then
echo "[!] WARNING: ECS Exec is ENABLED on $service"
fi
done
2. Disable ECS Exec on a flagged production service
aws ecs update-service
--cluster production-core-cluster
--service customer-api-service
--no-enable-execute-command
--region us-east-1
Stripping SSM Permissions from Task Roles ECS Exec requires the container's taskRoleArn to possess permissions to communicate with AWS Systems Manager messaging channels. Removing these permissions guarantees that even if an attacker enables ECS Exec on a task, the SSM agent inside the container fails to establish an interactive session.
Ensure that no production taskRoleArn contains the following SSM permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenySSMMessageChannelsOnTaskRoles",
"Effect": "Deny",
"Action": [
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Resource": "*"
}
]
}
Tier 4: Network Isolation, VPC Endpoints & Metadata Protection#
If an attacker manages to trigger an overridden task, strict network controls prevent the container from communicating with external command-and-control listeners or querying unauthorized cloud infrastructure.
Restricting Outbound Egress via Private Subnets and Security Groups#
ECS tasks should never be deployed into public subnets with direct Internet Gateways (IGW). Instead, tasks must reside within private subnets where outbound traffic is strictly governed:
Private Subnets with AWS PrivateLink: Provision interface VPC Endpoints for required AWS services (com.amazonaws.region.ecs, com.amazonaws.region.ecs-agent, com.amazonaws.region.ecs-telemetry, com.amazonaws.region.ecr.api, com.amazonaws.region.ecr.dkr, and com.amazonaws.region.s3). By keeping traffic entirely within the AWS private network backbone, containers have no default route to the public internet.
Egress Security Group Whitelisting: Configure the container's security group to deny all outbound traffic by default (0.0.0.0/0), allowing outbound TCP 443 strictly to internal VPC Endpoint security groups and authorized database subnets.
AWS Network Firewall and DNS Filtering: If external API access is required (e.g., calling third-party payment gateways), route traffic through AWS Network Firewall with stateful domain name filtering (SNI inspection) to block arbitrary external IP connections.
Hardening Task Metadata Access on EC2 Container Instances#
On the Amazon EC2 launch type, the ECS container agent exposes metadata via 169.254.170.2. To prevent containers running in host network mode from accessing the instance metadata service (IMDS) of the host EC2 instance:
Set the following configuration parameter in /etc/ecs/ecs.config on all container instance AMIs:
# /etc/ecs/ecs.config
ECS_ENABLE_TASK_IAM_ROLE=true
ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=false
ECS_AWSVPC_BLOCK_IMDS=true
Setting ECS_AWSVPC_BLOCK_IMDS=true instructs the agent to inject iptables firewall rules blocking tasks running in awsvpc network mode from accessing the underlying EC2 host metadata endpoint (169.254.169.254), preventing lateral movement from container tasks to host instance profiles.
Tier 5: Production Detection Queries and Monitoring Blueprints#
Detecting ECS privilege escalation in real time requires multi-source telemetry combining AWS CloudTrail management events, Amazon EventBridge rules, and Amazon GuardDuty runtime telemetry.
Production Sigma Rule: CloudTrail ECS RunTask Command Overrides#
Deploy the following Sigma rule within your Security Information and Event Management (SIEM) platform (e.g., Splunk, Microsoft Sentinel, Elastic, Datadog) to alert on anomalous task launches containing command overrides:
title: AWS ECS Task Launched with Suspicious Command Overrides
id: 4b1c7a8f-2e9d-4821-bc30-f92e01b45289
status: stable
description: Identifies AWS CloudTrail RunTask or StartTask management events where containerOverrides are supplied, indicating potential privilege escalation or metadata exfiltration.
references:
- https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-metadata-endpoint.html
- https://attack.mitre.org/techniques/T1552/005/
- https://attack.mitre.org/techniques/T1078/004/
tags:
- attack.privilege_escalation
- attack.credential_access
- attack.t1078.004
- attack.t1552.005
- attack.t1611
logsource:
service: cloudtrail
product: aws
detection:
selection_event:
eventSource: 'ecs.amazonaws.com'
eventName:
- 'RunTask'
- 'StartTask'
selection_overrides:
requestParameters.overrides.containerOverrides|contains:
- 'command'
- 'environment'
filter_approved_ci_cd:
userIdentity.arn|contains:
- 'role/EnterpriseProductionDeploymentPipelineRole'
- 'role/aws-service-role/ecs.amazonaws.com'
condition: selection_event and selection_overrides and not filter_approved_ci_cd
fields:
- eventTime
- userIdentity.arn
- userIdentity.userName
- sourceIPAddress
- requestParameters.cluster
- requestParameters.taskDefinition
- requestParameters.overrides
- responseElements.tasks.taskArn
falsepositives:
- Authorized batch processing tools that explicitly pass non-malicious arguments (must be whitelisted by role ARN)
level: high
Amazon EventBridge Real-Time Alerting Rule Configure Amazon EventBridge to capture CloudTrail events instantaneously and trigger an automated AWS Lambda quarantine function or alert a dedicated security Slack channel:
{
"source": ["aws.ecs"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {
"eventSource": ["ecs.amazonaws.com"],
"eventName": ["RunTask", "StartTask", "ExecuteCommand"],
"requestParameters": {
"overrides": {
"containerOverrides": [{
"command": [{ "exists": true }]
}]
}
}
}
}
Host-Level eBPF / Auditd Rule for Container Process Spawning On EC2 container host instances, blue teams can monitor container processes directly at the kernel boundary. Deploy the following Linux auditd rule to track any child processes spawned within container cgroups that invoke interactive shells or exfiltration utilities:
/etc/audit/rules.d/99-ecs-container-monitoring.rules#
### Monitor execution of shells inside container namespaces
-a always,exit -F arch=b64 -S execve -F exe=/bin/sh -k ecs_container_shell
-a always,exit -F arch=b64 -S execve -F exe=/bin/bash -k ecs_container_shell
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/curl -k ecs_container_network_tool
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/wget -k ecs_container_network_tool
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/nc -k ecs_container_network_tool
Enterprise Mitigation Matrix: Comparing Strategic Controls The following matrix evaluates the trade-offs, deployment complexities, and operational risk factors associated with implementing ECS task security controls:
Defensive Layer Mitigation Strategy Implementation Complexity Performance Overhead Operational Disruption Risk Security Effectiveness IAM Policy Scoping Exact ecs:TaskDefinition revision and ecs:cluster condition keys Low (Policy update) Zero latency impact Low (Requires updating developer policies) High (Eliminates Wildcard Abuse) Organizations SCP Deny containerOverrides for unauthorized roles at organization root Low to Medium Zero latency impact Medium (May impact non-standard batch pipelines) Critical (Enforces Enterprise Guardrail) ECS Exec Disablement Disable enableExecuteCommand across all production services Low (Single API call) Zero latency impact Low (Requires developers to use staging for debugging) High (Blocks Interactive Hijacking) Network Egress Lockdown Private subnets + AWS PrivateLink VPC Endpoints; deny internet Medium (Network routing) Improved (Keeps traffic on AWS backbone) Low (Well-architected standard practice) High (Prevents Outbound C2 Exfiltration) Metadata Protection Set ECS_AWSVPC_BLOCK_IMDS=true and enforce IMDSv2 hop limits Low (Host config) Zero latency impact Low (Does not disrupt task metadata endpoint) High (Prevents Host Metadata Theft) Runtime Detection Deploy EventBridge rules + GuardDuty ECS Runtime Monitoring Low to Medium Negligible agent overhead None (Passive monitoring & alerting) High (Provides Real-Time Incident Visibility) Incident Response & Verification Playbook When an alert flags suspected ECS task definition abuse or unauthorized command overrides, security responders must execute the following structured response playbook: Step-by-Step Response Checklist
Phase 1: Immediate Containment and Task Termination#
Identify the suspicious task ARN and cluster name from the CloudTrail or EventBridge alert.
Terminate the rogue container immediately using aws ecs stop-task --cluster <cluster_name> --task <task_arn> --reason "Suspected compromise via containerOverrides".
If ECS Exec was active on the task, terminate the active SSM session via aws ssm terminate-session --session-id <session_id>.
Identify the compromised IAM principal that invoked RunTask and apply an explicit Deny policy or deactivate its access keys immediately.
Phase 2: Credential Invalidation and Blast Radius Assessment#
Inspect the taskDefinitionArn of the compromised task to extract its attached taskRoleArn.
Assume all temporary STS credentials issued to that taskRoleArn within the past 12 hours are compromised.
Revoke all active STS sessions for the role by attaching an inline revocation policy with a PrincipalArn timestamp cutoff:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "",
"Resource": "",
"Condition": {
"DateLessThan": {
"aws:TokenIssueTime": "2026-11-03T15:30:00Z"
}
}
}
]
}
- Query AWS CloudTrail for all API activity performed using the assumed role identity within the incident window (userIdentity.arn matching assumed-role/
/ ).
Phase 3: Forensic Extraction and Network Flow Analysis#
Review Amazon VPC Flow Logs for outbound network connections originating from the container's private IP address to public IP destinations.
If the container was running on EC2, capture the container filesystem and Docker inspect logs before terminating the EC2 worker node.
Review CloudWatch Logs for the container's log stream to inspect standard output (stdout) and error streams (stderr).
Phase 4: Long-Term Policy Hardening and Verification#
Audit all IAM policies in the account for unconstrained ecs:RunTask and ecs:StartTask actions using the AWS IAM Policy Simulator.
Deploy the AWS Organizations Service Control Policy blocking containerOverrides across all member accounts.
Confirm that enableExecuteCommand is set to false across all production ECS services.
Execute the blue-team verification commands below to confirm policy enforcement.
Executive Takeaway Table: Threat Vectors, Telemetry Signals, and Primary Mitigations#
The following matrix consolidates the attack mechanisms, defensive telemetry signals, and required engineering controls for securing AWS ECS against task definition privilege escalation:
Attack Vector / Technique Primary Exploitation Mechanism Telemetry & Detection Signal Recommended Mitigation Verification Command RunTask Command Overrides (T1552.005) Caller passes containerOverrides with shell commands to harvest metadata CloudTrail RunTask event with requestParameters.overrides.containerOverrides populated Deploy SCP denying containerOverrides; scope IAM policies with ecs:TaskDefinition
aws iam simulate-principal-policy --action ecs:RunTask
Fargate Task Role Hijacking (T1078.004) Attacker launches serverless task with command overrides to steal STS credentials CloudWatch VPC Flow Logs showing outbound HTTP/S to unknown external IPs Implement VPC endpoints for ECS; restrict task subnet egress via security groups aws ec2 describe-vpc-endpoints --filters "Name=service-name,Values=ecs" Interactive ECS Exec Injection (T1059.004) Attacker uses ecs:ExecuteCommand to spawn interactive SSM shell in container CloudTrail ExecuteCommand events; SSM Session Manager session start logs Explicitly deny ecs:ExecuteCommand across production clusters via IAM SCP
aws ecs describe-services --query "services[*].enableExecuteCommand"
Task Definition Revision Creep (T1611) Attacker targets legacy task definitions retaining obsolete high-privilege roles CloudTrail DescribeTaskDefinition queries enumerating inactive revisions Deregister and delete obsolete task definitions containing over-privileged roles
aws ecs list-task-definitions --status INACTIVE
Metadata Endpoint Exfiltration Container process queries 169.254.170.2 to retrieve temporary session keys AWS GuardDuty finding: CredentialAccess:IAMUser/InstanceCredentialExfiltration Deploy egress proxy / Cilium network policies blocking non-essential metadata traffic Audit container network namespace routing tables
Authoritative References & Standards#
Amazon Web Services Documentation: Amazon ECS Task Metadata Endpoint & Credentials — AWS ECS Developer Guide
AWS Security Reference Architecture: IAM Policy Evaluation and Least Privilege in Container Workloads — AWS SRA Documentation
MITRE ATT&CK Framework: Technique T1552.005: Unsecured Credentials: Cloud Instance Metadata API — MITRE ATT&CK
MITRE ATT&CK Framework: Technique T1078.004: Valid Accounts: Cloud Accounts — MITRE ATT&CK Cloud
Sigma Project Repository: Generic CloudTrail Detection Rules for AWS Management Events — Sigma GitHub Repository
Comments
Post a Comment