Randpeer - Stealth

Since we have received many questions about what we mean by "stealth" this page explains it. Note that the last part about the encryption is not complete and very simplified.

This document explains techniques to make it hard for your ISP and other attackers to find out which application you run.

This document is about "application privacy" and "protocol privacy". Not about anonymous Internet communication.

Most of these stealth ideas are not our own but well known techniques. But the technique to encrypt/hide the hello message that we explain in the end of this document is new as far as we know.

If they can not see you they can not attack you

When you run applications that communicate on the Internet there are many reasons to hide for the world what application you are running. Or even hide that you are running an application at all. Especially if those applications are servers or p2p applications that will be receiving incoming connections.

If an attacker can identify what application you run they might be able to exploit known weaknesses in that application to attack you. If they don't know what application you run they have to try ALL kind of attacks for ALL known applications. Which will be much harder.

Another problem is that Internet Service Providers (ISPs) sometimes dislike certain applications and limit the bandwidth for such applications. What they call "traffic shaping". Sometimes they even totally block such applications or even disconnect such users. If they can not identify what application you run they have a much harder decision to limit or block your connection.

Random ports

Most server and p2p applications today that receives incoming connections listens to a certain IP port. This means that the mere fact that you use a certain port makes it pretty obvious which application you run. Open ports can easily be detected/measured by an attacker using "port scanning" tools. Also, traffic shaping routers at the ISP can see the port numbers in the traffic to and from your computer and thus detect the application.

So the first trick to become a bit more secret is to make the application use a randomly chosen port. Usually it is enough that the application chooses the port to use once at installation and then uses that port forever.

This off-course means that a stealthy application that acts as server now also has to tell it's clients / peers not only it's URL or IP-address but also it's port number.

Caller talks first

Once upon a time when you connected to applications they used to respond with a welcome message, for instance "Welcome to CoolMail Mailserver v0.3". That is very nice for the attackers. They immediately know what application it is and even which version!

That means an attacker can apply whatever known attacks there are on that application. And if there are no known attack they can get a copy of that application and study it to find any weakness in it...

Also for an ISP that means they can scan your computer and find out if you run any application they don't like.

Such a welcome message is pretty unnecessary since the caller should already know who and what it connects to if it is a legitimate caller. So instead it is better that the server says nothing until the caller has sent a proper hello message. That is, the caller talks first.

If the server does not get a proper hello message within some seconds from the connect it should simply drop the connection without sending any error message. Since such an error message of course would give away what application it is.

What drop time to use should preferably be randomly chosen at install time and then the same drop time should be used forever. Otherwise an attacker can make many connections and measure what minimum and maximum drop time your application uses and thus guess what application it is.

Server unique hello message

Note that just random ports and "caller talks first" does not stop all kinds of port scanning. If your application simply responds to an unencrypted hello message an attacker can scan your computer for open ports, then try all known kinds of hello messages on the ports that are open. Sure, that is a bit harder, but doable. And that is exactly what the more advanced port scanning tools do today.

So preferably the hello message should be unique to that server and not only to that kind of application. The simple solution is that the server tells it's clients / peers not only IP and port but also some "semi-secret" key to use in the hello message. The server should only respond if the hello message contains the right key. There are also more complex encrypted ways to do this which will be explained further on in this document.

Stealthy UDP

Most applications use TCP connections nowadays for a number of good reasons. But sometimes we chose to use UDP. In the UDP case we sometimes get a nice extra stealth feature, that the attacker can not even see that you have the port open.

When you have TCP ports open you have no way of hiding which port is open since the computer first accepts the connection, even before the application starts talking. But UDP ports work differently, they don't send anything back unless the application decides to send an UDP message in response. And mind you, we should only respond if we get a correct hello message.

But for a closed (not used) UDP port the operating system (the IP stack) usually automatically sends back an error message that the port is closed. Fortunately many modern locally installed firewalls changes that, so that such error messages never are sent! You can also configure most hardware firewalls to filter out such error messages. If such error messages are blocked, a port scanner has no way to tell closed and open UDP ports apart. Since the scanner doesn't get any response from any of the ports!

This means a port scanner does not know which port to bombard with all kinds of possible hello messages. Trying all possible hello messages on all ports is not doable...

Look alike or look random

So you got random ports and advanced caller talks first with some kind of key or crypto in the hello message? Well, what if the ISP or some attacker eavesdrops on your communication? And yes, ISPs and others often do that. Then they will quickly figure out what application and protocol you run, right? Well, not necessarily.

There are two good ways to make it hard for an eavesdropper to tell your traffic apart from other traffic. Either you look exactly like many other applications or you look very random (you encrypt from the first byte).

