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:
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.