1. Introduction
The former way to acquire the Windows logon password of user is to get a NTML hash value through the Windows logon session and registry then crack it. [Figure 1] shows the well-known ways to get a NTML hash value of user’s windows logon password. For more information, take a look at “Dump Windows password hashes efficiently” on http://bernardodamele.blogspot.kr/.
Table 1 Way of obtaining NTLM hash of user’s Windows logon password as per files
Files | Ways of obtaining NTLM hash of password |
SAM | Decrypt the value of SAM hive file |
NTDS.DIT | Decrypt after extracting the database table of NTDS.DIT |
NTDS.DIT /SAM | Use the password history of NTDS.DIT/SAM hive file |
SECURITY | Decrypt LSA secret of SECURITY hive file |
SECURITY | Use the cached domain logon information of SECURITY hive file |
MSV1.0 | Use the credential information of Windows logon session |
All of the obtained information using these methods is NTLM hash and it needs to be cracked with password crack tools. If the password is too long and even hard to crack, it is difficult to acquire the user’s Windows logon password. However, the tool called “Mimikatz” [1] has been announced in 2012 to solve the problem. It uses DLL injection on live status so that it can print out the user’s Windows logon password as a plaintext even though the password is long.
In this article, we’ll apply one of the methods used in “Mimikatz” called “extracting user’s Windows logon password using Wdigest” to memory dump, so we can help out the investigators with memory forensics.
2. Windows Authentication Package
Windows Authentication Package is one of the major components to implement the Windows security and it includes Lsass process context and DLLs executed in client’s process. The role of authentication DLL is to examine whether the user’s name is in agreement with the password. If the authentication information is consistent, it returns the user’s specific information to Lsass. Lsass create the token based on this. In typically, there are MSV1_0, TsPkg, Wdigest, LiveSSP, Kerberos, and SSP for windows authentication package and each package is carried out by various usage like Remote RDP, and Web service. It has a feature that it always carries the specific data in memory for Challenge-Response method. In this article, we will cover only Wdigest in Windows authentication package.
2.1 WDigest.dll
Wdigest.dll was first introduced in Windows XP system, and developed to authenticate the user in HTTP digest authentication and SASL (Simple Authentication Security Layer). This is used in digest authentication using Challenge-Response method as NTLM protocol. Also it transfers certificate through MD5 hash or message digest and it offers more improved security than before. However, to get a key for authentication, user’s plaintext password is necessary and it can be abused. [Figure 1] and [Table 2] explan the digest authentication architecture and the elements.
Figure 1 Digest Authentication Architecture
Table 2 Digest Authentication Elements
File | Explanation |
Wdigest.dll | It works for SSP which is used for LDAP and Web authentication |
Lsasrv.dll | Security service management of LSA (Security policy and behavior) |
Secur32.dll | It works for application SSPI of user mode |
Ksecdd.sys | It is used when kernel security device driver communicates with Lsass in user mode. |
3. Extracting Windows logon password on live status
[Figure 2] shows the process of extraction of Windows logon password on live status using DLL injection in Wdigest.Figure 2 The process of extraction of Windows logon password on live status using Wdigest
The working process for each element of conducted function/dll during extraction is as follows.
- First, you have to collect the number of sessions and logon session identifiers (LUIDs) which exist in system through the LsaEnumerateLogonSessions function of Lsass. [Figure 3] is the LsaEnumerateLogonSessions function.
Figure 3 LsaEnumerateLogonSessions Function
LogonSessionCount pointer variable has the number of logon sessions, and LogonSessionList pointer variable has the address value of the first element among the logon session identifiers. Based on this, you can trace the Logon session list existing in system.
- I_LogSessList of Wdigest.dll is made of LIST_ENTRY structure, and it has use name, domain, encrypted password, domain DNS and so on written in Unicode character as well as Flink, Blink, and LUID.
- Afterward, you can decrypt the encrypted password obtained from I_LogSessList through LsaUnprotectedMemory function of Lsasrv.dll. [Figure 4] shows the LsaUnprotectedMemory function[2].
Figure 4 LsaUnprotectedMemory Function
- When the LsaUnProtectedMemory function is decompiled, it looks like [Figure 5].
Figure 5 Decompile the LsaUnprotectMemory Function
It calls out LsaEncryptMemory function internally, and [Figure 6] suggests the result of decrypted LsaEncryptMemory function.
Figure 6 Decompile the LsaEncryptMemory function
With the result above, you can finally figure out that the LsaEncryptMemory function of Lsasrv.dll decrypt the encrypted password using pblV and 3DesKey handle value.
We tried to explain the whole working process so far. Anyone who wants to check out the working process through code, you can visit https://github.com/thomhastings/mimikatz-en/.
4. Extracting Windows Logon Information in memory dump
Before you extract the information, we will explain how to obtain windows logon password using WDigest in memory dump. Let’s take a look at [Table 3].
Table 3 What you need to know
Category | Explanation |
dll needed | WDigest.dll : It has the address of encrypted password value.Lsasrv.dll : It is needed to decrypt the encrypted password. |
value to find | WDigest.dll : The address of encrypted password value of l_LogSessListLsasrv.dll : The handle value of 3DesKey and pbIV value |
When you only refer to the contents of [Table 3], extracting password may look simple. However it has to go under complicated order to find and trace the value in memory dump. You can only access the memory dump file we have by physical address because the pointer value of dll is based on virtual address.
From now on, we will figure out how to extract the Windows Logon password in memory dump. First of all, you have to check out the parent process called PID of Lsass.exe to extract WDigest.dll and Lsasrv.dll. [Figure 7] shows the result of PID of Lsass.exe using pslist plugin of Volatility.
Figure 7 Check the PID of Lsass.exe
When Lsass.exe is being executed, it obtains the memory dump of Lsass.exe using memdump plugin to identify the value of allocated memory space. [Figure 8] shows the result of memory dump command of Lsass.exe, called PID488.
Figure 8 execution of Lsass.exe memory dump
So far, we have tried to reduced the size of dump file we need to analyze to obtain the Windows Logon password by Lsass.exe memory dump, which has “whole memory dump -> every value to extract”. As we mentioned, Lsass.exe memory dump also can be accessed by physical address. So you have to create the memory map file for mapping of virtual address and physical address. [Figure 9] shows how to extract memory map of relevant memory dump with memmap plugin.
Figure 9 Collecting Memory Map
Next, you have to dump WDigest.dll, one of the dlls needed to extract Windows Logon password. [Figure 10] shows the command how to dump Wdigest.dll.
Figure 10 WDigest.dll Dump
WDigest.dll has an address of encrypted password value, and you can check the very beginning address of the list out on I_LogSessList to trace it. It is made of LIST_ENTRY structure. [Figure 11] shows the stored value on I_LogSessList.
Figure 11 Identifying l_LogSessList
0x168D50 means the virtual address of the very first element of user’s logon session list. You have to find the space including the relevant address, and then identify the physical address of Lsass.exe memory dump file. [Figure 12] shows the searching of virtual address space including 0x168D50 in memory map file.
Figure 12 Searching the address including 0x168D50
The space from size 0x00168000 to 0x1000 is mapped from 0x5c000 of Lsass.exe memory dump file. You can check the value by moving to 0x5C00 + (0x168D50 – 0x168D00) = 0x5CD50 from Lsass.exe physical memory dump. [Figure 13] shows the point of offset 0x5CD50 on WinHex.
Figure 13 The Point of 0x5CD50 in Lsass.exe physical memory dump
On 0x5CD50, you can find the user account on 0x20. If you cannot find anything, you have to check the next 4 byte. In this memory dump, the user account is on the point 0x001C80A9. This point is 4 byte away from offset 0x5CD74. You can check it out in [Figure 14].
Figure 14 Searching the address including 0x001C80A8
Now let’s move to point 0xBC000 + (0x1C80A8 – 0x1C8000) = 0xBC0A8 in Lsass.exe memory dump.You can identify the user account by unicode. This is shown in [Figure 15].
Figure 15 Identifying User Account
The encrypted Windows Logon password of user is on offset 0x5CD74 + 0x10, which has the user’s account information address. You can check the value of physical address 0x001A1DB8 of point 0x5CD84 in [Figure 13] like shown in [Figure 16],
Figure 16 Searching The Address including 0x001A1DB8
If you move to point 0x95DB8 in Lsass.exe memory dump, you can find the hex value shown in [Figure 17]. That part refers to the encrypted user’s password achievable on WDigest. Because there is 0x00(NULL) in the middle, you can figure out that the actual valid value of encrypted user’s Windows logon password is by 0x95E23.
Figure 17 Encrypted User’s Windows Logon Password
For next, you have to dump the Lsasrv.dll which is necessary to decrypt the user’s encrypted Windows logon password. [Figure 18] shows the result of dumped dll. The way of plugin command is same as WDigest.dll.
Figure 18 Dump of Lsasrv.dll
The handle value of 3DesKey is used during the process of decryption of LsaEncryptMemory function, and it is shown in [Figure 19]. However, what we actually need is the value of pbSecret instead of the handle value of 3DesKey. Because the final values to decrypt are composed of pbSecret, pbIV, and encrypted user’s Windows logon password. The value of pbSecret exists in the address of 3DesKey and the location of 0x3C.
Figure 19 Address of 3DesKey
By [Figure 20], you can see that 0x31000 is mapped to the physical address of 0xFB000.
Figure 20 Searching the address including 0x310000
As we mentioned, pbSecret exists right after the location of 0x3C. Therefore you need to move to 0XFB000 + 0x3C = 0xFB03C of Lsass.exe memory dump. As [Figure 21] shows, there is room of 4 byte in front of the address, and you can find the hex value right after that.
Figure 21 The value of pbSecret
At last, you can figure out the pbIV value with just checking the first index value of array InitializationVector[4] of Lsasrv.dll. [Figure 22] shows the result of value of pbIV.
Figure 22 The value of pbIV
Last, you can check the actual user’s logon password through the 3Des and obtained value using Python. [Figure 23] is shows the relevant Python code.
Figure 23 Python code to decrypt the user’s password
[Figure 24] shows the result of executed code. You can decrypt the password even it is very long.
Figure 24 The result of executed code
5. Volatility Plugin – logon
We created the Volatility plugin based on the method of extracting the Windows logon password from memory, which we introduced in this article before. In this chapter, we will briefly cover how the plugin works. Let’s take a look at the working order of plugin.
5.1. Memory dump of Lsass.exe, Wdigest.dll, and Lsasrv.dll
First, you need to extract some space to collect the most necessary information. In this plugin, we will dump the memory space of the process which owns the necessary space. [Figure 25] shows the function executing the dumping.
Figure 25 dump() function
Each necessary image can be dumped by basic dump modules provided by Volatility. You can use the name of the images you need from the list so to automatically dump with filtering.
5.2. Extracting the name of user’s account
When extracting the name of user’s account from memory, you need to check the value of l_LogSessList+0x20(the address which has the name of user’s account as unicode). If the address is invalid, you have to check the address of 4 byte field to find the account. However, it is difficult to figure out which address has an account in which filed in plugin. Therefore you need to check the address value of specific space(4 byte * 3 times) first, and then move to that address to check if there is a valid character string and check if there is an account. When verifying a valid account, you have to follow the policy of Windows account name. [Figure 26] shows the routine to find the address which has account name.
Figure 26 Routine to find the address which has the account name
Then you need to verify whether the account name corresponds to the saved value in the routine as shown in [Figure 27].
Figure 27 Routine to verify the account name
5.3. Extracting the encrypted password
There exists an encrypted password of relevant account in +0x10 away from the field which has the account name. Therefore when verifying the account name, if you find any valid account, you have to calculate the field address +0x10, where the account was found. Then you can extract and check the address value which has an encrypted password. As we mentioned in [Figure 17], the length of the character string of encrypted password is different from that of the encrypted password saved 4 byte before. So you have to do the extracting only by 0x00(NULL) in the relevant routine, and save the necessary value for the actual decryption. [Figure 28] shows the routine of extracting encrypted password.
Figure 28 Routine to extract the encrypted password
5.4. Extracting the value of pbSecret
The pbSecret actually plays the key role during the process of decryption. You need to find pbSecret space with specific signature called “KSSM”, because the method you used in decompiling cannot be applied to find relevant value. The pbSecret has the length value of character string 16 byte after KSSM signature, and there exists a value of pbSecret right after it. [Figure 29] shows the routine of extracting the pbSecret.
Figure 29 Routine that extract the pbSecret
5.5. Extracting the value of pbIV
You have to find the pbIV value through a specific signature as well as pbSecret. “DebugFlags” is recommended signature, and there is a value of 0x00 (NULL) between signature and pbIV value. The size information of pbIV is not saved, but you can extract the size of 16 byte or the value from relevant value to 0x00 (NULL). [Figure 30] shows the routine of extracting the pbIV.
Figure 30 Routine that extract the pbIV
.
5.6. Decrypting the password
When decrypting the password, you can use the Crypto function provided by Python. Initial vector (pbIV), key (pbSecret), and encrypted password are necessary. When the decryption using the 3DES algorithm is done, it deletes the dumps and every image files already used. [Figure 31] shows the routine of password decryption.
Figure 31 Decryption Routine
5.7. Plugin Result
[Figure 32] shows the result of executed relevant plugin.Figure 32 The result of executed plugin
You can download the plugin from the following address.
https://withgit.com/For-MD/volatility-plugin-logon/blob/master/logon.py
6. Conclusion
First of all, we will keep upgrading this tool and show you a new method according to the computing environment which is changing. The environment which uses 32 bit system is now turning into an environment which uses 64 bit system, and the application range of this plugin is 50:50. Therefore we will apply the method of extracting the Windows account information in 64 bit system, and also add a new function to extract the account information from various authentication packages to broaden the application range of plugin. Finally, it is a big question for us how to extract the authentication session, the Windows account information when authenticating the domain, and multiple users within the memory considering the Active Directory environment.
In this article, we covered how to extract the information of Windows account from memory image in the view of digital forensics. In terms of digital forensics, the former way using dll injection is not appropriate, because it is against the integrity of memory. However, by the method we introduced in this article, you can extract the information of Windows account only by using the memory image on offline. Therefore we presume that it can be helpfully used in the field of investigation or security incidents.
[1] Mimikatz : http://blog.gentilkiwi.com/mimikatz
[2] http://msdn.microsoft.com/en-us/library/windows/desktop/ff714510(v=vs.85).aspx
This has been done in Passware (http://www.lostpassword.com/kit-forensic.htm) a few years ago.
Thank you for your comment. 🙂
can you capture the associated menu in “passware forensic kit”?
see you ~
Hi,
First of all, thanks for posting this article and for developing this plug-in.
I tried this on 2 WinXP memory images (using Volatility 2.3.1 on Linux), on both of them I got an error at the end “IOError: [Errno 2] No such file or directory: ‘lsasrv.dll”. I noticed that the status messages above say “lsasrv.dll dump start!” but it never says that the dump of lsasrv.dll is complete (like it does for other files). I don’t see lsasrv dumped anywhere.
I noticed in the code that it mentions that it works on Win7 SP1, so is the reason I got these errors because I was using a WinXP memory image and not Win7?
-Michael
Thank you for your comment. 🙂
Our tool only supports Windows 7.
Windows xp and Windows 7 memory data is not same !
so our current tools to get a windows xp password can not be..