Active Directory offers you many different ways of authentification. Most common are NTLM and Kerberos.
This article is about how to read the Kerberos Token with .Net classes in PowerShell.
The script get-sids-from-token.ps1 shows you how this can be done practically. To make it easier to understand, the article starts with an introduction to Kerberos and .Net classes in PowerShell.
Index
Kerberos Token – an Introduction
If a user logs on to a work station that is joint into an Active Directory, access permissions must be checked.
After a successful authentification against the domain controller the user receives a so-called Kerberos Token. It contains a lot of information like the SID (Security Identifiers) of the groups he is part of. So every time the user wants to access a central file system and other resources the token is read. Usually that data is protected by ACLs (Access Control Lists). Those consist of different rules, ACEs (Access Control Entries). These are defining the access rights of the SIDs. If the Kerberos Token’s SIDs match with the requirements of the ACLs users get access to the resources. “No match-no resources” explains best.
Note: You receive a Kerberos Token during the log-in-process only. If group memberships are changed after the login, it does not affect tokens that were already created.“ You log in, you receive a token”- that is the basic rule.
For debugging you need to know which user’s token contains certain group membership information. To find out there are many ways. One would be “klist”. Another one that is less famous but yet very elegant is PowerShell (PS)!
Read Kerberos Token using PowerShell
In order to read a KerberosToken with PS you can use a .Net-Class within a PowerShell Script.
That class is [System.Security.Principal.WindowsIdentity] and it is documented by Microsoft.
One of this class’ method is GetCurrent() (more Information).
It communicates the user’s context information as .Net-objects. This class may easily be used with PowerShell (also read Use .Net Code in PowerShell) as follows:
[System.Security.Principal.WindowsIdentity]::GetCurrent()
By using [System.Security.Principal.WindowsIdentity]::GetCurrent() you receive the following mask:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
PS C:\Users\tuser1> $token = [System.Security.Principal.WindowsIdentity]::GetCurrent() PS C:\Users\tuser1> $token AuthenticationType : Kerberos ImpersonationLevel : None IsAuthenticated : True IsGuest : False IsSystem : False IsAnonymous : False Name : SANCTUARY\tuser1 Owner : S-1-5-21-2667348191-198858073-1110801464-1189 User : S-1-5-21-2667348191-198858073-1110801464-1189 Groups : {S-1-5-21-2667348191-198858073-1110801464-513, S-1-1-0, S-1-5-32-545, S-1-5-4...} Token : 3300 |
The most important part is “groups” for you now. It contains relevant Kerberos Tokens:
Resolving SIDs Against the Domain
In order to read the list easier you need to resolve the SIDs against the domain. The objects in the list are of the following types:
- Base-type: System.Security.Principal.IdentityReference.SecurityIdentifier
- Security.Principal.IdentityReference
So you can apply the Translate Method.
As target type you may take “NTAccount”.
1 2 3 4 5 6 7 8 9 10 11 12 |
PS C:\Users\tuser1> $groupSIDS = $token.Groups PS C:\Users\tuser1> $groupSIDs[10] BinaryLength AccountDomainSid Value ------------ ---------------- ----- 28 S-1-5-21-2667348191-198858073-111080... S-1-5-21-2667348191-198858073-111080... PS C:\Users\tuser1> $groupSIDs[10].Translate([System.Security.Principal.NTAccount]) Value ----- SANCTUARY\F-A2-SALES-Abteilung1-RW |
PowerShell Script to Read Out Kerberos Token
The final script for reading the Kerberos Token information of about group memberships:
1 2 3 4 5 6 7 8 9 10 |
$token = [System.Security.Principal.WindowsIdentity]::GetCurrent() # Get current user context $groupSIDs = $token.Groups # Get SIDs in current Kerberos token foreach($sid in $groupSIDs) { # for each of those SIDs... try { # try to.. Write-Host (($sid).Translate([System.Security.Principal.NTAccount])) # translate the SID to an account name } catch { # if we can't translate it... Write-Warning ("Could not translate " + $sid.Value + ". Reason: " + $_.Exception.Message) # Output a warning and the corresponding exception } } |
This article has been created by FirstAttribute consultants during Active Directory Projects.
If you seek competence and advice, please contact us.
FirstAttribute AG – Microsoft Consulting Partner for Migration and Active Directory
Leave a Reply
<p>Your email is safe with us.<br/>Information about our <a href="https://activedirectoryfaq.com/contact-us/">data protection policies</a></p>