Skip to content

How to use Cowrie to monitor attackers

In the last months I have been working intensively with honeypots. Honeypots are real or simulated systems used to analyze and detect attacks in a network. By posing as a vulnerable system, they attract curious attackers. Any connection to such a device can be considered suspicious, as they are only used for the given purpose and can usually only be found by scanning and probing a network.

To give you an idea how they work, I present you Cowrie, a “medium interaction” honeypot that simulates an SSH server. Medium-interaction refers to the interaction between an attacker and the system. There are low-interaction honeypots that only simulate specific services (SSH, FTP, Web server) and there are high-interaction systems that run complete operating systems with the real services (sshd, a database server, etc). Cowrie only simulates SSH and Telnet, but it also provides a fake filesystem and a fake Linux shell if the attacker manages to “compromise” the system.

Cowrie is written in Python and since the user cannot escape the simulated environment, the actual system it runs on is untouched. The point of honeypots is to log the attacker’s actions, and Cowrie is not different. It generates logs of the provided username/password combinations and allows to define which combination is allowed to enter the fake shell environment. The commands entered by the attacker are not executed on the system, common Linux commands like cat are just simulated.
Also, the simulated filesystem can be made to look like any Linux distribution.

Run with Docker

I am a big fan of Docker, so I will use it to run Cowrie. You can follow along if you use Docker or you can install and run it on your local system by following the Installation guide on GitHub. I expect you to know how to use a SSH client, since we will be connecting to the Cowrie SSH service.

Pull the image: docker pull cowrie/cowrie

Using default tag: latest
latest: Pulling from cowrie/cowrie
d2ca7eff5948: Pull complete
664fdb697b21: Pull complete
abc94a586b7b: Pull complete
7a46c587cbe6: Pull complete
c38563c3e1c2: Pull complete
Digest: sha256:22a2c2376995107064371d2ad1e26bd3c7a5005649827c80e30022a4bd4df4a6
Status: Downloaded newer image for cowrie/cowrie:latest

Then run the container with:
docker run -d --name cowrie -p 2222:2222 cowrie/cowrie

This starts the service on port 2222 of the docker container. You can connect to it by finding out the container’s IP: docker inspect cowrie | grep IPAddress

            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.2",
                    "IPAddress": "172.17.0.2",

If you are on Windows, remove the part after the docker command and look for IPAddress in the output.

Then use the above IP address to connect to Cowrie. On most Linux distributions, you can use the ssh command, with Windows use PuTTY or any modern alternative to it. Use the Port 2222 as it was the port we exposed through Docker. You can specify any username, but the default Cowrie config only accepts “root” or “richard” with any password.
ssh root@172.17.0.2 -p 2222

The authenticity of host '[172.17.0.2]:2222 ([172.17.0.2]:2222)' can't be established.
RSA key fingerprint is SHA256:8fPlZMfPE+M0nrlD3c93PDKXCmwkywU/3S4XQfZv/JU.
Are you sure you want to continue connecting (yes/no)? yes

Password:

The password prompt is from Cowrie, and if you used root@ as the user, you can enter any password to enter the simulated system. You get the following prompt:

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

root@svr04:~#

Now you can use the fake shell to look through the system. You can look through the file system, which looks like a real Debian system:

root@svr04:~# w
 22:21:52 up 15 min,  1 user,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    172.17.0.1        22:21    0.00s  0.00s  0.00s w
root@svr04:~# pwd
/root
root@svr04:~# ls -al /
drwxr-xr-x 1 root root  4096 2013-04-05 12:03 .
drwxr-xr-x 1 root root  4096 2013-04-05 12:03 ..
drwxr-xr-x 1 root root  4096 2013-04-05 11:53 bin
drwxr-xr-x 1 root root  4096 2013-04-05 12:02 boot
drwxr-xr-x 1 root root  3060 2013-04-05 12:03 dev
drwxr-xr-x 1 root root  4096 2013-04-05 12:06 etc
drwxr-xr-x 1 root root  4096 2013-04-05 12:02 home
lrwxrwxrwx 1 root root    32 2013-04-05 11:53 initrd.img /boot/initrd.img-3.2.0-4-686-pae
drwxr-xr-x 1 root root  4096 2013-04-05 12:01 lib
drwx------ 1 root root 16384 2013-04-05 11:52 lost+found
drwxr-xr-x 1 root root  4096 2013-04-05 11:52 media
drwxr-xr-x 1 root root  4096 2013-04-05 11:52 mnt
drwxr-xr-x 1 root root  4096 2013-04-05 11:52 opt
dr-xr-xr-x 1 root root     0 2013-04-05 12:03 proc
drwx------ 1 root root  4096 2013-04-05 12:25 root
drwxr-xr-x 1 root root   380 2013-04-05 12:06 run
drwxr-xr-x 1 root root  4096 2013-04-05 12:03 sbin
drwxr-xr-x 1 root root  4096 2013-04-05 11:52 selinux
drwxr-xr-x 1 root root  4096 2013-04-05 11:52 srv
drwxr-xr-x 1 root root     0 2013-04-05 12:03 sys
drwxrwxrwt 1 root root  4096 2013-04-05 12:17 tmp
drwxr-xr-x 1 root root  4096 2013-04-05 11:52 usr
drwxr-xr-x 1 root root  4096 2013-04-05 11:52 var
lrwxrwxrwx 1 root root    28 2013-04-05 11:53 vmlinuz /boot/vmlinuz-3.2.0-4-686-pae

This looks impressing at first, but you get to the limits of the fake filesystem pretty fast:

root@svr04:~# cat /var/log/syslog
None
root@svr04:~#

As you can see, you can simulate files, directories and file contents, but you need to specify it beforehand by configuring Cowrie. In its default configuration, there is not much to do. Next, let’s look at the logs.

Inspect the logs

You can inspect the logs with the following command:
docker exec cowrie /bin/sh -c "cat log/cowrie.log" | less -r

Example output (shortened)

New connection: 172.17.0.1:54000 (172.17.0.2:2222) [session: 7bb2e6981c46]
[...]
login attempt [root/anypassword] succeeded
[...]
CMD: w
Command found: w
CMD: pwd
Command found: pwd
CMD: ls -al /
Command found: ls -al /
[...]

You can look at source IP addresses, login credentials etc. All of this is valuable data if you are interested in how SSH services are breached.

When you are finished, remove the service again with docker stop cowrie && docker rm cowrie.

Conclusion

Since you are inside a Python process, you are pretty much isolated from the real system. Add a Docker container as another layer and proper port forwarding and you have your very first (pretty safe) honeypot system online.

Cowrie is a really cool software and if you have any machine that is reachable from the outside which runs it, you get to see how a huge number of connection attempts reaches your machine, with most attackers brute-forcing login credentials until any goes through. Then you can take the logs (which are also generated in JSON format) and use it for improving your firewall rules. Or you can create cool statistics about the most used user/password combinations (Spoiler: the most used password is [tooltip tip=”No password :)”][/tooltip]).

Published inIT-SecurityTips and Tricks

One Comment

  1. […] Cowrie is an SSH and Telnet honeypot. This is one of the coolest honeypots I used, mainly because of its rich features. This tool simulates an SSH service with complete emulation of an interactive terminal. You can collect what a user enters into the command line and catch the user/password combinations used to login. You can also find a preconfigured Docker image if you want to try it out. I wrote about this software in a previous blog post. […]

Leave a Reply

Your email address will not be published. Required fields are marked *