Android: Биометрия в Android 11 и новый тип вымогателя

Android: Биометрия в Android 11 и новый тип вымогателя

Life-Hack [Жизнь-Взлом]/Хакинг

#Обучение

Се­год­ня в выпус­ке: улуч­шение сис­темы биомет­ричес­кой аутен­тифика­ции в Android 11, ransomware, уме­ющий бло­киро­вать устрой­ство без спе­циаль­ных раз­решений, мифы о про­изво­дитель­нос­ти Android, адап­тация при­ложе­ния к сов­ремен­ным тре­бова­ниям при­ват­ности, быс­трая муль­тип­латфор­менная NoSQL база дан­ных, бен­чмарк биб­лиотек заг­рузки изоб­ражений, запуск кода Java на устрой­стве без соз­дания APK. А так­же: под­борка инс­тру­мен­тов пен­тесте­ра и биб­лиотек для раз­работ­чиков.

ПОЧИТАТЬ

Безопасность экрана блокировки в Android 11

Lockscreen and authentication improvements in Android 11 — статья раз­работ­чиков из коман­ды безопас­ности Android об изме­нении в работе механиз­мов аутен­тифика­ции по отпе­чат­кам паль­цев и сним­ку лица.

До Android 11 сис­тема аутен­тифика­ции Android работа­ла по сле­дующим пра­вилам:

  1. Па­роль или PIN-код — счи­тает­ся наибо­лее надеж­ным методом аутен­тифика­ции и поэто­му дает пол­ный кон­троль над устрой­ством без вся­ких огра­ниче­ний.
  2. От­печаток паль­ца или сни­мок лица — менее надеж­ный, сис­тема зап­рашива­ет пароль пос­ле каж­дой перезаг­рузки телефо­на, а так­же через каж­дые 72 часа.
  3. Smart Lock — наиме­нее надеж­ный метод, поэто­му на него нак­ладыва­ются те же огра­ниче­ния, что и на биомет­ричес­кий метод, плюс он не поз­воля­ет получить дос­туп к аутен­тифика­цион­ным клю­чам Keymaster (нап­ример, тем, что исполь­зуют­ся для пла­тежей), а пароль зап­рашива­ет не через 72 часа, а уже через четыре.

В Android 11 появи­лось понятие надеж­ности спо­соба биомет­ричес­кой аутен­тифика­ции. Теперь сис­тема учи­тыва­ет, нас­коль­ко надеж­ный дат­чик отпе­чат­ков паль­цев или ска­нер лица уста­нов­лен в устрой­ство, и может изме­нить поведе­ние. Нап­ример, ненадеж­ный спо­соб аутен­тифика­ции нель­зя будет исполь­зовать для аутен­тифика­ции в сто­рон­них при­ложе­ниях и для раз­бло­киров­ки дос­тупа к KeyStore. Так­же для такого спо­соба аутен­тифика­ции тайм‑аут перед сле­дующим зап­росом пароля будет сни­жен с 72 до 24 часов.

Все­го есть три клас­са надеж­ности дат­чиков (спо­собов) биомет­ричес­кой аутен­тифика­ции:

  • класс 3 — надеж­ный, зап­рос пароля через 72 часа, дос­туп к KeyStore и воз­можность исполь­зования в сто­рон­них при­ложе­ниях;
  • класс 2 — сла­бый, зап­рос пароля через 24 часа, дос­туп к KeyStore, невоз­можно исполь­зовать в сто­рон­них при­ложе­ниях;
  • класс 1 — удоб­ный, зап­рос пароля через 24 часа, нет дос­тупа к KeyStore, невоз­можно исполь­зовать в сто­рон­них при­ложе­ниях.

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

Клас­сы биомет­ричес­кой аутен­тифика­ции и нак­ладыва­емые на них огра­ниче­ния

Ransomware нового типа

Sophisticated new Android malware marks the latest evolution of mobile ransomware — статья иссле­дова­телей из Microsoft о новом типе ransomware, най­ден­ном на прос­торах интерне­та.

