Detection Script: Identifying and Removing Unauthorized Local Admins
This blog post will walk you through the detection script, which aims to identify and remove unauthorized local admins from a Windows system. The script is designed to run as an administrator and uses various PowerShell cmdlets to achieve its goal.
Prerequisites
The Script
The script starts by clearing the console host and setting the security protocol for .NET ServicePointManager to TLS12. This is necessary because older versions of TLS may not be supported in modern systems.
Clear-Host
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Next, the script checks if it is running as an administrator. If not, it throws an error and terminates.
#Require Admin Privileges
If (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
[Security.Principal.WindowsBuiltInRole] "Administrator"))
{ throw "This script must be run as an administrator." }
The script then initializes a counter variable, $bad, to track the number of unauthorized local admins found.
$bad = 0
It then uses the Invoke-WebRequest cmdlet to fetch a list of excluded members from a SAS storage URL. The output is saved as a file named excluded.txt in the Windows temp directory.
invoke-webrequest -uri "[url to sas storage excluded.txt]" -OutFile c:\Windows\temp\excluded.txt
The script then reads the contents of the excluded.txt file into an array called $excludedmembers.
$excludedmembers = get-content C:\Windows\temp\excluded.txt
Next, it retrieves a list of local admins using the Get-LocalGroupMember cmdlet. The script then filters this list to exclude members that are not users and are not part of the Domain Admins group.
$localadmins = get-localgroupmember -Group Administrators | Where-Object { $_.PrincipalSource -ne 'Local' -and $_.objectclass -eq 'user' -and $_.name -ne "$env:userdomain\Domain Admins" } | Select-Object -ExpandProperty Name
The script then iterates over the list of local admins and checks if each member is excluded. If they are, it skips them; otherwise, it writes a message indicating that the user should not be in local admins and increments the $bad counter.
foreach ($user in $localadmins) {
if ($excludedmembers -like $user) {
Write-output "$user is excluded, skipping"
}
else {
Write-Output "$user shouldn't be in local admins, removing"
$bad++
#Remove-LocalGroupMember -Group administrators -Member $user -WhatIf -Verbose
}
}
Finally, the script checks if any unauthorized local admins were found. If so, it exits with an error code of 1; otherwise, it exits successfully.
if ($bad -gt 0 ) {
exit 1
} else {
exit 0
}
Before exiting, the script removes the temporary file containing the list of excluded members.
remove-item C:\Windows\temp\excluded.txt
How It Works
Section 1: Initialization and Security Settings
The script starts by initializing the console host and setting the security protocol for .NET ServicePointManager to TLS12.
Clear-Host
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Section 2: Checking Admin Privileges and Fetching Excluded Members
The script then checks if it is running as an administrator. If not, it throws an error and terminates.
#Require Admin Privileges
If (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
[Security.Principal.WindowsBuiltInRole] "Administrator"))
{ throw "This script must be run as an administrator." }
The script then initializes a counter variable, $bad, to track the number of unauthorized local admins found.
$bad = 0
It then uses the Invoke-WebRequest cmdlet to fetch a list of excluded members from a SAS storage URL. The output is saved as a file named excluded.txt in the Windows temp directory.
invoke-webrequest -uri "[url to sas storage excluded.txt]" -OutFile c:\Windows\temp\excluded.txt
The script then reads the contents of the excluded.txt file into an array called $excludedmembers.
$excludedmembers = get-content C:\Windows\temp\excluded.txt
Key Code Snippets
$localadmins = get-localgroupmember -Group Administrators | Where-Object { $_.PrincipalSource -ne 'Local' -and $_.objectclass -eq 'user' -and $_.name -ne "$env:userdomain\Domain Admins" } | Select-Object -ExpandProperty Name
foreach ($user in $localadmins) {
if ($excludedmembers -like $user) {
Write-output "$user is excluded, skipping"
}
else {
Write-Output "$user shouldn't be in local admins, removing"
$bad++
#Remove-LocalGroupMember -Group administrators -Member $user -WhatIf -Verbose
}
}
Usage Examples
This script is designed to run as an administrator and requires a SAS storage URL as input. The script will identify and remove any unauthorized local admins from the system.
Conclusion
The detection script provides a powerful tool for identifying and removing unauthorized local admins from a Windows system. By combining various PowerShell cmdlets, this script can help you maintain the security and integrity of your systems.