notes from my honeypot project

2f7c156 adding a new readme, updated

3 months ago

b608c67 fixed readme

6 months ago



Honeypots are meant to be useful for catching attacks by creating a mock system that is usually targeted by malware. In this brief tutorial I will show how to configure a honeypot with a Linux filesystem to study mainly cryptominers. For that Im using a customized cowrie.

#Step by step

#Step 1: setting up the server

So there are a few steps to do before using the cowrie project, itself, mostly to limit the interaction to a single specific user as well as setting the network so to work with the ideal ssh configuration.

1.1 Changing the Port 22 to port between 49152 and 65535:

sudo nvim /etc/ssh/sshd_config

1.2 Restart the service

sudo systemctl restart ssh
sudo systemctl status ssh

1.3 Install required stuff (although we will later use a requirements file as well)

sudo apt install -y python-virtualenv libssl-dev libffi-dev build-essential libpython3-dev python3-minimal authbind git

1.4 Create a password-less user for the management

sudo adduser --disabled-password cowrie

1.5 Installing authbind, running the command and changing ownership

sudo apt install authbind
sudo touch /etc/authbind/byport/22
sudo chown cowrie:cowrie /etc/authbind/byport/22

1.6 Permissions

sudo chmod 770 /etc/authbind/byport/22

1.7 Login as cowrie and go to home

sudo su cowrie
cd ~ 

1.8 Clonning the cowrie repo and entering it

git clone https://github.com/micheloosterhof/cowrie
cd cowrie

1.9 Create new configuration

cp etc/cowrie.cfg.dist etc/cowrie.cfg

1.10 Edit the file and replacing 2222 with 22 in listen_endpoints

nvim etc/cowrie.cfg

in the file, change:

listen_endpoints = tcp:2222:interface=


listen_endpoints = tcp:22:interface=

1.11 Create and activate the virtual environment

virtualenv cowrie-env
source cowrie-env/bin/activate

1.12 Install requirements (there are also dev requirements if needed)

pip3 install -r requirements.txt

Finally go to /etc/ in the cowrie directory and create a userdb.txt using the userdb.example guided template, you may add more mock-users if you want.

Until now, the basics are set. Now, the next steps are related to the customization. First of all,I'm going to use a custom Openwrt filesystem since it looks like an IoT device, which are common targets for miners.

#Customizing the honeypot with an Openwrt filesystem

In order to do this, I'm going to copy the filesystem using docker. Docker by default when configured probably need sudo to work, which is going to be messy for the following instructions, therefore here's how to allow an user to use it without sudo`:

1- Creating a group for docker 2- adding the user to the docker (in the following example is the same user it's being used) 3- Changing permissions

sudo groupadd docker
sudo usermod -aG docker $USER
sudo chown root:docker /var/run/docker.sock
sudo chown -R root:docker /var/run/docker

Now to get the OpenWRT:

docker container create -i -t --name mycontainer shellspec/openwrt

Look for the ID of the newly created image:

docker ps -all

Get the ID, or alternatively use a global variable to catch it:

myID=$(docker ps -all)
echo $myID #this is to check it

Now, use that ID in the following loop to create a filesystem copy in an output file, that we shall call picklefs but you could call it whatever.

for i in proc usr sbin sys lib etc bin; do docker cp <ID>:$i $i; done

Remember to change with the actual ID or the global variable.

I created this locally while my server is online, so I used scp -R with the port I configured for accessing to send it to the server. We will locate it in /tmp/picklefs

Now, we are going to need to use a script to transform that filesystem into something that the honeypot can process. The script is in /cowrie/bin/createfs under normal circumstances, the script should be executed from the cowrie user in the virtual environment, from the cowrie main folder like this:

bin/createfs -l /tmp/picklefs -d 6 -o /home/cowrie/cowrie/share/cowrie/honeyfs.pickle

In that, -d is the depth of the filesystem, -l <file> is our temporary file and -o is the output file located in /home/cowrie/cowrie/share/cowrie/. Now before continuing, some stuff might happen:

1- You don't have permissions over /tmp/picklefs

This might happen if, as I, you created it remotely or from another user to avoid setting up docker in the virtual environment. Worry now. Log out from cowrie,and from the regular sudo user, and then change permissions of the folder /tmp/picklefs so cowrie user can use it.

cd /tmp/
sudo chown -R cowrie picklefs/

Problem solved.

2- It gives you ERROR: exceptions.ImportError: No module named cowrie

So this is actually new for me, since it never happened to me until the last time I set up a cowrie. I already opened and issue about it but in the meantime, there's a dirty cheat to fix it. The issue is due to a path missing in python. If you take a look to the files in the repo, you will see there's a src/cowrie/scripts location with scripts that are meant to work from bin. What I did was copying the src to bin:

cp -r src bin/

and in bin modifying both createfs and fsctl headers adding:

import sys
import cowrie

before calling the cowrie.script. This works but I wonder how to fix it in a better way. Anyway, going back to track:

Once we did the createfs thing, we have to add the same filesystem to /home/cowrie/cowrie/honeyfs, this might be redundant but it's how it is. So:

$ cd /home/cowrie/cowrie/honeyfs
$ rm rf *
$ cp -r /tmp/picklefs/* .

Now everything should be ready. But in case you want to add somefiles or directories without building the whole thing up again you can use bin/fsctl. From the main cowrie directory with cowrie user and virtual env, use:

./bin/fsctl share/cowrie/fs.pickle

A shell will appear for you to add stuff, although you cannot edit the contents. In such case what you should do is do it manually and then re-build the filesystem with createfs, but don't forget about the honeyfs duplicate in the path mentioned above.

When you are all set, use bin/cowrie start to launch the shell to the world, or bin/cowrie stop to stop it. It should take a few seconds, only. If it takes more, you probably messed the network configuration, so double check it.


You can add some additional things to lure specific attacks. IN my case I have a plain password backup file for enumerations, as well as a stupid bash script that appears to poorly interact with it in another location of the filesystem, for example. If a log shows interaction with the first one and not the last one, it usually shows an automated reconn, yet if the script is also tested there's might be a manual interaction involved. ON the other hand if the passwords I setted for the mock users are used, since they are not typical brute-force list ones, this means that the both -reconn and the one login with the fake credentials- sessions are connected.

I added a few mock deprecated services, an I also edited some outputs from fake commands by using: