Недостаточная проверка на запуск на эмуляторе
|  | Критичность: СРЕДНЯЯ | 
| Способ обнаружения: 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; }