Upgrade to Pro — share decks privately, control downloads, hide ads and more …

(NULLCON Goa 2025)Windows Keylogger Detection: ...

(NULLCON Goa 2025)Windows Keylogger Detection: Targeting Past and Present Keylogging Techniques

Using software keyloggers to steal sensitive information, such as passwords, from computers has been a well-known technique for over 20 years, and reports indicate it continues to be employed in cyber attacks today. While keylogging itself does not directly damage a computer, early detection is critical to preventing subsequent, more invasive cyber attacks.

In this presentation, I will begin by explaining four common types of user-mode keyloggers on Windows (Polling-based, Hooking-based, RawInputModel, and DirectInput) and then discuss detection methods for each. Specifically, I will explain how to detect keyloggers using Event Tracing for Windows (ETW), a logging feature built into Windows and utilized by modern Endpoint Detection and Response (EDR) platforms, including examples of actual detection rules.

In the latter part of the presentation, I will focus on a hotkey-based keylogging technique disclosed in 2024, examining its threats and discussing detection methods. I will specifically highlight the difficulties in detecting this keylogging technique through ETW and then propose a new method for detecting it without ETW using an undocumented hotkey table.

Overall, this presentation will share information about both old and new keylogging techniques, along with useful tips and insights for successfully implementing detection methods.

Asuka Nakajima

March 17, 2025
Tweet

Other Decks in Research

