0% found this document useful (0 votes)
20 views69 pages

Hotkeyz

The document discusses keyloggers, which are software tools that record keystrokes and are often used by malicious actors to steal sensitive information. It outlines various types of keyloggers, including polling-based, hooking-based, and those using raw input and DirectInput models, and emphasizes the importance of early detection to prevent cyber attacks. The presentation also highlights the development of a detection feature for keyloggers through monitoring Windows API calls using Event Tracing for Windows (ETW).

Uploaded by

pgresql
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views69 pages

Hotkeyz

The document discusses keyloggers, which are software tools that record keystrokes and are often used by malicious actors to steal sensitive information. It outlines various types of keyloggers, including polling-based, hooking-based, and those using raw input and DirectInput models, and emphasizes the importance of early detection to prevent cyber attacks. The presentation also highlights the development of a detection feature for keyloggers through monitoring Windows API calls using Event Tracing for Windows (ETW).

Uploaded by

pgresql
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 69

Windows Keylogger Detection

Targeting Past and Present Keylogging Techniques

Asuka Nakajima | 中島 明日香


Senior Security Research Engineer @
❖ Senior Security Research Engineer @ Elastic
✓ Endpoint Protections Team
नमस्ते / Hello!😊
✓ 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


Asuka Nakajima ✓ BlackHat USA / BlackHat Asia / CODE BLUE
Keyloggers: Still Used in Todayʼs Cyber Attacks

❖ What is a keylogger ? 🤔
Password Credit Card Confidential Data
✓ 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


Types of Keyloggers

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

Hardware Software
Keyloggers Keyloggers
Types of Keyloggers

while(true)
💡This talk focuses on {
for (int key = 1; key <= 255; key++)
{
if (GetAsyncKeyState(key) & 0x01)
{
Windows API-based user mode
}
SaveTheKey(key, "log.txt");

keyloggers and their detection


}
}
Sleep(50);

Hardware Software
Keyloggers Keyloggers
About Todayʼs Talk

Part Detecting Common Types of Keyloggers Through

A Windows API Monitoring


💡Sharing my experience of adding a keylogger behavioral detection feature to an EDR

Part
Hotkey-based Keylogger Detection
B
About Todayʼs Talk

Part
A
Detecting Common Types of Keyloggers Through
Windows API Monitoring 👈
💡Sharing my experience of adding a keylogger behavioral detection feature to an EDR

Part
Hotkey-based Keylogger Detection
B
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
Note: All information in this talk is based on Windows 10 version 22H2 OS Build 19045.5371 without virtualization
keyboard -based security. Please note that internal data structures and behavior may differ in other versions of Windows.
Simplified Diagram of the Key Input Flow from Keyboard to Application Windows)

Original Legacy User-mode UI Thread Message Queue


Input Model Window
Procedure
(eg.show
App A typed keys)

Message while(GetMessage() or PeekMessage()) {


TranslateMessage()
loop
kbdxxx.dll DispatchMessage()
}
kbdxxx.dll Window Message
kbdxxx.dll (eg. WM_KEYDOWN
Window
Keyboard layout DLLs Procedure
App B

Kernel-mode
Virtual-Key win32k.sys
Raw Input Thread)
Async Key State Array
Code (eg. VK_A
(per session)
System Hardware Input Queue
kbdclass.sys

HID Keyboard Report USB Keyboard) Driver Stack


Usage ID
Scan Code (e.g.hidclass.sys/ kbdhid.sys )

keyboard USB Device Drivers


Four Common Types of Windows
API-based User-mode Keyloggers Polling-based Keylogger
How It Captures Keystrokes

Periodically checks each key state on the keyboard at very short intervals.
The GetAsyncKeyState API is commonly used for this.

Example Code
keyboard
while(true)
{

👉
for (int key = 1; key <= 255; key++)
{ Key press
if (GetAsyncKeyState(key) & 0x01)
{
SaveTheKey(key, "log.txt"); keyboard
}
} The J key
Sleep(50); was pressed!
} Check whether each key has been pressed
GetAsyncKeyState API https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate
Simplified Diagram of the Key Input Flow from Keyboard to Application Windows)

Original Legacy User-mode UI Thread Message Queue


Input Model Window
Procedure
(eg.show
App A typed keys)