Мал­варь называ­ется AndroidOS/MalLocker.B и в целом уже извес­тна и дос­таточ­но хорошо изу­чена. Инте­рес иссле­дова­телей выз­вала новая раз­новид­ность это­го вымога­теля: она научи­лась бло­киро­вать устрой­ство, показы­вая сооб­щение о выкупе без исполь­зования экранных овер­леев (SYSTEM_ALERT_WINDOW), воз­можнос­ти которых Google серь­езно огра­ничи­ла в пос­ледних вер­сиях Android.

Вмес­то овер­лея злов­ред исполь­зует так называ­емое пол­ноэк­ранное уве­дом­ление, с помощью которо­го легитим­ный софт показы­вает экран звон­ка. Кро­ме тек­ста (и дру­гих стан­дар­тных атри­бутов), такое уве­дом­ление так­же содер­жит ссыл­ку на активность (экран при­ложе­ния), который и будет показан, ког­да уве­дом­ление появит­ся в сис­теме.

Код, соз­дающий пол­ноэк­ранное уве­дом­ление

Од­нако один раз показы­вать сооб­щение о выкупе было бы бес­полез­но, так как поль­зователь смог бы нажать кноп­ку «Домой» или «Назад» и прос­то зак­рыть его. Поэто­му злов­ред исполь­зует еще один при­ем: переза­пус­кает активность в методе onUserLeaveHint().

Код злов­редной активнос­ти

Ме­тод onUserLeaveHint() — это кол­бэк, который сис­тема вызыва­ет перед тем, как активность исчезнет с экра­на. Поэто­му переза­пуск активнос­ти в этом методе при­водит к тому, что поль­зователь прос­то не может покинуть экран с сооб­щени­ем о выкупе.

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

Бе­зум­ное сооб­щение вымога­теля

Еще одна инте­рес­ная осо­бен­ность злов­реда — спо­соб шиф­рования кода, а точ­нее, спо­соб скры­тия методов шиф­рования кода. В основном DEX-фай­ле шиф­роваль­щика есть класс, содер­жащий методы для шиф­рования и рас­шифров­ки осталь­ных час­тей при­ложе­ния. На вход эти методы получа­ют стро­ку (которая на пер­вый взгляд кажет­ся клю­чом шиф­рования), а на выходе почему‑то воз­вра­щают объ­ект клас­са Intent (такие объ­екты в Android исполь­зуют­ся для отправ­ки сооб­щений дру­гим при­ложе­ниям).

На самом деле вход­ная стро­ка — это прос­то мусор, а сам интент содер­жит поле action, в котором как раз и хра­нит­ся адрес рас­шифро­ван­ных дан­ных.

РАЗРАБОТЧИКУ

Мифы о производительности Android

