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 0×00168000 to 0×1000 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 0×20. 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 +
0×10, 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 0×00(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 0×31000 is mapped to the physical address of 0xFB000.
Figure 20 Searching the address including 0×310000
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+0×20(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 +0×10 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 +0×10, 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 0×00(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 0×00 (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 0×00 (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://gitlab.kr/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
Fuente: http://articles.forensicfocus.com/2014/04/28/windows-logon-password-get-windows-logon-password-using-wdigest-in-memory-dump/