Transcript

  1. Targeting Past and Present Keylogging Techniques Asuka Nakajima | 中島

    明日香 Senior Security Research Engineer @ Windows Keylogger Detection
  2. Asuka Nakajima ❖ Senior Security Research Engineer @ Elastic ✓

    Endpoint Protections Team ✓ Endpoint Security R&D, especially developing new detection features for EDR Elastic Defend) ✓ 10+ years of experience in cyber security R&D ❖ Founder of CTF for GIRLS (est. 2014 ✓ First female infosec community in Japan ❖ Review Board Member ✓ BlackHat USA / BlackHat Asia / CODE BLUE नमस्ते / Hello!
  3. Keyloggers: Still Used in Todayʼs Cyber Attacks ❖ What is

    a keylogger ? ✓ Software that records keystrokes ✓ Often misused by malware / malicious actors to steal sensitive data ◦ Has been used for a long time and is still being found in malware today (e.g., Agent Tesla) ❖ What are the risks ? ✓ e.g., Stolen data may be used for financial theft or further cyber attacks. Early detection is crucial to prevent subsequent attacks Password Credit Card Confidential Data
  4. while(true) { for (int key = 1; key <= 255;

    key++) { if (GetAsyncKeyState(key) & 0x01) { SaveTheKey(key, "log.txt"); } } Sleep(50); } Hardware Keyloggers Software Keyloggers Types of Keyloggers
  5. while(true) { for (int key = 1; key <= 255;

    key++) { if (GetAsyncKeyState(key) & 0x01) { SaveTheKey(key, "log.txt"); } } Sleep(50); } Hardware Keyloggers Software Keyloggers Types of Keyloggers Windows API-based user mode keyloggers and their detection 💡This talk focuses on
  6. About Todayʼs Talk Part A Part B Hotkey-based Keylogger Detection

    💡Sharing my experience of adding a keylogger behavioral detection feature to an EDR Detecting Common Types of Keyloggers Through Windows API Monitoring
  7. About Todayʼs Talk Part A Part B Hotkey-based Keylogger Detection

    Detecting Common Types of Keyloggers Through Windows API Monitoring 💡Sharing my experience of adding a keylogger behavioral detection feature to an EDR
  8. Four Common Types of Windows API-based User-mode Keyloggers ✅ Polling-based

    Keyloggers ✅ Hooking-based Keyloggers ✅ Keyloggers using Raw Input Model ✅ Keyloggers using DirectInput To detect them, we must first understand how they work
  9. keyboard Note: All information in this talk is based on

    Windows 10 version 22H2 OS Build 19045.5371 without virtualization -based security. Please note that internal data structures and behavior may differ in other versions of Windows.
  10. keyboard USB Async Key State Array (per session) User-mode Kernel-mode

    Simplified Diagram of the Key Input Flow from Keyboard to Application Windows) HID Keyboard Report Usage ID UI Thread Message Queue Window Message (eg. WM_KEYDOWN Message loop Window Procedure (eg.show typed keys) App A Device Drivers win32k.sys Raw Input Thread) kbdclass.sys Virtual-Key Code (eg. VK_A while(GetMessage() or PeekMessage()) { TranslateMessage() DispatchMessage() } Window Procedure System Hardware Input Queue App B Original Legacy Input Model kbdxxx.dll kbdxxx.dll kbdxxx.dll Keyboard layout DLLs Scan Code USB Keyboard) Driver Stack (e.g.hidclass.sys/ kbdhid.sys )
  11. Four Common Types of Windows API-based User-mode Keyloggers Polling-based Keylogger

    Periodically checks each key state on the keyboard at very short intervals. The GetAsyncKeyState API is commonly used for this. How It Captures Keystrokes while(true) { for (int key = 1; key <= 255; key++) { if (GetAsyncKeyState(key) & 0x01) { SaveTheKey(key, "log.txt"); } } Sleep(50); } Example Code keyboard 👉 Key press keyboard Check whether each key has been pressed   The J key was pressed! GetAsyncKeyState API https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate
  12. Four Common Types of Windows API-based User-mode Keyloggers Hooking-based Keylogger

    Windows provides a hooking mechanism that allows programs to intercept certain window messages before they reach their intended application. How It Captures Keystrokes Example Code HMODULE hHookLibrary = LoadLibraryW(L"hook.dll"); FARPROC hookFunc = GetProcAddress(hHookLibrary, "SaveTheKey"); HHOOK keyboardHook = NULL; keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)hookFunc, hHookLibrary, 0); Example. WM_KEYDOWN WM_KEYUP SetWindowsHookEx API provides this feature SetWindowsHookEx API https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexw
  13. Four Common Types of Windows API-based User-mode Keyloggers Keylogger using

    Raw Input Model Input Model on Windows ❖ Original Input Model ✓ The data entered from input devices like keyboards is processed by the OS before it is delivered to the application. ❖ Raw Input Model ✓ The data entered from input devices is received directly by the application without any intermediate processing by the OS. 💡Raw keyboard input is sent to the application when the Raw Input Model is used. About Raw Input: https://learn.microsoft.com/en-us/windows/win32/inputdev/about-raw-input
  14. Four Common Types of Windows API-based User-mode Keyloggers Keylogger using

    Raw Input Model LRESULT CALLBACK WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam) { UINT dwSize = 0; RAWINPUT* buffer = NULL; switch (uMessage) { case WM_CREATE: RAWINPUTDEVICE rid; rid.usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC rid.usUsage = 0x06;   // HID_USAGE_GENERIC_KEYBOARD rid.dwFlags = RIDEV_INPUTSINK; rid.hwndTarget = hWnd; RegisterRawInputDevices(&rid, 1, sizeof(rid)); break; -[continues to the next page]- Example Code 1/2 How It Captures Keystrokes This type of keylogger captures and records raw input data obtained from input devices like keyboards. RegisterRawInputDevices API https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerrawinputdevices RegisterRawInputDevices API, registers the devices that supply raw input data.
  15. Four Common Types of Windows API-based User-mode Keyloggers Keylogger using

    Raw Input Model case WM_INPUT: GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)); buffer = (RAWINPUT*)HeapAlloc(GetProcessHeap(), 0, dwSize); if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, buffer, &dwSize, sizeof(RAWINPUTHEADER))){ if (buffer->header.dwType == RIM_TYPEKEYBOARD){ SaveTheKey(buffer, "log.txt"); } } HeapFree(GetProcessHeap(), 0, buffer); break; default: return DefWindowProc(hWnd, uMessage, wParam, lParam); } return 0; } Example Code 2/2 GetRawInputData API retrieves raw input from the registered device GetRawInputData API https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getrawinputdata
  16. Four Common Types of Windows API-based User-mode Keyloggers Keylogger using

    DirectInput What is DirectInput ? DirectInput: https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ee416842(v=vs.85 DirectInput8Create: https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ee416756(v=vs.85 IDirectInputDevice8Acquire:https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ee417818(v=vs.85 IDirectInputDevice8GetDeviceState:https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ee417897(v=vs.85 ❖ One of the components of Microsoft DirectX API ✓ e.g., DirectInput, DirectShow, DirectAudio, etc. ❖ DirectInput can retrieve the keyboard state using APIs such as the following ✓ DirectInput8Create ✓ IDirectInputDevice8Acquire ✓ IDirectInputDevice8GetDeviceState A collection of APIs used for handling multimedia tasks such as gaming and video
  17. Four Common Types of Windows API-based User-mode Keyloggers Keylogger using

    DirectInput LPDIRECTINPUT8   lpDI = NULL; LPDIRECTINPUTDEVICE8 lpKeyboard = NULL; BYTE key[256]; ZeroMemory(key, sizeof(key)); DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID*)&lpDI, NULL); lpDI->CreateDevice(GUID_SysKeyboard, &lpKeyboard, NULL); lpKeyboard->SetDataFormat(&c_dfDIKeyboard); lpKeyboard->SetCooperativeLevel(hwndMain, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE | DISCL_NOWINKEY); while(true) { HRESULT ret = lpKeyboard->GetDeviceState(sizeof(key), key); if (FAILED(ret)) { lpKeyboard->Acquire(); lpKeyboard->GetDeviceState(sizeof(key), key); } SaveTheKey(key, "log.txt"); Sleep(50); } Example Code
  18. Four Common Types of Windows API-based User-mode Keyloggers Keylogger using

    DirectInput 👆 From dinput8.dll (version: 10.0.19041.1 Confirmed that the RegisterRawInputDevices API is being called internally! Note: We haven't fully analyzed dinput8.dll, but at least when running the keylogger, we confirmed that the RegisterRawInputDevices was being called internally.
  19. Detecting Keyloggers by Monitoring Windows API calls ❖ How can

    we monitor Windows API calls? ✓ Event Tracing for Windows ETW ▪ Framework provided by Microsoft for tracing and logging the execution of applications and system components in Windows ▪ Microsoft-Windows-Win32k ETW Provider • Manifest-based ETW Provider (the modern ETW event provider) Event Tracing for Windows(ETW): https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/event-tracing-for-windows--etw- Kernel ETW is the best ETW, https://www.elastic.co/security-labs/kernel-etw-best-etw Developed a new feature in the EDR that detects keyloggers by monitoring API calls and analyzing their behavior Elastic Security Defend Integration EDR
  20. Session 1 Event Tracing for Windows ETW Session 1 Provider

    1 e.g.,Microsoft-Windows-Win32k ETW Provider ENABLED Controller Consumer (e.g., Event Viewer) Provider 2 e.g.,Microsoft-Windows-WMIActivity ETW Provider DISABLED ・・・ ETW Providers ・・・ Enable / Disable Control Data Flow Tracing Sessions Start / Stop Buffer Event Event Trace Files (.etl) Event Event delivery in real time
  21. Internals of Providers (e.g., Win32k) User-mode Kernel-mode 👆 From win32kbase.sys

    (version: 10.0.19041.5247 (user32.dll) GetAsyncKeyState (win32u.dll) NtUserGetAsyncKeyState (win32kbase.sys) NtUserGetAsyncKeyState EtwTraceGetAsyncKeyState function which is associated to ETW event writing The Microsoft-Windows-Win32k provider is a kernel-level provider that emits ETW events from the kernel level
  22. ETW Providers We can see all the providers registered in

    Windows using the logman query providers command More than 1,000 providers are registered by default!
  23. Manifest Files (for Manifest Based ETW Providers) A document that

    specifies event structures such as event categories, fields, and levels for the tracing https://github.com/microsoft/perfview > PerfView.exe /noGUI userCommand DumpRegisteredManifest Microsoft-Windows-Win32k Microsoft-Windows-Win32k.manifest.xml
  24. Event Fields Definition Manifest File) Microsoft-Windows-Win32k.manifest.xml GetAsyncKeyState Event ID 1003

    ETW events also include the process ID, thread ID, and other metadata of the triggered event.
  25. Challenges in Understanding Manifest Files ❖ The event name may

    not be provided. ❖ The field name may not clearly describe the collected data. ❖ Events and fields may change based on the Windows version. ❖ The manifest file does not specify event trigger conditions. Sometimes, it is necessary to perform reverse engineering, call relevant APIs to check which events are generated, and search for other researchers' findings. Challenges
  26. Target ETW Events and Useful Fields for Detection Event Name

    Event ID Field Name Reason GetAsyncKeyState Event ID 1003 MsSinceLastKeyEvent For detecting polling-based keyloggers BackgroundCallCount SetWindowsHookEx Event ID 1002 FilterType For detecting hooking-based keyloggers pstrLib pfnFilterProc RegisterRawInputDevices Event ID 1001 ReturnValue For detecting keyloggers using Raw Input and DirectInput UsagePage Usage Flags ThreadStartAddress cWindows cVisWindows ThreadInfoFlags ThreadStartAddressMappedModuleName ThreadStartAddressVadAllocationProtect
  27. Tool Release: ETW_Win32kAPIMonitor ❖ ETW APIs for starting, configuring, opening,

    and processing trace sessions ✓ StartTraceW ✓ EnableTraceEx2 ✓ OpenTraceW ✓ ProcessTrace https://github.com/AsuNa-jp/ETW_Win32kAPIMonitor A standalone tool which monitors API calls related to keyloggers (GetAsyncKeyState / SetWindowsHookEx / RegisterRawInputDevices ) using the Win32k ETW provider
  28. GetAsyncKeyState Event ID 1003 Field Name Description Example MsSinceLastKeyEvent The

    elapsed time in milliseconds since the last GetAsyncKeyState event. 141 BackgroundCallCount The total number of GetAsyncKeyState API calls, including unsuccessful calls, since the last successful GetAsyncKeyState event. 449 Useful Fields for Detection
  29. Behavioral Detection Rules for Polling-based Keyloggers GetAsyncKeyState API Call from

    Suspicious Process Excerpt of key points) https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collection_getasynckeysta te_api_call_from_suspicious_process.toml Checks whether BackgroundCallCount >= 400 ,which indicates that the GetAsyncKeyState API is being called frequently Behavior Detection Rule 💡Polling-based keylogger might be present
  30. SetWindowsHookEx Event ID 1002 Field Name Description Example FilterType Type

    of hook procedure that will be installed. 13 (WH_KEYBOARD_LL) pstrLib The DLL that contains the hook procedure. "C\Windows\System32\ Taskbar.dll" pfnFilterProc The memory address of the hooked procedure or function. 2431737462784 Useful Fields for Detection
  31. Behavioral Detection Rules for Hooking-based Keyloggers Behavior Detection Rule Keystrokes

    Input Capture via SetWindowsHookEx Excerpt of key points) https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collection_keystrokes_inp ut_capture_via_setwindowshookex.toml Checks whether a hook procedure for monitoring low-level keyboard input events is installed when SetWindowsHookEx is called 💡Hooking-based keylogger might be present FilterType (hook type) == “WH_KEYBOARD_LLˮ
  32. RegisterRawInputDevices Event ID 1001 Field Name Description Example ReturnValue Return

    value of the RegisterRawInputDevices API call. 1 UsagePage This parameter indicates the top-level collection Usage Page) of the device. It is the first member of the RAWINPUTDEVICE structure. 1 (HID_USAGE_PAGE _GENERIC) Usage This parameter indicates the specific device Usage within the Usage Page. It is the second member of the RAWINPUTDEVICE structure. 6 (HID_USAGE_GEN ERIC_KEYBOARD) Flags A mode flag that specifies how to interpret the information provided by UsagePage and Usage. It is the third member of the RAWINPUTDEVICE structure. 256 (RIDEV_ INPUTSINK) ThreadStartAddress The thread start address of the thread. 0x95b7de Useful Fields for Detection
  33. RegisterRawInputDevices Event ID 1001 Field Name Description Example cWindows Number

    of windows owned by the calling thread. 2 cVisWindows Number of visible windows owned by the calling thread. 0 ThreadInfoFlags Thread info flags. 16 ThreadStartAddressMapp edModuleName Name of the module associated with the starting address of a thread. \Device\HarddiskVol ume3\Users\vagrant \keylogger.exe ThreadStartAddressVadAll ocationProtect The memory protection attributes associated with the starting address of a thread. 128 Useful Fields for Detection
  34. Behavioral Detection Rules (for Raw Input Keyloggers) Behavior Detection Rule

    Keystroke Input Capture via RegisterRawInputDevices Excerpt of key points)  https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collection_keystroke_input _capture_via_registerrawinputdevices.toml Checks the arguments of the RegisterRawInputDevices API call to see if the registered device is a keyboard and if the RIDEV_INPUTSINK flag is set. 💡Keyloggers using Raw Input Model might be present commonly used by keyloggers
  35. Behavioral Detection Rule Name URL GetAsyncKeyState API Call from Suspicious

    Process https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio n_getasynckeystate_api_call_from_suspicious_process.toml GetAsyncKeyState API Call from Unusual Process https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio n_getasynckeystate_api_call_from_unusual_process.toml Keystroke Input Capture via DirectInput https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio n_keystroke_input_capture_via_directinput.toml Keystroke Input Capture via RegisterRawInputDevices https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio n_keystroke_input_capture_via_registerrawinputdevices.toml Keystroke Messages Hooking via SetWindowsHookEx https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio n_keystroke_messages_hooking_via_setwindowshookex.toml Keystrokes Input Capture from a Managed Application https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio n_keystrokes_input_capture_from_a_managed_application.toml Keystrokes Input Capture from a Suspicious Module https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio n_keystrokes_input_capture_from_a_suspicious_module.toml Keystrokes Input Capture from Suspicious CallStack https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio n_keystrokes_input_capture_from_suspicious_callstack.toml Keystrokes Input Capture from Unsigned DLL https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio n_keystrokes_input_capture_from_unsigned_dll.toml Keystrokes Input Capture via SetWindowsHookEx https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio n_keystrokes_input_capture_via_setwindowshookex.toml
  36. About Todayʼs Talk Part A Part B Hotkey-based Keylogger Detection

    Detecting Common Types of Keyloggers Through Windows API Monitoring 💡Sharing my experience of adding a keylogger behavioral detection feature to an EDR
  37. Encountering Hotkey-based Keylogging Method ※ https://x.com/yo_yo_yo_jbo/status/1797778371939893504 This message was originally

    written in Japanese, but translated in English) One day, I received a message introducing me to a new keylogging method jonathanbaror.com
  38. What is a Hotkey? A type of keyboard shortcut that

    directly invokes a specific function on a computer by pressing a single key or a combination of keys ALT  TAB Task Switching With the RegisterHotKey API, we can set custom hotkeys. 💡Hotkey-based keyloggers abuse this capability to capture the keystrokes entered by the user.
  39. How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 1 keyboard Basically,

    a keylogger registers each virtual keycode as a system-wide hotkey using the RegisterHotKey API (※) ※Modifier keys such as Alt VK_MENU, Ctrl VK_CONTROL, Shift VK_SHIFT, and Win VK_LWIN/VK_RWIN) cannot be registered as hotkeys on their own. However, combinations of these modifier keys with other keys, such as SHIFTA, can be registered as hotkeys.
  40. How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 1 Hotkey ※Modifier

    keys such as Alt VK_MENU, Ctrl VK_CONTROL, Shift VK_SHIFT, and Win VK_LWIN/VK_RWIN) cannot be registered as hotkeys on their own. However, combinations of these modifier keys with other keys, such as SHIFTA, can be registered as hotkeys. keyboard Basically, a keylogger registers each virtual keycode as a system-wide hotkey using the RegisterHotKey API (※)
  41. How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 2 ※Modifier keys

    such as Alt VK_MENU, Ctrl VK_CONTROL, Shift VK_SHIFT, and Win VK_LWIN/VK_RWIN) cannot be registered as hotkeys on their own. However, combinations of these modifier keys with other keys, such as SHIFTA, can be registered as hotkeys. Basically, a keylogger registers each virtual keycode as a system-wide hotkey using the RegisterHotKey API (※)
  42. How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 2 ※Modifier keys

    such as Alt VK_MENU, Ctrl VK_CONTROL, Shift VK_SHIFT, and Win VK_LWIN/VK_RWIN) cannot be registered as hotkeys on their own. However, combinations of these modifier keys with other keys, such as SHIFTA, can be registered as hotkeys.  Sends a WM_HOTKEY message, which includes virtual keycode (VK_J) to the keyloggerʼs thread message queue Basically, a keylogger registers each virtual keycode as a system-wide hotkey using the RegisterHotKey API (※)
  43. How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 3 Inside the

    keyloggerʼs message loop Retrieves the WM_HOTKEY message using the PeekMessage API and extracts the virtual keycode from it Get virtual key code (& log it)
  44. How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 5 Simulate a

    key press using the keybd_event API 💡To the user, it appears as if the key was pressed normally Sends a WM_KEYDOWN message to an application Hotkey keyboard
  45. How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 6 Re-register the

    key as a hotkey using the RegisterHotKey API, and wait for the further user input Back to Step 2 Hotkey keyboard
  46. Are there any detection methods other than ETW? ? ?

    If all main virtual key codes were registered as hotkeys, then ? keyboard keyboard Me Is hotkey information stored elsewhere? Hotkey
  47. Undocumented Hotkey-table (gphkHashTable) _RegisterHotKey (called by NtUserRegisterHotkey) Found a global

    hash table gphkHashTable, which contains registered hotkey data! The gphkHashTable stores HOT_KEY objects (i.e., Registered Hotkey Info) in a hash table, with their index calculated simply as virtual keycode % 0x80 win32kfull.sys (version: 10.0.19041.5247
  48. Structure of HOT_KEY Object Each HOT_KEY object contains a virtual

    key code and modifiers typedef struct _HOT_KEY { PTHREADINFO pti, PVOID callback, PWND pWnd, UINT16 fsModifiers1, // eg. MOD_CONTROL0x0002 UINT16 fsModifiers2, // eg. MOD_NOREPEAT0x4000 UINT32 vk, // virtual keycode UINT32 id, // identifier #ifdef _AMD64_ PADDING32 pad; #endif struct _HOT_KEY *pNext; // pointer to the next object …[skip]... } HOT_KEY, * PHOT_KEY; windbg Structure HOT_KEY object for the Enter key with no modifiers Virtual Key Code: 0xd, ID 3
  49. Structure of gphkHashTable 0 1 2 3 4 5 6

    7 . . . HOT_KEY HOT_KEY HOT_KEY HOT_KEY HOT_KEY example: VK 0x6  SHIFT index = vk % 0x80 example: VK 0x6 + ALT HOT_KEY example: VK 0x6 By scanning all HOT_KEY objects in gphkHashTable, we can identify all registered hotkeys. 💡If all of the main keys are registered as hotkeys, itʼs suspicious! . . . .
  50. Challenges in Developing a Detection Tool ❖ Challenge 1 How

    to Access Kernel Space? ❖ Challenge 2 How to Find the Address of gphkHashTable? ❖ Challenge 3: win32kfull.sys is a Session Driver Challenge #2 Challenge #1 Challenge #3
  51. Challenge #1 How to Access Kernel Space? User-mode Kernel-mode DeviceDriver.sys

    Hotkey Table (gphkHashTable ) App.exe The hotkey table cannot be directly accessed by a user-mode application since the table resides in kernel space. Windows We need to develop a device driver to access gphkHashTable !
  52. Challenge #2 How to Find the Address of gphkHashTable? Inside

    the IsHotKey function (win32kfull.sys) which is called from an exported function named EditionIsHotKey Opcode bytes Assembly Code 0x48 0x8D 0x1D ["32 bit offset"]; https://www.felixcloutier.com/x86/lea Find this pattern and determine the gphkHashTable address or, Intel® 64 and IA-32 Architectures Software Developer’s Manual, Vol. 2A 3-605 for the details on the LEA instruction Note - win32kfull.sys (version: 10.0.19041.5247
  53. Challenge #2 How to Find the Address of gphkHashTable? Overview

    of How to Find the gphkHashTable Address Resolve the base address of win32kfull.sys using PsLoadedModuleList API Resolve the address of the EditionIsHotKey function using RtlFindExportedRoutineByName, then find the address of IsHotKey. Step 1 Find the address of gphkHashTable win32kfull.sys Inside kernel space 48 83 EC 28 sub rsp, 28h E8 7F 74 EE FF call IsHotKey 33 C9 xor ecx, ecx 48 85 C0 test rax, rax Inside win32kfull.sys Inside win32kfull.sys Base address EditionIsHotKey 48 83 EC 50 sub rsp, 50h 0F B6 C2 movzx eax, dl 48 8D 1D 1F 8D 26 00 lea rbx, gphkHashTable 83 E0 7F and eax, 7Fh IsHotKey Signature:0xE8 Signature: 0x48, 0x8d, 0x1d Step 2 Step 3
  54. Challenge #3: win32kfull.sys is a Session Driver Session 0※ Session

    1 Session 2 Session 3 Service Process A Service Process B Service Process C Process A Process B Process C Process A Process B Process C Process A Process B Process C example: winlogon.exe What is a Session? Quick Summary) Hotkey info registered in Session 1 can only be accessed from within that session. ❖ In Windows, each logged-in user is assigned a separate session (starting from session 1, with a dedicated desktop environment. ❖ Kernel data that must be managed separately for each session, including win32k drivers data (such as keyboard input), is stored in an isolated kernel memory area called session space. ✓ This ensures that each user's screen and input remain separate and isolated. ※ Session 0 is dedicated exclusively to service processes.
  55. Challenge #3: win32kfull.sys is a Session Driver KAPC_STATE apc; PEPROCESS

    winlogon; UNICODE_STRING processName;  RtlInitUnicodeString(&processName, L"winlogon.exe"); HANDLE procId = GetPidFromProcessName(processName); NTSTATUS status = PsLookupProcessByProcessId(procId, &winlogon); KeStackAttachProcess(winlogon, &apc); ~ Can access gphkHashTable as the attached process context (session 1 context) ~ KeUnstackDetachProcess(&apc); ObDereferenceObject(winlogon); Session 1 winlogon.exe (if only one user is logged in) The KeStackAttachProcess API allows the current thread to temporarily attach to the address space of a specified process Example Code Thread is attached to the process
  56. Detection Logic keyboard If all alphanumeric keys are registered as

    hotkeys, an alert will be raised, as it is likely that a hotkey-based keylogger is present. Hotkey dbgview.exe It is also easy to check all VK + modifiers hotkeys 💡