Cowrie is a medium interaction honeypot written by Michel Oosterhof that is designed to not only log bruteforce attempts against an ssh server, but to “record” the entire shell session of an attacker. It creates a “fake” server that will be used to lure attackers to attempt access. The functionality of Cowrie extends far beyond what is described here, and will be the subject of future blog posts. I encourage you to visit the Cowrie repository on Github in the meantime to read about all that it can do. This post is intended to describe the steps to configure and deploy a Cowrie base install. Is this the only way to configure and deploy Cowrie? No. Have the steps below been tested on a live server? Yes. Have I missed anything? Maybe.
For the purposes of this post, Cowrie was installed on an Ubuntu 14.04 768MB Vultr VPS (affiliate link, I earn account credit) and it assumes that you are familiar with the basic idea of what a honeypot is. It begins with you connected via ssh to a fresh VPS instance with your hostname configured. I’ll use nano as my text editor. If you prefer vi, emacs, gedit etc., knock yourself out. And before you ask: Yes. You can run a honeypot from home, but that can get complicated and I’m not going to show you how to do it.
Once you’re logged in, it’s good practice to initiate updates:
apt-get update -y && apt-get upgrade
First, we’ll install the dependencies:
apt-get install git python-dev python-openssl openssh-server python-pyasn1 python-twisted authbind
We need to change the port that we will use to administer the server, as we will later configure Cowrie to listen for ssh attacks on port 22. This configuration is done in /etc/ssh/sshd_config:
When we open the file, we’ll see this:
We’ll need to change the port that we will use to administer the server after Cowrie is installed and running. In this example, we’ll use 8742. Change it in the file, so it looks like this:
We’ll need to restart the SSH server by entering:
service ssh restart
Cowrie cannot be run as root, so we’ll add a non root user (user “cowrie” in this example), and give the user a password. The rest of the user information can be left blank.
We now need to make preparations to have Cowrie listen on port 22, where ssh attacks will occur. Enter the following commands separately:
chown cowrie /etc/authbind/byport/22
chmod 777 /etc/authbind/byport/22
Now, we’ll switch to our new non root user, “cowrie”:
We’re now in the home directory of user “cowrie” where we’ll install the honeypot.
Enter the following command to pull the code out of the Github repository and create a new directory called cowrie that we’ll use to configure and start the honeypot.
git clone https://github.com/cowrie/cowrie.git
We’ll check to make sure that everything downloaded correctly by listing the contents of the home directory by entering
ls. You should see something like this:
Let’s move into the newly created cowrie directory and begin to configure the honeypot.
First, we need to change the name of the main configuration file:
mv cowrie.cfg.dist cowrie.cfg
Now we’ll open the file…
…and do two things:
1) We need to uncomment and change the line that defines on which port Cowrie will listen. Navigate to the line that reads “#listen_port = 2222” and change it to “listen_port = 22” as we will soon fully configure Cowrie to listen for attacks on this port.
2) When using Cowrie, we can define what the fake hostname the attacker will see if/when he or she is able to gain access to the fake server. The default is already configured in this file. It’s a good idea to change it to something that sounds like a legitimate server. We’ll choose one and enter it on the line that reads, “hostname”. In this example we’ll change it to “testSrv”. After the revisions, the file will look like this:
Save the file and exit.
Now we’ll finish configuring Cowrie so that it will listen for attacks on port 22. We’ll navigate to our home directory and enter:
authbind --deep to the beginning of the last line of the script so that it looks like this:
Cowrie allows us to create a “fake” file system using Python pickle that the attacker will interact with upon successful entry into the server.
We’ll enter the/cowrie/utils directory and use createfs.py.
./createfs.py > fs.pickle
Cowrie also allows us to define which username/password combinations will result in successful entry into the fake server. To do this, we’ll navigate to /cowrie/data and enter:
…where we’ll see:
Read the top comment section on how to deny specific passwords by using “!” and how to allow any password with a given username by using “*”. We’ll add a password to the list as shown below, then save and exit the file.
Now we’ll start Cowrie. Return to the home directory of user cowrie and initiate the start script:
There are two ways we’ll make sure it’s running. First we’ll find its process ID by entering:
We should see a process ID where the red box is (your process ID will be different):
Cowrie is built with python, so we’ll ensure that python is listening on port 22 by entering:
netstat -antp | grep 22
(the process ID will be the same in both cases, they differ here due to a revision in this blog post)
We now know that Cowrie is running and listening to port 22. Let’s test it. Disconnect from your server and using a utility like PuTTY, reconnect to your server as user root on port 22:
You’ll be prompted for a password, enter anything besides a password on your list in userdb.txt. We’re going to ensure that Cowrie is logging attempts to enter our server. After a few attempts, you’ll be disconnected from the server. We’ll now log back in to our server as user cowrie using the admin port that we configured in the beginning steps…in this case we used port 8742.
ssh -p 8742 cowrie@(ipaddress)
We’ll navigate to /cowrie/logs, then enter:
The result should appear as below. The attackers IP will appear in the blacked out area of the file, and we should see the failed username/password combinations that we just entered in the area within the red boxes.
We’ll now disconnect from our server. Again using PuTTY, we’ll connect to our server, enter a username/password combination that we know is in out userdb.txt file and make sure we are presented with the fake hostname that we configured in the cowrie.cfg file:
We’ll disconnect from this session then reconnect via out administration port, port 8742. Well again navigate to /cowrie/log where we’ll enter
again to see what a successful username/password entry looks like:
That’s it. We’ve installed and configured our Cowrie instance, ensured that it is running properly, and confirmed that it is logging attempts to bruteforce our ssh server.
You may start logging attacks soon after deployment, though sometimes it takes a while. Most of your attackers will be bots. Generally speaking, the longer Cowrie is deployed, the more it will be attacked. I have several instances of Cowrie deployed and it is not uncommon to log several thousand bruteforce attempts per day. As I mentioned above, Cowrie is capable of much more functionality like supporting JSON logging, logging of direct tcp connection attempts and SFTP and SCP file upload.
Thanks for reading, and if you have any questions or if there’s anything I missed, find me on Twitter.