intercepting TCP connections

we have an absolute pile of tools for MITM1 of lots of specific things, particularly HTTP and HTTPS because of course there needs to be a tool for Web. sometimes tools even have a generic packet filtering/modification interface, for example based on linux nfqueue (nfqueue is cool and good) which works fine for UDP stuff because that's fundamentally packet-oriented, and it also works for TCP applications where you only need to sniff data on the wire and not inject anything

but as soon as you need to inject everything suddenly gets really hard and this is a place where i'm really surprised that no good robust tooling actually seems to exist. i guess the problem with TCP is it's really complicated and implementing it is hard

there are two basic classes of solution to this problem. one is using the kernel TCP stack, and the other is using a userspace TCP emulation library. kernel TCP seems the easiest but both of these have their own issues

kernel TCP

basically, you set up netfilter2 to redirect incoming packets to a MITM socket server you have running locally, which then makes the real connection to the ultimate endpoint as a second socket

except wait how do you even get the original destination of a connection? because it's now redirected to you...
turns out the lesser known SO_ORIGINAL_DST sockoption or parsing /proc/net/nf_conntrack can help you figure it out. but even then, you suffer from potentially being fingerprinted (for example, Linux, various BSDs, and Windows all have fingerprintable TCP/IP quirks which could result in your MITM being detected). and you have no low level control over individual packets, all you get is the TCP stream interface, which works for most things, but suppose for a specific application you just want to inject one thing at a specific point into a single packet and avoid getting detected as much as possible. this wouldn't be possible with a kernel stack setup

userland TCP

so kernel TCP would work for a lot of typical applications but sometimes you might want actual low level control over the packets or TCP algorithms, depending on what the MITM project is. and the only way to get that is to use your own TCP implementation

now this would be an ideal, flawless solution that solves everything. except i actually can't find any robust hackable TCP implementations in userspace. at all. muXTCP is pretty much the only thing and that's a toy with bugs and missing implementation stuff in it that hasn't been updated in a decade and a half. picotcp might be a more ideal solution but it's obtuse and from a bit of hacking i wasn't able to hook it into nfqueue (but it probably could be with a bit more effort). smoltcp might work too but it's lacking some honestly critical features like IP fragmentation (i get that fragmentation sucks, and it was definitely a mistake but a general purpose MITM tool needs to support it otherwise it's completely useless against any project where the endpoints fragment packets). those are a few examples. and even if you could hook up one of these libraries to nfqueue and do the thing, there might still be a lot of modifications necessary to support low level control of the protocol - for example, inserting your MITM into an active connection, injecting some data into a specific packet and then fixing up the TCP sequence numbers on every subsequent packet without tampering with anything else to continue the stream without either side knowing that the sequence numbers are out of sync. then, perhaps injecting some more data to convince the other host to send some extra data to sync its local sequence number, then removing your MITM. this is a very contrived example i guess but there could be situations where you don't want to actually fully proxy a TCP connection for its entire lifetime in general. or other low level protocol hackery that really just doesn't seem possible to do with anything available right now.

imo the state of complete, robust and tested userspace TCP that's readily available and readily hackable is very poor. if you know of some magic library that i don't know about here please shoot me a message :P

conclusion

overall there seems to be a distinct lack of ideal tooling in this space. for either the kernel stack or userspace stack strategy. even the most popular MITM tools like bettercap have very minimal support for scriptable raw packet proxying (you have to write "scripts" in golang and absolutely no support is provided) and even the TCP proxy (kernel stack based) can only proxy connections to a single address/port that you specify beforehand which is strangely limiting (maybe they didn't know about the SO_ORIGINAL_DST option?). i guess some of the stuff here just isn't a very common need in the general security world. but it's still kind of wild to me that i might have to actually write a custom MITM tool because literally no good ones exist


1

monsterenby in the middle

2

or iptables, if you're into that