Credential Stealers

Attackers often go to great lengths to steal credentials, primarily with three types of malware:

  • Programs that wait for a user to log in in order to steal their credentials

  • Programs that dump information stored in Windows, such as password hashes, to be used directly or cracked offline

  • Programs that log keystrokes

    In this section, we will discuss each of these types of malware.

GINA Interception

On Windows XP, Microsoft’s Graphical Identification and Authentication (GINA) interception is a technique that malware uses to steal user credentials. The GINA system was intended to allow legitimate third parties to customize the logon process by adding support for things like authentication with hardware radio-frequency identification (RFID) tokens or smart cards. Malware authors take advantage of this third-party support to load their credential stealers.

GINA is implemented in a DLL, msgina.dll, and is loaded by the Winlogon executable during the login process. Winlogon also works for third-party customizations implemented in DLLs by loading them in between Winlogon and the GINA DLL (like a man-in-the-middle attack). Windows conveniently provides the following registry location where third-party DLLs will be found and loaded by Winlogon:

HKLMSOFTWAREMicrosoftWindows NTCurrentVersionWinlogonGinaDLL

In one instance, we found a malicious file fsgina.dll installed in this registry location as a GINA interceptor.

Figure 11-2 shows an example of the way that logon credentials flow through a system with a malicious file between Winlogon and msgina.dll. The malware (fsgina.dll) is able to capture all user credentials submitted to the system for authentication. It can log that information to disk or pass it over the network.

Malicious fsgina.dll sits in between the Windows system files to capture data.

Figure 11-2. Malicious fsgina.dll sits in between the Windows system files to capture data.

Because fsgina.dll intercepts the communication between Winlogon and msgina.dll, it must pass the credential information on to msgina.dll so that the system will continue to operate normally. In order to do so, the malware must contain all DLL exports required by GINA; specifically, it must export more than 15 functions, most of which are prepended with Wlx. Clearly, if you find that you are analyzing a DLL with many export functions that begin with the string Wlx, you have a good indicator that you are examining a GINA interceptor.

Most of these exports simply call through to the real functions in msgina.dll. In the case of fsgina.dll, all but the WlxLoggedOutSAS export call through to the real functions. Example 11-1 shows the WlxLoggedOutSAS export of fsgina.dll.

Example 11-1. GINA DLL WlxLoggedOutSAS export function for logging stolen credentials

100014A0 WlxLoggedOutSAS
100014A0         push    esi
100014A1         push    edi
100014A2         push    offset aWlxloggedout_0 ; "WlxLoggedOutSAS"
100014A7         call    Call_msgina_dll_function 
...
100014FB         push    eax ; Args
100014FC         push    offset aUSDSPSOpS ;"U: %s D: %s P: %s OP: %s"
10001501         push    offset aDRIVERS ; "drivers	cpudp.sys"
10001503         call    Log_To_File 

As you can see at , the credential information is immediately passed to msgina.dll by the call we have labeled Call_msgina_dll_function. This function dynamically resolves and calls WlxLoggedOutSAS in msgina.dll, which is passed in as a parameter. The call at performs the logging. It takes parameters of the credential information, a format string that will be used to print the credentials, and the log filename. As a result, all successful user logons are logged to %SystemRoot%system32drivers cpudp.sys. The log includes the username, domain, password, and old password.

Hash Dumping

Dumping Windows hashes is a popular way for malware to access system credentials. Attackers try to grab these hashes in order to crack them offline or to use them in a pass-the-hash attack. A pass-the-hash attack uses LM and NTLM hashes to authenticate to a remote host (using NTLM authentication) without needing to decrypt or crack the hashes to obtain the plaintext password to log in.

Pwdump and the Pass-the-Hash (PSH) Toolkit are freely available packages that provide hash dumping. Since both of these tools are open source, a lot of malware is derived from their source code. Most antivirus programs have signatures for the default compiled versions of these tools, so attackers often try to compile their own versions in order to avoid detection. The examples in this section are derived versions of pwdump or PSH that we have encountered in the field.

Pwdump is a set of programs that outputs the LM and NTLM password hashes of local user accounts from the Security Account Manager (SAM). Pwdump works by performing DLL injection inside the Local Security Authority Subsystem Service (LSASS) process (better known as lsass.exe). We’ll discuss DLL injection in depth in Chapter 12. For now, just know that it is a way that malware can run a DLL inside another process, thereby providing that DLL with all of the privileges of that process. Hash dumping tools often target lsass.exe because it has the necessary privilege level as well as access to many useful API functions.

