Hotkeyz
Hotkeyz
❖ 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)
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");
Hardware Software
Keyloggers Keyloggers
About Todayʼs Talk
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)
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
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)
In the background,
kbdxxx.dll this Async Key State Array loop
TranslateMessage()
DispatchMessage()
👈
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
Example.
WM_KEYDOWN
WM_KEYUP
SetWindowsHookEx API provides this feature
Example Code
👈
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
💡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
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
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
IDirectInputDevice8Acquire:https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ee417818(v=vs.85
IDirectInputDevice8GetDeviceState: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));
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
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
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-WMIActivity
ETW Provider DISABLED Buffer Event Consumer
(e.g., Event Viewer)
・・・ Event delivery
in real time
・・・
Internals of Providers (e.g., Win32k)
User-mode
(user32.dll) GetAsyncKeyState
EtwTraceGetAsyncKeyState function
which is associated to ETW event writing
(win32u.dll) NtUserGetAsyncKeyState
Kernel-mode
(win32kbase.sys) NtUserGetAsyncKeyState
Microsoft-Windows-Win32k.manifest.xml
Event Fields Definition Manifest File)
GetAsyncKeyState Event ID 1003
Microsoft-Windows-Win32k.manifest.xml
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.
https://github.com/AsuNa-jp/ETW_Win32kAPIMonitor
https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collection_getasynckeysta
te_api_call_from_suspicious_process.toml
https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collection_keystrokes_inp
ut_capture_via_setwindowshookex.toml
https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/collection_keystroke_input
_capture_via_registerrawinputdevices.toml
👈
Part
Hotkey-based Keylogger Detection
B
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) 🤔
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?
ALT TAB
Task Switching
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 SHIFTA, can be registered as hotkeys.
How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 1
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 SHIFTA, can be registered as hotkeys.
How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 2
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 SHIFTA, can be registered as hotkeys.
How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 2
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
😈
How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 4
keyboard
Hotkey
How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 5
Hotkey
Sends a WM_KEYDOWN message to an application
How Hotkey-based Keyloggers Capture Keystrokes Stealthily Step 6
keyboard
Hotkey
Can ETW Monitor the RegisterHotKey API Calls?
EtwTraceGetAsyncKeyState function
which is associated to the ETW event writing
ETW is not monitoring this API..
stored elsewhere?
? keyboard
🤔
Hotkey
?
registered as hotkeys, then
😈 ?
Me
Undocumented Hotkey-table (gphkHashTable)
��
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
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?
App.exe
Kernel-mode
Hotkey Table
(gphkHashTable )
DeviceDriver.sys
Signature:
Signature:0xE8 0x48, 0x8d, 0x1d
Hotkey info registered in Session 1 can only be accessed from within that session.
Challenge #3: win32kfull.sys is a Session Driver
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
Hotkey
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