July 30, 2024
Episode 8
Spoofing Mint Browser
Examining Vulnerabilities in Android Applications
Author: Hahna Kane Latonick
Introduction
Welcome to Part 2 of our Android Security Research Playbook (ASRP) blog series. In Part 1, we introduced the ASRP and the importance of first conducting reconnaissance of your target Android application (“app”). We specifically covered using Open-Source Intelligence (OSINT) to gather as much information as possible about the target application, so that we understand how the application works and what vulnerabilities have been publicly reported. In this post, we are going to describe the second stage of the ASRP where we will be performing static analysis of a vulnerable Android application.
What is Static Analysis?
Static analysis involves examining the source or binary code of a program without executing it. This allows us to gain greater insight into the design and implementation of the program, and what potential security vulnerabilities may exist due to design issues or implementation errors. We will walkthrough the following ASRP plays to illustrate steps of the Static Analysis process:
Play 05: Understand the APK’s Design and Compiler: APKiD
Play 06: Decompress and Decode the APK: Apktool
Play 07: Decompile the APK: JADX
Play 08: Examine the APK File Structure: Android Studio
Introducing our Target
We will be examining the target application, Mint Browser, which is a web browser for Android phones and developed by Xiaomi Inc. Some of its key features include ad blocking, incognito mode for privacy, video downloading, and being lightweight. Using the Static Analysis Plays of the ASRP, we’re going to investigate a URL spoofing vulnerability in Mint Browser version 1.6.1, which was reported as CVE-2019-10875 and later patched in version 1.6.3.
Diving Into the ASRP
The Static Analysis process that we are going to cover includes understanding the design and compiler of the Android Package Kit (APK), decompressing and decompiling the APK, examining the APK file structure, and identifying the URL spoofing vulnerability in the software.
Play 05: Understand the APK’s Design and Compiler: APKiD
APKiD is like PEiD, but for APK files, outputting what compilers, packers, obfuscators, and security mechanisms are used by the APK. This play illuminates APK design elements and potential issues that may need to be addressed throughout the security research process. When we run APKiD against the Mint Browser v1.6.1 APK, its output reveals that the application consists of anti-debugging and anti-virtual machine (VM) checks that may prevent dynamic analysis and virtualization of the software. It was compiled with R8, a modern code shrinker and optimizer developed by Google that is highly efficient at reducing app size, improving performance, and obfuscating code to some extent. However, APKiD didn't find the typical markers it expects to see for the R8 compiler and annotated the result as suspicious. It’s also worth noting that the output of APKiD did not indicate the APK’s use of other obfuscators and packers which can prevent or hinder the static analysis process, including reverse engineering.
Play 06: Decompress and Decode the APK: Apktool
Apktool lets you quickly familiarize yourself with the general structure of an APK file. Android applications are usually compressed into an APK, so we will decompress it to review its files. Apktool starts by loading the APK's resource table, which contains information about the app's layout files, images, strings, and other assets. It decodes the AndroidManifest.xml file, which defines the app's structure, permissions, components, and more. The APK consists of two classes.dex files, which contain the compiled Java code of the app in the Dalvik Executable (DEX) format. DEX is a type of bytecode specifically designed for the Dalvik Virtual Machine (DVM), which used to be the runtime environment for Android apps (up to Android 4.4 KitKat). Even though Android now primarily uses the Android Runtime (ART) instead of DVM, the DEX format is still used. Apktool uses a process called "baksmaling" to convert this bytecode into a more human-readable Smali representation. Smali is an assembly-like language that is easier to analyze than raw bytecode. Apktool then copies the APK’s assets, native libraries, unknown files, and original files to its output directory.
We can directly examine the files outputted by Apktool, such as viewing the Smali files in an editor of your choice or the native libraries in Ghidra; however, we recommend proceeding with decompiling the APK to get a high-level overview and understanding of the app’s overall logic, classes, methods, and flow before delving too deep into the low-level details.
Play 07: Decompile the APK: JADX
When we decompile the Mint Browser APK using JADX, a Dex-to-Java decompiler that comes equipped with automatic decoding and deobfuscation features, we can view the decoded AndroidManifest.xml file and the generated Java code that aims to be similar to the original source code that the developer might have written for the Android application. The AndroidManifest.xml reveals that the APK utilizes 35 permissions and consists of 18 Activities, 9 Services, 6 Receivers, and 8 Providers, many of which are exported and can be launched by other apps on the device.
The URL spoofing vulnerability described by CVE-2019-10875 exists in the MIUI native browser package, specifically within the NavigationBar class of the omnibox component, which provides the combined address and search bar functionality commonly found in modern web browsers. The vulnerable method within the NavigationBar class is pickSearchKeywords().
Navigating to the class and method in JADX, we can view its decompiled Java code (top), which is much easier to read and interpret than its Smali representation (bottom).
In summary, the method retrieves the URL from the current tab, parses it, and extracts the host (e.g., "www.google.com" from https://www.google.com/?q=www.example.com). It iterates through a list of predefined search engine domain names and if the host contains a known search engine label, it then retrieves the corresponding query parameter name for that search engine. Using the identified query parameter name (or defaulting to "q", "p" for Yahoo, or "text" for Yandex), it extracts the value of that parameter from the URL. For example, if the queryParameter is "q", it will look for ?q=www.example.com in the URL and return www.example.com, which is then displayed in the URL address bar.
The Vulnerability
An attacker can manipulate the browser’s behavior by controlling the query parameter that pickSearchKeyWords() returns regardless of whether a known search engine label was matched in the host. This allows an attacker to perform URL spoofing, which is commonly used for phishing campaigns, malware distribution, and traffic redirection. The browser displays the spoofed part of the URL in the omnibox but the page rendered by the browser is actually the host domain from the full URL, making the user believe they are on a different website or interacting with a different search query than they actually are.
For example, let’s say we have the URL: https://www.websiteA.com/?q=www.websiteB.com. The domain www.websiteA.com can pretend to be www.websiteB.com due to how Mint Browser mishandles the query parameter 'q' of the URL. This vulnerability was patched in Mint Browser version 1.6.3. Let’s decompile the v1.6.3 APK and perform patch analysis in Android Studio.
Play 08: Examine the APK File Structure: Android Studio
After decompiling the v1.6.1 and v.1.6.3 APKs in JADX, we can save the decompiled source code to their own directory on the file system and then further examine them in Android Studio, an IDE created by Google for Android application development. This allows us to utilize more advanced features, such as comparing files for diff analysis and patch analysis. Upon comparing the two versions of NavigationBar.java, Android Studio illuminates the changes that were made to the pickSearchKeyWords() method in v1.6.3.
Patch Analysis
The key element of this patch is the return statement on Line 515:
Let's break down why this seemingly minor change makes all the difference:
The added i != 0 check acts as a safeguard.
The variable i is now used as a flag. It's set to 1 only if a known search engine label is found in the host.
This means that if i is 0 (no known search engine label matched), the method will not blindly use the potentially manipulated string to extract the queryParameter. It will instead return queryParameter which would be null - preventing the potential for URL spoofing in this scenario.
Conclusion
Additional static analysis can be performed on the target application, such as using the Mobile Security Framework (MobSF) to further analyze the APK for hard coded secrets, shared object analysis, and more. We can reverse engineer its native libraries in Ghidra and perform similar diff analysis at the binary level. It is also important to incorporate dynamic analysis as it can help validate your static analysis findings. We will further explore dynamic analysis in the next installment of our blog series. In the meantime, remember to check out the ASRP for additional information and resources to enhance your Android security research!