Summary: Guest blogger, and Microsoft PFE Ian Farr, continues his series about JIT administration with Windows PowerShell.
Microsoft Scripting Guy, Ed Wilson, is here. Today, welcome back Ian Farr for the conclusion of his two-part blog. Before you dig into today's post, please read Use PowerShell for JIT Administration and PAM – Part 1. To read more of Ian's previous guest posts, see these Hey, Scripting Guy! Blog posts.
Yesterday, I discussed an advanced function that was written with my teammate, Phil Lane. The function grants membership of a high-privileged group for a defined period of time. I talked about just-in-time (JIT) administration, including time-bound elevation and privileged access management or PAM (that is, special administrative considerations for high-privileged users and groups).
Here’s the function:
Here’s its parameters:
- UserDn… The distinguished name of the user account to be granted high-privileged access
- Domain… The domain in which the privileged group resides
- PrivGroup… Either Domain Admins, Enterprise Admins, or Schema Admins
- TtlHours… The number of hours high-privileged access is granted for
And here's its switches:
- CountDown… A countdown, in seconds, of the time remaining before the dynamic group object is removed
- ProtectedUser… This makes use of some of the credential theft protections included in the later operating systems
Last time out, I also promised to discuss the –ProtectedUser switch. Here goes…
The three-headed dog
In testing Phil’s proof-of-concept JIT administration script, I realized that because of how the Kerberos authentication protocol works, we needed some additional functionality.
The background...
In Active Directory, Kerberos is the preferred authentication protocol. It provides you with a time-bound ticket that confirms who you are. Think of this ticket as a passport that’s issued for only 10 hours. You can use this passport to prove who you are to the various services that you’ll find in your Active Directory infrastructure (the file servers). In turn, you’ll get another passport/ticket to access that service until your original ticket expires.
What does all this mean? Well, ultimately, we want to grant high-privileged access for a defined period of time to our system administrator’s secondary user account. If we use the function to grant high-privileged group membership for two hours, we’re still going to get a Kerberos ticket-granting ticket (TGT, which is the original passport) that lasts for 10 hours. This means that despite no longer being a member of the high-privileged group, we can still use tickets issued during membership of the high-privileged group to legitimately persist high-privileged access—that means our time-bound elevation can last beyond the $TtlHours value passed to the script.
I thought about how to address this with Windows PowerShell…
Nice doggie
Windows Server 2012 R2 introduced a number of credential theft protections. The function also makes use of one of these features: a new Active Directory global security group called Protected Users, which affords a number of protections. Following are some of the safeguards immediately relevant to this discussion.
Members of the Protected Users group can no longer:
- Use Kerberos long term keys: A Kerberos TGT is acquired at logon and cannot be reacquired automatically
- Renew user tickets (TGTs) beyond the initial four-hour lifetime
Three important points about Protected Users:
- The second protection (four-hour TGTs) is only available if the domain functional level is Windows Server 2012 R2.
- You’ll need to assign your PDCe role to a domain controller running Windows Server 2012 R2 (it can be assigned back later) for the Protected Users group object to be created and replicated in a domain where you have down-level domain controllers.
- The ability to apply Protected Users safeguards have been back-ported to Windows 8, Windows Server 2012, Windows 7 with SP1 and Windows Server 2008 R2 with SP1. For more information, take a look at KB2871997.
The Windows PowerShell part is not far away now! Thank you for your patience, my friends.
There’s one more credential theft protection in Windows Server 2012 R2 that the function utilizes: Authentication Policies. With this we can configure a user’s Kerberos TGT to exist for the same amount of time as the duration of our privileged group membership.
Note For more details about prerequisites for authentication policies, see Authentication Silos Part 1.
At last: Windows PowerShell
If the –ProtectedUser switch is specified, the function does the following:
- Checks for the existence of the Protected Users group
- Checks whether our user account is a member of the group; if not, adds it
- Checks whether the dynamic group object time to live (TTL) is less than four hours; if it is, then…
- Checks whether the domain functional level is Windows Server 2012 R2; if it is, then…
- Creates an authentication policy with a TGT matching the TTL and assigns it to the user account
- Spins up a countdown
- Removes the authentication policy
Here’s how we check for the existence of the Protected Users group:
$DomainDn = (Get-ADDomain $Domain).DistinguishedName
$UsersContainerDn = "CN=Users,$DomainDn"
Get-ADGroup -Identity "CN=Protected Users,$UsersContainerDn" -Properties members
To check whether our user is a member of the group:
if (($ProtectedUsersGroup).members -like $UserDn) {..}
To perform the required addition:
Add-ADGroupMember -Identity "CN=Protected Users,$UsersContainerDn" -Members $UserDn
And here’s how we check whether the dynamic group object TTL is less than four hours and then check the domain FFL:
if ($TtlHours -lt 4) {
$DomainFL = (Get-ADDomain $Domain).DomainMode
if ($DomainFL -eq "Windows2012R2Domain") {…}
Now, create an authentication policy if the domain FFL is ‘Windows2012R2Domain’:
$AuthPolName = "Temp Auth Pol for $UserSamAccountName"
New-ADAuthenticationPolicy -Name $AuthPolName `
-Description "Temporary Authentication Policy to set $TtlHours hour TGT for $UserSamAccountName" `
-UserTGTLifetimeMins ($TtlHours * 60) `
-Enforce `
-ProtectedFromAccidentalDeletion $False
Here, we create an authentication policy that references our user account name and description. The user TGT lifetime is set to match the dynamic group object lifetime. The –UserTGTLifetimeMins parameter accepts values in minutes—hence, the reason we multiple the $TtlHours variable by 60.
The new authentication policy is not protected from accidental deletion, so we can easily remove it after the time-bound access has expired.
Now we assign the authentication policy to our user account. You’ll need to check that your version of Set-ADUser has the –AuthenticationPolicy parameter:
Set-ADUser -Identity $UserSamAccountName -AuthenticationPolicy $AuthPolName
We also set a couple of flags to be used later to trigger the countdown and the authentication policy deletion code later on in the function:
$CountDown = $true
$AuthPol = $true
We looked at the countdown code in the last post. Here’s the simple authentication policy deletion routine:
if ($AuthPol) {
Remove-ADAuthenticationPolicy -Identity $AuthPolName -Confirm:$false
}
We have to use –Confirm:$false to override the automatically trigged confirmation dialogue.
Putting it all together
Here’s what happens when we execute the function with the –ProtectedUser and –Verbose parameters:
Now, I log on to my administrative host with the ‘Master Chief’ account. I can only access this host when I am a member of the Domain Admins group. Let’s look at my group membership:
(Get-ADUser -Identity MasterChief -Properties MemberOf).MemberOf
Let’s look at the Kerberos TGT that is issued on the dedicated administrative workstation:
This ticket is only valid for one hour, and its Renew Time is the same as the End Time, meaning that we have to reauthenticate after expiry. We can no longer persist our high-privileged access. I can safely pat the dog on its head!
Whilst the ticket is valid, we can perform tasks, for example:
As shown here, as soon as the ticket expires, our access is revoked:
Function summary
Without the –ProtectedUser switch, the function ensures that high-privileged group membership is removed after an allotted period of time.
With the –ProtectedUser switch and a domain functional level of Windows Server 2012 R2, the TGT lifetime can match the TTL of the dynamic group object used to grant temporary high-privileged group membership, so our high-privileged access will be removed around the same time as our high-privileged group membership is removed.
~Ian
Thank you, Ian (and Phil)!
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy