Writing a Basic Keylogger for macOS in Python

A brief look at how to covertly log user activity on macOS

Photo by Christin Hume on Unsplash

??This post is for educational purposes only??

A keylogger is probably one of the last things you want on your computer. Unfortunately, this type of program is usually well hidden and often go completely undetected by the victim.

At its core, a keylogger is a device or program that logs everything you type on your computer. Meaning that every password, every private message you send, and every search you type can be recorded and read by a malicious party.

There are two primary categories of keyloggers, hardware loggers and software loggers. Hardware loggers are usually easier to detect. They are often characterized as a small device that physically sits between a wired keyboard and computer. With the advent of Bluetooth keyboards this type of logger is less common now, however Bluetooth sniffing attacks do exist.

Software loggers are often much better concealed and are a common feature to be included in rootkits. Rootkits are a particularly nasty class of malware that live at a very low level of the computer, often below where the operating system or anti-virus programs are able to detect. Rootkits typically run with such high privileges such that nothing is outside of their visibility. More advanced rootkits may also have capabilities beyond recording simple keystrokes, including taking screenshots and even covertly recording video and sounds using a computer’s camera and microphone.

In this post I’ll demonstrate how you can set up a simple keylogger on macOS using python. Apple’s security for macOS is generally held to a fairly high standard and therefore to get a program like this to run we’ll need to deliberately weaken macOS’ security for this purpose.

An actual malicious keylogger would likely exploit some kind of vulnerability in order to get past Apple’s security controls and an advanced logger may make use of other hiding mechanisms to conceal the process itself and communicate the collected keystroke data with a remote command and control server.

Disabling System Integrity Protection (SIP) ?

Apple introduced System Integrity Protection (SIP) mode for its macOS introduced in OS X El Capitan. SIP is a well-known feature in macOS 10.12 Sierra and macOS 10.13 High Sierra that protects files, directories, and processes at the root level from being modified. By protecting access to system locations and restricting runtime attachment to system processes it serves as a powerful defensive control against modification to low level processes.

In order to get our sample keylogger to work we’ll need to disable this feature. To do this:

  1. Restart your Mac.
  2. Immediately upon reboot hold down Command-R until the Apple logo appears.
  3. Wait for macOS to boot into the OS X Utility window.
  4. In the Utilities menu, select Terminal.
  5. Type csrutil disable and press enter.
  6. Type reboot and press enter.
  7. Log into your mac as usual.

Important: For your own security, remember to re-enable this feature after you’re done testing by following the steps above but entering csrutil enable in step 5.

The Python Code

The python code needed to run this sample key logger relies heavily on some of Apple’s own classes, namely NSApplication and NSEvent which we will install via the pyobjc library. The full code is available here, but I’ll go through the interesting bits below.

I like to make my applications configurable, in this case I’m using ConfigParser to configure my settings for where to write the collected data. I’ve also provided some defaults in-case the config is missing.

Next we’ll create our Writer class. This class is responsible for creating a log file and logging all collected keystrokes.

Finally we’ll look at our AppDelegate class which will actually collect the keydown events as well as our handler which will interpret the keydown events and send the results to the Writer class “write_to_log” method.

The Launch Script

In order to ensure our key logger can run we’ll use a handy launch script that can do some of the setup for us. You can look at the full script here, for our purposes I’ll just cover a few interesting bits.

First we check the macOS version and whether SIP is enabled, we’ll assume this script can only run on systems running 10.12 and above and SIP must be disabled.

Next we try to add the Terminal app to macOS’ assistive devices whitelist. This is required in order to give our script access to capture keydown events which would normally not be accessible. In this example I add both Terminal and iTerm2, which is my shell of choice. If you use a different shell application you can add it here.

Finally we will install the python dependencies silently and launch the python script in the background.

Testing it out and Cleaning up ??

Finding the logged file

As you may have noticed in the python code, I’m attempting to write my data to /Library/Caches/com.apple.pkl. The idea here is to try to write the data somewhere inconspicuous, such as where system caches are located. Most users will never visit this location, much less know to look for anything suspicious.

Killing the script

Assuming the script runs successfully, it should simply be a python process running in the background. If you named the python file “pkl.py” as I did you can kill it by running: kill -9 $(ps aux | grep pkl.py | awk ‘{print $2}'.

Cleaning up the Assistive Devices Whitelist

I like to do this by modifying the sqlite database that houses these permissions, but it can also easily be done within System Preferences.

  1. Open “System Preferences”.
  2. Click “Security & Privacy”.
  3. Click the “Privacy” tab.
  4. Click “Accessibility” in the left sidebar.
  5. Click the “-” button below the table listing the Applications with Accessibility access.

Wrapping up

You can access my full code here. Have some fun with it!

Remember, this code is only for education purposes and you should only run it on your own computer. Once you’ve finished running be sure to re-enable SIP for your own safety.

Facebook Comments

More Stuff

The Engine That Powers Winds https://getstream.io/windsFor those of you who don’t know, Winds (the popular open-source RSS and Podcast application) is powered by Stream?—?a S...
Pick your battles: Choosing and Learning the “righ... Comparison MetricsLevels of abstractionIt can be helpful to look at today’s programming languages across 3 different levels?—?“build fast” program...
How to Make Your Code Robust For the robust, an error is information. If we can sum up the definition of good code, in a nutshell, it will be as below.“Good code is short, sim...
Top 5 Courses to Learn Python in 2018 — Best of Lo... How to become a Python Programmer If you have just started learning to code a Computer Science graduate and thinking to learn Python in 2018 then...
Spread the love

Posted by News Monkey