9

I need to make some small modification to incoming traffic from a known tcp host:port before the process handling the connection get the stream.

For example, let 192.168.1.88 be a remote host which runs a web server.
I need that, when a process on my local host receives data from 192.168.1.88:80 (e.g. the browser), the data is first changed replacing text-A with text-B, like this:

  • 127.0.0.1:... connects to 192.168.1.88:80
  • 127.0.0.1:... sends to 192.168.1.88:80:

    GET /
    
  • 192.168.1.88:80 sends to 127.0.0.1:...:

    HTTP/1.0 200 OK
    Content-Type: text/plain
    
    Some text-A, some other text
    
  • That data is somewhat intercepted by the system and passed to a program whose output is:

    HTTP/1.0 200 OK
    Content-Type: text/plain
    
    Some text-B, some other text
    
  • the system gives the so changed data to the process handling 127.0.0.1:..., like if it comes from 192.168.1.88:80.

Assuming I have a stream-based way to make this changes (using sed for instance), what is the easiest way to pre-process the incoming tcp stream?

I guess this would involve iptables, but I'm not very good at it.

Note that the application should feel to deal with the original host, so setting up a proxy is not likely a solution.

etuardu
  • 237
  • 2
  • 3
  • 11
  • Are these HTTP requests? – polynomial Oct 06 '11 at 06:36
  • Your question is not clear enough. You need to provide more details. – Khaled Oct 06 '11 at 07:28
  • 1
    You can't do it at the packet level. One packet might contain "text-" and the next might contain "A". You will have to develop an invisible proxy that follows the protocol. (You have to follow the protocol because if you get "text-" and it's part of "text-A", you need to wait for the next chunk before passing it on or your filter won't work. But if it's the end of a logical message, you can't wait because you'd be waiting forever.) I believe there is no easy way to do this. – David Schwartz Oct 06 '11 at 08:06
  • There already exist stateful packet inspection systems that can do e.g. rewriting of FTP traffic so that it works across NAT. That's the sort of place to start. – pjc50 Oct 06 '11 at 12:56
  • I need it to work with http response primarily but it would be good if it works on any application layer. – etuardu Oct 06 '11 at 20:19
  • Do you mean you want to modify the HTTP response header? – quanta Oct 12 '11 at 15:22
  • This seems like a classic case of the XY problem: http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem What does the OP actually want to fix? Wouldn't it be much easier to change the data at the source or destination rather than during transit? – jamesbtate Oct 16 '11 at 20:02

3 Answers3

23

Use netsed and iptables proxying.

iptables -t nat -D PREROUTING -s yourhost -d desthost -p tcp --dport 80 -j REDIRECT --to 10101

Then run:

netsed tcp 10101 desthost 80 s/text-A/text-B

NetSED is a small and handy utility designed to alter, in real time, the contents of packets forwarded through your network. It is really useful for network packet alteration, forging, or manipulation. NetSED supports:

  • black-box protocol auditing - whenever there are two or more proprietary boxes communicating using some undocumented protocol. By enforcing changes in ongoing transmissions, you will be able to test if the examined application can be claimed secure.

  • fuzz generating experiments, integrity tests - whenever you do stability tests of an application to see how it cares for data integrity;

  • other common use-cases: deceptive transfers, content filtering, protocol conversion - whatever best fits your task at hand.

Giacomo1968
  • 3,522
  • 25
  • 38
dfc
  • 1,331
  • 8
  • 16
  • That's really simple and cool. – mbrownnyc Oct 16 '11 at 03:27
  • I didn't know `netsed`, it fits almost perfectly for my purpose. The only thing I don't get is how to set up the "local transparent proxy" (see the question). Perhaps I ought to set up another (virtual) network interface to obtain that. By the way, for now this is the most satisfying answer. – etuardu Oct 16 '11 at 14:32
  • Are you running a generic distribution kernel? If you are iptables support is probably already compiled in. In order to set up the transparent proxy you just need to fill in the appropriate details for your host/ports. Take a look at the readme and see if it fills in some of the details. http://silicone.homelinux.org/git/netsed.git/blob_plain/HEAD:/README – dfc Oct 17 '11 at 05:10
  • I thought netsed would only work on one packet at a time? So if the http request were split across two packets the regex for the substitution won't match and the request will be passed to the server unmodified. – paulos Oct 17 '11 at 12:39
  • from netsed readme: "For now, only TCP and UDP user-space filtering is possible no support for kernel firewalling / routing, raw packets, ICMP and other things." netsed operates at layer four, not layer three. – dfc Oct 17 '11 at 20:49
  • I am a little new to serverfault. I do not know if this should be a new answer or and appendix to the answer I have provided above. If all you want to do is fudge around with data submitted from the browser you can use "tamper data" from within firefox. If you only need to modify http requests and cannot use "tamper data" extension try Paros Proxy. Tamper Data: https://addons.mozilla.org/en-US/firefox/addon/tamper-data/ Paros Proxy: http://parosproxy.org/functions.shtml – dfc Oct 17 '11 at 20:58
  • I understood how to configure a gateway machine as a transparent proxy for e.g. an internal LAN. The issue is that I need a "local transparent proxy", I mean a machine being its own transparent proxy. It seems this can't be done with the iptables rule shown because even the outgoing connection of `netsed` would be then redirected to its local port, in a infinite loop. – etuardu Oct 18 '11 at 15:20
  • I'm going to investigate further on how to do this but I'm realizing that this is a different (and not trivial) question from the starting one, so the bounty is yours. – etuardu Oct 18 '11 at 15:26
  • nice in theory, however netsed only gives segmentation error and iptables says `No chain/target/match by that name.`. – phil294 Sep 14 '16 at 21:42
  • @Blauhirn with all due respect whatever problems you are having are likely your own fault. I have used and seen others use netsed many times for many purposes. If I were you I would recheck your configuration and start with a simple example from the readme. – dfc Sep 14 '16 at 23:10
  • 1
    ok now, just in case someone needs this one day: not that I fully understand it, but for actually modifying OUTGOING packets (which is what op did NOT want to do), you'll have to modify `OUTPUT`, not `PREROUTING`. also, the `-D` option had to be `-A` for me. also, for the `-j` option, I had to use `DNAT --to-destination (ip)` or `REDIRECT --to-port`. Finally, I could NOT fix netsed's segmentation error. see also: https://ubuntuforums.org/showthread.php?t=2337389 – phil294 Oct 09 '16 at 17:07
  • really sorry for the spam. Netseds segmentation fault can be fixed manually: see https://ubuntuforums.org/showthread.php?t=2337389 – phil294 Oct 21 '16 at 00:16
5

You can do exactly this by using iptables to transparently proxy connections through a squid proxy, and then having squid re-write the http content for you.

paulos
  • 1,694
  • 9
  • 12
3

iptables + the use of libnetfilter_qu is another option that will do what you wish:

"...[reinject] altered packets to the kernel nfnetlink_queue subsystem."

It likely will give you most extensibility as it's up to you to code software.

There's a python wrapper available as well.

mbrownnyc
  • 1,825
  • 8
  • 30
  • 50