Android Software Reverse Engineering & Decompilation

Intent Filter Hacking: Unmasking Hidden Vulnerabilities in AndroidManifest.xml

Google AdSense Native Placement - Horizontal Top-Post banner

Introduction: The AndroidManifest.xml – A Blueprint for Vulnerabilities

The AndroidManifest.xml file is the cornerstone of every Android application, serving as its essential blueprint. It declares the app’s components (activities, services, broadcast receivers, content providers), required permissions, hardware features, and more. Crucially, it’s also where intent filters are defined – mechanisms that declare a component’s ability to respond to specific types of intents. While fundamental for inter-component communication and app functionality, misconfigurations within intent filters, particularly concerning the android:exported attribute, are a common source of critical security vulnerabilities. This article dives deep into analyzing AndroidManifest.xml for such misconfigurations, demonstrating how intent filter hacking can lead to data theft, denial of service, and even privilege escalation.

Understanding Intent Filters and the ‘exported’ Attribute

An intent filter essentially tells the Android system what types of intents a particular component can receive. It specifies actions (e.g., android.intent.action.VIEW), categories (e.g., android.intent.category.BROWSABLE), and data schemes/types (e.g., http://, content://) that the component is capable of handling.

The security implications largely revolve around the android:exported attribute. This boolean flag indicates whether a component can be launched by components from other applications. Its default value depends on the component type and whether it declares intent filters:

  • For an activity, service, or broadcast receiver with no intent filters: android:exported is false by default.
  • For an activity, service, or broadcast receiver with at least one intent filter: android:exported is true by default.
  • For a content provider: android:exported is true by default, unless android:grantUriPermissions is true, then it’s false.

The default true when an intent filter is present is a common pitfall. If an exported component doesn’t adequately validate the caller or the incoming intent, it becomes a prime target for malicious applications.

Tools for Manifest Analysis

To unmask these vulnerabilities, we need to inspect the AndroidManifest.xml of target applications. Here are essential tools:

  • aapt (Android Asset Packaging Tool): Provides a quick summary.
  • apktool: Decompiles APKs into Smali code and recreates resources, including a human-readable AndroidManifest.xml.
  • grep: For searching specific patterns within the manifest file.

Analyzing with aapt

For a quick overview of exported components, aapt dump badging is useful:

aapt dump badging <path_to_apk> | grep "launchable-activity|activity|service|receiver"

This command can reveal directly launchable activities and often indicates which components are exported. However, for deep analysis, full decompilation is preferred.

Detailed Analysis with apktool

apktool provides the full manifest, allowing us to inspect every attribute.

Step 1: Decompile the APK

apktool d <path_to_apk> -o <output_directory>

This will create a directory containing the decompiled resources, including AndroidManifest.xml.

Step 2: Inspect the Manifest

cat <output_directory>/AndroidManifest.xml | less

Now, we can search for specific patterns. Key search terms include:

  • android:exported="true"
  • Components with <intent-filter> tags (implying exported="true" by default if not explicitly set to false).
  • <permission> declarations and usage.

Common Vulnerability Scenarios and Exploitation

Scenario 1: Exposed Activity Leading to Local File Disclosure

Consider an application that features a simple WebViewerActivity intended to display internal help documents or web content. If this activity is exported and doesn’t properly validate incoming intents, it can be exploited to read arbitrary local files.

Vulnerable AndroidManifest.xml Snippet:

<activity android:name=".WebViewerActivity" android:exported="true">    <intent-filter>        <action android:name="com.example.vulnerableapp.VIEW_CONTENT" />        <category android:name="android.intent.category.DEFAULT" />        <data android:scheme="http" />        <data android:scheme="https" / />    </intent-filter></activity>

Vulnerable Java Code Snippet (from WebViewerActivity.java):

protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_webview_viewer);    WebView webView = findViewById(R.id.webView);    webView.getSettings().setJavaScriptEnabled(true);    // Potentially dangerous if not handled carefully    webView.setWebViewClient(new WebViewClient());    Intent intent = getIntent();    if (intent != null && intent.getData() != null) {        String url = intent.getDataString();        if (url != null) {            webView.loadUrl(url); // Vulnerable point        }    } else if (intent != null && intent.hasExtra("html_content")) {        String htmlContent = intent.getStringExtra("html_content");        webView.loadDataWithBaseURL(null, htmlContent, "text/html", "UTF-8", null);    }}

