droe / sslsplit

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

Segmentation fault with -w/W (generated certificates) option #271

Closed faperea closed 4 years ago

faperea commented 4 years ago

Hi, I downloaded and compiled sslsplit from GitHub and whenever I try to run anysslsplit command with the -W / -w option I have a segmentation fault. I thought it might be problems with my Raspberry compilers, so I installed it with sudo apt-get install sslsplit and tried again but got the same result. My system is as follows:

pi@raspberrypi:~/sslsplit $ sudo sslsplit -D -W masterkeys -l connections.log -j /tmp/sslsplit/ -S logdir/ -k ./cert/ca.key -c ./cert/ca.crt tcp 0.0.0.0 8843 | Warning: -F requires a privileged operation for each connection! | Warning: -w/-W require a privileged op for each connection! | Privileged operations require communication between parent and child process | and will negatively impact latency and performance on each connection. SSLsplit 0.5.4 (built 2018-11-27) Copyright (c) 2009-2018, Daniel Roethlisberger daniel@roe.ch https://www.roe.ch/SSLsplit Build info: V:FILE HDIFF:0 N:06fdafa Features: -DHAVE_NETFILTER NAT engines: netfilter* tproxy netfilter: IP_TRANSPARENT IP6T_SO_ORIGINAL_DST Local process info support: no compiled against OpenSSL 1.1.1a 20 Nov 2018 (1010101f) rtlinked against OpenSSL 1.1.1d 10 Sep 2019 (1010104f) 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.8-stable rtlinked against libevent 2.1.8-stable compiled against libnet 1.1.6 rtlinked against libnet 1.1.6 compiled against libpcap n/a rtlinked against libpcap 1.8.1 4 CPU cores detected Segmentation fault

sonertari commented 4 years ago

Be careful with compiled and rtlinked libraries:

compiled against OpenSSL 1.1.1a 20 Nov 2018 (1010101f) rtlinked against OpenSSL 1.1.1d 10 Sep 2019 (1010104f)

This may or may not be the reason. So please compile and run using the same OpenSSL version, and report back if it fixes the issue.

faperea commented 4 years ago

After having "Segmentation fault" errors with raspbian package, I tried to recompile from source (git). Results were the same. A "segmentation fault" error is present with locally compiled version from github. The full steps are as follows (included every step to avoid probably problems mixing libraries):

To remove previously installed packages, I ran:

sudo apt-get -y remove sslsplit sudo apt-get update -y

Then I ran:

sudo apt autoremove -y

to remove libraries marked as unnecessary from raspbian repository: libevent-core-2.1-6 libevent-openssl-2.1-6 libevent-pthreads-2.1-6 libnet1

After downloading latest version of ssplit with:

git clone https://github.com/droe/sslsplit.git

I installed dependencies:

sudo apt-get install -y libpcap-dev libnet1 libnet1-dev check

Also download and compile libevent-2.1.11

wget https://github.com/libevent/libevent/releases/download/release-2.1.11-stable/libevent-2.1.11-stable.tar.gz

After compiling sslsplit (make), I tried out to run test:

make test

It failed, as shown (compilation had no errors. I deleted some output to shorten the message):

pi@raspberrypi:~/sslsplit/src/sslsplit $ sudo make test
------------------------------------------------------------------------------
SSLsplit 0.5.5-1-g065f8cf
------------------------------------------------------------------------------
Report bugs at https://github.com/droe/sslsplit/issues/new
Please supply this header for diagnostics when reporting build issues
Before reporting bugs, make sure to try the latest develop branch first:
% git clone -b develop https://github.com/droe/sslsplit.git
------------------------------------------------------------------------------
Via pkg-config: openssl libevent libevent_openssl libevent_pthreads check
LIBPCAP_BASE:   /usr
LIBNET_BASE:    /usr
Build options:  -DHAVE_NETFILTER
Build info:     V:GIT
uname -a:       Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux
------------------------------------------------------------------------------
.
.
.
cc -L/usr/lib -L/usr/lib -L/usr/local/lib -pthread -pthread -o sslsplit.test cert.t.o cachefkcrt.t.o opts.t.o defaults.t.o cachetgcrt.t.o cachemgr.t.o pxythrmgr.t.o main.t.o url.t.o base64.t.o sys.t.o cachessess.t.o dynbuf.t.o logbuf.t.o ssl.t.o cachedsess.t.o util.t.o cert.o cachefkcrt.o opts.o proc.o cachetgcrt.o pxythrmgr.o cachemgr.o cache.o dynbuf.o sys.o proxy.o ssl.o url.o thrqueue.o logpkt.o log.o pxyconn.o privsep.o logger.o base64.o nat.o cachedsess.o logbuf.o cachessess.o util.o build.o -lnet -lpcap -lssl -lcrypto -levent_openssl -levent_pthreads -levent -lcheck_pic -lrt -lm -lsubunit
make -C extra/engine
make[1]: Entering directory '/home/pi/sslsplit/src/sslsplit/extra/engine'
cc -shared -fPIC -I/usr/include -L/usr/lib -o dummy-engine.so dummy-engine.c -lcrypto
make[1]: Leaving directory '/home/pi/sslsplit/src/sslsplit/extra/engine'
make -C extra/pki testreqs
make[1]: Entering directory '/home/pi/sslsplit/src/sslsplit/extra/pki'
rm -f rsa.srl
make[1]: Leaving directory '/home/pi/sslsplit/src/sslsplit/extra/pki'
./sslsplit.test
Running suite(s): 
 main
 opts
Cannot resolve address '::1' port '10443': Name or service not known
Cannot resolve address '::1' port '10443': Name or service not known
Cannot resolve address '::1' port '10443': Name or service not known
 dynbuf
 logbuf
 cert
 cachemgr
 cachefkcrt
 cachetgcrt
 cachedsess
 cachessess
 ssl
 sys
 base64
 url
 util
 pxythrmgr
 defaults
97%: Checks: 144, Failures: 0, Errors: 3
opts.t.c:124:E:proxyspec_parse:proxyspec_parse_02:0: (after this point) Early exit with return value 1
opts.t.c:342:E:proxyspec_parse:proxyspec_parse_13:0: (after this point) Early exit with return value 1
opts.t.c:377:E:proxyspec_parse:proxyspec_parse_14:0: (after this point) Early exit with return value 1
make: *** [GNUmakefile:500: test] Error 1

I tried again with make sudotest:

pi@raspberrypi:~/sslsplit/src/sslsplit $ make sudotest 
------------------------------------------------------------------------------
SSLsplit 0.5.5-1-g065f8cf
------------------------------------------------------------------------------
Report bugs at https://github.com/droe/sslsplit/issues/new
Please supply this header for diagnostics when reporting build issues
Before reporting bugs, make sure to try the latest develop branch first:
% git clone -b develop https://github.com/droe/sslsplit.git
------------------------------------------------------------------------------
Via pkg-config: openssl libevent libevent_openssl libevent_pthreads check
LIBPCAP_BASE:   /usr
LIBNET_BASE:    /usr
Build options:  -DHAVE_NETFILTER
Build info:     V:GIT
uname -a:       Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux
------------------------------------------------------------------------------
cc -c -isystem/usr/include -isystem/usr/include -isystem/usr/local/include -D_GNU_SOURCE -D"PKGLABEL=\"SSLsplit\"" -DHAVE_NETFILTER -D"BUILD_PKGNAME=\"sslsplit\"" -D"BUILD_VERSION=\"0.5.5-1-g065f8cf\"" -D"BUILD_DATE=\"2020-04-07\"" -D"BUILD_INFO=\"V:GIT\"" -D"BUILD_FEATURES=\"-DHAVE_NETFILTER\"" -g -pthread -std=c99 -Wall -Wextra -pedantic -D_FORTIFY_SOURCE=2 -fstack-protector-all -pthread -O -o build.o build.c
cc -L/usr/lib -L/usr/lib -L/usr/local/lib -pthread -pthread -o sslsplit.test cachessess.t.o url.t.o cert.t.o cachefkcrt.t.o opts.t.o cachetgcrt.t.o cachemgr.t.o pxythrmgr.t.o defaults.t.o main.t.o base64.t.o sys.t.o dynbuf.t.o logbuf.t.o ssl.t.o cachedsess.t.o util.t.o cachemgr.o url.o cachefkcrt.o opts.o sys.o proc.o build.o pxythrmgr.o cert.o nat.o cache.o dynbuf.o proxy.o logbuf.o ssl.o thrqueue.o logpkt.o log.o pxyconn.o privsep.o logger.o base64.o cachedsess.o cachessess.o util.o cachetgcrt.o -lnet -lpcap -lssl -lcrypto -levent_openssl -levent_pthreads -levent -lcheck_pic -lrt -lm -lsubunit
make -C extra/engine
make[1]: Entering directory '/home/pi/sslsplit/src/sslsplit/extra/engine'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/sslsplit/src/sslsplit/extra/engine'
make -C extra/pki testreqs
make[1]: Entering directory '/home/pi/sslsplit/src/sslsplit/extra/pki'
rm -f rsa.srl
make[1]: Leaving directory '/home/pi/sslsplit/src/sslsplit/extra/pki'
sudo ./sslsplit.test
Running suite(s): 
 main
 opts