The most popular way is to use a well-standardised encryption protocol like SSL, TLS or SSH. And only use the same type of crypto and other settings for it that many other applications use. This means your encryption headers and hello messages etc will look just like everybody else's. And the rest of your communication will be encrypted. Unfortunately it is a bit hard to look exactly like everyone else in this way since what everyone else looks like tends to change over time...

The other much more timeless option is to look completely random. That is, to encrypt from the first byte. Since all applications that encrypt from the first byte look the same. Such a protocol should encrypt even the hello message.

Traffic analysis

We previously stated that "all applications that encrypt from the first byte look the same". Unfortunately that is not entirely true. Even if you use all techniques mentioned here there is one method an eavesdropper can use to identify your application. It is called traffic analysis.

In traffic analysis the eavesdropper analyses the size of messages sent and the timing between messages etc. The application's "rhythm" so to speak.

Some applications tries to prevent traffic analysis by adding some bytes to each message to change their size randomly and also tries to send the messages with somewhat random intervals. However this only means a traffic analyser needs to listen a bit longer to gather better statistics. So it does not pay of much. (And costs a lot of extra implementation time and bandwidth.)

In spite the existence of traffic analysis it is worthwhile to use full stealth. Since it still protects against port scanning and you want to encrypt your communication anyway, right? Also, traffic analysis is not that commonly used since it is expensive to implement and costs a lot of CPU power and memory to run. Which means ISPs are not likely to use traffic analysis for their traffic shaping.

And besides, traffic analysis can only indicate that it is likely that you run a certain application, it can not prove what you run. Which gives you as a user "plausible deniability".

Encrypted hello message

Usually when applications connect they send a hello message. Such a message usually contains information about which protocol the application wants to talk, who is connecting and so on. Not until after that will the server know what encryption and what key can be used. So encrypting from the first byte can be a bit tricky.

Here we describe a technique for hiding the hello message that was invented by Rik Rose from England and that we (the Randpeer team) have developed a bit further. Note that this description is very brief. If you want to know more about this method feel free to contact us for an extended explanation and for pointers to relevant crypto literature etc.

The first bytes that the caller sends should be:

Client-IV -> hash( Client-IV + key ) -> hash( Client-IV + key + protocol name ) -> If the server understands then it should respond like this: <- Server-IV <- hash( Client-IV + server-IV + key + protocol name ) IV = Initial Value / nonce. 8-20 randomly chosen bytes. The number of bytes can be protocol and application specific but should be at least 8. The purpose of IVs is to make each session unique.

Key = A key or password that preferably is unique to one user or node in the network. If the users are allowed to chose their own passwords the passwords might not be unique. But the key can easily be made unique like this: key = (user password + user name).

Protocol name = A name that specifies exactly what protocol the client wants to talk with the server. This name identifies how the rest of the log in should be done and how the application data should be encrypted etc. The protocol name should be pretty verbose so anyone designing a similar protocol will be unlikely to chose the same name.

Test hashing
To figure out what key the client wants to use the server will test hash (Client-IV + key) once for each key (user) it knows. Since a modern PC today can do at least 65 000 SHA1 hashes per second this is not a problem...

When the server has figured out what key to use it can go on and test hash ( Client-IV + key + protocol name ) once for each protocol it supports.

When the server has figured out which key and which protocol the client wants to use the server knows who wants to log in and how. And an external eavesdropper can not even figure out what protocol is being used since only those who know the key can do the test hashing.

Initial values (IVs)
The IVs used here can also be reused to create the shared session secret used for encryption later on. To prevent replay attacks it is necessary that both parties supply an IV. Therefore also the server sends an IV.

To tell the client that the connection succeeded the server responds hash( Client-IV + server-IV + key + protocol name ). This response is not really necessary, since the client would anyway notice later on if it failed when trying to talk encrypted with the server. But it is convenient to know if the login succeeded before initiating all the real crypto stuff.

Semi-secret keys
Note that in many cases the key used here need not be very secret. Since the main purpose here is to hide what protocol is being used and that usually is not that critical a "semi-secret" key can be used. The key could for instance be the ID (hash) of the server's public key. Since if an attacker already knows your public key he usually already knows what application you are running. To late to hide what protocol you use then.

If we use a semi-secret key or a weak key such as a human memorable password the two nodes should do like this: First initiate a temporary encryption mode using the shared secret "Client-IV + server-IV + key". Then exchange public keys and establish a new shared secret using those public keys. Then switch to using that new, more secure shared secret for encryption.


2007-05-07
Copyright © 1997-2007 The Randpeer development team - team@randpeer.com