Message while(GetMessage() or PeekMessage()) {

In the background,
kbdxxx.dll this Async Key State Array loop
TranslateMessage()
DispatchMessage()

in the kernel side(eg.


isWM_KEYDOWN
being checked
}
kbdxxx.dll Window Message
kbdxxx.dll

👈
Window
Keyboard layout DLLs Procedure
App B

Kernel-mode
Virtual-Key win32k.sys
Raw Input Thread)
Async Key State Array
Code (eg. VK_A
(per session)
System Hardware Input Queue
kbdclass.sys

HID Keyboard Report USB Keyboard) Driver Stack


Usage ID
Scan Code (e.g.hidclass.sys/ kbdhid.sys )

keyboard USB Device Drivers


Four Common Types of Windows
API-based User-mode Keyloggers Hooking-based Keylogger
How It Captures Keystrokes

Windows provides a hooking mechanism that allows programs to intercept


certain window messages before they reach their intended application.

Example.
WM_KEYDOWN
WM_KEYUP
SetWindowsHookEx API provides this feature

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);

SetWindowsHookEx API https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexw


Simplified Diagram of the Key Input Flow from Keyboard to Application Windows)

Original Legacy User-mode UI Thread Message Queue


Input Model Window
Procedure
(eg.show
App A typed keys)

In the background, it hooks (intercepts) keys Message while(GetMessage() or PeekMessage()) {


TranslateMessage()
loop
kbdxxx.dll DispatchMessage()
before posting them toWindow
kbdxxx.dll the target
Messagemessage queue
}

kbdxxx.dll (eg. WM_KEYDOWN


Window
Keyboard layout DLLs Procedure

👈
App B

Kernel-mode
Virtual-Key win32k.sys
Raw Input Thread)
Async Key State Array
Code (eg. VK_A
(per session)
System Hardware Input Queue
kbdclass.sys

HID Keyboard Report USB Keyboard) Driver Stack


Usage ID
Scan Code (e.g.hidclass.sys/ kbdhid.sys )

keyboard USB Device Drivers


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
Four Common Types of Windows
API-based User-mode Keyloggers Keylogger using Raw Input Model
How It Captures Keystrokes

This type of keylogger captures and records


raw input data obtained from input devices like keyboards.
Example Code 1/2
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 RegisterRawInputDevices API,
rid.dwFlags = RIDEV_INPUTSINK; registers the devices that supply
rid.hwndTarget = hWnd;
RegisterRawInputDevices(&rid, 1, sizeof(rid)); raw input data.
break;
-[continues to the next page]-
RegisterRawInputDevices API https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerrawinputdevices
Four Common Types of Windows
API-based User-mode Keyloggers Keylogger using Raw Input Model

Example Code 2/2


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");
}
} GetRawInputData API retrieves raw
HeapFree(GetProcessHeap(), 0, buffer); input from the registered device
break;
default:
return DefWindowProc(hWnd, uMessage, wParam, lParam);
}
return 0;
}
GetRawInputData API https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getrawinputdata
Four Common Types of Windows
API-based User-mode Keyloggers Keylogger using DirectInput

What is DirectInput ? A collection of APIs used for handling


multimedia tasks such as gaming and video

❖ 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

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
Four Common Types of Windows
API-based User-mode Keyloggers Keylogger using DirectInput

Example Code
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);
}
Four Common Types of Windows
API-based User-mode Keyloggers Keylogger using DirectInput

Confirmed that the RegisterRawInputDevices API


is being called internally!

👆 From dinput8.dll (version: 10.0.19041.1

Note: We haven't fully analyzed dinput8.dll, but at least when running the keylogger, we confirmed that the RegisterRawInputDevices was being called internally.
Detecting Keyloggers by Monitoring Windows API calls

Developed a new feature in the EDR that detects keyloggers


by monitoring API calls and analyzing their behavior

❖ 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)
Elastic Security
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 Defend Integration EDR
Event Tracing for Windows ETW
Enable / Disable Control
Controller Data Flow
Start / Stop
ETW Providers Tracing Sessions

Provider 1
e.g.,Microsoft-Windows-Win32k Session 1 Trace Files (.etl)
ETW Provider ENABLED Session 1
Event Event
Provider 2
e.g.,Microsoft-Windows-WMIActivity
ETW Provider DISABLED Buffer Event Consumer
(e.g., Event Viewer)
・・・ Event delivery
in real time
・・・
Internals of Providers (e.g., Win32k)

