← Back to list

What a Week of SSH Honeypot Logs Taught Me

Part 1: The Illusion of the IP

Beniamin D. · 2026-05-27 21:09 · 0 claps · 4.8 min read
#cybersecurity #threat-intelligence #honeypot #cloud-security #botnet
Open on Medium ↗
Wiki topics: 🔒 · Cybersecurity

What a Week of SSH Honeypot Logs Taught Me

Part 1: The Illusion of the IP

I’m a computer geek. I like building things, breaking them, and digging through the logs to figure out what’s going on underneath the surface. Recently, I wanted to see what would happen if I left a deliberately vulnerable system exposed to the internet and simply watched who turned up.

So, I deployed a high-interaction SSH honeypot using Cowrie on Microsoft Azure.

I expected the usual background noise: automated scanners, a few brute-force attempts, maybe the odd bored script kiddie. What I ended up finding was far more organised than I expected, and it taught me an important lesson quickly:

IP addresses on their own don’t tell you very much.

Building the Honeypot

1. Blocking Access to Azure Metadata

Azure VMs can access instance metadata through 169.254.169.254. If an attacker reaches that service, there’s potential for privilege escalation or subscription level abuse depending on configuration.

To avoid that, I used iptables to block all outbound access to the metadata endpoint.

Preventing access to Azure Instance Metadata Service (IMDS) ensured the attacker remained confined to the VM itself rather than pivoting into Azure resources.

Preventing access to Azure Instance Metadata Service (IMDS) ensured the attacker remained confined to the VM itself rather than pivoting into Azure resources.

2. Moving the Real SSH Service

The actual management SSH service was moved to port 22222.

Cowrie listened on 2222, which was mapped back to standard port 22 using NAT so the honeypot still appeared to be a normal internet-facing Linux host.

Simple, but effective.

3. Restricting Outbound Traffic

This was probably the most important part of the setup.

Using UFW, I restricted outbound traffic to only what was absolutely necessary. DNS and HTTPS were allowed, but I deliberately blocked port 80.

That meant if malware landed on the box, it would struggle to fetch additional tooling or secondary payloads. The VM effectively became a dead end rather than a useful staging point for the attacker.

It also meant I couldn’t really install packages or run normal updates once the experiment began, but that was a trade off I was happy to make.

The final firewall setup. Outbound traffic was limited to DNS and HTTPS only, which helped keep the VM isolated and stopped attackers from easily pulling down additional tools or payloads.

The final firewall setup. Outbound traffic was limited to DNS and HTTPS only, which helped keep the VM isolated and stopped attackers from easily pulling down additional tools or payloads.

1. Day 1 and the Immediate Noise

Within minutes of the VM going live, the probes started arriving.

During the first 24 hours alone, the honeypot logged 883 connections and 806 login attempts.

Initial 24-hour connection and login attempt volume.

Initial 24-hour connection and login attempt volume.

The vast majority were straightforward credential-stuffing attacks relying on default usernames and weak passwords. Nothing especially sophisticated, it was just volume.

Most of the login attempts during the first 24 hours relied on default usernames and weak passwords.

Most of the login attempts during the first 24 hours relied on default usernames and weak passwords.

If I’d been treating this like a production server, my first instinct would probably have been to start blocking IPs with fail2ban and move on.

Instead, I decided to leave it running and see what happened over time. I wanted to know whether this traffic was genuinely random or whether there was some sort of pattern underneath it.

2. The Wall of Noise (Day 7)

By the end of the week, the numbers had climbed to over 11,000 login attempts.

Watching the live Cowrie logs was genuinely relentless. There was traffic at all hours of the day and night from what appeared to be systems all over the world.

A live view of the honeypot logs, showing the constant, day and night stream of automated brute-force attempts and credential stuffing.

A live view of the honeypot logs, showing the constant, day and night stream of automated brute-force attempts and credential stuffing.

At first glance it looked chaotic.

But after watching it for long enough, I started noticing similarities. The timing was oddly consistent. The SSH negotiation patterns looked familiar. Even the behaviour after login attempts followed the same sequence over and over again.

That was the point where it became obvious that I probably wasn’t dealing with thousands of unrelated attackers. I was looking at a relatively small number of automated toolsets operating across large pools of rotating IP addresses.

3. Looking beyond the IP Address

That’s where HASSH became useful.

Rather than focusing on source IPs, I started grouping connections by their SSH fingerprint.

Every SSH client presents a slightly different cryptographic handshake depending on the libraries and ciphers it supports. Even if an attacker rotates through VPNs, proxies, or compromised hosts, their tooling often remains consistent.

Using jq against the Cowrie JSON logs, I grouped activity by HASSH fingerprint instead of IP address.

Grouping a week of attack traffic by HASSH fingerprint instead of source IP address.

Grouping a week of attack traffic by HASSH fingerprint instead of source IP address.

The results were interesting straight away.

Large numbers of seemingly unrelated IPs were sharing identical fingerprints. What originally looked like globally distributed attacks turned out to be clusters of systems running the same tooling with the same SSH configuration. For example, the fingerprint starting with af8223… isn’t just one attacker; it’s a massive cluster of compromised IP addresses all running the exact same client setup.

That completely changed how I viewed the traffic.

4. Why IP Blocklists aren’t enough

One thing this experiment reinforced is how limited traditional IP-based blocking can be.

Most of these botnets aren’t operating from a single host. They rotate constantly through cloud instances, compromised devices, and disposable infrastructure.

You block one address and another takes its place almost immediately.

That doesn’t mean IP blocking is useless, but on its own it is reactive rather than strategic.

The Automated Playbook

By the end of the week, I ran frequency analysis against the commands executed by successful logins.

The behaviour was remarkably consistent.

The bots would:

  • identify the environment,
  • attempt persistence,
  • kill competing malware with pkill,
  • and lock down SSH access for themselves.

There was very little evidence of hands-on keyboard activity. Most of it appeared to be fully automated.

The 15 most common commands executed during the experiment. A large number were focused on maintaining SSH access and killing off competing malware already running on the host.

The 15 most common commands executed during the experiment. A large number were focused on maintaining SSH access and killing off competing malware already running on the host.

What’s Next?

Grouping activity by HASSH fingerprint made it much easier to identify which systems were related to one another behind the rotating infrastructure.

The next step is looking at the payloads themselves.

In Part 2, I’ll be analysing the binaries dropped onto the honeypot, looking at how they maintain persistence, communicate with command and control infrastructure, and what they appear to be targeting.

Geek Note: How I did it

For those who want to reproduce the HASSH clustering on their own Cowrie deployments, here is the exact jq pipeline I used to unmask the infrastructure:

sudo sh -c 'grep -h "cowrie.client.kex" /home/cowrie/cowrie/var/log/cowrie/cowrie.json*' | jq -s -r '[.[] | select(.hassh != null)] | group_by(.hassh)[] | .[0].hassh + " - -> " + (map(.src_ip) | unique | join(", "))'

Disclaimer: This research was conducted in a controlled, isolated honeypot environment for educational purposes. No actual production data was at risk.


메타데이터
post_id
bf0991e7c679
slug
what-a-week-of-ssh-honeypot-logs-taught-me-bf0991e7c679
url
https://medium.com/@benidan.db/what-a-week-of-ssh-honeypot-logs-taught-me-bf0991e7c679
canonical_url
https://medium.com/@benidan.db/what-a-week-of-ssh-honeypot-logs-taught-me-bf0991e7c679
author_url
https://medium.com/@benidan.db
status
ok
fetched_at
2026-07-10 09:52:19