droe / sslsplit

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

Possible issue trying to utilize IPv4 and IPv6 with 0.0.0.0 and :: at same time #275

Open Chaskel opened 4 years ago

Chaskel commented 4 years ago

Hello,

I am trying to use sslsplit on a client that has both IPv4 and IPv6 capabilities connected to an upstream MITM system bridged interface that also has both IPv4 and IPv6 capabilities.

On the client system if I try to reach sites (e.g. with curl) that are IPv6 only or sites that are only IPv4, it would seem that I would need to be able to do the following:

sudo sslsplit -D -k certauth.key -c ca.crt ssl :: 8443 tcp :: 8080 ssl 0.0.0.0 8443 tcp 0.0.0.0 8080

Unfortunately this does not appear to work as sslsplit references "Address already in use". If I take the command and test IPv4 and IPv6 individually:

sudo sslsplit -D -k certauth.key -c ca.crt ssl :: 8443 tcp :: 8080 will work for sites that handle both IPv6 or are only IPv6 and sudo sslsplit -D -k certauth.key -c ca.crt ssl 0.0.0.0 8443 tcp 0.0.0.0 8080 will work for sites that handle IPv4

Should the first sslsplit command I pasted above work, and if not what would be your recommendation to accomplish this?

Thank you

Requested details below:

- Output of sslsplit -V SSLsplit 0.5.5 (built 2019-08-31) Copyright (c) 2009-2019, Daniel Roethlisberger daniel@roe.ch https://www.roe.ch/SSLsplit Build info: V:FILE HDIFF:0 N:83c4edf Features: -DHAVE_NETFILTER NAT engines: netfilter* tproxy netfilter: IP_TRANSPARENT IP6T_SO_ORIGINAL_DST Local process info support: no compiled against OpenSSL 1.1.1c 28 May 2019 (1010103f) rtlinked against OpenSSL 1.1.1f 31 Mar 2020 (1010106f) OpenSSL has support for TLS extensions TLS Server Name Indication (SNI) supported OpenSSL is thread-safe with THREADID OpenSSL has engine support Using SSL_MODE_RELEASE_BUFFERS SSL/TLS protocol availability: tls10 tls11 tls12 SSL/TLS algorithm availability: !SHA0 RSA DSA ECDSA DH ECDH EC OpenSSL option availability: SSL_OP_NO_COMPRESSION SSL_OP_NO_TICKET SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION SSL_OP_TLS_ROLLBACK_BUG compiled against libevent 2.1.11-stable rtlinked against libevent 2.1.11-stable compiled against libnet 1.1.6 rtlinked against libnet 1.1.6 compiled against libpcap n/a rtlinked against libpcap 1.9.1 (with TPACKET_V3) 1 CPU cores detected

- Output of uname -a Linux utla02 5.4.0-42-generic #46-Ubuntu SMP Fri Jul 10 00:24:02 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

- Exact command line arguments used to run sslsplit sudo sslsplit -D -k certauth.key -c ca.crt ssl :: 8443 tcp :: 8080 ssl 0.0.0.0 8443 tcp 0.0.0.0 8080

- Relevant part of debug mode (-D) output, if applicable Generated 2048 bit RSA key for leaf certs. SSL/TLS protocol: negotiate proxyspecs:

- NAT redirection rules you are using, if applicable Copy of script I created to setup bridge and associated nft config below:

!/bin/bash

By Chaskel 2020-07-25 v1.0

Note: Tested on Ubuntu 20.04 which uses nftables to replace iptables/ip6tables/ebtables/etc.

DESCRIPTION:

Sets system interfaces up for doing sslsplit MITM traffic observation

Modify lines below to reflect your needs

Be sure to execute script with sudo

Set the interface names of the 2 NICs that traffic will traverse

NIC1=eth1 NIC2=eth2

Set the interface name of the bridge

BR=br0

Set the ports you would like to redirect keep the same formatting as listed below

NON_SSL="80, 5522" SSL="443, 465, 587, 993"

Set the redirect ports relating to the ports above

REDIR_NON_SSL=8080 REDIR_SSL=8443

######## DO NOT MODIFY LINES BELOW ########

Create bridge interface

ip link set $NIC1 up ip link set $NIC2 up ip link add name $BR type bridge ip link set $BR up ip link set $NIC1 up ip link set $NIC1 master $BR ip link set $NIC2 up ip link set $NIC2 master $BR

Define variable with MAC of bridge interface

BR_MAC=$(cat /sys/class/net/$BR/address)

Assign DHCP address to bridge interface

Note: If you see a "cmp: EOD on /tmp......." message you may most likely ignore it

dhclient $BR

Execute nftables related items

nft add table bridge table1 nft -- add chain bridge table1 chain1 { type filter hook prerouting priority -200 \; } nft add rule bridge table1 chain1 tcp dport { $NON_SSL } meta pkttype set host ether daddr set $BR_MAC counter nft add rule bridge table1 chain1 tcp dport { $SSL } meta pkttype set host ether daddr set $BR_MAC counter

