Endlessh: An SSH Tarpit
nullprogram.com
nullprogram.com
Any tarpit has the potential to piss someone off. I'd run it on a sacrificial server with no obvious way to tie back to who is running it.
Yeah, just speculating but at least from what I've seen in the past if you successfully tarpit some script kiddie and they notice the IP their scan got stuck on there is some potential to move from "one of a billion random lowest common denominator bulk scan targets" to "paid attention to specifically some minimal amount", which is a genuinely different scenario. Even if all that amounts to is a relatively low volume revenge DDOS pointed at you for a bit it's still more of a disruption then if the auto scan had just moved on without seeing anything of note in the first place. This looks like fun on some systems, but on anything real I'm inclined to just stick to cutting down on log spam via single packet auth or a port knocker or the like. The old outrun-the-hiker-not-the-bear aphorism fits a lot of cases, just something to keep in mind before implementing something like this if you aren't directly experimenting with more active reactions.
Conversely as a research project I'm now actually curious what sort of extra attention even something like this could attract. Maybe these days everyone would just adapt and move on instead and the above is all obsolete?
The thing is most people will not see the trap as malicious but as a "misconfiguration" on their end or the other person's end (network or ssh in this case).
I see your point but then I never heard of honeypots getting some kind of "revenge" for instance.
2019-03-22T19:54:06.303Z ACCEPT host=::ffff:196.52.43.xx port=50327 fd=4 n=1/4096
2019-03-22T19:54:38.838Z CLOSE host=::ffff:196.52.43.xx port=50327 fd=4 time=32.535 bytes=199
2019-03-22T19:57:12.008Z ACCEPT host=::ffff:141.98.81.xx port=53646 fd=4 n=1/4096
2019-03-22T19:57:21.118Z CLOSE host=::ffff:141.98.81.xx port=53646 fd=4 time=9.110 bytes=30
The 141 bot never stays longer than 5 seconds. I'm guessing they are using 'expect' and waiting 5 seconds for a particular string.The only thing missing is setting some glibc hardening options
RELRO STACK CANARY NX PIE RPATH RUNPATH FORTIFY Fortified Fortifiable FILE
Partial RELRO No canary found NX enabled No PIE No RPATH No RUNPATH No 0 8 ./endlessh
I modified one line in the Makefile CFLAGS = -std=c99 -Wall -Wextra -Wno-missing-field-initializers -D_FORTIFY_SOURCE=2 -O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -ftrapv -s -g -Wl,-z,relro,-z,now -Wl,-z,noexecstack -pipe -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -fstack-clash-protection --param ssp-buffer-size=4 -fPIE -pie -m64 -mtune=generic
It's better now RELRO STACK CANARY NX PIE RPATH RUNPATH FORTIFY Fortified Fortifiable FILE
Full RELRO Canary found NX enabled PIE enabled No RPATH No RUNPATH Yes 3 4 ./endlesshThere are decent examples in the Tor source code.
echo "deb http://ftp.us.debian.org/debian/ testing main non-free contrib deb-src http://ftp.us.debian.org/debian/ testing main non-free contrib" > /etc/apt/source.list.d/debian-testing.list
apt-get update
apt-get install gcc-8/testing
The Makefile can then contain the above line:
CFLAGS = -std=c99 -Wall -Wextra -Wno-missing-field-initializers -D_FORTIFY_SOURCE=2 -O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -ftrapv -s -g -Wl,-z,relro,-z,now -Wl,-z,noexecstack -pipe -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -fstack-clash-protection --param ssp-buffer-size=4 -fPIE -pie -m64 -mtune=generic
and:CC = gcc-8
Replace -mtune=generic by your CPU, cf https://wiki.gentoo.org/wiki/Safe_CFLAGS
That said, I'm a little confused even after reading the linked RFC paragraph; it claims "The primary use of this feature is to allow TCP-wrappers to display an error message before disconnecting." but I'm not familiar with that term and there are no other occurrences of the word "wrapper" in that document.
Firefox and Chrome will spin on that server for hours before giving up.
For a web browser, this behaviour makes a lot of sense: timeouts are usually based on "I've waited for X and haven't received anything", not "this connection is like collecting water from a dripping tap". As long as there is a slow but steady stream of content coming in, you wouldn't want to abort until the user gives up or an internal limit on the data collected is hit (which is probably what happened with the author's tests --- a quick search doesn't yield the maximum size of the response headers browsers will accept, but servers usually have a configurable limit of a few KB at most for the request headers alone.)
It does a number of things in userspace (with a simple minimalist code base) that people might nowadays more often do in a firewall.
The best stuff is automated. Lenny has been at it for years now.
https://www.reddit.com/r/itslenny/comments/aylq20/lenny_qual...
YOU ARE STANDING AT THE END OF A ROAD BEFORE A SMALL BRICK BUILDING. AROUND YOU IS A FOREST. A SMALL STREAM FLOWS OUT OF THE BUILDING AND DOWN A GULLY.
>
and if they typed in something it would continue to play the game. After hundreds of thousands of automated SSH worm probes over several months, an actual human did connect and play the game for a few minutes! But even this triumph was short lived, they did not even play it to the end to see if something interesting might be unlocked (it would have been an invitation to contact my email address).
It listens in your unused IP space and both tar-pits scanners and creates actionable intelligence about scans against your hosts.
I've used Labrea on unused address space to make ARIN/RIPE happy back in the day and that was harmless, as entire /16's and /17's were unused. They used to nag about nothing in the /16's being pingable, so Labrea made it all 100% pingable
The agreement you make to get an allocation requires a certain level of utilization depending on the size of the block to prevent squatting and exhaustion of resources. This is a good thing, and if it was actually respected we wouldn't be in a mad rush to migrate to IPv6.
it only took 20 years to standardize after all. we're seriously rushing here!
> Captures and holds incoming TCP connections using no local per-connection resources. Connections are accepted, but immediately switched to the persist state (0 byte window), in which the remote side stops sending data and asks to continue every 60-240 seconds. Attempts to close the connection are ignored, forcing the remote side to time out the connection in 12-24 minutes.
I think that I'll start running this there.
But in this case I think the parent was proposing tricking the attacker into computing a PoW without realizing it, which sounds pretty tricky.
Simple timer to count to 10. Go over all open sockets, drain incoming, pump junk. Handle accept. Repeat.
Also, don't think that posting this blog article on March 22 didn't go unnoticed :)
Attackers that are smart enough to detect and avoid pubkey only hosts will probably easily adapt to this program.
However even then there's 65535 different ports (not to mention almost 4.3 billion ipv4 addresses), and you'll likely can firewalled off pretty fast. So instead of scanning 65535 ports, scanning just 22 usually works anyway, as few people change their ssh ports (and those that do are more likely to have other security measures in place)
iptables -t nat -I PREROUTING -m tcp -p tcp --dport 1:79 -j DNAT --to-destination x.x.x.x:2222
iptables -t nat -I PREROUTING -m tcp -p tcp --dport 81:442 -j DNAT --to-destination x.x.x.x:2222
...etcJust remember to open those same ports in the INPUT rules. If you get DDoS, then also create NOTRACK target rules in the raw table to avoid hitting the conntrack table.
And can one prevent ddos using iptables?
No, but you can minimize the impact or effectiveness of the attack. This is a long topic however. Probably better suited to a blog post or a youtube video.
https://www.cloudshark.org/captures/b64150b66908
IP addresses have been change to protect the innocent. This is from macOS but definitely seeing some different behavior from other clients.
cause we are never going to give you up ;)
I wonder if security-oriented OSs like openBSD could offer something like this out of the box. So that an admin can just say enable_tarpits='yes', and it would automatically enable tarpits like this for all the currently installed packages (with some default ports).
PF has the max-src-conn-rate state tracking option which is commonly use to blackhole scanners:
pass in on egress proto tcp to port ssh keep state \
(max-src-conn-rate 10/60, overload <scanners>)
block quick from <scanners>
Rather than blocking you could instead redirect new connections to a tar pit by replacing the block rule with something like pass in on egress proto tcp from <scanners> to port ssh \
divert-to 127.0.0.1 port 2222
where your SSH tar pit service listens on 127.0.0.1:2222. This is basically the reverse of how spamd works, which diverts all inbound SMTP connections not in the <nospamd> table to spamd. When spamd's greylisting rules are satisfied it adds the sender's IP to <nospamd>.IPv6 poses a problem for selective tar pitting, though. Realistically you need to tar pit at least /64 subnets, but even then it's not difficult to get your hands on a /48. But if you lumped /48s together you'd have a huge false positive problem. Also, AFAIU PF's state tracking capability can't track subnets, anyhow.
Does this still allow whitelisted machines to connect, or is this just a troll thing to do?
On the other hand a dedicated attacker who really wants to pwn your server will just scan all the ports and figure out what is listening and where. At this point you're better off implementing some form of port knocking if that's a cause for concern.
That being said, running sshd on port 2222 is probably not a good idea because it's not a privileged port.
The idea is that you set Endlessh on your server's port 22 (standard SSH port), then configure "actual" SSH to listen on a different (randomly selected) port. You connect to that port to get stuff done. Bots that troll for connections on port 22 will get stuck on port 22.
i.e. you get 2 chances to authenticate correctly, then I put you in this hamster wheel for a day. Hamster wheels and intermittent fasting are all the rage these days.
I was thinking I could take the IP address of anyone who hangs out in the tarpit for longer than a minute or so and automatically add it to my firewall's blacklist.
For fun and giggles, I also kept the user and password they tried to see if any of my systems was at risk
'Tacky' is a consistency. O:-)
On my home server, there are only two ports open to the internet -- one for my SSH server, and one for my VPN server. Both of those are running on nonstandard ports.
In order to DDOS me, an attacker has to find those ports, which would require a comprehensive scan (increasing the chances that they'll get blocked by my ISP or detected by my antiscan monitor) or a huge amount of luck. And even then, they'll just be able to DDOS my SSH server and VPN. That wouldn't be awesome, but wouldn't exactly be disastrous.
I can prevent being blocked by your ISP by adjusting the timings etc. of my scripts.
I think it's far more important to take a look at the supported key exchange algorithms etc.
> I can prevent being blocked by your ISP by adjusting the timings etc. of my scripts.
But that won't let you escape detection by my system's own defenses. Well, you could if you slowed down the scan enough -- but "enough" is pretty darned slow.
Years ago when I was playing network admin for a company, I set up a tarpit system which ran for a few years. In that time we never encountered one pissed off person in person (or on the Internet).
Is there something I'm missing here (probably related to poll(2)) that could cause this to be insecure?
Since it doesn't actually have the ability to do anything, it's pretty darned secure.