The Microsoft-Windows-Win32k provider is a kernel-level provider


that emits ETW events from the kernel level

User-mode

(user32.dll) GetAsyncKeyState
EtwTraceGetAsyncKeyState function
which is associated to ETW event writing

(win32u.dll) NtUserGetAsyncKeyState

Kernel-mode

(win32kbase.sys) NtUserGetAsyncKeyState

👆 From win32kbase.sys (version: 10.0.19041.5247


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!😮
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
Event Fields Definition Manifest File)
GetAsyncKeyState Event ID 1003

Microsoft-Windows-Win32k.manifest.xml

ETW events also include the process ID, thread ID,


and other metadata of the triggered event.
Challenges in Understanding Manifest Files

Challenges
❖ 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.
Target ETW Events and Useful Fields for Detection
Event Name Event ID Field Name Reason
GetAsyncKeyState MsSinceLastKeyEvent For detecting
Event ID 1003 BackgroundCallCount polling-based keyloggers
FilterType
SetWindowsHookEx pstrLib
For detecting
Event ID 1002 hooking-based keyloggers
pfnFilterProc
ReturnValue
UsagePage
Usage
Flags
For detecting keyloggers
RegisterRawInputDevices ThreadStartAddress
using Raw Input and
Event ID 1001 cWindows
DirectInput
cVisWindows
ThreadInfoFlags
ThreadStartAddressMappedModuleName
ThreadStartAddressVadAllocationProtect
Tool Release: ETW_Win32kAPIMonitor

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

❖ ETW APIs for starting, configuring,


opening, and processing trace sessions
✓ StartTraceW
✓ EnableTraceEx2
✓ OpenTraceW
✓ ProcessTrace
Developing Behavioral Detection Rules
GetAsyncKeyState Event ID 1003

Useful Fields for Detection

Field Name Description Example

The elapsed time in milliseconds since the


MsSinceLastKeyEvent
last GetAsyncKeyState event. 141

The total number of GetAsyncKeyState API


BackgroundCallCount calls, including unsuccessful calls, since the 449
last successful GetAsyncKeyState event.
Behavioral Detection Rules for Polling-based Keyloggers

Behavior Detection Rule


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

💡Polling-based keylogger might be present

Checks whether BackgroundCallCount >= 400 ,which indicates


that the GetAsyncKeyState API is being called frequently
SetWindowsHookEx Event ID 1002

Useful Fields for Detection

Field Name Description Example

Type of hook procedure that will be 13


FilterType installed. (WH_KEYBOARD_LL)

The DLL that contains the hook "C\Windows\System32\


pstrLib procedure. Taskbar.dll"

The memory address of the hooked


pfnFilterProc procedure or function.
2431737462784
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

💡Hooking-based keylogger might be present

Checks whether a hook procedure for monitoring low-level keyboard


input events is installed when SetWindowsHookEx is called
FilterType (hook type) == “WH_KEYBOARD_LLˮ
RegisterRawInputDevices Event ID 1001
Useful Fields for Detection
Field Name Description Example

ReturnValue Return value of the RegisterRawInputDevices API call. 1

This parameter indicates the top-level collection 1


UsagePage Usage Page) of the device. It is the first member of (HID_USAGE_PAGE
the RAWINPUTDEVICE structure. _GENERIC)

This parameter indicates the specific device Usage 6


Usage within the Usage Page. It is the second member of the (HID_USAGE_GEN
RAWINPUTDEVICE structure. ERIC_KEYBOARD)
A mode flag that specifies how to interpret the 256
Flags information provided by UsagePage and Usage. It is (RIDEV_
the third member of the RAWINPUTDEVICE structure. INPUTSINK)
ThreadStartAddress The thread start address of the thread. 0x95b7de
RegisterRawInputDevices Event ID 1001
Useful Fields for Detection
Field Name Description Example
Number of windows owned by the
cWindows 2
calling thread.
Number of visible windows owned
cVisWindows 0
by the calling thread.
ThreadInfoFlags Thread info flags. 16

Name of the module associated with \Device\HarddiskVol


ThreadStartAddressMapp ume3\Users\vagrant
the starting address of a thread. \keylogger.exe
edModuleName
The memory protection attributes
ThreadStartAddressVadAll associated with the starting address 128
ocationProtect of a thread.
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

