How to transparently redirect a TCP connection
12 Jun 2009 Robin Berthier honeybrid-gsoc-redirection
TCP was built to allow 2 hosts to exchange a stream of packets reliably. Honeybrid must add a third host to this operation when it decides to investigate further a connection. The keys for this process to work are: 1) a replay process that gets the high interaction honeypot to the same state than the low interaction honeypot; and 2) a forwarding process that translates not only IP addresses but also TCP sequence and acknowledgement numbers. Here is how things work in detail:
-
An external source S initiates a TCP connection with an IP address D1 belonging to a honeynet instrumented with Honeybrid. Honeybrid is configured so that D1 is a low interaction honeypot that will complete the TCP handshake with S.
-
Packets sent by S and carrying data are analyzed by the Decision Engine of Honeybrid. If a packet payload matches a decision rule, then Honeybrid decides to investigate further this connection by forwarding it to a high interaction honeypot D2.
-
Before this forwarding process to start, Honeybrid has first to get D2 to the same state than D1. This is achieved by replaying the beginning of the connection between S and D1 to D2.
-
When D2 is ready to take over the connection, Honeybrid starts the forwarding process between S and D2. The source IP of packets sent by D2 are replaced with the address of D1, and the destination IP of packets sent by S are replaced with the address of D2. TCP sequence and acknoweldgement numbers as well as TCP options are also translated, otherwise packets would be discarded by the TCP/IP stacks of S and D2.
The main challenge with this process it to prevent the source S from noticing that the destination of the connection has been changed from D1 to D2. Therefore, the replay phase should go as fast as possible so that it does not add a latency that could be fingerprinted by S. The fact that S is an external host while D1 and D2 are on the local network reduces such risk.
The diagram attached illustrates the entire mechanism with a short TCP connection of 13 packets.
From an implementation perspective, Honeybrid uses libnetfilter queue to be able to process packets in user land. The decision engine of Honeybrid was previously working on a separate thread to prevent the decision process from delaying the main packet processing queue. The problem was that the decision thread and the main thread had to concurrently access the same data structure. This could create severe instability issue when a large volume of packets were handled. This week I added a #define statement to Honeybrid so that the thread can be easily disabled. I will now test with and without the thread to precisely measure the efficiency drop and the stability gain.