Busting Android performance myths — раз­бор ста­рых и новых мифов о про­изво­дитель­нос­ти Android.

  1. При­ложе­ния на Kotlin мед­леннее и боль­ше при­ложе­ний на Java. Кон­верта­ция при­ложе­ния Google Drive на Kotlin показа­ла, что раз­мер и ско­рость запус­ка при­ложе­ния прак­тичес­ки не изме­нились, зато раз­мер кодовой базы сок­ратил­ся при­мер­но на 25%.
  2. Гет­теры сле­дует изме­нять на пуб­личные поля. Некото­рые раз­работ­чики отка­зыва­ются от гет­теров в поль­зу пуб­личных полей (foo.bar про­тив foo.getBar()), что­бы повысить про­изво­дитель­ность. Одна­ко это ничего не дает, потому что ком­пилятор ART уме­ет инлай­нить гет­теры, прев­ращая их в обыч­ные обра­щения к полям.
  3. Лям­бды луч­ше заменять вло­жен­ными клас­сами. Лям­бды счи­тают­ся очень мед­ленны­ми, и ты можешь встре­тить советы заменить их. На самом деле пос­ле ком­пиляции лям­бды прев­раща­ются в те же ано­ним­ные вло­жен­ные клас­сы.
  4. Ал­локация объ­ектов и сбор­ка мусора в Android — мед­ленные. Ког­да‑то это дей­стви­тель­но было прав­дой, но за пос­ледние годы раз­работ­чики сде­лали алло­катор объ­ектов в десят­ки раз, а сбор­щик мусора — в нес­коль­ко раз быс­трее. Нап­ример, на Android 10 авто­мати­чес­кая алло­кация объ­ектов в тес­тах про­изво­дитель­нос­ти ничем не отли­чает­ся от алло­кации и осво­бож­дения пула объ­ектов вруч­ную (имен­но такой спо­соб рекомен­довали исполь­зовать для сох­ранения про­изво­дитель­нос­ти рань­ше).
  5. Про­фай­линг дебаг‑сбо­рок — это нор­маль­но. Обыч­но при про­фай­лин­ге при­ложе­ния раз­работ­чики не обра­щают вни­мания, что име­ют дело с debug-сбор­кой. В резуль­тате они ана­лизи­руют про­изво­дитель­ность неоп­тимизи­рован­ного кода и получа­ют невер­ные резуль­таты про­фай­лин­га.
  6. У MultiDex-при­ложе­ний более мед­ленный холод­ный старт. При пре­выше­нии лимита на количес­тво методов ком­пилятор раз­бива­ет при­ложе­ние на нес­коль­ко исполня­емых фай­лов DEX. Счи­тает­ся, что это при­водит к сни­жению вре­мени стар­та при­ложе­ния. На деле если такой эффект и есть, то он про­явля­ется толь­ко при наличии сотен фай­лов DEX. С дру­гой сто­роны, MultiDex-при­ложе­ния занима­ют на нес­коль­ко про­цен­тов боль­ше опе­ратив­ной и пос­тоян­ной памяти.
  7. При­ложе­ния содер­жат мно­го мер­тво­го кода. Это дей­стви­тель­но так. Иссле­дова­ние показа­ло, что при­ложе­ние Google содер­жит боль­шое количес­тво никог­да не исполь­зуемо­го кода. Одна­ко это не прос­то мер­твый код, это код обра­бот­ки оши­бок, код под­дер­жки ста­рых вер­сий Android и код ред­ко исполь­зуемых фун­кций. Нас­тоящий мер­твый код, который не исполь­зует­ся ни при каких обсто­ятель­ствах, уда­ляет­ся опти­миза­тором R8.
Вре­мя стар­та при­ложе­ния до и пос­ле кон­верта­ции на Kotlin

Адаптация приложения к современным требованиям приватности

Adapt your app for the latest privacy best practices — статья о том, как написать пра­виль­ное с точ­ки зре­ния при­ват­ности поль­зовате­ля при­ложе­ние.

  1. Раз­решение на «обще­ние» с дру­гими при­ложе­ниями. Для при­ложе­ний, соб­ранных для Android 11 (targetSdkVersion 30), дей­ству­ют огра­ниче­ния на прос­мотр информа­ции и ком­муника­цию с дру­гими при­ложе­ниями. Теперь при­ложе­ние дол­жно пря­мо ука­зывать в манифес­те, с какими при­ложе­ниями оно может вза­имо­дей­ство­вать и какие интенты может исполь­зовать. Офи­циаль­ная докумен­тация рас­смат­рива­ет мно­жес­тво при­меров, пок­рыва­ющих поч­ти все воз­можные слу­чаи. Плюс ко все­му, если твое при­ложе­ние исполь­зует content provider, что­бы рас­шаривать информа­цию дру­гим при­ложе­ниям, ты дол­жен ука­зывать флаг Intent.FLAG_GRANT_READ_URI_PERMISSION в любом интенте, рас­шарива­ющем дан­ные про­вай­дера:
  2. val shareIntent = Intent(Intent.ACTION_VIEW).apply {
  3. flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
  4. data = // URI, расшариваемый с другим приложением
  5. }
  6. Пос­тепен­ный зап­рос раз­решений. Иссле­дова­ния по­казы­вают, что поль­зовате­ли склон­ны пре­дос­тавлять при­ложе­ниям пол­номочия, ког­да им тре­бует­ся кон­крет­ная фун­кци­ональ­ность при­ложе­ния, которая не будет работать без это­го раз­решения. Толь­ко 32% поль­зовате­лей пре­дос­тавля­ют раз­решение потому, что доверя­ют раз­работ­чику при­ложе­ния. Вто­рой момент, который необ­ходимо пом­нить: если при­ложе­ние соб­рано для Android 11, оно боль­ше не может зап­рашивать раз­решение на опре­деле­ние мес­тополо­жения в фоне (background location) сра­зу, сна­чала оно дол­жно зап­росить раз­решение foreground location.
  7. Кор­рек­тный дос­туп к камере и мик­рофону. Android раз­реша­ет исполь­зовать дос­туп к камере и мик­рофону, толь­ко если при­ложе­ние видимо на экра­не. Это же отно­сит­ся и к сер­висам: foreground service име­ет икон­ку в панели сос­тояния, и поэто­му он видим и может исполь­зовать камеру и мик­рофон. Android 11 вво­дит еще одно тре­бова­ние — сер­вис дол­жен пря­мо ука­зать, какие типы сен­соров он будет исполь­зовать:
  8. android:foregroundServiceType = "microphone | location | camera"
  9. Иден­тифика­торы устрой­ства. Android 10 зап­реща­ет чте­ние мно­гих хар­двар­ных иден­тифика­торов устрой­ства, вклю­чая серий­ный номер SIM-кар­ты и IMEI. Android 11 так­же зак­рыва­ет воз­можность читать ICC ID. В качес­тве аль­тер­нативы мож­но исполь­зовать метод getSubscriptionId(), который воз­вра­щает иден­тифика­тор, уни­каль­ный для каж­дой SIM-кар­ты.

