In Part 2 we discussed the Email Sending, here we finish our discussion by looking at the heart of the key logger. The HOOKS! How the key logger will hook into each key press and intercept the interrupt code message so it can pass it off to its own sub routine callback procedure for logging. We then move onto the entry point of the application main.cpp and finish with a resource file (.rc file) which lets us make the key logger undetectable in task manager by saying it was published by Microsoft Corporation.
- [Teacher] Now that we've seen the keymap, the logging objects, and the mail sending objects, let's look at the files that bring it all together. First off is KeyHook.h. KeyHook.h is not an object. It is simply a header file to handle all the prep work we need to do before calling the objects in main.cpp. Main.cpp is the entry point to our application. The string containing all current keystroke recordings is g_keyLog. It's global so that it's accessible by all files.
There should only be one. It's unique, so do not add another one. The next global variable that we want to have accessible by other files, particularly to main.cpp is g_MailSender. The global MailSender object is what contains the Logger and MailTimer objects. Remember that the Logger object itself has the DateTime object and Encrypter object. This is a very modular object oriented design so that further improvements can be made by easily adding another object, like a Decrypter object.
Moving down, the first function that we see is SendMailTimer. This is where writing the encrypted keystrokes happens and the email containing the encrypted logfile and plain text is performed. Return codes and error handling are also performed here. After the email containing the plain text, which is g_keyLog is sent the global string is reset to blank. That's the mail sending function. Let's pass it as the task to execute for the MailTimer thread object. Which is right here.
The second parameter is what dictates how often to send the email. Here it's set to send every 60 seconds. This is of course can easily be changed by changing this value, in the second parameter. The third argument is to tell the MailTimer to run forever, indicated by s_Infinite. Next, are the KeyboardHook and keymap declarations, which are again global, indicated by the g_. This portion right here indicates that the variable is global.
This is followed by the callback procedure that is executed every time a key is pressed on the keyboard. This is where Window's APIs such as CallNextHook and KBDLLHookStruct are seen. This is what we need to find when inspecting our trace file later on in the windows performance analyzer. Below this KeyPress callback procedure is the function which attaches the KeyHook to intercept all keys pressed and pass them to our sub-routine callback procedure for logging. The sub-routine that's called every time a keystroke is intercepted is the KeyboardProc callback procedure.
The other functions are for removing the KeyboardHook. This cleanup is so that there's no evidence left that the KeyLogger was on the victim's machine, recording them. Last, there's a helper to check if the KeyboardHook attachment occurred successfully. With all the prep work done in KeyHook.h, we can now move on to main.cpp, which is the entry point to the application. Here we initialize the MailSender object with the Logger and the path to where the Microsoft_Service PowerShell script is created.
Then we attach the KeyboardHook and dive into the Windows Message Pump system. Since Windows is a message based OS, we use GetMessage to wait for a message to be in the queue. When it sees a message it will return and translate that message and have our KeyboardProc callback record the key presses. This KeyLogger will run forever, meaning in order to stop it, we have to locate it in our task manager and end task. The last file that we will look at is a resource file. KeyLogger.rc.
If we double click on this, we will see a version folder. Click on the drop down arrow and then double click on VS_VERSION_INFO. Here we can state that it's published by Microsoft and even use the file name version of real Window's processes. This resource file makes it so that even if someone suspects our process as being malicious, they will be very hesitant to remove it since it's disguised as coming from Microsoft Corporation. All of these fields can be changed to whatever you like.
This is the KeyLogger we will try to find during our collection process. Let's recap. In short, the MailSender object contains the MailTimer and Logger objects. The Logger object itself contains the DateTime, and Encrypter objects. The Keys object is left alone and is only used in KeyHook.h. KeyHook.h is the header file that brings it all together. It's the heart of the KeyLogger. It sets up the mail sending, the mail timing, the hook callback procedure and the keystroke recording for the current session.
These objects are then initialized in main.cpp and AttachKeyHook is called to setup the callback procedure before entering the Windows Message Pump system.