Backend
I rented three servers, told nobody, and watched the internet break in anyway
Remdore Dev.to (EN Zone)
2 views
I rented three servers this afternoon, one in Frankfurt, one in New York, one in Singapore. I gave the addresses to nobody. They are not in DNS, not in a certificate, not committed anywhere, not pasted into a chat. The only systems that knew these machines existed were the ones I rented them from.
Frankfurt got its first uninvited connection 107 seconds after it booted. Singapore took 48. Over the next three quarters of an hour the three of them logged 3,480 connection attempts from 860 different addresses, and 1,085 attempts to log in with a real password.
None of this is aimed at me. Nobody chose these machines. This is just the background radiation of a public IP, and I wanted to measure it rather than wave at it.
The setup
Each box ran a small Python program that listens on the ports things actually knock on: telnet on 23, HTTP on 80 and 8080, TLS on 443. The SSH honeypot sat on 2222 so the machine's real SSH could keep port 22 for me to administer it.
Every listener is a fake. The telnet service shows a Ubuntu login prompt and rejects every password. The HTTP one logs the request and returns 404. Nothing is ever let in, and none of the credentials collected are used for anything. Alongside the listeners, tcpdump recorded every inbound TCP SYN that was not a reply to my own traffic, so I could count knocks on ports where nothing was listening as well.
The whole thing ran for about 45 minutes per region and then destroyed itself. Total cost was under three cents.
First contact is fast
Region
First unsolicited packet
Singapore
48 seconds after boot
Frankfurt
107 seconds
New York
324 seconds
There is no grace period. The address space is scanned continuously by everyone at once, so the clock starts the moment the IP is routable, not when you deploy anything. Whatever you were planning to harden after the demo works is already being probed.
The volume is steadier than the totals suggest
The raw totals are lopsided. Frankfurt logged 2,325 attempts against Singapore's 516, which looks like a big regional difference until you look at who sent them. A single host on Korea Telecom's network sent 1,663 packets to Frankfurt on its own, almost all to telnet. It was hammering one box, not scanning.
Take that one address out and the three regions agree closely:
Region
Attempts/hour, busiest source removed
Frankfurt
829
New York
759
Singapore
677
That is the real number I would quote: a fresh public IP, anywhere, fields somewhere around 700 to 800 unsolicited connection attempts an hour from the general noise, plus the occasional individual who decides to lean on you.
The shape of the crowd backs this up. Of the 860 distinct addresses, 672 of them, 78%, sent exactly one packet in the whole window. This is overwhelmingly wide, shallow scanning: touch an address, note what answers, move on. Only a handful of hosts ever settled in to actually try things.
What they want
Ranked by connection attempts across all three boxes, the ports asked for most:
23, telnet. By a mile, once the Korea Telecom host is included. This is the IoT story. Telnet is where routers, cameras and DVRs live, and the botnets never left.
8088. Steady on every box, from many sources. That is the Hadoop YARN and various admin panels port. Someone maintains a list.
22, SSH. Constant but not dramatic.
587 and 465. On New York specifically, one host tried the mail submission ports 50 times each. Freshly rented cloud IPs are prized for sending spam before anyone has reported them.
5555. Android Debug Bridge. A phone or TV box with ADB exposed is a free computer.
The HTTP requests were almost all bare probes to / with no Host header, which is a scanner checking whether anything answers rather than a browser. Only a trickle carried a real hostname, and none of them matched anything a previous tenant of these IPs might have run.
The passwords are the interesting part
The telnet listener collected 1,085 login attempts with an actual password, covering 107 distinct username and password pairs. This very nearly did not work, and the reason it failed at first is the best thing I learned all day. A bot connects, sends the username, and then waits for the server to negotiate telnet options before it sends the password. My first prompt did not speak that negotiation, so I collected a pile of usernames and no passwords at all. The fix was to answer the option negotiation the way a real telnet daemon does. Then the passwords poured in.
Here are the most common, by frequency:
Password
Times tried
annie2015
43
OxhlwSG8
42
S2fGqNFs
40
annie2014
40
annie2016
39
motorola
39
tlJwpbo6
39
7ujMko0admin
37
epicrouter
34
123456
33
If you have ever looked at a Mirai source dump these will be familiar. 7ujMko0admin is a Dahua camera backdoor. epicrouter is a Conexant DSL default. Zte521, further down the list, is a ZTE router default. The annie20xx run and the random eight-character strings like OxhlwSG8 are a specific botnet family cycling its built-in list. 123456 is in there too, because it always is.
The thing to notice is what is absent. Almost nobody tried to guess a human's password. There were no dictionary runs against admin with password1, qwerty, letmein. The traffic is not trying to break into accounts. It is trying every known factory default for every mass-produced device, at machine speed, against every address at once. You are not being attacked as a person. You are being enumerated as a device that might have shipped with a known password.
What I got wrong on the way
Three things, and the first two cost me real money, though not much of it.
I tried to move the machine's real SSH off port 22 so the honeypot could have it, by editing sshd_config. On Ubuntu 24.04 that does nothing, because SSH is socket-activated by systemd and the config's Port line is ignored. My attempt to fix that through the systemd socket instead took the box off the network completely, and I had to destroy it and start over. I did it a second time on another box before I accepted that relocating the admin SSH was not worth the risk and left it on 22, with the honeypot's SSH on 2222. The teardown ran in a finally block throughout, so both dead boxes were destroyed within seconds rather than billing overnight.
I also nearly reported a beautiful, clean finding of zero. My TLS parser pulled the server name out of every handshake and returned nothing, every time, and I almost wrote "nobody sends SNI to a bare IP". The parser was broken: it ended in a .decode('idna') that throws on an ordinary hostname, and a broad except turned every exception into a tidy None. A result of zero that comes from a bug looks exactly like a result of zero that is true. The only defence is to test your instrument against a positive control, so I pointed a real client with a known hostname at it and watched the None come back when it should not have.
Run it yourself
The listeners are plain sockets. The telnet negotiation is the one non-obvious part, and it is the difference between collecting passwords and collecting nothing:
IAC = 0xff
def handle(conn):
# DO suppress-go-ahead, WILL echo, WILL suppress-go-ahead
conn.sendall(bytes([IAC, 0xfd, 3, IAC, 0xfb, 1, IAC, 0xfb, 3]))
conn.sendall(b'\r\nUbuntu 24.04.1 LTS\r\nlogin: ')
user = read_line(conn) # strip IAC sequences from the reply
conn.sendall(b'Password: ')
pw = read_line(conn)
log(user=user, password=pw) # then always reject
conn.sendall(b'\r\nLogin incorrect\r\n')
The connection count came from tcpdump rather than the listeners, because I wanted to see knocks on ports where nothing answered too. This is where I burned an hour the first time I did this sort of thing, so it is worth saying plainly. If you capture everything you will mostly record your own machine talking back to apt and pip, and the number comes out enormous and meaningless. You want inbound SYN packets only, the opening knock of a connection and nothing else, and you want to exclude your own address so the SSH session you are watching from does not count itself. That is this:
tcpdump -i eth0 -nn -q \
"tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0 and not host YOUR_IP" \
-w knocks.pcap
Mine were the cheapest droplets DigitalOcean rents, one in Frankfurt, one in New York, one in Singapore, each gone the second its capture ended. I did not use three regions to compare them against each other. I used three because I wanted to know if this was some quirk of one datacentre or just what the internet is like everywhere, and it is everywhere: the knocking started within a couple of minutes on all three, wherever they were.
What to do about it
What stayed with me is how dumb all of it is. Nothing tried to be clever. It was 860 machines reading down the same list of factory passwords for cameras and routers, firing it at every address they could reach, and my three boxes were simply in the range that afternoon. If your server has no default credentials and nothing extra listening, this traffic does not get defeated, it just misses, because it was never looking for you in the first place.
So the advice everyone already gives turns out to be right, which is not surprising, except now I have watched why. Keep telnet off the internet. Change the password that shipped with the box, especially on the cameras and routers where it never gets changed because nobody signs back into a camera once it is on the wall. And the idea that you deploy first and harden afterwards does not survive contact with the numbers here, because Singapore was being probed 48 seconds in. The afterwards you were counting on is already gone.
Read original: https://dev.to/remdore/i-rented-three-servers-told-nobody-and-watched-the-internet-break-in-anyway-i0a
← Previous
A Spreadsheet Was Running a Process We Called Automated
Next →
layout with traffic light on iPad
Related
Astra won't kill anything. It will silence everything. (And why that's good news.)
Backend
0
DEV Community
Ho scritto Ratiform per smettere di scrivere i form in Ratatui
Backend
0
Dev.to (EN Zone)
Idempotency: Protecting User Intent Beyond the Buy Button
Backend
0
Dev.to (EN Zone)
What One Iteration Costs
Backend
0
Dev.to (EN Zone)
Comments0
No comments yet — be the first