Since summer 2014 I’ve been working on extensions and contributions to the well known
Kippo honeypot developed by
I noticed some SSH attacks against my systems were not logged in full detail and I started to work on additional logging,
from there I’ve added ‘ssh exec commands’ support, SFTP support, SCP support, direct-tcpip (proxying) support and many other features.
To distinguish this from the original software, I have now renamed the system to "Cowrie".
All features below are incorporated in my cowrie repository on github.
Cowrie now supports the SFTP protocol to upload and download files. Uploaded files are placed into the ‘dl/’ directory, like files that were downloaded by ‘wget’.
SFTP offers a file system interface to the pickled fs and you can list any file available in there. Downloads are also supported, if the contents are in honeyfs.
Programmatically it is based on the Twisted Conch code, and uses a UNIX file system like interface to the pickled file system.
One way to run remote commands is ‘exec’ commands. Like so:
ssh user@host 'cat /etc/passwd'
Support for this has been merged into the original Kippo repository, so it’s probably already in your version. This includes logging and executing these commands.
I’ve seen other uses as well, where malicious code is uploaded through stdin. Less common now, but I did see this last year:
So I added ‘stdin’ logging whenever standard-in data is encountered in combination with an exec command.
SSH tunnelling (direct-tcpip) support
I added logging initially for additional channels and saw I received some ‘direct-tcpip’ requests.
This is the TCP/IP tunneling through SSH. After some more modifications, kippo now pretends
to accept these requests so it can log the initial connection data. This is often HTTP, but sometimes SSL, BitTorrent and sometimes something else.
2015-02-09 04:48:08+0000 [SSHService ssh-userauth on HoneyPotTransport,1151,130.211.164.xx] ubnt trying auth password
2015-02-09 04:48:08+0000 [SSHService ssh-userauth on HoneyPotTransport,1151,130.211.164.xx] login attempt [ubnt/ubnt] succeeded
2015-02-09 04:48:08+0000 [SSHService ssh-userauth on HoneyPotTransport,1151,130.211.164.xx] ubnt authenticated with password
2015-02-09 04:48:08+0000 [SSHService ssh-userauth on HoneyPotTransport,1151,130.211.164.xx] starting service ssh-connection
2015-02-09 04:48:08+0000 [SSHService ssh-connection on HoneyPotTransport,1151,130.211.164.xx] got channel direct-tcpip request
2015-02-09 04:48:08+0000 [SSHService ssh-connection on HoneyPotTransport,1151,130.211.164.xx] direct-tcp connection attempt to 126.96.36.199:80
2015-02-09 04:48:08+0000 [SSHChannel None (0) on SSHService ssh-connection on HoneyPotTransport,1151,130.211.164.xx] Faking channel open 188.8.131.52:80
2015-02-09 04:48:09+0000 [SSHChannel None (0) on SSHService ssh-connection on HoneyPotTransport,1151,130.211.164.xx] received data 'POST http://www.ip-score.com/ajax_handler/check_pbl HTTP/1.1\r\nHost: www.ip-score.com\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0\r\nReferer: http://www.ip-score.com/\r\nX-Requested-With: XMLHttpRequest\r\nConnection: Keep-Alive\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 0\r\n\r\n'
SSH Fingerprint logging
Some adversaries have (accidently?) public keys configured on their attack hosts. The SSH client attempts to login with this public key.
Cowrie now accept, logs and then denies public-key authentication. An easy way to fingerprint (sic) attackers.
2014-11-15 00:26:11+0000 [SSHService ssh-userauth on HoneyPotTransport,206,193.104.41.***] Public Key attempt for user admin with fingerprint b4:2b:f0:30:3a:97:04:90:b1:99:47:b4:7b:89:56:xx:
SSH Protocol Updates
I’ve enabled the diffie-hellman-group-exchange-sha1 algorithm. And updated the ciphers to the ones supported by OpenSSH.
Als added ‘dss’ keys.
Also I ported code from honssh to stop the Metasploit kippo detection by Andrew Morris. The issue is more with Conch (the Twisted SSH implementation), but there’s a workaround in Cowrie now.
It’s good to realize that Cowrie is a medium interaction honeypot, and there will always be ways to fingerprint the honeypot. Another easy way is to look just at the ciphers offered by the SSH server.
I added additional commmands:
SSH has a way to transfer the exit status of the remote command back to the original host. This is called exit status.
$ ssh -p 2222 root@host ls /
bin boot dev etc home initrd.img lib
lost+found media mnt opt proc root run
sbin selinux srv sys tmp usr var
$ echo $?
Original kippo sends no exit status.
Cowrie always sends a ‘0’ exit code signifying succes, regardless of the command that’s executed.
Command line support
Cowrie supports additional emacs keybindings such as ctrl-a (start of line), ctrl-e (end of line), ctrl-p (previous command), ctrl-n (next command),
ctrl-b (one character left) and ctrl-f (one character forward)
I added ‘which’, ‘netstat’, ‘gcc’ from kippo-extra by basilfx.
Usernames and passwords.
I added wildcard support for the password database. Passwords can now be ‘*’ to allow any password. There’s also a ‘!’ operator to deny explicit passwords.
The rules are evaluated in order, so the ‘*’ should usually come last. My userdb is now:
disabled the ‘exit-jail’ that gave people the fake ‘localhost’ prompt after logout
Fixed ability to ping IP addresses like 555.555.555.555
The bannerfile is now always ‘<honeyfs>>/etc/issue.net’.
I added hpeeds.py from threatstream’s repository. It uses sockets and no deferred and should not work all that well with
Twisted’s asynchronous system, but in practice people use it.
I’m in the process of converting Cowrie to more structured logging and a new dblog framework
that’s more extensible. One result so far is a JSON dblog plugin.
This logs the same information as the general dblog modules, but in JSON format, so it can be easily picked up by log analysis tools.
It writes timestamps in UTC with microseconds and adds a unique UUID session identifier to each log entry. It also adds
argument as their own JSON attributes so text log parsing is no longer necessary.
Now JSON logging is available, Cowrie includes sample configuration files for logstash and kibana
, to display honeypot data in a Kibana dashboard.
The nice thing about logstash is that it can do data enrichment offline. There’s no need to configure GeoIP into Cowrie, just
load the IP data in logstash and enrich with GeoIP data such as country and city and ASN number from Maxmind:
If you then load data in a Kibana dashboard it should look something like this:
I ported katkad’s SHAsum patches to log binaries, and made some modifications to consolidate the log messages.
Malware is now saved as its SHA-256 checksum, and only once per unique sample.
Roadmap & Plans
Most of the current development plans focus on improving the logging. Currently the logging is unstructured text and there is even internal
log parsing with regexes to create database entries in some of the dblog modules. I’d like to move to structured output formats to make
data easier to parse. The JSON output will improve and contain more data in structured fields.