Hi, my name is Philipp C. Heckel and this is my tech blog.

Use SSLsplit to transparently sniff TLS/SSL connections – including non-HTTP(S) protocols


Use SSLsplit to transparently sniff TLS/SSL connections – including non-HTTP(S) protocols

I recently demonstrated how to perform a man-in-the-middle attack on HTTP(S) connections using mitmproxy. While mitmproxy works just great for HTTP-based communication, it does not understand other TLS/SSL-based traffic such as FTPS, SMTP over SSL, IMAP over SSL or any other protocol wrapped in TLS/SSL.

SSLsplit is a generic transparent TLS/SSL proxy for performing man-in-the-middle attacks on all kinds of secure communication protocols. Using SSLsplit, one can intercept and save SSL-based traffic and thereby listen in on any secure connection.


1. How it works

SSLsplit works quite similar to other transparent SSL proxy tools: It acts as a middle man between the client and the actual server. Provided that traffic is being redirected to the server on which SSLsplit is running (by changing the default gateway, ARP spoofing or other means, see below), SSLsplit picks up SSL connections and pretends to be the server the client is connecting to. To do so, it dynamically generates a certificate and signs it with a the private key of a CA certificate that the client must trust.

If, for example, a client wants to send an e-mail using the secure Gmail SMTP server (smtp.gmail.com on port 465), SSLsplit creates a certificate for “smtp.gmail.com” and thereby pretends to be the Gmail mail server towards the client. In the upstream direction (towards the actual Gmail mail server), SSLsplit connects to the server just like a normal client — forwarding all the traffic the actual client writes on the SSL socket.

If you are interested in a little more details, please check out the “How it works” section of the post about HTTPS interception with mitmproxy. The basic concept is the same, so it should be relatively easy to understand.

2. Install & run SSLsplit

After explaining the basic concept of how SSLsplit works, this section will describe how to actually use it to intercept SSL (and non-SSL) traffic.

2.1. Redirect traffic

This tutorial assumes that you have already placed your attacker system somewhere in between the victim machine and the server. This can be done in many different ways — here are some examples:

  • Use ARP spoofing to redirect the traffic of the victim by publishing false mappings from the standard gateway MAC address to the attacker’s IP address. You do not need physical access to the victim’s device to do that. Check out the arpspoof tool.
  • Change the default gateway address in the victim’s network settings. This is the easiest method if you have access to the victim’s device.
  • Forging DNS entries with a DNS server that returns the attacker’s IP address for certain (or all) domains. See my tutorial about DNS spoofing with Dnsmasq to learn how to do that.
  • Redirect traffic for individual domains by modifying entries in the /etc/hosts file of the victim’s machine.

As mentioned above, the easiest way is to just change the default gateway address in your victim’s device to the attacker’s IP address. That makes sure that all the traffic goes through your machine. And since we later need to install a CA certificate, we need physical access to the victim’s machine anyway.

2.2. Installation

As of now, there is no Debian package in the repositories for SSLsplit. The code is hosted on different mirrors, managed by the author Daniel Roethlisberger, as well as on Github.

To download and compile SSLsplit, run the following commands:

These commands download and extract the source code (wget, bunzip2, tar), install necessary dependencies (apt-get), and then compile it using make.

The temporary directory created at /tmp/sslsplit is later used to dump the connection log file and the raw data of the incoming and outgoing SSL sockets.

2.3. Create and install root CA certificate

For SSLsplit to act as a middle man for SSL connections, it needs to be able to generate and sign certificates that the victim trusts. In order to do so, the victim must have the attacker’s root CA certificate in its trust store. Depending on the type of client (desktop browser, mobile phone), installing root certificates differs a bit (see here for Firefox, Windows, Android, …)

If you don’t already have a self-signed CA private key and certificate, you can generate one using the following commands:

The first command generates an 4096-bit RSA private key in PEM format (ca.key), and the second command uses this private key to generate a self-signed root CA certificate (ca.crt). Both are needed by SSLsplit later, but only the certificate file needs to be installed in the browser or operating system of the victim.

2.4. Enable IP forwarding and NAT engine (iptables)

In this example, SSLsplit will be running on two ports: 8080 for non-SSL TCP connections such as HTTP, SMTP or FTP, and 8443 for SSL connections such as SMTP over SSL, HTTPS, etc. In order to forward packets arriving at the attacker’s machine to these internal ports, the NAT engine in iptables can be used.

The commands above first enable IP forwarding (sysctl ...) to enable the system’s router functionality. After running this command, Linux will forward IP packets not meant for the local machine to its standard/default gateway, thereby acting as a router.

To prevent Linux from forwarding everything right away, NAT rules can be defined. In this example, certain packets are redirected to the local port 8080 and 8443. Packets for the plain text traffic on ports HTTP (80) and WhatsApp (5222) are redirected to port 8080, and packets for SSL-based traffic on ports HTTPS (443), IMAP over SSL (993), SMTP over SSL (465 and 587) are redirected to port 8443.

2.5. Run SSLsplit

Once the IP forwarding is active and packets are being forwarded to the relevant ports, you can start SSLsplit. That sounds easier than it actually is, because SSLsplit is a very powerful tool and therefore very flexible. Check out the short documentation on the SSLsplit website, as well as the more verbose SSLsplit man page.

For the use case described above, a sensible parameter configuration would be something like this:

This command starts SSLsplit in debug mode (-D, runs in foreground, no daemon, verbose output) and outputs connection attempts in the log file “connections.log” (-l ..). The actual content of the connections is written to the “/tmp/sslsplit/logdir/” (-j .. and -S ..) — each incoming/outgoing TCP stream of each connection in a separate file.

This is it. Assuming you have configured your clients correctly, you can now start browsing and send/receive e-mails. SSLsplit will output connection details on the console:

In addition to the console output, SSLsplit will write the TCP socket conversations to the above mentioned log directories. After running SSLsplit for a while, there will be quite a few files in the log directory — one for each connection or TCP socket between client and server:

Each file indicates the exact time the TCP socket was opened as well as the source and destination IP address and port. You can take a peek in the file using head ..., or use your favorite text editor:

3. Examples

You can listen into many different protocols using SSLsplit. Below are a few examples for HTTPS, IMAP over SSL and SMTP over SSL.

3.1. Sniffing HTTPS (google.de & facebook.com)

Once the SSLsplit is running, all communication between the client and the actual servers goes through SSLsplit. Using the -D option, SSLsplit prints connections and certificate forgeries on STDOUT. In addition to that, the content is written to the logdir (“/tmp/sslsplit/logdir/”). Using something like tail -f /tmp/sslsplit/loggdir/20130804T162301Z-*.log, you can follow the communication between server and client.

In the screenshot above, the upper console window shows the output of SSLsplit. It shows the real upstream Facebook certificate (with the fingerprint f5:6b:f2:44:...), and the forged certificate by SSLsplit — naturally with a different fingerprint, because it was signed by a different certificate authority.

The lower console window shows the content of the HTTPS communication between the browser and the Facebook server. The example screenshot shows the HTTPS POST request to “https://www.facebook.com/login.php?login_attempt=1″, including my username (&email=...) and the password (&pass=...).

If one were to click on the little lock icon on any SSL/TLS encrypted site whilst redirecting traffic through SSLsplit, the certificate would be issued to the real common name (CN), organization (O) and organizational unit (OU), but not issued by the real CA.

The example above shows the fake certificate for “www.google.de”, issued by my previously generated “Fake CA Certificate”.

Note:: If you’re interested in sniffing into HTTPS only (not: SMTP over SSL, IMAP over SSL, or any other non-HTTPS traffic), be sure to check out mitmproxy and my mitmproxy tutorial. It is much more convenient to use than SSLsplit.

