Watching the Bad Guys with Cowrie
Honeypots

Photo by Christina Branco on Unsplash
Use Cowrie as a honeypot to capture attack data and learn more about your attacker's methods.
Special Thanks: This article was made possible by support from Linux Professional Institute
For one reason or another, I stumbled across a relatively old piece of software the other day while researching some unrelated DevOps security news. Doing so reminded me that I hadn’t run a honeypot for around fifteen years, and it inspired me to see if there were any advances in honeypot functionality.
There are three key types of honeypots, which fall into categories base on interactivity:
- A “low interaction” honeypot tempts attackers to probe a system or network with, for example, visible but inaccessible admin network ports for common applications.
- A “medium interaction” honeypot might tempt an attacker with some interaction on the system itself (I'll look more at this type of honeypot in a moment).
- A “high interaction” honeypot looks like a precious system and alludes to being fully open and exploitable. Any business offering a this type of honeypot publicly will most likely treat it as a disposable resource that can be resurrected with relative ease.
Nectar
Because my professional background with Linux, I was initially drawn to Kippo, which then led me to Cowrie, a more-recently maintained fork of Kippo.
Cowrie appealed to me mainly because I wanted to use a container to capture some real attack data. I liked the idea of seeing precisely what commands an attacker might have been typing, with the aim of being able to gauge the sophistication and maturity level of an attack and whether the attack used manually input commands or automated bot behavior.
In this article, I’ll show you how to install Cowrie using Docker, attack it non-invasively, and then analyze the results. Cowrie describes itself on Docker Hub as “a medium interaction SSH and Telnet honeypot designed to log brute force attacks and the shell interaction performed by the attacker.” Intrigued? Let’s crack on. But a serious word of warning before you get started, see the “Danger, High Voltage!” box.
Danger, High Voltage!
Be advised that you need to be extremely selective about where you put honeypots. You are effectively leaving your front door open to a burglar so you can surveil them.
Just in case I any rattled cages, I wanted some clarity about the Acceptable Usage Policy (AUP) in place for AWS (Amazon Web Services) EC2 server instances, so I contacted the AWS team responsible for penetration tests by filling out an online form stating that I wanted to run a single honeypot.
I have to admit that I was a little surprised by the response, which was something along the lines of “only passive Honeypots are allowed.” For further clarification, I confirmed that systems that “appear” vulnerable are okay to run on AWS publicly. However, if an attacker can log into such a system, then it breaches their AUP. As a result, the rest of this article shows testing software on a locked-down (non-public) AWS instance, which was then destroyed shortly afterwards.
It’s safe to say that not all cloud providers or ISPs are equal, so check with your host before doing anything that might raise eyebrows. AWS frowns on all kinds of floods or denial or service (DoS) testing from what I could see. Additionally they don’t want the smaller instances used for penetration tests, such as the nano, small, and micro sizes.
However, I found that Digital Ocean actually wrote a tutorial on the older Kippo software. It’s well written making it worth a quick look, but it is deprecated on a number of levels. I have a Digital Ocean account, so I raised a support ticket checking their stance given the tutorial. Their response was refreshing. It alluded to the fact that so long as shared hardware resources weren’t affected by running servers for security research (servers are called “droplets” in this case) then their Terms of Service (TOS) wouldn’t be breached. As cloud servers follow the shared tenancy model, this made perfect sense. Later on in this article, you'll see that the Docker container offers a degree of isolation. If I was running Cowrie on Digital Ocean, I would limit that container’s CPU, IO, and kernel system calls to meet their TOS.
In short, whichever host you use (including running a honeypot on your home broadband), consider yourself suitably warned that you’re better of checking first.
Stack ‘Em Up
For speed, reproducibility, and a DevOps approach, I wanted to fire up Terraform on AWS to create a locked-down EC2 instance and then use Docker running Cowrie for testing. I started with this Docker Hub page, which provided a Dockerfile to view and then use to build a container.
To get Docker installed on my shiny Ubuntu 18.04 instance that Terraform built, I used the Docker Community Edition (CE) install instructions. If you don’t have Docker installed, then skip to the “Install from a repository” section in the instructions and continue from there. However, for testing, the route that I prefer is installing from Docker in its newer containerd incarnation as a compressed package, so I found the packages URL for my Ubuntu version (Bionic Beaver) and then ran the command as shown in Listing 1 to install the latest package I could find. I’m using m1.large for the instance size if it helps (which uses the amd64 architecture).
Listing 1: Installing Docker CE
$ wget https://download.docker.com/linux/ubuntu/dists/bionic/pool/stable/ amd64/containerd.io_1.2.2-1_amd64.deb $ dpkg -i containerd.io_1.2.2-1_amd64.deb $ wget https://download.docker.com/linux/ubuntu/dists/bionic/pool/stable/ amd64/docker-ce-cli_18.09.1~3-0~ubuntu-bionic_amd64.deb $ dpkg -i docker-ce-cli_18.09.1~3-0~ubuntu-bionic_amd64.deb $ apt install -f # meet unmet package dependencies $ wget https://download.docker.com/linux/ubuntu/dists/bionic/pool/stable/ amd64/docker-ce_18.09.1~3-0~ubuntu-bionic_amd64.deb $ dpkg -i docker-ce_18.09.1~3-0~ubuntu-bionic_amd64.deb
As shown in Listing 1, there’s some tidying up of unmet dependencies midway through the installation.
Innards
Now that I’ve got a container run time working on a non-public host, I can build my Cowrie container.
Cowrie's author is Michel Oosterhof, who originally forked Kippo from what I can determine. Having looked through the Dockerfile a bit more closely, I can see that there are two ports exposed on the last line, which provide SSH and Telnet servers, as shown in Listing 2.
Listing 2: The Bottom of the Dockerfile
USER ${COWRIE_USER} WORKDIR ${COWRIE_HOME}/cowrie-git VOLUME [ "/cowrie/cowrie-git/var", "/cowrie/cowrie-git/etc" ] ENTRYPOINT [ "cowrie" ] CMD [ "start", "-n" ] EXPOSE 2222 2223
Keep in mind the following about the Dockerfile: Two images are created, with one trimmed down for running (see the comments at the top of the Dockerfile); I'm using a Debian OS as my base for the images; the images will be built fresh from the latest GitHub source; and there’s a few fairly sizable chunks of Python involved.
Build It and They Will Come
To get started, I copy the Dockerfile to my server’s filesystem and then run the following command, which kicks off the image-building process beautifully if all goes well:
$ docker build -t cowrie
As you can see, the images built from that command begin with cowrie. Size-wise, the images come in at 553MB and 386MB for the run-time image. As promised in the Dockerfile comments, there’s a difference in image size between the unnamed <none> “builder” image and the “run-time” images, which is good news. Figure 1 shows what denotes success once your terminal has stopped scrolling with build information.
Figure 1's output looks promising; next I will try to fire up Cowrie.
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.
News
-
The GNU Project Celebrates Its 40th Birthday
September 27 marks the 40th anniversary of the GNU Project, and it was celebrated with a hacker meeting in Biel/Bienne, Switzerland.
-
Linux Kernel Reducing Long-Term Support
LTS support for the Linux kernel is about to undergo some serious changes that will have a considerable impact on the future.
-
Fedora 39 Beta Now Available for Testing
For fans and users of Fedora Linux, the first beta of release 39 is now available, which is a minor upgrade but does include GNOME 45.
-
Fedora Linux 40 to Drop X11 for KDE Plasma
When Fedora 40 arrives in 2024, there will be a few big changes coming, especially for the KDE Plasma option.
-
Real-Time Ubuntu Available in AWS Marketplace
Anyone looking for a Linux distribution for real-time processing could do a whole lot worse than Real-Time Ubuntu.
-
KSMBD Finally Reaches a Stable State
For those who've been looking forward to the first release of KSMBD, after two years it's no longer considered experimental.
-
Nitrux 3.0.0 Has Been Released
The latest version of Nitrux brings plenty of innovation and fresh apps to the table.
-
Linux From Scratch 12.0 Now Available
If you're looking to roll your own Linux distribution, the latest version of Linux From Scratch is now available with plenty of updates.
-
Linux Kernel 6.5 Has Been Released
The newest Linux kernel, version 6.5, now includes initial support for two very exciting features.
-
UbuntuDDE 23.04 Now Available
A new version of the UbuntuDDE remix has finally arrived with all the updates from the Deepin desktop and everything that comes with the Ubuntu 23.04 base.