Cannot resolve address '::1' port '10443': Name or service not known
Cannot resolve address '::1' port '10443': Name or service not known
Cannot resolve address '::1' port '10443': Name or service not known
 dynbuf
 logbuf
 cert
 cachemgr
 cachefkcrt
 cachetgcrt
 cachedsess
 cachessess
 ssl
 sys
 base64
 url
 util
 pxythrmgr
 defaults
97%: Checks: 144, Failures: 0, Errors: 3
opts.t.c:124:E:proxyspec_parse:proxyspec_parse_02:0: (after this point) Early exit with return value 1
opts.t.c:342:E:proxyspec_parse:proxyspec_parse_13:0: (after this point) Early exit with return value 1
opts.t.c:377:E:proxyspec_parse:proxyspec_parse_14:0: (after this point) Early exit with return value 1
make: *** [GNUmakefile:503: sudotest] Error 1

I think it is not too important!

After installing sslsplit (make install), I ran again with -W/-w option and it failed again:

pi@raspberrypi:~/sslsplit $ sudo sslsplit -D -W masterkeys -l connections.log -j /tmp/sslsplit/ -S logdir/ -k ./cert/ca.key -c ./cert/ca.crt tcp 0.0.0.0 8843
| Warning: -F requires a privileged operation for each connection!
| Warning: -w/-W require a privileged op for each connection!
| Privileged operations require communication between parent and child process
| and will negatively impact latency and performance on each connection.
SSLsplit 0.5.5-1-g065f8cf (built 2020-04-07)
Copyright (c) 2009-2019, Daniel Roethlisberger <daniel@roe.ch>
https://www.roe.ch/SSLsplit
Build info: V:GIT
Features: -DHAVE_NETFILTER
NAT engines: netfilter* tproxy
netfilter: IP_TRANSPARENT IP6T_SO_ORIGINAL_DST
Local process info support: no
compiled against OpenSSL 1.1.1d  10 Sep 2019 (1010104f)
rtlinked against OpenSSL 1.1.1d  10 Sep 2019 (1010104f)
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.8.1
4 CPU cores detected
Segmentation fault

Version is:

pi@raspberrypi:~/sslsplit $ sslsplit -V
SSLsplit 0.5.5-1-g065f8cf (built 2020-04-07)
Copyright (c) 2009-2019, Daniel Roethlisberger <daniel@roe.ch>
https://www.roe.ch/SSLsplit
Build info: V:GIT
Features: -DHAVE_NETFILTER
NAT engines: netfilter* tproxy
netfilter: IP_TRANSPARENT IP6T_SO_ORIGINAL_DST
Local process info support: no
compiled against OpenSSL 1.1.1d  10 Sep 2019 (1010104f)
rtlinked against OpenSSL 1.1.1d  10 Sep 2019 (1010104f)
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.8.1
4 CPU cores detected

Software in Raspberry is:

pi@raspberrypi:~/sslsplit $ uname -a
Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux

With all libraries version matching!

The problem remains!

I will try with Ubuntu 18.04 to see if problem is related to Raspbian or it is the GitHub repo

sonertari commented 4 years ago