Быстрая мультиплатформенная NoSQL база данных

Announcing a painless Kotlin/Multiplatform NoSQL embedded database — анонс новой NoSQL базы дан­ных для муль­тип­латфор­менных про­ектов на Kotlin.

Kodein-DB спе­циаль­но соз­дана для несер­верных про­ектов, в которых важ­но удобс­тво исполь­зования и гиб­кость, а не воз­можность соз­давать слож­ные схе­мы хра­нения дан­ных. Это край­не быс­трая база дан­ных, в некото­рых опе­раци­ях в десят­ки раз опе­режа­ющая SQLite по ско­рос­ти. Она очень прос­та в исполь­зовании и не тре­бует никаких под­готови­тель­ных шагов. Базу дан­ных мож­но открыть и сра­зу исполь­зовать для сох­ранения объ­ектов:

// Все модели должны быть сериализуемы и реализовать интерфейс Metadata

@Serializable

data class User(

// Каждый экземпляр должен использовать уникальный ID

override val id: String,

val firstName: String,

val lastName: String

) : Metadata

fun store(db: DB, user: User) { db.put(user) }

fun load(db: DB, id: String): User = db.get(db.newKey<User>(id)).model

fun test(db: DB) {

val id = UUID.randomUUID()

val user = User(id, "John", "Doe")

store(db, user)

val otherUser = load(db, id)

assertEquals(user, otherUser)

}

Kodein-DB кеширу­ет все дан­ные в опе­ратив­ной памяти и уме­ет сооб­щать о выпол­ненных опе­раци­ях, поэто­му ее мож­но исполь­зовать как еди­ный источник исти­ны (single source of truth), не дуб­лируя сос­тояние БД в опе­ратив­ной памяти самос­тоятель­но:

fun listenForChange(db: DB) {

db.on<ChatMessage>().register {

didPut {

addMessageToUI(it)

}

didDelete {

reloadList(

db.find<Chat>()

.byIndex("time")

.useModels(reverse = true) { it.toList() }

)

}

}

}

В нас­тоящий момент про­ект находит­ся в сос­тоянии беты, но уже впол­не при­годен для пов­седнев­ного исполь­зования.

Бен­чмарк про­изво­дитель­нос­ти

Бенчмарк библиотек загрузки изображений

Benchmarking Image Loading Libraries on Android — бен­чмарк биб­лиотек для сетевой заг­рузки изоб­ражений: Coil, Glide, Fresco, Picasso 2/3.

Биб­лиоте­ки заг­рузки изоб­ражений нуж­ны поч­ти в каж­дом мобиль­ном при­ложе­нии. Они вхо­дят в must have спи­сок любых под­борок биб­лиотек. Поэто­му выбор биб­лиоте­ки важен. Раз­работ­чик одной из популяр­ных биб­лиотек Coil срав­нил нес­коль­ко биб­лиотек и при­шел к выводу, что по соот­ношению про­изво­дитель­ность/раз­мер безого­вороч­но выиг­рыва­ет Picasso. Это край­не ком­пак­тная и про­изво­дитель­ная биб­лиоте­ка, одна­ко она не обла­дает рядом фун­кций, которые, нап­ример, есть в Coil, и не опти­мизи­рует пот­ребле­ние опе­ратив­ной памяти. Поэто­му окон­чатель­ный выбор сле­дует делать исхо­дя из текущих пот­ребнос­тей при­ложе­ния.