Standard pwdump uses the DLL lsaext.dll. Once it is running inside lsass.exe, pwdump calls GetHash, which is exported by lsaext.dll in order to perform the hash extraction. This extraction uses undocumented Windows function calls to enumerate the users on a system and get the password hashes in unencrypted form for each user.

When dealing with pwdump variants, you will need to analyze DLLs in order to determine how the hash dumping operates. Start by looking at the DLL’s exports. The default export name for pwdump is GetHash, but attackers can easily change the name to make it less obvious. Next, try to determine the API functions used by the exports. Many of these functions will be dynamically resolved, so the hash dumping exports often call GetProcAddress many times.

Example 11-2 shows the code in the exported function GrabHash from a pwdump variant DLL. Since this DLL was injected into lsass.exe, it must manually resolve numerous symbols before using them.

Example 11-2. Unique API calls used by a pwdump variant’s export function GrabHash

1000123F         push    offset LibFileName      ; "samsrv.dll" 
10001244         call    esi ; LoadLibraryA
...
10001248         push    offset aAdvapi32_dll_0  ; "advapi32.dll" 
...
10001251         call    esi ; LoadLibraryA
...
1000125B         push    offset ProcName         ; "SamIConnect"
10001260         push    ebx                     ; hModule
...
10001265         call    esi ; GetProcAddress
...
10001281         push    offset aSamrqu ; "SamrQueryInformationUser"
10001286         push    ebx                     ; hModule
...
1000128C         call    esi ; GetProcAddress
...
100012C2         push    offset aSamigetpriv ; "SamIGetPrivateData"
100012C7         push    ebx                     ; hModule
...
100012CD         call    esi ; GetProcAddress
100012CF         push    offset aSystemfuncti  ; "SystemFunction025" 
100012D4         push    edi                     ; hModule
...
100012DA         call    esi ; GetProcAddress
100012DC         push    offset aSystemfuni_0  ; "SystemFunction027" 
100012E1         push    edi                     ; hModule
...
100012E7         call    esi ; GetProcAddress

Example 11-2 shows the code obtaining handles to the libraries samsrv.dll and advapi32.dll via LoadLibrary at and . Samsrv.dll contains an API to easily access the SAM, and advapi32.dll is resolved to access functions not already imported into lsass.exe. The pwdump variant DLL uses the handles to these libraries to resolve many functions, with the most important five shown in the listing (look for the GetProcAddress calls and parameters).

The interesting imports resolved from samsrv.dll are SamIConnect, SamrQueryInformationUser, and SamIGetPrivateData. Later in the code, SamIConnect is used to connect to the SAM, followed by calling SamrQueryInformationUser for each user on the system.

The hashes will be extracted with SamIGetPrivateData and decrypted by SystemFunction025 and SystemFunction027, which are imported from advapi32.dll, as seen at and . None of the API functions in this listing are documented by Microsoft.

The PSH Toolkit contains programs that dump hashes, the most popular of which is known as whosthere-alt. whosthere-alt dumps the SAM by injecting a DLL into lsass.exe, but using a completely different set of API functions from pwdump. Example 11-3 shows code from a whosthere-alt variant that exports a function named TestDump.

Example 11-3. Unique API calls used by a whosthere-alt variant’s export function TestDump

10001119        push    offset LibFileName ; "secur32.dll"
1000111E        call    ds:LoadLibraryA
10001130        push    offset ProcName ; "LsaEnumerateLogonSessions"
10001135        push    esi             ; hModule
10001136        call    ds:GetProcAddress 
...
10001670        call    ds:GetSystemDirectoryA
10001676        mov     edi, offset aMsv1_0_dll ; \msv1_0.dll
...
100016A6        push    eax             ; path to msv1_0.dll
100016A9        call    ds:GetModuleHandleA 

Since this DLL is injected into lsass.exe, its TestDump function performs the hash dumping. This export dynamically loads secur32.dll and resolves its LsaEnumerateLogonSessions function at to obtain a list of locally unique identifiers (known as LUIDs). This list contains the usernames and domains for each logon and is iterated through by the DLL, which gets access to the credentials by finding a nonexported function in the msv1_0.dll Windows DLL in the memory space of lsass.exe using the call to GetModuleHandle shown at . This function, NlpGetPrimaryCredential, is used to dump the NT and LM hashes.

Note

