Skip to content

What 3,500 brute-force attempts in 24 hours look like

One exposed VM, one day, 3,516 failed logons. Most of them came from a single address, which changes what the right defense is.

Date

This is the data from the Azure Sentinel honeypot. The project page covers how it was built. This is about what showed up.

The shape of a day

3,516 failed RDP logons (Windows event 4625) in the first 24 hours, from 12 distinct source addresses in 8 countries.

Country Attempts Share
Indonesia 3,106 88.3%
Egypt 303 8.6%
Romania 55 1.6%
Saudi Arabia 31 0.9%
United States 13 0.4%
South Korea 6 0.2%
France 1 0.0%
Russia 1 0.0%

One address did almost all of it

A single IP in Indonesia accounted for 3,106 attempts. The next two addresses, both in Egypt, managed 164 and 139. Everything else was single digits: a scanner touching the port, trying a couple of defaults, and moving on.

SecurityEvent
| where EventID == 4625
| where isnotempty(IpAddress)
| summarize Attempts = count(), First = min(TimeGenerated), Last = max(TimeGenerated) by IpAddress
| extend Duration = Last - First
| extend PerMinute = round(todouble(Attempts) / max_of(1, toint(Duration / 1m)), 1)
| order by Attempts desc

What they tried

The other cut worth making is by username, which shows whether the traffic is credential stuffing against known accounts or plain guessing at defaults:

SecurityEvent
| where EventID == 4625
| summarize Attempts = count() by TargetUserName
| top 15 by Attempts

What it means for defenders

  • Geo-blocking is the wrong lesson. Blocking Indonesia would have cut 88% of this day’s noise and told me nothing about tomorrow’s. The single-source pattern argues for per-address rate limiting and account lockout, which work regardless of where the next scanner sits.
  • The long tail is the reconnaissance. The one-attempt sources are inventory scans. They are what a targeted attacker would use to find the host in the first place.
  • Exposure, not weak passwords, was the finding. No credential was guessed. The problem is that RDP was answerable from the internet at all. A bastion, a VPN, or just-in-time access removes the whole category.
  • The detection is cheap. One KQL query on a built-in table, one workbook, no external enrichment service. The expensive part of detection is usually deciding to look.