NEW 08/30/2013
Version 0.63 has been released. Download from here.
Why are you encrypting?
If you are using OpenSSH in some form or other, chances are good you want to keep something confidential. SSH does that very well, but in the process of opening up a standard SSH connection on TCP port 22 you are essentially screaming your intentions to the world.
Clever girl that you are, you decide to use a non-standard port for your sshd server, perhaps port 443. Nice trick, since now you can tunnel through almost any proxy server. Five years ago, you could have gotten away with that.
Unfortunately, since SSH Key Exchange (KEX) is done in clear text during the handshake of every SSH connection, you're popping off alarms in any IDS/IPS system peeking at your connection. In firewall-marketing speak that's called "deep packet inspection". And even though there may be no IDS/IPS at the client or server end, there is no way for you to know if there's one between them (see this article).
Luckily, there's a fix for that. In 2009, Bruce Leidl (a.k.a. brl) gave us a patch for OpenSSH that obfuscates the SSH handshake. I stumbled across it a year later. I had been looking for something like it ever since they removed the ipt_XOR target from Netfilter.
But besides Cygwin, there were no options for Windows users. In April 2010 I took it upon myself to create PoTTY, an obfuscated-openssh version of PuTTY.
And here we are.
Requirements
In order to take advantage of the obfuscated handshake in PoTTY, you need to have an obfuscated openssh server.
Yes, there's work involved. Most people lose interest here, so I won't be offended if you leave now.
PoTTY will still work fine with "normal" SSH servers, but there's hardly any point without obfuscation.
First, get over port 22 and use something else. And don't give me any grief over "security by obscurity". You only dislike that because it rhymes and it's easy to remember. The only benefit to running osshd—as I like to call it—on port 22 is it will immediately crush all standard ssh brute force attacks. That's fine, but talking over port 22 is still a dead give-away. A random port is fine, but it can raise eyebrows and it may not be available through every firewall you encounter. Consider instead a false port, such as one of the common alternate SSL ports (8443, 4443, 1443, 444, et. al.). The flash server ports (1935, 1936) are also a good choice.
Next, download brl's code and install it. You're going to have to do something about your Linux distro's stock ssh utilities, so you may want to consider an installation something like this one:
./configure --prefix=/opt/ossh \
--localstatedir=/opt/ossh/var \
--with-pid-dir=/opt/ossh/var/run \
--with-default-path=/opt/ossh/bin:/opt/ossh/sbin:/bin:/sbin:/usr/bin:/usr/sbin: \
--with-privsep-path=/opt/ossh/var/empty
...which will put everything in /opt/ossh after a "make install". Don't remove your distro's ssh packages because sooner or later it will be a dependency for something and it will get reinstalled when you least expect it.
After building and installing you'll have to jack around your /etc/init.d scripts to make sure you run osshd at start-up.
Your old ssh utils will still be in your PATH, so you'll have to change that as well. You could copy the ossh utils over the old ones since they have the same names (changing the names of the executables is a bad idea), but they will be replaced the next time your system decides to update ssh. Of course, nothing is preventing you from running two sshd daemons but you still have to make changes to prevent them from stomping on each other.
Personally, I keep port 22 open on the inside of the firewall because I still have to use things that don't support ossh, like WinSCP (and, yes, I have thought about creating a "WinoSCP" just because I like the name). All except one of my outside ports (I have six, for various reasons) are obfuscated. The unobfuscated oddball is for emergencies.
If you don't have a Linux system to install an obufuscated-openssh server on, you can use the same instructions as above on Cygwin.
Code changes to PuTTY
Stuffing the obfuscated-openssh code, along with some requirements from OpenSSL, into PuTTY was surprisingly simple. I didn't have to write a single line of code, although I did have to make some adjustments due to name clashes between PuTTY's functions and OpenSSL's equivalents. Besides the cosmetic changes, the only difference between PuTTY and PoTTY is shown below.
This is the dialog where you specify the obfuscation options. For the PLoNK, oSCP, and oSFTP commandline utilities, "-z" enables obfuscation and "-Z keywd" specifies the keyword.
Due to the static linking with the OpenSSL libs, PoTTY is somewhat bloated (1.12M) compared to PuTTY (480KB). If this offends you, you can recompile using dynamic linking to the OpenSSL DLLs. It works fine that way. I simply wanted to distribute a standalone, portable executable without any external requirements. Plus, a variety of vendors distribute their own, "proprietary" versions of the Windows OpenSSL DLLs (libeay32.dll & ssleay32.dll) that have been known to cause headaches.
PoTTY was compiled with Microsoft Visual C++ 2008 Express Edition. Be advised if you want to recompile everything that all compiler optimization must be disabled (/Od), per Simon Tatham's recommendation.
Since PuTTY is not available for Windows in a 64bit version, neither is PoTTY. I have a feeling it's not possible.
Changes from PoTTY 0.60
You can assume all the changes to PuTTY 0.61 also apply to PoTTY 0.61, with the following (PoTTY-specific) additions:
- For completeness, PoTTY now consists of all of the PuTTY utilities
- The DLL injection issue has been fixed
- Restoring the Obfuscated Keyword from the Registry now works
- Private key authentication with *.ppk files has been fixed
I had called the "Obfuscated Keyword" the "Obfuscated Password" in 0.60. Since that value is called ObfuscateKeyword in sshd_config, I felt I had to change it to maintain consistency between the client and server naming conventions.
Although I have seldom used pageant, after looking at the code it was obvious that it would not have worked at all with PoTTY 0.60, assuming private key authentication had been working.
This is due to pageant hard-coding the name "putty.exe" into its search path. That was changed to "potty.exe". Other than that and the cosmetic changes, "pogeant" is identical in function to pageant.
Once I included pogeant, I also added pottygen and pottytel. Both of these programs have only cosmetic changes.
So now you have the entire "PoTTY Suite" consisting of all seven PuTTY utilities.
Why not PoTTY?
If you run Cygwin in Windows, it is a much better choice for port-forwarding. But before you compile obfuscated-openssh on Cygwin, look for SSH_IOBUFSZ in config.h and change it to 65535.
Why? It fixes... things... in PuTTY that can't be fixed.
Consider this example: You connect to your SSHd server from Windows and configure PoTTY (or PuTTY, it doesn't matter) to forward a port back up the wire to Windows' RDP port (3389). Then, you travel to your remote SSHd server and try to start an RDP session back on that box where PuTTY is running. At first it appears to work, but after you log in you get a Black Screen of Death and the session times out. Occasionally, you may get it to run, but it will hang on you sooner or later.
I like refer to this as RDP back-tunneling. It won't work with PuTTY, but if you make the aforementioned change to SSH_IOBUFSZ in obfuscated-openssh under Cygwin it will work with no problems.
I have tried but I can't find a similar fix for PuTTY/PoTTY.
Does it work?
Yes. I have seen IDS warnings (specifically "SSH over non-standard port"—guess the vendor) disappear after switching to obfuscated-openssh, but my field testing has been limited. You may also set off a "non-SSL traffic over port 443" if you use port 443, so be aware of that, especially if you're trying to punch through a proxy server.
Will it work forever?
Not sure about that one. The clear text handshake is low hanging fruit for an IDS, as is any traffic over port 22. There is a certain rhythm or cadence that is obviously SSH terminal activity if you know what you're looking for during a live sniff. I am certain that type of detection could be automated in an advanced IDS system.