Powershell Working With AD and Variables
This is going to be the first in a series of posts chronicling my journey with PowerShell:
See here for the details, I shan’t bore you again.
Setting the scene…
I recently found myself in a position with a client where they passed on a request that was: “Our CISO has requested that we go out and find all privileged service accounts”
For this particular client service accounts are identified with “SRV_ACC” at the start of the username. So that does make it slightly easier, but how do we determine a level of privilege?
Get-AdGroupMember
Microsoft have a lovely collection of PowerShell cmdlets that you can install by adding it as feature in Windows or by downloading and installing the package
After some rumaging around on the Get-AdGroupMember Docs Page I found this handy dandy paramater:
-Recursive
-Recursive Specifies that the cmdlet get all members in the hierarchy of a group that do not contain child objects .If the specified group does not have any members, then nothing is returned
Perfect This is great, I can just:
Get-AdGroupMember -Identity "Domain Admins" -Recursive | Where-Object name -Like "SVC*"
This will give me an output similar to this (but only for service accounts):
This was good, this is what the client wanted, but I wanted to go further and maybe make it easier for myself and maybe colleagues to run again.
All Builtin AD groups have an initial security identifier of S-1-5-32 and S-1-5-21. Here is a list of all well-known security identifiers in Windows operating systems. Enumerating all members of these groups is a great starting place to identify privileged. However not all of them give privileged access. You can see them by running
Get-ADGroup -ResultSetSize $null -Filter * -Properties GroupType |Where-Object {$_.SID -like "S-1-5-32-*"} | foreach {$_.name}
Sean Metcalf has some great resources about groups that are important in active directory, and you should absolutely go and read everything on his site as he is a proper AD wizard.
Note: AD groups can be provisioned administrative access as part of group policy. ie. adding certain groups to administrators on servers or computers, but this was not in scope for this work, so it was not explored. Probably a more suitable task for something like bloodhound, I wanted to keep this pretty simple for now.
Brief intro to PowerShell variables
Regular Variables
In a nutshell, a variable is just a place in memory to store information. Hence the name, a variable can be whatever you want it to be and in PowerShell it can contain several different types of values. It can contain a large one liner, or it can contain the output of several commands chained together. Great video explaining variables here
Variables in PowerShell are set using $x = yz, For example. I can set the output of a command to be CoolVariable:
$CoolVariable = Get-Process
That will store the output of the Get-Process command in $CoolVariable.
One thing that is important to remember is variable type. Variables can contain many different types. You can determine the variable type by using the following command:
$CoolVariable = Get-Process
$CoolVariable.GetType().FullName
This will show you for the example above, that we are working with a type of “System.Object” (which is technically an array)
There are many other types. Integers, strings and booleans can all be stored in a variable. If you want to set the type of variable you are using you can set it like so:
[string]$CoolVariable = "FancyString"
Pipeline Variables ($_)
PowerShell is very powerful due to it’s usage of objects (vs lets say bash which is mainly manipulation of text). What we use above is called a pipeline variable. It’s in essence a time saving venture. It saves us from having to declare a variable and just treats information in the pipeline as a variable.
Heres an example without using a pipeline variable:
$process = get-process$Processes | Where-Object {$Processes.ProcessName -contain "winlogon"}
And here is with a pipeline variable
Get-Process | Where-Object {$_.ProcessName -contains "winlogon"}
Arrays or list of items
An array is a fixed size collection of elements, a good way to think about it is they are like a collection of variables or objects.
Very similar to how a standard variable works, but you separate each item in the variable with commas.
Groups = "Administrators","Users", "Remote Desktop Users"
Solving our problem
So the best way to enumerate all the relevant groups was to:
- Create array with groups that are “privileged”
- Loop through get-adgroupmember -recursive to get all the members of all the groups
This ended up looking like this:
$PrivilegeGroups = "Administrators","DNSadmins", "Account Operators", "Server Operators", "Schema Admins"
$PrivilegeUsers = foreach ($group in $PrivilegeGroups)
{
Get-ADGroupMember $group -Recursive | Select-Object name
}
$PrivilegeUsers | Where-Object name -Like "srv*"
https://github.com/archb1sh0p/powershell
(probably best to work with the code here on GitHub, as this code here on the site will not be updated)
Up next
Further reading
- Highly recommend the PowerShell Cookbook by Lee Holmes However is is quite exhaustive, but it’s an excellent resource
- Great Article exploring Variables and Arrays in powershell
Thanks for reading