0

For some private purposes I need to enrich HTTP header with additional information (which will be handled by app on the HTTP server side). The basic idea was to modify received packet, send it to destination and never care about answer. The very simplified scheme of traffic paths is

+---+       +------+        +---+
|   +<<-----o MDFY +<<------o   |
| R |       +------+        | S |
| C |                       | N |
| V |                       | D |
|   o--------------------->>+   |
+---+                       +---+

The issue comes with TCP SEQ/ACK numbers. After TCP handshake, Sender send packet of 4 bytes length, which come to Modifier where length change to 22, then packet arrive Receiver and it sends ACK number +23, while Sender expects for +5. This blows Sender's mind and session becomes unsynced. I see this when, for example, try netcat for testing - for unmodified packets, session closes immediately after data exchange, while for modified packets session stales for a long time (actually, I stop it by pressing Ctrl-C).

I don't see an easy way to deal with this situation. Looks as once modified in-the-middle, entire session must be handled by Modifier because Sender knows nothing about Sequence number's modification and will rely on his own numbers. Doing this will significantly both impact performance and increase complexity, since I need to maintain state of every session and modify every packet coming from both sides to maintain SEQ/ACK numbers.

May be I don't see another way except writing own DPI? :-) Any knowledge, ideas and suggestions are appreciated.

Thank you.

2 Answers2

0

The only simpler option I see is to use a transparent proxy.

In this case, client sends the request to destination server. Proxy server captures the request, adds the header and creates another request to destination server. Destination server return response to proxy, which then returns it to client.

The drawback here is that the server does not see client's original IP address, but the proxy's IP address.

Then, for the TCP level MITM approach, there might exist toolkits that implement required functionality so that full implementation is not required.

Tero Kilkanen
  • 34,499
  • 3
  • 38
  • 58
  • Thank, Tero. This can be a solution, but the basic idea behind this effort was to use flows-aware switches to push "modified" flows out of the proxy server (this wasn't in my original question). Such approach solves the issue with performance requirements to the system. – Volodymyr Litovka Dec 09 '20 at 08:12
0

This looks like some sort of half-fledged NAT; and the problem is exacty in it being half-fledged.

You can't MITM only one direction of a TCP packet flow: you need to handle both flows, exactly to handle situations like this (standard NAT usually only cares about source and destination addresses/ports, but the principle is the same; if you want to mangle packets while in transit, and you want for this mangling to be transparent to both endpoints, you need to get everything right).

Once you start taking everything into account, soon enough you will have full-fledged NAT: no need to reinvent the wheel then, there are plenty of implementations around which will let you mangle packets as you wish.

The actual available options will of course depend on the operating system and routing/firewal software in use.

Massimo
  • 68,714
  • 56
  • 196
  • 319
  • 1
    Thanks, Massimo. Actually, NAT is not a solution because I mangle packet, changing payload, IP and TCP checksum and length (and, in fact, length change leads to unsyncing of SEQ/ACK numbers). The transparent proxy is an approach which solves the issue itself, while requires powerful hardware and/or cluster to deal with the traffic. – Volodymyr Litovka Dec 09 '20 at 08:04
  • And yes, it seems I need to handle both directions until I will be able to sync SEQ/ACK numbers and then quit the game. One way is to modify (decrease) ISN in order to get it synced with the "original" SEQ after enrichment. – Volodymyr Litovka Dec 09 '20 at 08:12