nft add table inet table2 nft add chain inet table2 chain2 { type nat hook prerouting priority 0 \; } nft add rule inet table2 chain2 tcp dport { $NON_SSL } counter redirect to $REDIR_NON_SSL nft add rule inet table2 chain2 tcp dport { $SSL } counter redirect to $REDIR_SSL

sonertari commented 4 years ago

As I am sure you have realized, you are trying to use the same port in two different proxyspecs, twice: 8443 and 8080. Hence, you get an "Address already in use" error, even if the one is for IPv4 and the other for IPv6. You should use different ports for each proxyspec. So I recommend the following command line:

sudo sslsplit -D -k certauth.key -c ca.crt ssl :: 8443 tcp :: 8080 ssl 0.0.0.0 8444 tcp 0.0.0.0 8081

But this of course is possible if you can configure your target device to listen on 8444 and 8081 for IPv4.

On an unrelated issue, sslsplit reports that you are compiling and linking sslsplit using different OpenSSL versions.

Chaskel commented 4 years ago

Hello,

Thank you for the quick response and guidance. I appear to have successfully accomplished what you recommended and I greatly appreciate your tip.

In case the following information is helpful:

I am also including a copy of my updated script in case this could help anyone else in the future:

!/bin/bash

By Chaskel 2020-07-26 1.0.1

Note: Tested on Ubuntu 20.04 system with IPv4/IPv6 using nftables (replaces iptables/ip6tables/ebtables/etc.)

DESCRIPTION:

Sets system interfaces up for doing sslsplit MITM traffic observation

Modify lines below to reflect your needs

Be sure to execute script with sudo

Set the interface names of the 2 NICs that traffic will traverse

NIC1=eth1 NIC2=eth2

Set the interface name of the bridge

BR=br0

Set the ports you would like to redirect and keep the same formatting as listed below

NON_SSL="80, 5522" SSL="443, 465, 587, 993"

Set the redirect ports relating to the ports above

REDIR_NON_SSL_IPV4=8080 REDIR_NON_SSL_IPV6=8081 REDIR_SSL_IPV4=8443 REDIR_SSL_IPV6=8444

######## DO NOT MODIFY BELOW THIS LINE ########

Create bridge interface

ip link set $NIC1 up ip link set $NIC2 up ip link add name $BR type bridge ip link set $BR up ip link set $NIC1 up ip link set $NIC1 master $BR ip link set $NIC2 up ip link set $NIC2 master $BR

Define variable with MAC of bridge interface

BR_MAC=$(cat /sys/class/net/$BR/address)

Assign DHCP address to bridge interface

Note: If you see a "cmp: EOD on /tmp......." message you may most likely ignore it

dhclient $BR

Execute nftables related items

nft add table bridge table1 nft -- add chain bridge table1 chain1 { type filter hook prerouting priority -200 \; } nft add rule bridge table1 chain1 tcp dport { $NON_SSL } meta pkttype set host ether daddr set $BR_MAC counter nft add rule bridge table1 chain1 tcp dport { $SSL } meta pkttype set host ether daddr set $BR_MAC counter

nft add table ip table2 nft add chain ip table2 chain2 { type nat hook prerouting priority 0 \; } nft add rule ip table2 chain2 tcp dport { $NON_SSL } counter redirect to $REDIR_NON_SSL_IPV4 nft add rule ip table2 chain2 tcp dport { $SSL } counter redirect to $REDIR_SSL_IPV4

nft add table ip6 table3 nft add chain ip6 table3 chain3 { type nat hook prerouting priority 0 \; } nft add rule ip6 table3 chain3 tcp dport { $NON_SSL } counter redirect to $REDIR_NON_SSL_IPV6 nft add rule ip6 table3 chain3 tcp dport { $SSL } counter redirect to $REDIR_SSL_IPV6

sonertari commented 4 years ago

Thanks @Chaskel for detailed explanations.

You are right about the usage help, there is an example with loopback addresses for both IPv4 and IPv6, which by the way works without any issues. Afaik, you can do that with individual IP addresses, but if you use "unspecified" addresses, as they call it, e.g. 0.0.0.0 and ::, I read that it does not work. Quoting from here:

"Servers can either listen on a specific IP address/port combination or can listen on a port for all addresses. The latter is specified by specifying a listen address of 0.0.0.0 for IPv4 or :: for ipv6. If a server is listening on a port for all addresses then other servers can't listen on that port for a specific address."

I don't know the reason behind this difference. Sorry for the confusion.

You are right about the version issue of OpenSSL. The same issue exists on Linux Mint 20 too, quite naturally as it uses Ubuntu packages. I don't see any openssl updates yet, so I find it a bit strange that they have compiled the sslsplit package on an older system than the one they have released for. I hope the differences between 1.1.1c and 1.1.1f do not cause any issues with sslsplit.

Chaskel commented 4 years ago

No problem @sonertari and I appreciate the help.

Thank you again for your support and solution.