Containerized Demo for Insecure TLS Certificate Checking in Android
Overview
This repository contains the files you need to run the demos for our blog post on insecure TLS certificate checking in Android apps. There are two parts to the repo:
- Example app: In app/ you will find the full AndroidStudio project for the example app that showcases different TLS checking implementations.
- Docker setup: By running setup.sh you prepare a Docker environment consisting of several containers: An Android emulator is spawned and a web frontend to interact with it is made available on https://localhost (Note that this frontend uses a self-signed certificate). Additionally, an example web server container is created, which will be used as the backend for the demo scenarios. The last part of the setup is an attacker container, through which you will be able to interactively intercept web traffic between backend server and Android emulator.
Scenario Overview
The backend serves a simple HTML website over HTTPs. This mimicks the situation where sensitive data is provided over a secure connection. The catch is that the certificate it uses (see backend/nginx-certs/) has not been issued by a globally trusted CA but rather by a custom one.
The Android app in app/ fetches the data provided by this server and displays it to the user. In order to make Android accept the custom certificate, the default certificate checking mechanism needs to be modified. To showcase different insecure ways of doing so, the app consists of several tabs, where each fetches the data using a different workaround commonly found online. You can check out the corresponding source code in WebViewFragment.kt.
In the blog post we cover three different types of implementation errors:
- WebView ignores all SSL errors: See setupInsecureWebView()
- Malfunctioning X509TrustManager Implementations: See setupInsecureTrustManager()
- Disabled Host Name Checks: See setupInsecureHostnameVerifier()
This app will be installed to a containerized Android emulator that lives in the same virtual network as the backend server and the attacker. Setting this network up is explained in the next section.
Prerequisites
In order to launch the demo environment, you will need to have docker-compose installed, as well as Python3, NodeJS and npm. Also make sure to have the Android SDK installed (SDK platform version 31). The ANDROID_SDK_ROOT
environment variable needs to point to its installation directory, usually ~/Android/Sdk
. All other necessary dependencies will be downloaded automatically.
Docker Setup
Running setup.sh will get the necessary files to set up the Docker containers, which may take a while, depending on your system performance and Internet speed. Afterwards you can launch the containers with run.sh. This script takes care of several things:
- The Android emulator will be booted and a web interface to interact with it is made available on https://localhost (Note that the website uses a self-signed certificate). Login with username
user
and passwordpass
. Then you should see the emulator screen, with which you can interact using your mouse. - In the meantime, the example app is compiled and once the emulator is fully booted up it is installed and launched automatically.
- Once the app is running, a bash shell is opened on the attacker container so that you can interactively experiment with the man-in-the-middle setup. As a quick start, you can simply execute the start.sh script that you will find in the current working directory where the shell was spawned (
/eve_files
on the container). This script sets up the attacker proxy using the mitmproxy tool without needing any user input. You can then observe intercepted traffic in the console that will show up. To exit the console and stop the attack, simply press Ctrl+C and confirm. Should you want to deviate from the default attacker script, feel free to inspect start.sh and the associated proxy.py file. - After you are done exploring the demos, simply exit the attacker shell as usual (Ctrl+D or typing
exit
). This will automatically shut down the containers in a clean way.