TL;DR: I feel I'm pretty close to doing so by using sslsplit's interface mirroring, but I ran into an issue where the kernel is not replying to ARP requests that sslsplit is sending out on the mirrored interface.
I want to intercept an SSL/TLS connection of a program I'm running in my machine and see the decrypted contents in wireshark. It seems sslsplit's interface mirroring is what I need so I've been trying to set that up.
This command properly sets up the interception without mirroring and simply outputting some info to stdout:
sudo sslsplit -D -l /dev/stdout -c ca.crt -k ca.key tcp 192.168.10.1 9090 ssl 192.168.10.1 9091
192.168.10.0/24 is a subnet that's on a veth link. I put one end of the veth in a new network namespace and setup the other end as the default route in that namespace. EDIT 2: In other words, I did:
ip link add veth0a type veth peer veth0b ip address add 192.168.10.1/24 dev veth0a ip netns add sslsplitns ip link set veth0b netns sslsplitns ip netns exec sslsplitns ip address add 192.168.10.2/24 dev veth0b ip link set veth0a up ip netns exec sslsplitns ip link set veth0b up ip netns exec sslsplitns ip route add default via 192.168.10.1
The idea is to run the program whose connection I want to intercept in that network namespace (i.e.
ip netns exec sslsplitns $cmd). I found this setup necessary because sslsplit works using the NAT engine, and it seems it can't pickup on packets unless they go through the INPUT chains.
Anyway, to use network mirroring I apparently select the interface I want to mirror to with
-I. However, sslsplit says that
-I depends on
-T which is:
-T addr Mirror connection content as emulated packets to destination address addr on the interface given by -I. Only IPv4 target addresses are currently supported. This option is not available if SSLsplit was built without mirroring support.
EDIT 4: I imagine this means that if I made an HTTPS request to, for example, 184.108.40.206, sslsplit would make an equivalent HTTP request to whatever I provide to this option. Somebody, please correct me if I'm misunderstanding this, because I'm not completely sure how this would work. Would sslsplit really be able to use this provided address as source and destination IP? Would it make sure that no other program would receive these mirrored packets in case they're actually listening? How would this mirroring work if I provided sslsplit with an actual physical link and the IP of another physical computer? Are these mirrored packets actually meant to be received and not merely inspected by a tool like wireshark or tcpdump?
So I made a dummy interface (
ip link add dummy0 type dummy), gave it an address and provided that address to sslplit's
EDIT: Here's the command:
sudo sslsplit -D -l /dev/stdout -T 192.168.12.2 -I veth1a -c ca.crt -k ca.key tcp 192.168.10.1 9090 ssl 192.168.10.1 9091
Looking through wireshark, in preparation to see the decrypted SSL packets, I see that sslsplit sends ARP requests querying the hardware address of the ip address I gave it. After various attempts,
sslsplit ends up dying with the message
failed to lookup target ether. I thought, maybe the kernel won't reply because it's the same address it's sending from, so it's too silly to take seriously. So I made another veth link, gave both ends a different address in the same /24 subnet, and provided one of them to sslsplit's
-T. It correctly used the other address to ARP query the hardware address of the IP I gave it, but the kernel still wouldn't reply to the ARP request.
I've tried activating all
sysctl options relating to ARP, and also
rp_filter, basing myself from this answer.
By the way, I know that various programs have support for looking into decrypted SSL in wireshark by use of the
SSLKEYLOGFILE environment variable, but the program whose connection I want to intercept has no support for that environment variable.
Here is a picture of wireshark with the ARP requests. When those fail I also see SSDP packets, but I don't know what those are, and they seem little relevant:
EDIT 3: For the record, here's some of the output from
ip link, which shows the ethernet address that the kernel should be replying with:
46: veth1b@veth1a: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 4a:36:55:f8:e1:d2 brd ff:ff:ff:ff:ff:ff