Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/powershell/tests/Test-Assessment.21955.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
When local administrators on Microsoft Entra joined devices aren't properly managed, threat actors with compromised credentials can execute device takeover attacks by removing organizational administrators and disabling the device's connection to Microsoft Entra. This lack of control results in complete loss of organizational control, creating orphaned assets that can't be managed or recovered.
When local administrators on Microsoft Entra joined devices are not managed by the organization, threat actors who could compromise user accounts can execute device takeover attacks that result in permanent loss of organizational control. Threat actors can leverage compromised account credentials to perform account manipulation by removing all organizational administrators from the device’s local administrators, including the global administrators who normally retain management access. Once threat actors do that, they can modify user account control settings and disable the device's connection to Microsoft Entra, effectively severing the cloud management channel. This attack progression results in a complete device takeover where organizational global administrators lose all administrative pathways to regain control. The device becomes an orphaned asset that cannot be managed any more.

**Remediation action**

- [Manage the local administrators on Microsoft Entra joined devices](https://learn.microsoft.com/entra/identity/devices/assign-local-admin?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#manage-the-microsoft-entra-joined-device-local-administrator-role)
- [Manage the local administrators on Microsoft Entra joined devices](https://learn.microsoft.com/en-us/entra/identity/devices/assign-local-admin)
<!--- Results --->
%TestResult%

92 changes: 78 additions & 14 deletions src/powershell/tests/Test-Assessment.21955.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,99 @@ function Test-Assessment-21955 {
UserImpact = 'Low'
)]
[CmdletBinding()]
param()
param(
$Database
)

Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose

#region Data Collection
$activity = 'Checking Manage the local administrators on Microsoft Entra joined devices'
Write-ZtProgress -Activity $activity -Status 'Getting policy'

# Query device registration policy
$policy = Invoke-ZtGraphRequest -RelativeUri 'policies/deviceRegistrationPolicy' -ApiVersion beta
# Query role assignments from database
Write-ZtProgress -Activity $activity -Status 'Getting role assignments'
$deviceLocalAdminRoleId = '9f06204d-73c1-4d4c-880a-6edb90606fd8'

$enableGlobalAdmins = ${policy}?.azureADJoin?.localAdmins?.enableGlobalAdmins
# Query database for assigned and eligible users/groups for this role
$sql = "SELECT principalDisplayName, userPrincipalName, `"@odata.type`", principalId, privilegeType
FROM zt.main.vwRole
WHERE roleDefinitionId = '$deviceLocalAdminRoleId';"

$portalLink = 'https://entra.microsoft.com/#view/Microsoft_AAD_Devices/DevicesMenuBlade/~/DeviceSettings/menuId/Overview'
$roleAssignments = Invoke-DatabaseQuery -Database $Database -Sql $sql

Write-PSFMessage "Found $($roleAssignments.Count) role assignments for Azure AD Joined Device Local Administrator" -Level Verbose

# Separate assigned vs eligible
$assignedMembers = $roleAssignments | Where-Object { $_.privilegeType -eq 'Permanent' }
$eligibleMembers = $roleAssignments | Where-Object { $_.privilegeType -eq 'Eligible' }
#endregion Data Collection

$portalLinkMd = "[Global administrator role is added as local administrator on the device during Microsoft Entra join?]($portalLink)`n`n"
#region Assessment Logic

if ($enableGlobalAdmins) {
if ($roleAssignments.Count -gt 0) {
$passed = $true
$testResultMarkdown = "Local administrators on Microsoft Entra joined devices are managed by the organization.`n`n"
$testResultMarkdown += $portalLinkMd
$testResultMarkdown += "- **Yes** → ✅"
$testResultMarkdown = "Local administrators on Microsoft Entra joined devices are managed by the organization.`n`n%TestResult%"
}
else {
$passed = $false
$testResultMarkdown = "Local administrators on Microsoft Entra joined devices are not managed by the organization.`n`n"
$testResultMarkdown += $portalLinkMd
$testResultMarkdown += "- **No** → ❌"
$testResultMarkdown = "Local administrators on Microsoft Entra joined devices are not managed by the organization.`n`n%TestResult%"
}

$portalLink = 'https://entra.microsoft.com/#view/Microsoft_AAD_Devices/DevicesMenuBlade/~/DeviceSettings/menuId/Overview'
$portalLinkMd = "[Device Settings - Global administrator role is added as local administrator]($portalLink)`n`n"
#endregion Assessment Logic

#region Report Generation

# Build detailed markdown
$mdInfo = ''

if ($assignedMembers.Count -gt 0) {
$mdInfo += "`n## Active Microsoft Entra Joined Device Local Administrator assignments`n`n"
$mdInfo += "| Display Name | UPN | Type | Assignment Type |`n"
$mdInfo += "| :----------- | :--- | :-- | :-------------- |`n"

foreach ($member in ($assignedMembers | Sort-Object -Property principalDisplayName)) {
$objectType = if ($member.'@odata.type' -eq '#microsoft.graph.user') { 'User' } else { 'Group' }
$upn = if ($member.userPrincipalName) { $member.userPrincipalName } else { '-' }

$portalLink = if ($member.'@odata.type' -eq '#microsoft.graph.user') {
"https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/$($member.principalId)"
} else {
"https://entra.microsoft.com/#view/Microsoft_AAD_IAM/GroupDetailsMenuBlade/~/Overview/groupId/$($member.principalId)"
}

$mdInfo += "| [$(Get-SafeMarkdown($member.principalDisplayName))]($portalLink) | $upn | $objectType | $($member.privilegeType) |`n"
}
}

if ($eligibleMembers.Count -gt 0) {
$mdInfo += "`n## Eligible Microsoft Entra Joined Device Local Administrator assignments`n`n"
$mdInfo += "| Display Name | UPN | Type | Assignment Type |`n"
$mdInfo += "| :----------- | :--- | :-- | :-------------- |`n"

foreach ($member in ($eligibleMembers | Sort-Object -Property principalDisplayName)) {
$objectType = if ($member.'@odata.type' -eq '#microsoft.graph.user') { 'User' } else { 'Group' }
$upn = if ($member.userPrincipalName) { $member.userPrincipalName } else { '-' }

$portalLink = if ($member.'@odata.type' -eq '#microsoft.graph.user') {
"https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/$($member.principalId)"
} else {
"https://entra.microsoft.com/#view/Microsoft_AAD_IAM/GroupDetailsMenuBlade/~/Overview/groupId/$($member.principalId)"
}

$mdInfo += "| [$(Get-SafeMarkdown($member.principalDisplayName))]($portalLink) | $upn | $objectType | $($member.privilegeType) |`n"
}
}

if ($roleAssignments.Count -eq 0) {
$mdInfo = "`n❌ No assigned or eligible users/groups found for the Microsoft Entra Joined Device Local Administrator role.`n"
}

# Replace placeholder with detailed information
$testResultMarkdown = $testResultMarkdown -replace '%TestResult%', $mdInfo
#endregion Report Generation

$params = @{
TestId = '21955'
Status = $passed
Expand Down