Intro
For the longest time I had the idea to implement a notification system that would alert me if someone ever logged in (or tried to login) to an SSH server or XSession on a machine I controlled, using known compromised credentials that were obtained via a data breach or a canary password. In this post I am going to show you how I implemented just that using Canary Tokens.
Regardless of how the password was obtained, the objective of this was that I wanted to be alerted as soon as possible. To this end I remembered an app that was built by haroon@thinkst eons ago that worked on MacOS (https://thinkst.com/tools/itried/). The software took a picture of whoever disturbed the mac’s screensaver.
I wanted to achieve something similar for Linux and then hopefully Windows at some point, but only when someone tried to login using compromised credentials or a canary password. While my current implementation doesn’t take a picture (its only hooked up to SSH authentication), you could in theory hook it up to a systems’ GUI login and capture those attempts as well.
Initial Research
After some basic investigations I found that this can be done fairly easily using a Pluggable Authentication Module (PAM). By implementing it this way its fairly dynamic and no major system changes are required.
Implementation
The final implementation I built uses the pam_script
module which lets you hook into PAM and call a shell script of your choice.
Unfortunately pam_script
is pretty old and is not included in most active linux distributions, so we first need to grab a copy of the pam_script
repo located @ https://github.com/jeroennijhof/pam_script. Once downloaded compile and install the library with the following commands:
cd pam_script # Assuming you aren't already in the folder
autoreconf -i
./configure
make
make install
Once installed we need to configure PAM by adding the line below to the following file, /etc/pam.d/sshd
. This location is based on my current setup and may differ depending on how PAM is configured on your system.
auth optional pam_script.so
Once we have PAM configured we need to modify the script that is called when a user fails authentication. On my system this was located at /usr/local/etc/pam_script_auth
. Note, by default this is linked to a script located in the same folder, so either modify the linked script or create a new script and update the link. I took the path of creating a new script and updating the link. You can find the demo script I used below.
#! /bin/sh
# Available Env variables
# PAM_SERVICE - the application that's invoking the PAM stack
# PAM_TYPE - the module-type (e.g. auth,account,session,password)
# PAM_USER - the user being authenticated into
# PAM_RUSER - the remote user, the user invoking the application
# PAM_RHOST - remote host
# PAM_TTY - the controlling tty
# PAM_AUTHTOK - password in readable text
if [ $PAM_USER = "rc1140" ] && [ $PAM_AUTHTOK = "ThePoliceHaveMe" ]; then
curl 'http://canarytokens.com/articles/n6p9nzmbq4o1o19vmvzxuqg8m/index.html'
fi
# success
exit 0
The script itself doesn’t do much aside from curling a canary token. The canary token works great here since you can send the alert notification with very minimal infrastructure and without indicating who has been alerted. Once the token is triggered, an email similar to the one shown below will be sent to the recipient of the token.
I tend to restart the SSH service to ensure that the PAM modifications are loaded but this is probably not needed. It should also be noted that while a plaintext username and password are stored in the script, this is only meant to illustrate the concept, you could hash those values and pass them to another application for verification against a db or file.
Conclusion
That’s it really. You can probably make this way more complicated and covert it to a full PAM module or by modifying the source for different login applications.
Implementing this through a PAM plugin does provide a generic interface to implement this notification method across any system that uses PAM for auth. Using pam_script
the implementation is dynamic and easy to implement.