Перейти к содержанию

Недостаточная проверка на запуск на эмуляторе

Критичность: СРЕДНЯЯ
Способ обнаружения: IAST

Описание

Запуск и работа приложений в ОС без проверки окружения может нести значительные риски.

Злоумышленник или легальный пользователь могут запускать приложение на эмуляторе с целью создания фейковых аккаунтов, накруток различных показателей, исследования взаимодействия приложения с ОС и другими приложениями, а также исследования взаимодействия приложения по сети, в том числе с серверной частью (исследование API). Установка и работа в таком окружении значительно снижает безопасность данных пользователя и потенциально увеличивает риск финансовых и репутационных потерь для поставщика приложения.

Использование эмулятора зачастую противоречит политике и целям производителя приложения. В некоторых случаях установка на эмулятор производится с целью получения прямой выгоды пользователем или преимущества перед другими пользователями. Кроме того, исследование и использование приложений злоумышленниками в большинстве случаев производится также на эмуляторах.

Слабой или недостаточной проверкой на запуск на эмуляторе является использование менее двух проверок разного типа.

Стандартная проверка на эмулятор:

  • SystemProperties;

  • BuildProperites;

  • наличие пакетов, сопутствующих эмуляторам ("com.bluestacks", "com.google.android.launcher.layouts.genymotion" и т. д.);

  • наличие файлов, сопутствующих эмуляторам (ueventd.ttVM_x86.rc, fstab.andy и т. п.);

  • проверка мобильного оператора на значение "Android";

  • проверка телефонии на наличие известных фейковых значений (проверка номера телефона, проверка DEVICE_ID).

    Примечание

    Проверкой одного типа называется проверка, использующая один из методов API. При этом сама проверка может быть использована многократно с разными входными данными. Яркий пример — использование метода File.exist() для проверки наличия в файловой системе некоторого перечня файлов. Другой пример — использование статических полей класса Build для проверки на эмулятор. Данный класс содержит множество полей, однако их использование относится к одному и тому же типу проверок.

Рекомендации

Приложение при запуске и во время работы должно проверять косвенные и непосредственные значения параметров ОС, указывающие на наличие прав root и эмулятора.

Определение эмулятора:

  • Поиск файлов, характерных для различных эмуляторов: "ueventd.android_x86.rc", "x86.prop", "ueventd.ttVM_x86.rc", "init.ttVM_x86.rc", "fstab.ttVM_x86", "fstab.vbox86", "init.vbox86.rc", "ueventd.vbox86.rc", "/dev/socket/qemud", "qemud", "/dev/qemu_pipe", "qemu_pipe", "/system/lib/libc_malloc_debug_qemu.so", "libc_malloc_debug_qemu.so", "/sys/qemu_trace", "/system/bin/qemu-props", "qemu_trace", "qemu-props", "/dev/socket/genyd", "genyd", "/dev/socket/baseband_genyd", "baseband_genyd", "/proc/tty/drivers", "drivers", "/proc/cpuinfo", "cpuinfo", "/dev/goldfish_pipe", "goldfish_pipe".

  • Проверка системных свойств: "init.svc.qemud", "init.svc.qemu-props", "qemu.hw.mainkeys", "qemu.sf.fake_camera", "qemu.sf.lcd_density", "ro.bootloader", "ro.bootmode", "ro.hardware", "ro.kernel.android.qemud","ro.kernel.qemu.gles", "ro.kernel.qemu", "ro.product.device", "ro.product.model", "ro.product.name", "ro.serialno", "ro.build.display.id", "ro.product.cpu.abi", "ro.debuggable", "ro.secure".

  • Проверка полей класса Build: "FINGERPRINT", "MODEL", "MANUFACTURER", "BRAND", "BOARD", "ID", "SERIAL", "TAGS", "USER", "HARDWARE","PRODUCT", "TYPE".

    Пример кода:

    public static boolean isEmulator() {
        return (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")
                || Build.FINGERPRINT.startsWith("generic")
                || Build.FINGERPRINT.startsWith("unknown")
                || Build.HARDWARE.contains("goldfish")
                || Build.HARDWARE.contains("ranchu")
                || Build.MODEL.contains("google_sdk")
                || Build.MODEL.contains("Emulator")
                || Build.MODEL.contains("Android SDK built for x86")
                || Build.MANUFACTURER.contains("Genymotion")
                || Build.PRODUCT.contains("sdk_google")
                || Build.PRODUCT.contains("google_sdk")
                || Build.PRODUCT.contains("sdk")
                || Build.PRODUCT.contains("sdk_x86")
                || Build.PRODUCT.contains("vbox86p")
                || Build.PRODUCT.contains("emulator")
                || Build.PRODUCT.contains("simulator"));
    }
    
  • Проверка телефонии: телефонный номер в списке известных фейковых номеров, device_id в списке известных фейковых device_id и т. п. пример кода:

    static final String[] DEVICE_IDS = {
            "000000000000000",
            "e21833235b6eef10",
            "012345678912345"
        };
        boolean checkDeviceId() {
            TelephonyManager telephonyManager =
                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
    
            @SuppressLint("HardwareIds") String deviceId = telephonyManager.getDeviceId();
            for (String known_deviceId : DEVICE_IDS) {
                if (known_deviceId.equalsIgnoreCase(deviceId)) {
                    return true;
                }
            }
            return false;
        }
    

Ссылки

  1. GitHub - framgia/android-emulator-detector: Easy to detect android emulator

  2. Android Emulator Detection

  3. Emulator detection in Android

  4. Android Emulator Detection | VerSprite

  5. owasp-mstg/0x05b-Basic-Security_Testing.md at master · OWASP/owasp-mstg

  6. owasp-mstg/0x05j-Testing-Resiliency-Against-Reverse-Engineering.md at master · OWASP/owasp-mstg

К началу