💡Keyloggers using Raw Input Model might be present

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.
commonly used by keyloggers
Behavioral Detection Rule Name URL
GetAsyncKeyState API Call from https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio
Suspicious Process n_getasynckeystate_api_call_from_suspicious_process.toml

GetAsyncKeyState API Call from https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio


Unusual Process n_getasynckeystate_api_call_from_unusual_process.toml

Keystroke Input Capture via https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio


DirectInput n_keystroke_input_capture_via_directinput.toml

Keystroke Input Capture via https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio


RegisterRawInputDevices n_keystroke_input_capture_via_registerrawinputdevices.toml

Keystroke Messages Hooking via https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio


SetWindowsHookEx n_keystroke_messages_hooking_via_setwindowshookex.toml

Keystrokes Input Capture from a https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio


Managed Application n_keystrokes_input_capture_from_a_managed_application.toml

Keystrokes Input Capture from a https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio


Suspicious Module n_keystrokes_input_capture_from_a_suspicious_module.toml

Keystrokes Input Capture from https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio


Suspicious CallStack n_keystrokes_input_capture_from_suspicious_callstack.toml

Keystrokes Input Capture from https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio


Unsigned DLL n_keystrokes_input_capture_from_unsigned_dll.toml

Keystrokes Input Capture via https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collectio


SetWindowsHookEx n_keystrokes_input_capture_via_setwindowshookex.toml
https://www.elastic.co/security-labs/protecting-your-devices-from-information-theft-keylogger-protection
About Todayʼs Talk

Part Detecting Common Types of Keyloggers Through

A Windows API Monitoring


💡Sharing my experience of adding a keylogger behavioral detection feature to an EDR

👈
Part
Hotkey-based Keylogger Detection
B
Encountering Hotkey-based Keylogging Method

One day, I received a message introducing me


to a new keylogging method
jonathanbaror.com

※ https://x.com/yo_yo_yo_jbo/status/1797778371939893504
This message was originally written in Japanese, but translated in English) 🤔
Encountering Hotkey-based Keylogging Method

https://nullcon.net/review-panel/jonathan-bar-or

��
Encountering Hotkey-based Keylogging Method
https://github.com/yo-yo-yo-jbo/hotkeyz
https://nullcon.net/review-panel/jonathan-bar-or

��
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.
How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 1

Basically, a keylogger registers each virtual keycode as a


system-wide hotkey using the RegisterHotKey API (※)

keyboard

※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.
How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 1

Basically, a keylogger registers each virtual keycode as a


system-wide hotkey using the RegisterHotKey API (※)

keyboard

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.
How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 2

Basically, a keylogger registers each virtual keycode as a


system-wide hotkey using the RegisterHotKey API (※)

keyboard

👉
Key press
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.
How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 2

Basically, a keylogger registers each virtual keycode as a


system-wide hotkey using the RegisterHotKey API (※)

keyboard

👉
Key press
Hotkey
Sends a WM_HOTKEY message, which includes
※Modifier keys such as Alt VK_MENU, Ctrl VK_CONTROL, Shift VK_SHIFT, and Win VK_LWIN/VK_RWIN) cannot be registered as hotkeys

virtual keycode (VK_J) to the keyloggerʼs thread message queue


on their own. However, combinations of these modifier keys with other keys, such as SHIFTA, can be registered as hotkeys.
How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 3

Retrieves the WM_HOTKEY message using


the PeekMessage API and extracts the virtual keycode from it

Inside the keyloggerʼs message loop

Get virtual key code (& log it)

😈
How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 4

Unregister the hotkey using the UnRegisterHotKey API

keyboard

Hotkey
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
keyboard

Hotkey
Sends a WM_KEYDOWN message to an application
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

keyboard

Hotkey
Can ETW Monitor the RegisterHotKey API Calls?

NtUserGetAsyncKeyState (win32k) NtUserRegisterHotKey (win32k)

EtwTraceGetAsyncKeyState function
which is associated to the ETW event writing
ETW is not monitoring this API..