3.2. Sniffing IMAP over SSL (imap.gmail.com)

In the second example I used Thunderbird to connect to my Gmail account. Unlike a web based mail client, Thunderbird connects to the Google/Gmail server via IMAP on port 143 or via IMAP over SSL on port 993. While the communication on port 143 is unencrypted and can be read with other tools (Wireshark, tcpdump, etc.), IMAP over SSL requires a man-in-the-middle proxy to split the SSL communication.

The screenshot above captures the initial connection of Thunderbird to the Gmail IMAP server (normally imap.gmail.com, here: imap.googlemail.com) on port 993. Like in the first example, the upper console shows the SSLsplit debug output (showing how SSLsplit forged the certificate), and the lower console shows the bytes exchanged over the SSL socket.

As you can see in the screenshot, the IMAP communication includes an exchange of client and server capabilities (1 capability) with a little inside joke from the developers of the server (1 OK That's all she wrote ...), as well as the authentication (3 login "e-mail@gmail.com" "password"). The latter part is probably most interesting to attackers.

After the authentication, client and server both agree to continue the conversation using compression (4 COMPRESS DEFLATE), so the rest of the message is naturally not human readable anymore. However, since it’s only compressed and not encrypted, it can be made readable using simple Linux tools.

3.3. Sniffing SMTP over SSL (smtp.gmail.com)

As you might have guessed by now, this method also works for SMTP over SSL: In this example, I used Thunderbird to send an e-mail to myself using the Gmail SMTP server on port 465.

Like in the two other examples, the screenshot shows the SSLsplit output in the upper console window and the conversation output in the bottom console. The SMTP conversation shows a humorous greeting of the Gmail server (250-mx.google.com at your service ...), as well as the initial login of the Thunderbird client using SMTP AUTH (AUTH PLAIN ...). It then starts drafting the mail using standard SMTP commands (MAIL FROM, RCPT TO, …).

Again, the most interesting part is the plain text authentication: Since the transport is secure, the password is sent in plain text — only encoded using Base64. So if the line above was something like AUTH PLAIN Qml0ZSBtZSBpZiB5b3UgY2FuISEhISEhIQo=, it could be easily decoded with the one-liner:

echo 'Qml0ZSBtZSBpZiB5b3UgY2FuISEhISEhIQo=' | base64 --decode.
I’ll leave it to you to decode this :-).


  1. Anonymous

    Dear Philipp,

    First of all thank you very much for the nice and detailed tutorial on sslsplit usage. I am trying to show my management that having WI-FI in corporate network without changing a short password for years is not secure and that is very possible to sniff the whole internet traffic by someone else.

    All works great, but I have problems with gmail. sslstrip is not working in modern browsers, seems to be because of HSTS. sslsniff is not working either, all my browsers always ask to confirm certificates and that never ends. permanent connection timeouts with ettercap, etc, etc.

    I am sorry for bothering you with this, but do you have a working workaround for intercepting gmail today?

    Thank you!

  2. Philipp C. Heckel


    You must import your generated root CA in your browser’s or operating system’s trust store. If you do that, your browser should not complain about the certificate because it was signed by a trusted CA. Without importing this CA, there is no chance deliver a certificate that the browser does not complain about.

    I hope that answers your questions.

    Best regards

  3. Benidiktus

    Hi Philipp,

    Nice to read your blog. I’m interesting to sniffing and of course how to prevent myself to be sniffed. I use an old tool for windows the name is Chain and Abel i think you know that tools. This tool is complete to HTTP, SSL and other protocol.

    From my experiments the important think to success sniff HTTP and SSL is accept CA. I found some vulnerability in email application on android. Setting option to accept all certificate can make all inbox can be read i have done this with gmail and work perfectly. I try to sniff outlook.com but i can’t get to read the message. I found a big problem in outlook.com when my email client setting is check for accept all certificate it can capture my username and password perfectly. I try to uncheck that option and email client can not connect to server and get my account.

  4. Schawen

    Hello Philipp,
    first of all … – thank you for your very interesting blogs!
    I installed sslsplit on
    Linux raspberrypi 3.6.11+ #538 PREEMPT armv6l GNU/Linux
    following your description but getting following error on execution:

    Event base supports: edge yes, O(1) yes, anyfd no
    Inserted events:
    0xf53238 [fd 7] Read Persist
    0xf532a4 [fd 8] Read Persist
    0xf54224 [fd 9] Read Persist
    0xf53128 [fd 6] Read Persist
    0xf52558 [fd 3] Signal Persist
    0xf51738 [fd 1] Signal Persist
    0xf54600 [fd 2] Signal Persist
    0xf562c0 [fd 13] Signal Persist
    Failed to start thread manager
    *** glibc detected *** ./sslsplit: double free or corruption (fasttop): 0x00f530e0 ***

    Any idea?

    Grüße von der Alb

  5. Philipp C. Heckel

    Hello Sven,

    this is probably an issue with the Raspberry Pi, but I cannot say for sure. I am not the developer of SSLsplit, so I know very little about its inner workings — except maybe for the general concepts of SSL interception. You can contact the author of the tool here: http://www.roe.ch/SSLsplit

    Grüße in die Alb :-)

  6. Timo

    Nice tutorial. How do I set up my android phone for this to work? I have already installed the certificate. Do I have to change the gateaway settings and to what exactly? Im normally working with Fiddler or Charles but this time I want to dig a little deeper

  7. Jackie

    is there any way to use this for a captive portal situation? I know browsers will complain about the certificate. I can simply use iptables to redirect non ssl to my landing page, but just wondering if its possible to use this to catch ssl site and send them to my landing page? or is it just a 1:1 proxy ?

  8. John Van Dijk

    Dear Philipp, great Tutorial!!
    I got this running on Ubuntu in the first attempt, but before that I spent hours trying to get SSLSplit running on OSX 10.9 (Mavericks) and OSX 10.8.5, eventually I had to give up. The SSLSplit website says that it supports ipfw fwd but I read somewhere that ipfw has been deprecated and dropped in the latest OSX releases and instead we have to use pf and something like ‘rdr pass on lo0 inet proto tcp from any to port 80 -> port 40070′ in the pf.conf file to forward traffic on OSX. Is this true? Or does ipfw still work? Also if it doesn’t, will SSLSplit work if I use pf? I could not get it to work either ways, could you help me out?

  9. Philipp C. Heckel

    Hello John,

    I’m really sorry but unfortunately I cannot help you here. PLease contact the author of the software, Daniel Roethlisberger.


  10. John Van Dijk

    Thanks for the reply Philipp. I’m looking forward to a solution from Daniel and would let you know so that you can update this wonderful tutorial. :)

  11. Tamara

    Hello Phillip,

    Can you show a network diagram for your setup. I tried all the steps but I am getting the following error
    “Error from bufferevent: 111″ It seems to me that my network configs are wrong.


  12. James

    Any hits on gunzipping some of the content that’s saved in the individual files?

  13. Pankaj

    Good Day, Phillip!
    Thanks a lot for this very informative post. I had a question regarding the plain text encryption for the passwords used for SMTP over SSL. Is this a industry standard? If you can decode so easily, can any real intruder not capture the password for next to nothing by following the steps here? How can we make the password more secure?

  14. Simo

    No need for bunzip2, tar supports that.
    tar -jxvf sslsplit-0.4.7.tar.bz2

  15. Philipp C. Heckel

    I haven’t tested it in a while, but if FF verifies the certificates differently, e.g. by remembering the fingerprint or something like that, it might not work anymore.

  16. Bolle

    Hello Phillip,
    Thanks for the great tutorial!
    I followed all the steps exactly the same, excepted that I used the new SSLSplit version (0.4.8)

    I started the Software even with the same parameters like you did.
    But it shows me just the established connections and the ports. I tested Facebook and Whatapp. The logdir-files were written but the content is encrypted.
    So the part where SSLSplit displays the original Certificate and the steps after that do not work, I think..
    I tested it with an iPhone (Safari Browser) Where could be the problem?

    Best regards

  17. Dominik

    Hello Phillip,
    Thank you for the great tutorial.
    I went trough it steo by step, just like you did.
    When I start SslStrip it even shows me the connections and logs it.
    But the part that starts with:
    ===> Original server certificate (…)
    doesn’t work. The content of the log is encrypted.

    Where could be the reason?
    My victim was an iPhone 4s

    Thanks a lot!

  18. Abhishek

    Hi Philipp,

    I was wondering that if we purchase singed certificate from trusted companies like verisign etc. And use that certificate in MITM attack. Will browser still complain about certificate error or not?

  19. Tyndyll

    Hi Philipp

    Can you suggest where I am going wrong in my setup? I can make the connection correctly, it is intercepted by sslsplit, but it seems like it is trying to redirect to localhost

    OSX Client:

    ~ curl -k -vvv https://facebook.com
    * About to connect() to facebook.com port 443 (#0)
    * Trying…
    * Connected to facebook.com ( port 443 (#0)
    * Server aborted the SSL handshake
    * Closing connection 0
    curl: (35) Server aborted the SSL handshake

    Starting main event loop.
    SNI peek: [n/a] [complete]
    Connecting to []:443
    Error from bufferevent: 111:Connection refused 0:0:-:0:-:0:-
    SSL_free() in state 00001211 = SSL_ST_CONNECT|0211 = UNKWN (unknown state) [connect socket]

    $ sysctl net.ipv4.ip_forward
    net.ipv4.ip_forward = 1

    Any help appreciated!

  20. Tyndyll

    If it makes any difference I’m running the server on Ubuntu 14.04 and I’m redirecting the client to the server by setting the IP address of the server in /etc/hosts

  21. Tyndyll

    Can you confirm that I don’t need anything set up on my server to handle the SSL connection other than sslsplit, and it should automatically forward the request on?

  22. Tyndyll

    Yep – have that set. The connection is being forwarded to sslsplit correctly – I think the problem is when sslsplit is trying to forward it on. It seems like it is treating itself as the endpoint and it tries to connect to the same server sslsplit is on on port 443

  23. napo

    Hi is there any way I can capture the full unencrypted packets.

  24. b45ic

    Very good tutorial!!!!
    But when i connect to the proxy on port 8080 with an iPhone app, i always get the following error (on Kali):

    Error 24 on listener: Too many open files
    Main event loop stopped.
    Error from bufferevent: 104:Connection reset by peer 0:0:-:0:-:0:-
    Segmentation fault

    Could you help me???

  25. Vijay

    Hi Philipp,

    Can you suggest tools which can work as a MITM to alter IMAP server responses for fuzzing thick email client like thunderbird.


  26. Andrey

    Philipp, many thanks for great tutorial.
    I try to verify what 3rd party android application sends to the server, I followed everything you’ve described in the article, but what I get in result in the log is still encrypted and android app says that it is failed to establish SSL connection. Does it mean that my generated certificates are not accepted by application/server? Does it mean that the only way to verify what is sent is to extract original certificates from the app?

  27. noiala

    Nice detailed tutorial! Sadly I’m getting this error after I setup NAT on iptables
    Before that I was trying to fix a NAT error, which wasn’t working (lack of forwarding I guess)

    Error 24 on listener: Too many open files
    Main event loop stopped.
    Error from bufferevent: 104:Connection reset by peer 0:0:-:0:-:0:-
    Segmentation fault (core dumped)

    Any clues ?

  28. v457

    Dear Phillip, thanks for your tuto… it was helpfull …
    Please tell me what’s the reason of :
    1st: Failed to start thread manager
    2nd: Erreur de segmentation

  29. Mohamed

    Hello, I followed all steps in this tuto, but I don’t have the directory /tmp/sslsplit/logdir.
    I get this result:
    momo@momo-K55VM:~/sslsplit-0.4.7$ sudo ./sslsplit -D -l connections.log -j /tmp/sslsplit/ -S logdir/ -k ca.key -c ca.crt ssl 8443 tcp 8080
    Generated RSA key for leaf certs.
    SSLsplit 0.4.7 (built 2014-12-05)
    Copyright (c) 2009-2013, Daniel Roethlisberger
    NAT engines: netfilter* tproxy
    compiled against OpenSSL 1.0.1e 11 Feb 2013 (1000105f)
    rtlinked against OpenSSL 1.0.1e 11 Feb 2013 (1000105f)
    TLS Server Name Indication (SNI) supported
    OpenSSL is thread-safe with THREADID
    Using direct access workaround when loading certs
    SSL/TLS algorithm availability: RSA DSA ECDSA DH ECDH EC
    compiled against libevent 2.0.21-stable
    rtlinked against libevent 2.0.21-stable
    8 CPU cores detected
    – []:8080 tcp plain netfilter
    – []:8443 ssl plain netfilter
    Loaded CA: ‘/C=FR/ST=PACA/L=Nice/O=Momo/emailAddress=m.abdeljelil@outlook.com’
    Using libevent backend ‘epoll’
    Event base supports: edge yes, O(1) yes, anyfd no
    Inserted events:
    0x14bdad0 [fd 7] Read Persist
    0x14be440 [fd 8] Read Persist
    0x14bcc40 [fd 9] Read Persist
    0x14bd908 [fd 6] Read Persist
    0x14be840 [fd 3] Signal Persist
    0x14c0ae0 [fd 1] Signal Persist
    0x14c0c10 [fd 2] Signal Persist
    0x14c0d80 [fd 13] Signal Persist
    Started 16 connection handling threads
    Starting main event loop.
    Garbage collecting caches started.
    Garbage collecting caches done.
    Garbage collecting caches started.
    Garbage collecting caches done.
    Garbage collecting caches started.
    Garbage collecting caches done.
    Garbage collecting caches started.
    Garbage collecting caches done.

    So I can’t explore the request… Can you help me please?

    Thank you for your time.

  30. Devil_D

    Sorry , Mr. Philipp C. Heckel
    but there is an little error in the guide to the point
    mkdir /tmp/sslsplit
    in this way i tink is good
    cd /temp
    mkdir sslsplit && cd sslsplit && mkdir logdir
    sslsplit -D -l connections.log -j /tmp/sslsplit/ -S logdir -k ca.key -c /root/ca.cer ssl 8443 tcp 8080
    correct is:
    sslsplit -D -l connections.log -j /tmp/sslsplit/ -S logdir -k ca.key -c ca.crt ssl 8443 tcp 8080
    only small typos :) however, I wanted to compliment a good job is a brilliant idea and thank you for your very detailed guides
    in kali works great as a system and a great alternative to OpenSSL Heartbleed attack
    thanks sorry for my english

  31. sorcier

    Hi Philip,
    I have a same problem with Mohamed :
    0x84e35e8 [fd 2] Signal Persist
    0x84e36c8 [fd 13] Signal Persist
    Initialized 2 connection handling threads
    Started 2 connection handling threads
    Starting main event loop.
    Garbage collecting caches started.
    Garbage collecting caches done.
    Garbage collecting caches started.

    Can you help us,
    Thx for your help

  32. Raphaël

    Hi All,

    I had also the error “Error from bufferevent: 111:Connection refused” when I tried to redirect only in the host file. My solution was to use the “default gateway” redirection rather than the host file.

    It’s really a great tool. It could help me to solve some trouble at work :)

Leave a comment

I'd very much like to hear what you think of this post. Feel free to leave a comment. I usually respond within a day or two, sometimes even faster. I will not share or publish your e-mail address anywhere.