Our Blog

Protected Users: you thought you were safe uh?

Reading time ~10 min

On the 31st of October 2022, a PR on CrackMapExec from Thomas Seigneuret (@Zblurx) was merged. This PR fixed Kerberos authentication in the CrackMapExec framework. Seeing that, I instantly wanted to try it out and play a bit with it. While doing so I discovered a weird behaviour with the Protected Users group. In this blogpost I’ll explain what the Protected Users group is, why it is a nice security feature and yet why it is incomplete for the Administrator (RID500) user.

I/ Usual internal assessment scenario and PtH/OPtH

In my previous blogpost about Windows Access Tokens I described one of the most common scenarios we encounter on internal assessments. Basically we compromise one server, dump its SAM database and LSASS memory to retrieve cleartext credentials or NT hashes. We can also dump Kerberos tickets and generally any other material that we could use to connect elsewhere:

Whether it is in the SAM database or in the memory of the LSASS process, you will probably find NT hashes:

On Windows, having a NT hash is equivalent to having a cleartext password. If we take a look at the NTLM authentication protocol we can see that the challenge is cyphered using the NT hash of the user:

Since we have the NT hash we can cypher the challenge without knowing the corresponding cleartext password.

On Kerberos it is pretty much the same. The Kerberos authentication protocol relies on four packets which are:

  • KRB_AS_REQ
  • KRB_AS_REP
  • KRB_TGS_REQ
  • KRB_TGS_REP

The process is the following:

The important part is the “timestamp ciphered with a key derived from the password of the user”. As a user, we can cipher the timestamp using a key that can be obtained using one of the following algorithms:

  • RC4
  • DES
  • AES-128
  • AES-256

The interesting thing is that RC4 cyphers the timestamp using the NT hash of the user. Since we have a valid NT hash, we can cipher the timestamp and have a valid KRB_AS_REQ packet. With the CrackMapExec framework we can now connect to remote servers using two well known attacks:

  • Pass the Hash (for the NTLM authentication protocol):
  • OverPass the Hash (for the Kerberos authentication protocol):

These attacks rely on the fact that it is possible to use a NT hash to cypher a secret used to authenticate a user. To protect against this, one approach is to add sensitive users to the “Protected Users” group.

II/ Protected Users group

The “Protected Users” group was introduced in Windows Server 2012R2. If we take a look at the MSDN article we can see that users in this group have hardened security options:

As you can see, NTLM authentication is disabled, the RC4 algorithm cannot be used to cipher the timestamp for Kerberos authentication and finally, Kerberos delegation is disabled. Let’s test this.

First I will add a new domain administrator user (admin2) that is in the “Protected Users” group:

Now let’s try to authenticate using NTLM:

As you can see it’s not working, we receive the “STATUS_ACCOUNT_RESTRICTION”. And now lets try using Kerberos:

It’s not working either (KDC_ERR_PREAUTH_FAILED). So yeah it looks like the expected Protected Users security features apply to the admin2 user. But do they apply to all users ?

III/ The strange behaviour

1 – The RC4 key case

While I was playing with the CrackMapExec PR, I randomly tried to authenticate using Kerberos as the WHITEFLAG/Administrator account and what I realised was that it works even if the user is in the Protected Users group:

In contrast, NTLM authentication fails:

Which means that the restriction of the Protected Users group is not complete when it comes to the RID500 user of the Active Directory domain. We cannot connect using the NTLM authentication protocol but we can connect using the Kerberos authentication protocol with RC4.

2 – The delegation case

Another strange behaviour relates to Kerberos Delegation. Normally, when a user is in the Protected Users group, they cannot be delegated. Here I’m trying to abuse a RBCD delegation scenario from OCD$ to ADCS1$ to get a service ticket first as pu_user, which is a Protected Users, and second as not_pu_user, which is not. First, lets take a look at the delegation:

Lets look at the difference between RBCD delegating pu_user and not_pu_user:

We clearly see a difference: Protected Users cannot be delegated. But wait, lets see how things are going with the RID 500 Administrator account…

Even if the RID 500 Administrator account is in the Protected Users group, they can be delegated. Ok, but why ?

RBCD delegation abuse consists of the following two steps:

  • S4U2Self : Request a service ticket for an arbitrary user to the controlled account.
  • S4U2Proxy: Request a service ticket as the arbitrary user to the targeted machine account, using the previously obtained service ticket as an additional ticket.

When you try to impersonate Protected Users, the S4U2Self gives you a service ticket without the forwardable flag set. This is why the S4U2Proxy part fails with a KDC_BADOPTION error. However, when impersonating the RID 500 Administrator user, the forwardable flag is set regardless of whether the user is a Protected User:

IV/ Exploitation scenario

1 – The RC4 key case

Using this bug we can execute a particular scenario. Let’s say that we have a fictitious company called Whiteflag. Two years ago they created their Active Driectory domain (whiteflag.local) without taking care of security. Thus, they were using the RID500 account of the domain (WHITEFLAG/Administrator) to administer their servers.

Fast forward a year ago, they asked for an internal assessment. Pentesters were able to compromise the domain and told the security team to add all domain administrators users to the Protected Users group. The security team did this but since they were not properly closing RDP sessions, the NT hash of the WHITEFLAG/Administrator account was still stored in the memory of the LSASS process.

Today you are hired to test their newly hardened Active Directory network. If you can compromise a server on which a RDP session is still active for the WHITEFLAG/Administrator account, you will be able to retrieve its NT hash. Since Protected Users restrictions are not enforced for that user you will be able to connect to the DC using Kerberos authentication.

Yeah I know, it’s a very specific scenario but hey, it could happen! Another interesting thing is that Kerberos delegation will also work for this account.

2 – The delegation case

Here the scenario is more straight forward. If every administrator account is in Protected Users and you need to abuse a RBCD delegation scenario (or any other Kerberos delegation), you can just choose to impersonate the RID 500 Administrator account and it will work!

V/ Remediation

If we take a look at the attributes of the RID500 account we can see that the ms-DSSupportedProtocolEncryption value is set to 0x0

This attribute holds a hexadecimal value that indicates which type of authentication protocol is enabled for that account. Since the value is 0x0, we can conclude that any authentication protocol can be used. If we set this value to 24 (0x18) which only enables AES-128 and AES-256:

We will see that we can still connect using the OverPass-the-Hash attack. The only way I found to completely disable RC4 is to restrict it for the entire Active Directory environment which could be dangerous if servers / applications still rely on this type of authentication.

To avoid the delegation trick you need to tick the option “Account is sensitive and cannot be delegated” even if the RID500 account is in Protected Users.

Another fix would be to simply disable the RID500 domain account which, according to the Microsoft documentation, is dangerous as well:

Note that this bug was reported to MSRC. They replied that this behaviour is intended and is not a bug. Still, the RID500 account can be abused so be aware of it ;)!


This article was co-written by Aurélien CHALOT (@Defte_) and Thomas SEIGNEURET (@_zblurx). We would also like to thank some friends for these late night talks we had in order to try to understand what was happening: Charlie BROMBER (@_nwodtuhs), Martial PUYGRENIER (@mpgn_x64), Wilfried BECARD (@tiyeuse) as well as the the Hide&Sec community.

This article is a cross-post from https://blog.whiteflag.io.