SSH honeypot, deployed in the wild, collecting and sharing data

Let The Hackers In!

26 Oct 2013 • 5 min read

anonymous hackerThis week I've implemented a basic version of the SSH honeypot. After putting the honeypot live on Sunday (20th Oct) evening there have been a total of 2,897 login attempts.

The password "123456" has been used 48 times and the username "root" has been used 1992 times.

What's most interesting about these attacks on the honeypot is that I've not advertised, promoted or otherwise told anyone the honeypot's IP address. How is this possible?

Also this week I've added a mini stats box to this website which will show a breakdown of recent attacks.

Logging the login attempts

To recap: last week I ended by saying I would implement a version of SSHpot by Pete Morris.

The main changes I made to SSHpot were to add a call to a new function curl and to place this call inside the function log_attempt which stores all login attempts to a file. The new log_attempt function now looks like this (additional line highlighted):

/* Write interesting information about a connection attempt to  LOGFILE. 
 * Returns -1 on error. */
static int log_attempt(struct connection *c) {
    FILE *f;
    int r;

    if ((f = fopen(LOGFILE, "a+")) == NULL) {
        fprintf(stderr, "Unable to open %s\n", LOGFILE);
        return -1;

    if (get_utc(c) <= 0) {
        fprintf(stderr, "Error getting time\n");
        return -1;

    if (get_client_ip(c) < 0) {
        fprintf(stderr, "Error getting client ip\n");
        return -1;

    c->user = ssh_message_auth_user(c->message);
    c->pass = ssh_message_auth_password(c->message);

    if (DEBUG) { printf("%s %s %s %s\n", c->con_time, c->client_ip, c->user, c->pass); }
    r = fprintf(f, "%s %s %s %s\n", c->con_time, c->client_ip, c->user, c->pass);
    curl(c->con_time, c->client_ip, c->user, c->pass);
    return r;

Whereby the function curl is defined as:

int curl(char* con_time, char* client_ip, char* user, char* passwd) {
   CURL *curl;
   char buf[500];
   snprintf(buf, sizeof buf, "", user, passwd, client_ip);
   curl = curl_easy_init();
   curl_easy_setopt(curl, CURLOPT_URL, buf);

return 0; 

This new function basically sends the login attempt data directly to where the data's stored in a database. This makes it much easier to produce data and statistics on the honeypot login attempts

I put this basic version of the honeypot live on Sunday evening in the hope that I'd possibly get at least a few login attempts.

How I'd underestimated what would happen next...

Analysing the attacks

So I'm not going to lie; I've been quite excited this week by the sheer volume of attacks occurring on the honeypot. The honeypot's been running for only 5 full days and it's already received a total of 2,897 login attempts.

In addition to the pre-existing honeypot server, yesterday I installed the honeypot on a second server which I've had running for a few years. I'll be referring to these two servers as the honeypots "alpha" and "bravo", respectively.

The top 10 most common passwords used to attempt to login to the honeypot were:

  • 123456
  • password
  • scricideea
  • P@ssw0rd
  • test
  • 1234
  • abc123
  • changeme
  • test123
  • oracle

The top 10 most common usernames used to attempt to login to the honeypot were:

  • root
  • test
  • oracle
  • admin
  • bin
  • nagios
  • guest
  • info
  • user
  • ftpuser

This week I've also implemented a new element/box on this website called "Live Stats" (shown up at the top right of every page). This will show a condensed version of the statistics for recent attacks on the honeypots.

I'm currently working on a full statistics page which will include a comprehensive breakdown of recent attacks along with charts to help analyse the data. I'll update more on this in future posts.

How are there so many login attempts?

So how come so many people are attacking the honeypot already when I've not even promoted its IP address?

The simple answer: IP scanning.

It's relatively easy to scan a range of IP addresses and determine if port 22 (default SSH port) is open or not.

For example, using nmap, the command:

nmap -p 80

Will check to see if port 80 is open on the web server behind But how would someone go about checking every single public IP address on the planet?

There are 4,294,967,296 IPv4 addresses available and 17,891,328 of them are IANA-reserved private IPv4 addresses. So this leaves 4,277,075,968 available IP addresses to scan to determine if port 22 is open.

Once a list of these IP addresses - along with their port 22 status - is produced (which can easily be automated via a script and left to run for a while), the hacking / brute-force attempts can begin.

Problems with the code

One of the main issues that has arisen this week is that child processes (of the honeypot) are not always terminating automatically. This happens when someone connects to the honeypot but doesn't send the correct disconnect message.

When this happens; the child process just waits, instead of terminating. There have been a few instances this week where the sever has become almost unresponsive because it's clogged up with so many waiting child processes. This is an issue I'll try to resolve this week.

Arch linux

This isn't strictly related to the project but it's impacting on the project...

A few years ago I bought an HP Mini netbook. It's such a basic machine and so slow to use that I gave up on it. Plus the battery died about a year after purchasing it. However, this week I discovered that HP have released a BIOS update to fix the battery dying issue. So I bought a cheap £15 replacement battery off Amazon and installed Arch Linux onto the little machine.

I installed the tiling window manager i3 (using this handy guide) onto Arch and, I have to say, I'm impressed with the results. The netbook runs blindingly fast and it's a very productive environment to work in. My only gripe is that I'm getting just under 4 hours from the battery.

As I said, not strictly relevant, but I can highly recommend Arch Linux with i3 window manager. I'll be using it to work on a lot of this project.

Moving onto phase two

Phase one was to setup the honeypot and log all attempted logins. So my challenge this week will be to start implementing phase two: allow users to "login" (or appear to login) to the SSH server and attempt to execute commands.

Phase two won't actually allow the user to execute any commands in the shell, but simply log all attempted commands. I can then log all these attempted commands for analysis.

I'm also keen to add the ability to detect and log what SSH client each user is using. This will be useful in determining what sort of environments users are in.

Image credit: "Anonymous Hacker" by Brian Klug,

About the author

Simon BellSimon Bell is an award-winning Cyber Security Researcher, Software Engineer, and Web Security Specialist. Simon's research papers have been published internationally, and his findings have featured in Ars Technica, The Hacker News, PC World, among others. He founded Secure Honey, an open-source honeypot and threat intelligence project, in 2013. He has a PhD in Information Security and a BSc in Computer Science.

Follow Simon on Twitter: @SimonByte