In my previous blog post, I’ve described a rather simple setup that enables an attacker to re-route a victim‘s network traffic using
bettercap and observing clear-text HTTP communication via
mitmproxy. Today’s blog post will describe how this setup can be extended to enable eavesdropping on certain encrypted connections.
Transport Socket Layer
Let’s start off by brushing up our knowledge on the Transport Socket Layer (TLS), which puts the
https. The TLS protocol used in HTTPS provides connection security that has three basic properties:
- The connection is private because data is encrypted using symmetric cryptography
- The connection is reliable, thanks to integrity checks through secure hash functions
- The peer’s identity can be authenticated, via asymmetric or public-key encryption
While data encryption ensures that someone observing the network traffic from the outside can’t make any sense of what is seen, it still allows for a so-called man-in-the-middle (MITM) attack, where the attacker secretly relays the communication between two parties who believe they are directly communicating with each other. Roughly speaking, the attacker “acts” as the server to the client and as a client to the server:
Given just encryption and integrity, the client is not able to tell if the server is really the one the data should be sent to, and the server is not able to tell if it receives the data from a valid client. Both legs (from client to the attacker and from the attacker to the server) would be private and reliable, but the attacker is still able to see all data in the clear.
This problem of trust is solved using the third property of TLS —Authentication— primarily using Digital Certificates in conjunction with a so-called Public-Key Infrastructure (PKI). It’s rather complicated, but for the purpose of this post this will do; there is something called a certificate that is sent to the client and the client can check the validity of that certificate (and therefore the identity of the server).
There are reasons to ignore the validity of the certificate, though. Probably the most common case is using self-signed certificates to avoid the cost and organizational hassle of obtaining a valid certificate from the PKI, e.g. during development and testing. Disabling authentication for a connection can be done easily on iOS or Android, but both —Apple and Google— strongly suggest to never do this in production. So, obviously, no one ever would, right?
In The Wild
During my analysis of the Top-200 Free iOS apps a few months ago I, therefore, tested if apps do proper server certificate validation. I did not expect to find a single app, but boy was I wrong; a whopping 31 apps —15.5% of all apps I checked, or roughly 28 million combined monthly downloads1— did, in fact, ignore the validity of the server certificate.2
Again: All these apps use
https, but we can still perform a MITM attack and therefore eavesdrop on the network traffic!
As a practical example, we will try to eavesdrop on the
https traffic of the popular SHEIN shopping app. Let’s update the setup of the previous post; the
bettercap configuration stays the same because it already re-routed all of the victim‘s network traffic —including
https— through the attacker‘s device. However, we have to add another rule to
iptables to redirect TLS traffic to the transparent proxy running on port
# Route all TCP traffic on port 80 to port 8080 (we did this last week already) sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080 # Route all TCP traffic on port 443 to port 8080 (this is new) sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8080
https traffic is now processed by
mitmproxy, which secures the connection to the client with a self-signed certificate. And while this works fine for the apps we have in mind (i.e. the ones that disable server certificate validation) it’ll fail for apps that authenticate properly — resulting in numerous client-side disconnects.
This can be solved by instructing
mitmproxy to ignore all but the domains we know are vulnerable — for instance, the SHEIN app uses
api-service.shein.com without proper certificate validation:3
mitmproxy --mode transparent \ --ignore-hosts '^(?!api-service\.shein\.com)' \ --ssl-insecure \ --show-host
Now, running the SHEIN app on an iOS device —without having the MITM root certificate installed— will allow us to sniff the credentials, regardless of the usage of
To conclude: Using a similar setup as before —without special hardware, without physical access to neither the victim‘s device nor the network infrastructure, and without any visual indication about an ongoing attack on the victim‘s device— the attacker was able to listen into encrypted
https traffic, due to a lack of certificate validation on the client.
I hope you enjoyed the post, which is the second in a series of three; the previous post was talking about sniffing of unencrypted network traffic and the third post will show how code can be injected over insecure network communication.
Update (07/12/2018): A major new version of
mitmproxy has been released a while back, so I went back and updated the command line and scripts to the new syntax. I’ve also updated the screen capture and vulnerability disclosure section.
Bonus: Vulnerability Disclosure and History
The vulnerability is still present at the time of this writing. I reached out a total of six times and only heard back once.
|09/12/2017||Reached out to SHEIN via Twitter to learn about the disclosure process|
|09/15/2017||SHEIN is asking for my email address — they want to reach out to me|
|09/22/2017||CVE-2017-14710 got assigned to the vulnerability|
|09/22/2017||Sent reminder to SHEIN|
|10/05/2017||Sent yet another reminder, this time to |
|10/10/2017||Sent final reminder to several email addresses I found via Google|
|07/12/2018||Checked the latest version (|
The described vulnerability has been fixed as of version 3.17.0 of the app.
|09/12/2017||Reached out to Shpock to learn about the disclosure process|
|09/12/2017||Sent detailed report to |
|09/20/2017||CVE-2017-14612 got assigned to the vulnerability|
|10/17/2017||Requested status update|
|10/18/2017||Shpock confirms that the vulnerability has been closed|
The described vulnerability has been fixed as of version 9.3.2 of the app.
|09/12/2017||Reached out to Komoot to learn about the disclosure process|
|09/13/2017||Sent detailed report to |
|09/19/2017||Komoot confirms that the vulnerability has been closed|
|09/20/2017||CVE-2017-14709 got assigned to the vulnerability|
Download numbers are estimated using SensorTower. ↩︎
This does not mean that all communication of the app was ignoring the server certificate, but I saw at least some of the network traffic is vulnerable to this problem. ↩︎
The command line includes the
mitmproxyuses an incomplete certificate bundle on some Linux distros. ↩︎