😄👆 From win32kbase.sys (version: 10.0.19041.5247


󰷺
👆 From win32kfull.sys (version: 10.0.19041.5247
Are there any detection methods other than ETW?

Is hotkey information keyboard

stored elsewhere?

? keyboard

🤔
Hotkey

If all main virtual key codes were

?
registered as hotkeys, then
😈 ?

Me
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
Structure of HOT_KEY Object

windbg typedef struct _HOT_KEY { Structure


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 object for the Enter key with no modifiers } HOT_KEY, * PHOT_KEY;
Virtual Key Code: 0xd, ID 3

Each HOT_KEY object contains a virtual key code and modifiers


Structure of gphkHashTable

0
index =
vk % 0x80 1 HOT_KEY HOT_KEY
2
3 HOT_KEY
4
5
6 HOT_KEY HOT_KEY HOT_KEY

7 . example:
. example: example:
. VK 0x6 +
. VK 0x6  SHIFT VK 0x6
ALT
.
.
.
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!
Challenges in Developing a Detection Tool

❖ Challenge
Challenge #1 1 How to Access Kernel Space?

❖ Challenge
Challenge #2 2 How to Find the Address of gphkHashTable?

❖ Challenge
Challenge #3 3: win32kfull.sys is a Session Driver
Challenge #1 How to Access Kernel Space?

The hotkey table cannot be directly accessed by


a user-mode application since the table resides in kernel space.
Windows User-mode

App.exe

Kernel-mode

Hotkey Table
(gphkHashTable )
DeviceDriver.sys

We need to develop a device driver to access gphkHashTable !


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"];

Find this pattern and determine the gphkHashTable address


https://www.felixcloutier.com/x86/lea 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
Challenge #2 How to Find the Address of gphkHashTable?

Overview of How to Find the gphkHashTable Address

Step 1 Step 2 Step 3


Inside Inside Inside
kernel space win32kfull.sys win32kfull.sys
Base address
EditionIsHotKey IsHotKey
48 83 EC 28 sub rsp, 28h 48 83 EC 50 sub rsp, 50h
E8 7F 74 EE FF call IsHotKey
win32kfull.sys 33 C9 xor ecx, ecx
0F B6 C2
48 8D 1D 1F 8D 26 00
movzx eax, dl
lea rbx, gphkHashTable
48 85 C0 test rax, rax 83 E0 7F and eax, 7Fh

Signature:
Signature:0xE8 0x48, 0x8d, 0x1d

Resolve the base address Resolve the address of the


EditionIsHotKey function using Find the address of
of win32kfull.sys using
PsLoadedModuleList API
RtlFindExportedRoutineByName, gphkHashTable
then find the address of IsHotKey.
Challenge #3: win32kfull.sys is a Session Driver

What is a Session? Quick Summary)


example:
Session 0※ Session 1 winlogon.exe

❖ In Windows, each logged-in user is assigned Service Process A Process A

a separate session (starting from session 1, Service Process B Process B


with a dedicated desktop environment. Service Process C Process C

❖ Kernel data that must be managed separately for


each session, including win32k drivers data (such Session 2 Session 3
as keyboard input), is stored in an isolated kernel
Process A Process A
memory area called session space.
Process B Process B
✓ This ensures that each user's screen and input
remain separate and isolated. Process C Process C

※ Session 0 is dedicated exclusively to service processes.

Hotkey info registered in Session 1 can only be accessed from within that session.
Challenge #3: win32kfull.sys is a Session Driver

The KeStackAttachProcess API allows the current thread to


temporarily attach to the address space of a specified process
Example Code
KAPC_STATE apc;
PEPROCESS winlogon; Session 1
UNICODE_STRING processName; winlogon.exe
(if only one user is logged in)

RtlInitUnicodeString(&processName, L"winlogon.exe");
HANDLE procId = GetPidFromProcessName(processName);
NTSTATUS status = PsLookupProcessByProcessId(procId, &winlogon);
KeStackAttachProcess(winlogon, &apc);
Thread is attached to the process
~ Can access gphkHashTable as the attached process context (session 1 context) ~

KeUnstackDetachProcess(&apc);
ObDereferenceObject(winlogon);
Detection Logic

If all alphanumeric keys are registered as hotkeys, an alert


will be raised, as it is likely that a hotkey-based keylogger is present.
keyboard

Hotkey

It is also easy to check all


💡 VK + modifiers hotkeys
dbgview.exe
Tool Release: Hotkey-based Keylogger Detector

https://github.com/AsuNa-jp/HotkeybasedKeyloggerDetector

��
DEMO TIME!
धन्यवा

Thank You !

E-mail asuka.nakajima@elastic.co

X Twitter) AsuNa_jp

Website https://www.kun0ichi.net

Github https://github.com/AsuNa-jp

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy