Сегодня в выпуске: простой и эффективный способ обмана Face ID, реверс-инжиниринг прошивок IoT-устройств, неожиданные результаты сравнения производительности Java и Kotlin, сравнение паттернов MVC, MVP, MVVM и MVI, советы по использованию Android Studio. А также: набор свежих инструментов пентестера и библиотек для программистов.
Как обмануть Face ID
Biometric Authentication Under Threat: Liveness Detection Hacking — презентация с Black Hat, посвященная способам обмана биометрических сенсоров в смартфонах (датчик отпечатка пальца, сканер лица и сетчатки). Авторы приводят несколько способов обхода датчиков, в том числе с помощью прямого подключения к шине камеры и подачи на нее заранее снятого изображения (это позволяет обойти алгоритмы определения реального присутствия человека, но не лазерные сканеры в iPhone и некоторых других смартфонах). Но интереснее всего способ обмана сканера Face ID в iPhone X и более поздних моделях.
Во время сканирования iPhone строит подробную 3D-модель лица человека и требует, чтобы глаза были открыты. Такой подход сводит на нет почти все методы манипуляции, включая показ фотографии, видеозаписи, поднесение смартфона к лицу спящего человека и так далее.
Но у этого механизма есть фундаментальный изъян. При сканировании лица человека в очках он не может полагаться на 3D-сканирование глаз и переключается на куда более простой алгоритм: если в районе глаз есть белая точка на черном фоне — глаза считаются открытыми. Достаточно взять любые очки, наклеить на них два кусочка черной изоленты, нарисовать в их центре белые кружки, и вуаля: надеваем очки на спящего человека, подносим к его лицу смартфон — и экран разблокирован.
Реверс-инжиниринг прошивок IoT-устройств
How to Start IoT device Firmware Reverse Engineering? — введение в реверс-инжиниринг прошивок различных IoT-устройств, таких как роутеры, камеры, устройства для умного дома и так далее. Статья короткая, простая, но содержит несколько вводных рекомендаций, которые могут пригодиться новичкам.
- Любой реверс начинается с поиска самой прошивки. Обычно ее можно скачать с сайта производителя или на форумах.
- Зачастую прошивки распространяются в zip-архиве, внутри которого находится файл с расширением .bin.
-
Обычно файл .bin — это сплав из загрузчика, ядра Linux и образов одного или нескольких разделов. Чтобы узнать адреса смещений, по которым находятся эти образы в файле, можно использовать утилиту
binwalk
:$ binwalk -e TL-WR841Nv14_EU_0.9.1_4.16_up_boot[180319-rel57291].bin
-
Адрес смещения можно использовать, чтобы извлечь образ раздела с помощью утилиты
dd
(в данном случае образ корневой файловой системы squashfs):$ dd if= TL-WR841Nv14_EU_0.9.1_4.16_up_boot[180319-rel57291].bin skip=1049088 bs=1 of=TP.sfs
-
Получить содержимое файловой системы squashfs позволяет утилита
unsquashfs
:$ unsquashfs TP.sfs
-
На этом все, можно начинать анализ содержимого прошивки.
Сравнение производительности Java и Kotlin
Java vs. Kotlin — Part 1: Performance — сравнение производительности Java и Kotlin с помощью набора бенчмарков Computer Language Benchmark Game (CLBG), используемого во многих исследовательских работах.
Автор взял шесть бенчмарков CLBG на Java, сконвертировал их в Kotlin с помощью встроенного в Android Studio конвертера, а затем переписал их в соответствии с особенностями Kotlin и рекомендациями JetBrains по написанию кода. Затем сравнил производительность и потребление памяти всех трех версий кода на стандартной виртуальной машине Java HotSpot.
Результаты получились интересные. Почти во всех тестах выиграла Java, и лишь в двух впереди оказался Kotlin, но не вручную написанный код, а сконвертированный из Java. Так получилось потому, что разработчики Kotlin рекомендуют использовать синтаксический сахар и функциональное программирование, которые существенно упрощают написание кода, но создают дополнительный оверхед.
Заметно также, что Kotlin значительно проиграл по потреблению памяти в тесте Fannkuch Redux. Причина: использование полноценного объекта Integer для хранения простых чисел в противовес Java, которая использует для этого переменные.
В целом Java-код оказался на 6,7% быстрее кода на Kotlin.
MVC, MVP, MVVM, MVI: в чем разница?
MVWTF: Demystifying Architecture Patterns — разбор и сравнение различных паттернов проектирования ПО, позволяющих разделить бизнес-логику, данные и графический интерфейс приложения.
MVC (Model — View — Controller) — старейший паттерн проектирования, родившийся в 1970-х годах в среде разработчиков Smalltalk. Он разделяет приложение на три компонента:
- Модель — источник данных: база данных, сетевой ресурс, файл, что угодно. Модель отвечает только за извлечение данных, но не за их отображение.
- Представление (View) отвечает только за отображение данных, без какой-либо логики: что получил, то и показал.
- Контроллер — связующее звено между моделью и представлением. Контроллер ответственен за получение данных модели и передачу их представлению с внесением необходимых преобразований. Также контроллер отвечает за получение данных из форм ввода и передачу их модели.
Главная проблема MVC в случае с Android заключается в том, что контроллер и представление приходится реализовать внутри активности или фрагмента, а это значит, что они не будут по-настоящему разделены, а написание unit-тестов существенно затруднится (нельзя просто так взять и написать JUnit-тест для активности или фрагмента).
MVP (Model — View — Presenter) — развитие идеи MVC, в котором контроллер отделен от представления с помощью абстрактного интерфейса. MVP позволяет по-настоящему отделить компоненты приложения друг от друга и упрощает unit-тестирование.
MVVM (Model — View — ViewModel) — дальнейшее развитие MVP, в котором контроллер/презентер полностью отвязан от представления. Роль контроллера здесь выполняет ViewModel, которая, как и контроллер/презентер, получает данные от модели и выполняет необходимые преобразования, но не отдает их напрямую представлению. Вместо этого представление подписывается на обновления ViewModel и отображает их по мере обновления. MVVM реализуется с помощью реактивных фреймворков, таких как RxJava или Android Architecture Components.
В случае с Android MVVM решает одну из самых раздражающих проблем: потерю связей при изменении конфигурации. Например, когда пользователь поворачивает экран смартфона, Android убивает текущую активность и воссоздает ее заново. При использовании паттерна MVP презентер будет продолжать хранить ссылку на представление, которое находится в теперь уже несуществующей активности. При использовании MVVM представление во вновь созданной активности просто подпишется на ViewModel, получит от нее данные и отобразит их.
MVI (Model — View — Intent) — паттерн, призванный решить проблему MVVM под названием «согласованность состояния». Дело в том, что на определенном уровне сложности ViewModel на поверхность быстро вылезет сложность контроля текущего состояния: ViewModel может быть изменена сразу несколькими компонентами приложения, а каждое изменение может привести к конфликтам в общем состоянии ViewModel.
Решить эту проблему можно с помощью хорошо известных веб-программистам инструментов: стейт-контейнера и редусера (привет, Redux). С их помощью можно создать единую точку хранения состояния приложения, позволяющую менять состояние атомарно и консистентно.
Примеры реализации паттернов размещены на GitHub автора статьи.
Советы по использованию Android Studio
Get the most out of Android Studio as an IDE — очередная статья на тему эффективного использования Android Studio.
- Скретч-файл. Время от времени мы хотим проверить фрагмент кода на работоспособность. Android Studio позволяет сделать это с помощью так называемого скретч-файла, представляющего собой нечто вроде интерактивной консоли, в которой можно быстро запустить код на Java, Kotlin и других языках. Для вызова скретч-файла набираем Ctrl + Shift + A, затем набираем scratch и жмем Enter. В коде можно использовать любые классы из текущего проекта.
- Документация на модуль. Android Studio умеет автоматически показывать документацию на любой модуль, подключенный к проекту. Для этого необходимо включить настройку File -> Settings -> Editor -> General -> Other section -> Show quick documentation on mouse move, а затем провести мышкой над именем нужной функции.
- Поиск по коду. Чтобы найти нужную функцию или переменную в коде проекта, достаточно нажать Ctrl + Shift + F и ввести ее имя.
- Форматирование кода. Выровнять отступы в коде, убрать лишние пробелы и пустые строки можно с помощью комбинации Ctrl + Alt + L.
- Быстрая навигация. Комбинации Ctrl + Alt + Влево и Ctrl + Alt + Вправо позволяют быстро перемещаться между фрагментами кода, на которые ты переходил или которые правил в последний раз.
- Переключение вкладок. Комбинации Ctrl + Alt + [ и Ctrl + Alt + ] переключают открытые вкладки кода.
Инструменты
- Mobile Security Penetration Testing List — подборка инструментов для мобильного пентестера;
- kobackupdec — скрипт для расшифровки бэкапов, сделанных с помощью встроенных в смартфоны Huawei приложений HiSuite и KoBackup;
- FBUnpinner — патч для Android-версий приложений Facebook и WhatsApp, позволяющий обойти SSL Pinning.
Библиотеки
- AndroidX Tech — сайт с дополнительной информацией о библиотеках семейства Android X;
- Colibri — библиотека для автоматизированного тестирования UI приложения;
- Ulfberht — написанный на Kotlin DI-фреймворк;
- Submarine — всплывающая панель навигации;
- Coil — написанная на Kotlin библиотека для загрузки изображений, быстрая и легкая альтернатива Picasso и Glide;
- sign-in-with-apple-button-android — Android-библиотека для аутентификации с помощью сервиса Sign In with Apple;
- finch — панель для инспекции okHttp-трафика;
- kotlin-multiplatform-template — готовый темплейт для мультиплатформенного Kotlin-приложения, в комплекте: бэкенд, фронтенд, Android-приложение и iOS-приложение;
- Bulldog — библиотека, упрощающая работу с SharedPreferences;
- SimpleGenericAdapter — универсальный адаптер для RecyclerView;
- ProgressView — анимированный гибко настраиваемый виджет прогресса;
- BottomNavigator — библиотека для навигации между фрагментами с помощью табов в нижней части экрана.