I think make test fails on Raspbian because it does not support IPv6, similar to Travis CI (@droe's commit message from 25/03/16):

Fix Travis build by disabling tests using IPv6

TravisCI has removed IPv6 support in 2016. To cope with this regression in the testing infrastructure, disable all tests on Travis that depend on the system being able to handle ::1 as an IP address. Normal unit testing still uses the full test suite.

So if you run make travis instead, the tests will pass on Raspbian. But I have doubts that the segmentation fault you are getting is related with IPv6 issue, because sslsplit runs fine on Travis. And I think you will see that sslsplit runs fine on Ubuntu too.

Can you enable DEBUG_PROXY and perhaps other macros in GNUmakefile, recompile, and run with -D to see if we can learn something from debug logs?

faperea commented 4 years ago

I tried in Ubuntu 18.04 in a virtual machine and have same "segmentation fault". This time make test had no errors. I will try with DEBUG_PROXY and other macros in Ubuntu. By the way, I disabled IPv6 in Raspberry, so it could be the source of make test errors

faperea commented 4 years ago

Compiled in Ubuntu 18.04 VM with this options enabled in GNUMakefile:

### Debugging

# These flags are added to CFLAGS iff building from a git repo.
DEBUG_CFLAGS?=  -g
#DEBUG_CFLAGS+= -Werror

# Define to remove false positives when debugging memory allocation.
# Note that you probably want to build OpenSSL with -DPURIFY too.
#FEATURES+= -DPURIFY

# Define to add proxy state machine debugging; dump state in debug mode.
FEATURES+=  -DDEBUG_PROXY

# Define to add certificate debugging; dump all certificates in debug mode.
FEATURES+=  -DDEBUG_CERTIFICATE

# Define to add SSL session cache debugging; dump all sessions in debug mode.
FEATURES+=  -DDEBUG_SESSION_CACHE

# Define to add debugging of sslsplit's own ClientHello message parser.
FEATURES+=  -DDEBUG_CLIENTHELLO_PARSER

# Define to add thread debugging; dump thread state when choosing a thread.
FEATURES+=  -DDEBUG_THREAD

# Define to add privilege separation server event loop debugging.
FEATURES+=  -DDEBUG_PRIVSEP_SERVER

# Define to add diagnostic output for debugging option parsing.
FEATURES+=  -DDEBUG_OPTS

Output is:

francisco@Casa-VM:~/sslsplit$ sudo sslsplit -D -W masterkeys -l connections.log -j /tmp/sslsplit/ -S logdir/ -k ./cert/ca.key -c ./cert/ca.crt tcp 0.0.0.0 8843
WriteAllCertsDir: certgendir=masterkeys, writeall=1
ConnectLog: /home/francisco/sslsplit/connections.log
Chroot: /tmp/sslsplit
ContentLogDir: /home/francisco/sslsplit/logdir
CAKey: ./cert/ca.key
CACert: ./cert/ca.crt
| Warning: -F requires a privileged operation for each connection!
| Warning: -w/-W require a privileged op for each connection!
| Privileged operations require communication between parent and child process
| and will negatively impact latency and performance on each connection.
SSLsplit 0.5.5-1-g065f8cf-dirty (built 2020-04-07)
Copyright (c) 2009-2019, Daniel Roethlisberger <daniel@roe.ch>
https://www.roe.ch/SSLsplit
Build info: V:GIT
Features: -DDEBUG_CERTIFICATE -DDEBUG_CLIENTHELLO_PARSER -DDEBUG_OPTS -DDEBUG_PRIVSEP_SERVER -DDEBUG_PROXY -DDEBUG_SESSION_CACHE -DDEBUG_THREAD -DHAVE_NETFILTER
NAT engines: netfilter* tproxy
netfilter: IP_TRANSPARENT IP6T_SO_ORIGINAL_DST
Local process info support: no
compiled against OpenSSL 1.1.1  11 Sep 2018 (1010100f)
rtlinked against OpenSSL 1.1.1  11 Sep 2018 (1010100f)
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.8-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.8.1
8 CPU cores detected
Segmentation fault

Output from -V option is:

francisco@Casa-VM:~/sslsplit$ sslsplit -V
SSLsplit 0.5.5-1-g065f8cf-dirty (built 2020-04-07)
Copyright (c) 2009-2019, Daniel Roethlisberger <daniel@roe.ch>
https://www.roe.ch/SSLsplit
Build info: V:GIT
Features: -DDEBUG_CERTIFICATE -DDEBUG_CLIENTHELLO_PARSER -DDEBUG_OPTS -DDEBUG_PRIVSEP_SERVER -DDEBUG_PROXY -DDEBUG_SESSION_CACHE -DDEBUG_THREAD -DHAVE_NETFILTER
NAT engines: netfilter* tproxy
netfilter: IP_TRANSPARENT IP6T_SO_ORIGINAL_DST
Local process info support: no
compiled against OpenSSL 1.1.1  11 Sep 2018 (1010100f)
rtlinked against OpenSSL 1.1.1  11 Sep 2018 (1010100f)
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.8-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.8.1
8 CPU cores detected

The machine is:

francisco@Casa-VM:~/sslsplit$ uname -a
Linux Casa-VM 5.3.0-46-generic #38~18.04.1-Ubuntu SMP Tue Mar 31 04:17:56 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

What function / process does -W / -w option call? This "segmentation fault" is quite "instantaneous", I mean, as soon as I pass this option - even in a configuration file - the program breaks!

sonertari commented 4 years ago

Alright, I have found the issue with your command line, you use -k/-c options with a tcp proxyspec. If you use an ssl proxyspec instead, the issue will go away. (I can reproduce and fix here like that.)

I'll look into why sslsplit segfaults, and perhaps we should check such inconsistent options and warn the user, instead of segfaulting.

faperea commented 4 years ago

Ok. Let me try with -c/-k/-W options and ssl proxyspec

faperea commented 4 years ago

Yes! It worked! I need to test in a "live" system, but Why -c/-k/-W/-w options causes "segmentation fault" with tcp proxyspec? What is the difference?

sonertari commented 4 years ago

-c/-k/-W/-w options are for ssl proxyspecs. Normally we wouldn't expect a user to use them with a configuration with tcp proxyspecs only. So you need at least one ssl proxyspec for those options. You can have other tcp proxyspecs along with ssl proxyspecs too.

But it is certain that there is a bug in sslsplit. It shouldn't crash if a user passes such inconsistent options. We should fix that bug, and I'll be working on a fix asap. However, it is not so urgent, because the workaround is for the user to fix his command line.

Thank you for finding and reporting this bug.