Here, the intent filter specifies http and https schemes, but the code directly loads intent.getDataString() without strict scheme validation. A malicious app can craft an intent with a file:// scheme.

Exploitation Steps:

  1. Identify the target component: Using apktool, locate WebViewerActivity and confirm it’s exported and handles URL intents.
  2. Craft a malicious intent: Use adb shell am start to send an intent with a file:// URL to access restricted files like /etc/hosts or /data/data/com.example.vulnerableapp/shared_prefs/some_creds.xml.
# Example to read /etc/hostsdb shell am start -n com.example.vulnerableapp/.WebViewerActivity -d "file:///etc/hosts"

If the application has appropriate file read permissions (which many do implicitly for their own data directory or for system files), the content of /etc/hosts will be loaded and displayed within the vulnerable app’s WebView, potentially viewable by an attacker if the app’s UI is visible or if the content is returned through other means.

Scenario 2: Denial of Service (DoS) via Uncontrolled Intent Parameters

An exported service or broadcast receiver that attempts to process overly large or malformed data received via an intent, without proper size or type validation, can be coerced into a DoS. For instance, an intent extra containing a huge byte array that the receiver attempts to load into memory without checks could crash the application.

Vulnerable Code Snippet:

public class VulnerableReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        if (intent.getAction().equals("com.example.vulnerableapp.ACTION_PROCESS_DATA")) {            byte[] largeData = intent.getByteArrayExtra("data");            if (largeData != null) {                // Processing largeData without memory limits, potentially leading to OOM                // Example: new String(largeData); or heavy computation            }        }    }}

Exploitation:

# This is conceptual; sending truly 'large' data via adb shell is tricky.# In a real exploit, this would be done programmatically by a malicious app.adb shell am broadcast -a com.example.vulnerableapp.ACTION_PROCESS_DATA --eu "data" "<a_very_large_string_or_byte_array>"

A malicious app could construct an intent with an excessively large byte array and send it to VulnerableReceiver, triggering an OutOfMemoryError and crashing the target application.

Mitigation Strategies

Preventing these intent filter vulnerabilities requires careful design and implementation:

  • Explicitly set android:exported="false": For any component not intended for external interaction. This is the simplest and most effective measure.
  • Implement Permission Checks: If a component must be exported, protect it with a custom permission using android:permission="com.example.MY_PERMISSION". This ensures only apps holding that specific permission can interact with the component.
  • Validate Incoming Intents: Always validate the data, URI, and caller of any incoming intent, even from trusted sources. Check schemes, host, path, and ensure parameters are within expected bounds.
  • Use Intent.setPackage(): When creating intents to launch known components within your own application, explicitly set the package name. This ensures the intent is delivered only to components within that specific package, preventing intent ambiguity and hijacking.
  • Avoid Implicit Intents to Sensitive Components: Do not rely on implicit intents for sensitive operations if the target component is exported.
  • Limit Data Exposure for Content Providers: Carefully define android:readPermission and android:writePermission for content providers.

Conclusion

The AndroidManifest.xml is a powerful configuration file, but its misconfiguration, particularly around intent filters and the android:exported attribute, creates significant security risks. By understanding how components are exposed and how intent filters work, security researchers and developers can identify and mitigate these vulnerabilities. Thorough analysis using tools like apktool, combined with a deep understanding of Android’s component model, is crucial for building robust and secure Android applications. Always default to the least privilege principle and meticulously validate all inter-component communication.

Android Mobile Specs & Compare Directory

Are you researching mobile hardware properties, processor SoCs, GPU chipsets, or RAM configurations? Access our complete specs catalog to compare up to 5 devices side-by-side!

Compare Devices Specs →
Google AdSense Inline Placement - Content Footer banner