droe / sslsplit

Transparent SSL/TLS interception
https://www.roe.ch/SSLsplit
BSD 2-Clause "Simplified" License
1.75k stars 328 forks source link

Mirroring to local IFB interface, without ARP #260

Open emning opened 4 years ago

emning commented 4 years ago

I'm running sslsplit with the -T and -I options, mirroring decrypted streams to a local IFB interface ifb0.

This works, but the issue is that sslsplit insists on doing an ARP request and expects a response, even for a local interface.

To work around this I first start sslsplit, wait a second, and then spoof an ARP reply both from and to ifb0, including its own MAC and IP.

This works, but seems unnecessary. I have looked at _logpkt_etherlookup in log.c, but have been unable to figure out how to shortcut the process when the interface is local and already known. It seems it should also be possible to mirror to a local interface without requiring it to have a configured IP address, although this is less of an issue.

This may seem like an unusual case, but I believe it could be very useful. My application here is to do the following:

In effect this means we can run tcpdump against ifb0 and get all the traffic from the monitored interface, with all the SSL/TLS flows decrypted. A useful feature, imho.

sonertari commented 4 years ago

I guess you have already figured it out that we use the ethernet address to forward emulated packets to the given target IPv4 address (-T) on the given interface (-I). So the question is: How do we forward an emulated packet to an ifb interface? I guess the answer seems like by using the ethernet address of the physical interface that the ifb interface is redirected from.

I have never used tc or ifb ifs, but reading the descriptions here, I would use the IPv4 address of the actual physical interface, say eth0 as in the descriptions I mention, with the -T option, because I suppose if we send the emulated packets to the ethernet address of eth0, ifb0 should receive them too. Just to make sure I understand, I guess that's what you did too, but it doesn't work, right? Because eth0 is local to the system on which we send arp requests to (arping(8) cannot get any response for local IP addresses either).

So I guess we should check if the given IPv4 address is local, then we should get its ethernet address from the system (option 1), not send arp requests to the network. Or more easily, perhaps we should ask the user to supply the ethernet address of eth0 himself (option 2). I would vote for the latter option, so that since we already know the ethernet address to send the emulated packets to, we could skip the arp requests: in logpkt_ether_lookup() I would skip the code after we set src_ether (memcpy()), because dst_ether would have been already set using the new configuration option I propose.

Now, assuming we know the ethernet address of eth0, we send the emulated packets to that ethernet address. But, will they go through the same packet flow in netfilter as would a packet from an outside source? Based on your report, yes, the emulated packets follow the same packet flow.

I am sure Daniel would have better ideas, and my comments above are just theoretical. But you are welcome to implement my suggestions yourself to see if it works (and then hopefully submit a pull request?).