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:

  1. Example app: In app/ you will find the full AndroidStudio project for the example app that showcases
    different TLS checking implementations.
  2. 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:

  1. WebView ignores all SSL errors:
    See setupInsecureWebView()
  2. Malfunctioning X509TrustManager Implementations:
    See setupInsecureTrustManager()
  3. 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:

  1. 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 password
    pass. Then you should see the emulator screen, with which you can interact using your mouse.
  2. In the meantime, the example app is compiled and once the emulator is fully booted up it is installed
    and launched automatically.
  3. 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.
  4. 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.

GitHub

View Github