Бен­чмарк биб­лиотек (control — заг­рузка изоб­ражений вруч­ную)

Запуск кода Java на устройстве без создания APK

HOWTO: Running Java code directly on Android (without creating an APK) — неболь­шая замет­ка о том, как запус­тить исполня­емый код на Android без соз­дания пакета APK.

До­пус­тим, у нас есть такой код на Java (необя­затель­но вда­вать­ся в под­робнос­ти его реали­зации):

package com.example;

import org.apache.commons.cli.DefaultParser;

import org.apache.commons.cli.HelpFormatter;

import org.apache.commons.cli.Option;

import org.apache.commons.cli.Options;

import org.apache.commons.cli.ParseException;

public class HelloWorld {

public static void main(String[] args) throws ParseException {

Option version = new Option("v", "Print version");

Option help = new Option("h", "Print help");

Options options = new Options();

options.addOption(help);

options.addOption(version);

for (Option opt : new DefaultParser().parse(options, args).getOptions()) {

if (opt.equals(version)) {

String os = System.getProperty("os.arch");

System.out.println("Hello World (" + os + ") v0.1");

}

if (opt.equals(help)) {

new HelpFormatter().printHelp("Hello World", options);

}

}

}

}

Мы хотим запус­тить его пря­мо на устрой­стве, не соз­давая файл APK. Для это­го его необ­ходимо ском­пилиро­вать:

$ javac -source 1.7 -target 1.7 -d bin -cp lib/commons-cli-1.3.1.jar src/com/example/HelloWorld.java

В дан­ном слу­чае bin — это каталог, в который ком­пилятор помес­тит получен­ный байт‑код Java, lib/commons-cli-1.3.1.jar — биб­лиоте­ка — зависи­мость кода, а src/com/example/HelloWorld.java — путь к исходно­му фай­лу.

Те­перь получен­ный байт‑код Java необ­ходимо пре­обра­зовать в байт‑код DEX, при­год­ный для исполне­ния на Android-смар­тфо­не:

$ ./android-sdk-linux/build-tools/23.0.2/dx --output=helloworld.jar --dex ./bin lib/commons-cli-1.3.1.jar

В тво­ем слу­чае путь к коман­де dx может быть дру­гим (обыч­но каталог android-sdk-linux рас­полага­ется в катало­ге Android Studio или рядом с ним).

Да­лее необ­ходимо соз­дать shell-скрипт, который будет запус­кать наш код:

base=/data/local/tmp/helloworld

export CLASSPATH=$base/helloworld.jar

export ANDROID_DATA=$base

mkdir -p $base/dalvik-cache

exec app_process $base com.example.HelloWorld "$@"

Здесь app_process — это коман­да Android, которая запус­кает новую вир­туаль­ную машину. Точ­но таким же обра­зом запус­кают­ся стан­дар­тные при­ложе­ния для Android.

Те­перь скрипт вмес­те с байт‑кодом мож­но переки­нуть на устрой­ство:

$ adb shell mkdir -p /data/local/tmp/helloworld

$ adb push helloworld.jar /data/local/tmp/helloworld

$ adb push helloworld.sh /data/local/tmp/helloworld

$ adb shell chmod 777 /data/local/tmp/helloworld/helloworld.sh

И запус­тить:

$ adb shell /data/local/tmp/helloworld/helloworld.sh -v

ИНСТРУМЕНТЫ

  • MEDUZA — скрипт для быс­тро­го отклю­чения SSL-валида­ции, вклю­чая SSL Pinning в при­ложе­ниях для Android;
  • Cryptoguard — ути­лита для обна­руже­ния неп­равиль­ного исполь­зования крип­тогра­фии в при­ложе­нии;
  • Crylogger — еще одна ути­лита для поис­ка оши­бок в исполь­зовании крип­тогра­фии.

Источник


Report Page