While it is important to recognize the dumping technique, it might be more critical to determine what the malware is doing with the hashes. Is it storing them on a disk, posting them to a website, or using them in a pass-the-hash attack? These details could be really important, so identifying the low-level hash dumping method should be avoided until the overall functionality is determined.

Keystroke Logging

Keylogging is a classic form of credential stealing. When keylogging, malware records keystrokes so that an attacker can observe typed data like usernames and passwords. Windows malware uses many forms of keylogging.

Kernel-Based Keyloggers

Kernel-based keyloggers are difficult to detect with user-mode applications. They are frequently part of a rootkit and they can act as keyboard drivers to capture keystrokes, bypassing user-space programs and protections.

User-Space Keyloggers

Windows user-space keyloggers typically use the Windows API and are usually implemented with either hooking or polling. Hooking uses the Windows API to notify the malware each time a key is pressed, typically with the SetWindowsHookEx function. Polling uses the Windows API to constantly poll the state of the keys, typically using the GetAsyncKeyState and GetForegroundWindow functions.

Hooking keyloggers leverage the Windows API function SetWindowsHookEx. This type of keylogger may come packaged as an executable that initiates the hook function, and may include a DLL file to handle logging that can be mapped into many processes on the system automatically. We discuss using SetWindowsHookEx in Chapter 12.

We’ll focus on polling keyloggers that use GetAsyncKeyState and GetForegroundWindow. The GetAsyncKeyState function identifies whether a key is pressed or depressed, and whether the key was pressed after the most recent call to GetAsyncKeyState. The GetForegroundWindow function identifies the foreground window—the one that has focus—which tells the keylogger which application is being used for keyboard entry (Notepad or Internet Explorer, for example).

Figure 11-3 illustrates a typical loop structure found in a polling keylogger. The program begins by calling GetForegroundWindow, which logs the active window. Next, the inner loop iterates through a list of keys on the keyboard. For each key, it calls GetAsyncKeyState to determine if a key has been pressed. If so, the program checks the SHIFT and CAPS LOCK keys to determine how to log the keystroke properly. Once the inner loop has iterated through the entire list of keys, the GetForegroundWindow function is called again to ensure the user is still in the same window. This process repeats quickly enough to keep up with a user’s typing. (The keylogger may call the Sleep function to keep the program from eating up system resources.)

Loop structure of GetAsyncKeyState and GetForegroundWindow keylogger

Figure 11-3. Loop structure of GetAsyncKeyState and GetForegroundWindow keylogger

Example 11-4 shows the loop structure in Figure 11-3 disassembled.

Example 11-4. Disassembly of GetAsyncKeyState and GetForegroundWindow keylogger

00401162         call    ds:GetForegroundWindow
...
00401272         push    10h                    ; nVirtKey Shift
00401274         call    ds:GetKeyState
0040127A         mov     esi, dword_403308[ebx] 
00401280         push    esi                     ; vKey
00401281         movsx   edi, ax
00401284         call    ds:GetAsyncKeyState
0040128A         test    ah, 80h
0040128D         jz      short loc_40130A
0040128F         push    14h                     ; nVirtKey Caps Lock
00401291         call    ds:GetKeyState
...
004013EF         add     ebx, 4 
004013F2         cmp     ebx, 368
004013F8         jl      loc_401272

The program calls GetForegroundWindow before entering the inner loop. The inner loop starts at and immediately checks the status of the SHIFT key using a call to GetKeyState. GetKeyState is a quick way to check a key status, but it does not remember whether or not the key was pressed since the last time it was called, as GetAsyncKeyState does. Next, at the keylogger indexes an array of the keys on the keyboard using EBX. If a new key is pressed, then the keystroke is logged after calling GetKeyState to see if CAPS LOCK is activated. Finally, EBX is incremented at so that the next key in the list can be checked. Once 92 keys (368/4) have been checked, the inner loop terminates, and GetForegroundWindow is called again to start the inner loop from the beginning.

Identifying Keyloggers in Strings Listings

You can recognize keylogger functionality in malware by looking at the imports for the API functions, or by examining the strings listing for indicators, which is particularly useful if the imports are obfuscated or the malware is using keylogging functionality that you have not encountered before. For example, the following listing of strings is from the keylogger described in the previous section:

[Up]
[Num Lock]
[Down]
[Right]
[UP]
[Left]
[PageDown]

If a keylogger wants to log all keystrokes, it must have a way to print keys like PAGE DOWN, and must have access to these strings. Working backward from the cross-references to these strings can be a way to recognize keylogging functionality in malware.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.89.85