Tuesday, November 13, 2007

Cryptographically and Constantly Changing Port Opening (or C3PO)

In another forum I was just talking about a little technique that I came up with for securing a server that I want on the Internet, but to be hard for hackers to get into. I've done all the right things with firewalling and shutting down services so that only SSH is available. But that still leaves port 22 sitting there open for someone to bang on.

So what I wanted was something like port knocking (for an introduction to that you can read my DDJ article Practical Secure Port Knocking). To avoid doing the classic port knocking where you have to knock the right way to open port 22 I came up with a different scheme which I call Cryptographically and Constantly Changing Port Opening or C3PO.

The server and any SSH client who wish to connect to it share a common secret. In my case that's just a long passphrase that we both know. Both bits of software hash this secret with the current UTC time in minutes (using SHA256) to get 256 bits of random data. This data changes every minute.

The 256 bits gives me 16 words of random data. Those 16 words can be interpreted as 16 different port numbers. Once a minute the server reconfigures iptables to open those 16 ports forwarding one of them (which corresponds to word[0] in the hash) to SSH and the other 15 to a blacklist service.

At any one time 16 ports are open (i.e. respond to a SYN) with only one being SSH and the other 15 being a trap to be sprung by an attacker. The 16 ports change once a minute.

Since both sides can compute the hash the client is able to compute where the SSH server is residing at that moment and contact it. Once contact is established the connection remains open for the duration of the session. New sessions, of course, will need to recompute the hash once a minute.

The blacklist service serves to tarpit an attacker. Any connection attempt to one of the other 15 sockets causes the IP address of the attacker to be blacklisted (again an iptables change) which means that hitting any of the 15 ports causes the attacker to shut off their access to the SSH server for the next 15 minutes.

A casual NMAP of my machine gets your IP address blacklisted and shows up a random selection of open ports. A real user connects to the SSH server first time because they know where it resides.

Of course, this doesn't replace making sure that the SSH server is up to date, and that passwords are generated carefully, but it seriously frustrates a potential attacker.

If this is of interest to others I'd be happy to release my code (which is currently in Perl) as a GPL2 project.


Anonymous said...

please do.

Matt Secoske said...

What happens with multiple (legal) connections occurring at the same time and causing collisions?

3DPacker said...

How large is the range of ports that you are selecting from?

John Graham-Cumming said...

I have 16 bits available so I can select from 0-65535, but in practice I restrict the range to avoid hitting common ports.


Tobin said...

What if someone in the same internet cafe as me sees that I'm connecting to that IP, so they decide to attack it. Then we're both NATTed to the same IP, so they get the cafe blacklisted and I can't make new connections? :)

Unknown said...

Yeah, as tobin said it has the possibility for DoS. What about forged packets, is that a problem with your system as well? I could just forge a bunch of packets and suddenly you could be blocking alot of legit traffic. Still, I'm interesting in knowing more about your implementation.

Unknown said...

I really like the sound of this. How are connections handled if they need to last longer than the one minute that the port is maintained?

tillo said...

This really is a nice idea, and multiplies by a huge number the noise factor during an attack; doing a MITM attack or using a large amount of reconnaissance techniques on a system like that would be really painful!

It concerns me what tobin, brad and david said by the way, did you already search for a solution on those matters?

I would appreciate the code you put together to make it work, as I'm sure many do.

tillo said...
This comment has been removed by the author.
Pradeep said...

Once Shimmerd has selected 16 ports, why would it only blacklist those incoming connections which are for the 15 ports? why it is not blacklisting other connection requests which falls in the range(in one of the websites u have mentioned range from 10000-10999)