Skip to content

Application code not obfuscated

Application code not obfuscated

Description

Obfuscation refers to methods to obscure code and make it hard to understand. Compiled Java classes can be decompiled if there is no obfuscation during compilation step. It works by modifying the code and metadata of the app in a way that makes it difficult for attackers to understand the code and modify it to introduce vulnerabilities or add malicious functionality. Obfuscators typically achieve this by renaming classes, methods, and variables to non-meaningful names, removing debugging information, and adding bogus code to confuse decompilers.

Adversaries can steal code and sensitive information, introduce vulnerabilities that can compromise the app's security, or repurpose and sell the code in a new application or create a malicious fake application based on the initial one. If this code is not obfuscated, it can be easily decompiled using tools like Apktool or JADX.

Code obfuscation only slows the attacker from reverse engineering but does not make it impossible.

Recommendation

Design the application to add the following protections and slow reverse engineering of the application:

  • Obfuscate Java source code with tools like Proguard.
buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

This tells Gradle to use ProGuard for code obfuscation in the release build. You can then create a "proguard-rules.pro" file in the app's "app" directory to configure the obfuscation rules.

  • Obfuscate Java source code with tools like Dexguard.
buildTypes {
        release {
            minifyEnabled true
            useProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            dexguard {
                config 'dexguard-release.cfg'
            }
        }
    }

This tells Gradle to use DexGuard for code obfuscation in the release build. You can create a"dexguard-project.txt" file in the app's "app" directory to configure the DexGuard project, and a"dexguard-release.cfg" file to configure the obfuscation for the release build.

By default, when you enable code obfuscation using DexGuard, it will use its own obfuscation rules in addition to any rules specified in the ProGuard configuration file. However, you can disable the use of ProGuard's rules by setting the useProguard option to false.

  • Verification application signing certificate during runtime by checking context.getPackageManager().signature
  • Check application installer to ensure it matches the Android Market by calling context.getPackageManager().getInstallerPackageName
  • Check running environment at runtime
private static String getSystemProperty(String name) throws Exception {
    Class systemPropertyClazz = Class.forName("android.os.SystemProperties");
    return (String) systemPropertyClazz.getMethod("get", new Class[] { String.class }).invoke(systemPropertyClazz, new Object[] { name });
}

public static boolean checkEmulator() {

    try {
        boolean goldfish = getSystemProperty("ro.hardware").contains("goldfish");
        boolean qemu = getSystemProperty("ro.kernel.qemu").length() > 0;
        boolean sdk = getSystemProperty("ro.product.model").equals("sdk");

        if (qemu || goldfish || sdk) {
            return true;
        }

    } catch (Exception e) {}

    return false;
}
  • Check debug flag at runtime
    context.getApplicationInfo().applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE;

Standards

  • OWASP_MASVS_RESILIENCE:
    • MSTG_RESILIENCE_9
    • MSTG_RESILIENCE_12
  • PCI_STANDARDS:
    • REQ_2_2