Search code examples
linuxnetwork-programmingtcppacket-capturesniffing

Howto intercept tcp packet and modify in the fly?


Howto intercept tcp packet and modify in the fly without proxy in Linux (Ubuntu)? by example, capture packet as wireshark but modify the packets.

Need capture, search and replace packets, but example:

Search regex "/(<form\s+.*?>)/i", replace by "$1\n<input name=\"newinput\">"

Only for local packets using ftp, smtp, http, etc. Howto made this?


Solution

  • Given your example you do not want to change only single bytes in a packet but a string which might span multiple packets. Also, your replacement might have a different length than the original string. If you do this at the packet level (since you don't want to use a proxy) you would need to:

    • possibly delay the forwarding of packets in case they might be need to be changed based on the content of following packets
    • rewrite not only the few packet where you change the payload but also all following packets because due to changes in size of the data all sequence numbers need to be adjusted
    • rewrite also all future packets you've received from the peer since the sequence number in the ACK need to be adjusted so that the original sender can associate the ACK with the original packet

    Apart from the complexity to implement this the first point of delaying a packet could also infer with the TCP flow control which might your connection to slow down or even to stall.

    Thus the usual approach to implement such deep packet modifications is to use a proxy where there is one TCP connection between client and proxy and another between proxy and server. This way you have two independent TCP connections which both have their own independent TCP flow control. Also, the kernel automatically deals with the correct sequence numbers etc so no manual adjustments are needed.

    I don't know how unalterable your requirement of not having a proxy is. It might be that you only don't want to have an explicit proxy which needs to be configured at the client. But, proxies can also be used in a transparent way which don't need explicit configuration in the client.

    Thus, you might better implement your actual requirement with a transparent proxy. See for example this documentation for mitmproxy on how to do this for HTTP. One can implement this also for different protocols than HTTP in a similar way.