Håll koll på grupperna
Bakgrund
I en AD-domän styrs en hel del behörigheter av säkerhetsgrupper, och med diverse arv och stort antal grupper etc. blir det snabbt oöverskådligt vilka grupper varje användare är med i.
För att bibehålla en god säkerhetshälsa bör man regelbundet gå igenom behörigheter och verifiera att de fortfarande är aktuella, och rensa bort de som inte är det.
En företagsledning eller andra i verksamheten som beslutar om behörigheter har ofta inte själva tillgång till de administrationsverktyg som behövs för att kika direkt i AD:t (exempelvis ”Users & Computers”).
I det syftet fick jag tidigare i uppdrag av vår företagsledning att ta ut en överskådlig lista på alla användares gruppmedlemskaper i AD.
Ett problem med de flesta skript och beskrivningar som jag sett på nätet är att de oftast bara tittar på användarens direkta medlemskap, och inte tar hänsyn till nästlade grupper, alltså såna grupper som är medlem i en eller fler andra grupper vars medlemskap därmed ärvs till användaren. Såna grupper kan även lätt missas när man använder de vanliga administrationsverktygen.
I bilden ovan syns att användaren Hjulben är medlem i två grupper. För att upptäcka nästlade grupper måste man klicka vidare till varje av de aktuella gruppernas egenskaper och titta på om de är medlemmar i annan grupp. I Hjulbens fall fanns exempelvis Testgrupp 1, som när man kikar vidare är medlem i Testgrupp 2, som man i sin tur får titta vidare på osv. Att manuellt sitta och klicka vidare för att följa alla sådana nästlingar blir lätt förvirrande och oöverskådligt (om den som tittar ens inser att man måste göra den kontrollen).
Så jag tänkte dela med mig av mitt powershell-skript som är ganska enkelt och inte på något sätt banbrytande eller innovativt, men det kan kanske vara till hjälp för någon som behöver göra en behörighetskontroll i sitt (eller kunds) AD.
Skriptet kollar alltså upp alla användares grupptillhörigheter (inklusive nästlade sådana), skapar en överskådlig lista av detta samt exporterar resultatet till en Excel-fil med färdiga filtreringsbara kolumner, direkt redo att lämnas över till berörda behörighetsansvariga. Man kan även exportera till CSV-fil om man skulle föredra det.
Skriptet kan även vara till hjälp i penetrationstest och granskningar av AD-miljöer, om man inte har möjlighet eller tillstånd att använda mer avancerade verktyg såsom Bloodhound[1] eller liknande, utan behöver köra något enklare och mer windowsnativt.
Förhandskrav
Skriptet använder Powershell-modulerna:
ActiveDirectory-modulen kräver installation av RSAT-verktyget för ADDS[2]. Detta görs (på moderna Windows) på inställningssidan för valfria funktioner:
Därefter kan man som admin köra kommandot:
import-module ActiveDirectory
ImportExcel-modulen kan hämtas och installeras via kommandot:
Install-Module -Name ImportExcel
Om man ska köra skriptet på icke internetansluten dator eller av annan anledning föredrar manuell installation, finns en länk till modulfilen på PowerShell Gallery via länk i referens [3].
Anpassa/köra skriptet
I princip går det att bara köra skriptet som det är på en dator medlem i den domän som ska granskas, så länge förhandskraven är uppfyllda och då framför allt att AD-modulen fungerar.
Det rekommenderas dock starkt att köra som eleverad användare för att undvika konstiga resultat. Av någon anledning tillåts exempelvis inte vanliga användare använda flaggan ”enabled” i just filtret i kommandot Get-ADUser, även om man får läsa den i övrigt. Givetvis kan det även finnas behörighetsbegränsningar satta i organisationen som ger en administratör bättre möjligheter att få ut mer kompletta resultat.
Tips på anpassningar:
- Har ni inte möjlighet att installera Excel-modulen, bör ni för att undvika felmeddelanden kommentera bort raderna 36 samt 64.
- Vill ni bara granska användare i ett specifikt OU eller annan containertyp, lägg i kommandot på rad 39 till exempelvis något av argumenten
- -SearchBase ”CN=Users,DC=DINCOMDOMÄN,DC=com”
- -SearchBase ”OU=Stockholmskontoret,DC=DINSEDOMÄN,DC=se”
- Vill ni byta sökväg/filnamn på de skapade filerna, ändra på rad 58 för Excelfilen, och på rad 60 för CSV-filen. Som det är nu sparas de i aktuellt working directory.
- Nu exporterar skriptet både Excel- samt CSV-fil. Vill ni inaktivera ett format, kommentera bort rad 64 respektive 67.
Om Excel-fil med samma sökväg/namn redan finns läggs det till en ny flik med dagens datum till den gamla filen. På så sätt kan man ha historik från tidigare körningar i samma fil. För csv-filerna innehåller filnamnet aktuellt datum istället.
Exempel
Min demokörning gav resultatet nedan.
Kolumnen ”Nästling” visar hur medlemskap leder fram till den aktuella slutgruppen i Gruppnamn-kolumnen. Om Nästling-kolumnen är tom har användaren direkt medlemskap i den aktuella gruppen. Övriga kolumner förklarar sig själva.
I standard AD-verktygen ser användaren Rick Astleys medlemskap vid första anblick rätt ointressant ut om man inte tittar vidare, men i den genererade listan kan man exempelvis lätt kan se att Rick är medlem i fler grupper som på olika sätt indirekt ger honom åtkomst till SuperDuperDomänAdmin-kontot. Så även om man exempelvis skulle ta bort hans medlemskap i Testgrupp 1, som via Testgrupp 2 leder till Domänadmin, så leder fortfarande medlemskapet i Testgrupp 3 till samma behörighet via två olika vägar.
Här visas en av vägarna man lätt hittar i den skriptgenererade listan:
Det något friskt kommenterade skriptet finns att ladda ned här:
Eller kopiera texten här och klistra in i egen ps1-fil:
Clear-Host
# Funktion för att lägga till behörighetsposter i lista (rekursivt om applicerbart)
# Ingående parametrar är aktuell AD-användare, aktuell AD-grupp, samt en sträng som representerar "sökvägen" med övergrupper för ett nästlat gruppmedlemsskap
function AddBehorighet {
Param ([parameter(Mandatory=$true)] $user, [parameter(Mandatory=$true)] $group, $nestedPath)
# Skapa ett nytt customobjekt med de egenskaper/kolumner vi vill ha med, som sen blir en behörighetspost (rad i listan)
$behorighet = New-Object System.Object
$behorighet | Add-Member -MemberType NoteProperty -Name "Användarnamn" -Value $user.name
$behorighet | Add-Member -MemberType NoteProperty -Name "Användarbeskrivning" -Value $user.description
$behorighet | Add-Member -MemberType NoteProperty -Name "Nästling" -Value $nestedPath
$behorighet | Add-Member -MemberType NoteProperty -Name "Gruppnamn" -Value $group.name
$behorighet | Add-Member -MemberType NoteProperty -Name "Gruppkategori" -Value $group.GroupCategory
$behorighet | Add-Member -MemberType NoteProperty -Name "Gruppbeskrivning" -Value $group.description
if ($user.LastLogonDate -ne $null)
{
$behorighet | Add-Member -MemberType NoteProperty -Name "Användare senast inloggad" -Value $user.LastLogonDate.Date.ToShortDateString()
}
# Lägg till behörighetsposten i listan
$behorighetslista.Add($behorighet) | Out-Null
# För aktuell grupp, läs in eventuella övergrupper som den är medlem i
$group = Get-ADGroup -Identity $group.SamAccountName -Properties MemberOf
# För varje sådan övergrupp, gör ett rekursivt anrop till denna funktion för att lägga till gruppen som ytterligare en behörighetspost
foreach ($memberof in $group.MemberOf)
{
$parentGroup = Get-ADGroup -Identity $memberof -Properties Name, Description
AddBehorighet $user $parentGroup ($nestedPath + $group.name + " -> ")
}
}
# För export till Excel-fil krävs installation av modulen ImportExcel (kommenteras bort om ImportExcel-modulen inte kan installeras)
Import-module ImportExcel
# Dra ut användare ur hela AD:t (eller lägg till SearchBase som argument nedan, exempelvis: -SearchBase "CN=Users,DC=DINDOMÄN,DC=com") och ta då bara med aktiva användare. Säkerställ att egenskaperna namn, beskrivning och sista inloggningsdatum finns med.
$relevantaanvandare = Get-ADUser -Filter "objectclass -eq 'user' -and enabled -eq 'true'" -Properties Name, Description, LastLogonDate
# Initiera en arraylista för att spara våra customobject i
$behorighetslista = New-Object System.Collections.ArrayList
# Extrahera de egenskaper vi vill ha med för varje användare och spara i listan
foreach ($anvandare in $relevantaanvandare)
{
# Extrahera de grupper användaren är medlem i, och säkerställ att egenskaperna namn och beskrivning finns med. Sortera även så distributionsgrupper kommer under säkerhetsgrupper.
$anvandaresgrupper = Get-ADPrincipalGroupMembership $anvandare | Get-ADGroup -Properties Name, Description | Sort-Object -Property @{Expression = "GroupCategory"; Descending=$true}, @{Expression = "Name"; Descending=$false}
# För varje grupp användaren är medlem i, kalla den rekursiva funktionen ovan för att lägga till aktuell behörighetspost samt dess nästlade behörighetsposter i listan
foreach ($grupp in $anvandaresgrupper)
{
AddBehorighet $anvandare $grupp ""
}
}
# Ange en önskad sökväg/filnamn för Excelfilen (just nu sparas den i det aktuella working directoryt).
$exportexcelpath = ".\Behörighetslista.xlsx"
# Ange en önskad sökväg/filnamn för CSV-filen (just nu sparas den i det aktuella working directoryt), och lägg till datumet i filnamnet
$exportcsvpath = ".\" + (Get-Date -Format "yyyy-MM-dd") + " - Behörighetslista.csv"
# Skriv listan till excelfil enligt den skapade pathen ovan. Finns redan filen läggs ett worksheet till med dagens datum i befintlig fil.
# Kommentera bort nedan rad om exempelvis modulen ExportExcel inte kan installeras
$behorighetslista | Export-Excel -Path $exportexcelpath -WorksheetName (Get-Date -Format "yyyy-MM-dd") -AutoSize -AutoFilter -BoldTopRow
# Skriv listan till csv-fil enligt den skapade pathen ovan (avkommentera/kommentera raden beroende på om csv önskas eller ej)
$behorighetslista | Export-Csv -Path $exportcsvpath -NoTypeInformation -Encoding UTF8
Referenser
- BloodHound https://github.com/BloodHoundAD/BloodHound
- Microsoft ActiveDirectory Powershell Module
https://learn.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2022-ps - ImportExcel Powershell Module
https://www.powershellgallery.com/packages/ImportExcel/