Хакер - Android: инструменты пентестера, уязвимости экрана блокировки iOS и множество советов по Kotlin
Содержание статьи
- Инструменты
- Почитать
- Отключение защиты от запуска в эмуляторе
- Уязвимости экрана блокировки iOS и способы их митигации
- (Не)безопасность приложений, использующих ADB Workaround
- Разработчику
- Запуск Java-кода с привилегиями shell
- Более лучшая обфускация
- Inline-функции Kotlin
- 15 инструментов, необходимых любому Android-разработчику
- Полезные клавиатурные комбинации Android Studio
- 31 день с Kotlin
- Инструменты
- Библиотеки
Инструменты
- SnoopSnitch — приложение для проверки прошивки телефона на установленные и пропущенные патчи безопасности;
- uitkyk — простой скрипт Frida, помогающий обнаружить малварь путем анализа хранящихся в стеке объектов и перехвата функций запуска шелл-команд;
- AndHook — еще один DBI-фреймворк для Android, подобный Cydia Substrate и Xposed;
- androidre — образ Docker с набором утилит для анализа Android-приложений: Apktool, jadx, APKiD, Radare2, Frida и другие;
- iCloudBrutter — брутфорсер паролей Apple ID;
- QARK — инструмент для автоматизированного поиска уязвимостей многих типов в Android-приложениях; в некоторых случаях QARK может генерировать готовый эксплоит или набор команд ADB для эксплуатации уязвимости;
- droidstatx — утилита, генерирующая майнд мап с информацией о приложении и его возможных уязвимостях;
- avd-root — скрипт для рутинга эмулятора Android;
- bfinject — утилита для внедрения библиотек в любые iOS-приложения; требует iOS 11.0–11.1.2 с джейлбрейком;
- bfdecrypt — утилита для дешифровки iOS-приложений; требует iOS 11.0–11.1.2 с джейлбрейком.
Карта, сгенерированная droidstatxПочитать
Отключение защиты от запуска в эмуляторе
Bypassing Android Anti-Emulation, Part (I), Part (II) — серия из двух статей, посвященных взлому защиты от запуска в эмуляторе. Первая часть вводная, рассказывает об устройстве приложения для Android и о том, как работает система защиты от запуска в эмуляторе. Вторая часть практическая и рассказывает, как декомпилировать приложение и отключить защиту.
Интересные моменты:
- Практически все механизмы защиты от запуска в эмуляторе основаны на чтении системных переменных и поиске в них определенных строк. Например,
Build.FINGERPRINT.startsWith("generic"),Build.MODEL.contains("google_sdk"),Build.BRAND.startsWith("generic"). - Процесс отключения защиты от запуска в эмуляторе в целом почти не отличается от процесса взлома легитимного приложения. Декомпилируем приложение с помощью jadx или любого другого декомпилятора, находим код проверки на эмулятор (он часто расположен в функциях с именами типа
isEmulator(),carrierNameFromTelephonyManager()илиsmellsLikeAnEmulator()), затем дизассемблируем приложение с помощью apktool, находим тот же вызов функции в коде smali и вырезаем его. В случае применения ProGuard или другого обфускатора это будет сделать сложнее (читаемые имена превратятся в нечто вроде «ab»), но все же достаточно легко.
Пример кода защиты от запуска в эмуляторе
Другой пример кода
И еще один примерУязвимости экрана блокировки iOS и способы их митигации
http://blog.dinosec.com/2014/09/bypassing-ios-lock-screens.html — список всех уязвимостей экрана блокировки iOS, найденных с версии iOS 5 по текущую. Список включает в себя ссылки на описание уязвимостей, а также видеодемонстрации их эксплуатации.
Суммарные данные:
- iOS 5.x — 4 уязвимости;
- iOS 6.x — 8 уязвимостей;
- iOS 7.x — 12 уязвимостей;
- iOS 8.x — 11 уязвимостей;
- iOS 9.x — 6 уязвимостей;
- iOS 10.x — 10 уязвимостей;
- iOS 11.x — 5 уязвимостей.
Советы, как обезопасить себя от взлома через экран блокировки:
- отключи Siri на экране блокировки: Settings → Passcode → Siri (or Voice Dial) → Allow access when locked;
- отключи Passbook на экране блокировки: Settings → Passcode → Passbook → Allow access when locked;
- отключи Control Center на экране блокировки: Settings → Control Center → Access on Lock Screen;
- отключи панель уведомлений на экране блокировки: Settings → Passcode → Allow access when locked;
- отключи показ пропущенных звонков на экране блокировки: Settings → Notifications → Phone → Show on Lock Screen;
- отключи показ СМС на экране блокировки: Settings → Notifications → Messages → Show Previews;
- отключи блокировку/разблокировку с помощью чехла: Settings → General → Lock/Unlock;
- отключи камеру на экране блокировки: Settings → General → Camera;
- установи цифро-буквенный пароль.
(Не)безопасность приложений, использующих ADB Workaround
Analysing Use of High Privileges in Android Applications — исследование, посвященное безопасности приложений, использующих так называемый ADB Workaround для получения более высоких привилегий в системе без root.
Суть в следующем. В Android, кроме так называемых normal и dangerous полномочий, доступных любым приложениям (вторые только с согласия пользователя), существуют также полномочия уровня system и signature, которые позволяют приложениям устанавливать и удалять любой софт, делать скриншоты и скринкасты, бэкап и многие другие вещи, запрещенные обычным приложениям.
Полномочия уровня system доступны только приложениям, поставляемым вместе с прошивкой (каталог /system/priv-app), полномочия signature — приложениям, подписанным ключом самой прошивки (то есть тем, который разработала компания — производитель смартфона).
Но есть один трюк, позволяющий получить полномочия уровня signature даже приложениям, не подписанным ключом прошивки. Дело в том, что полномочия signature получает любой процесс, запущенный с помощью команды adb shell. Некоторые разработчики пользуются этим трюком и встраивают в свои приложения специальные прокси, которые затем просят запустить пользователя с помощью ADB или скрипта. Прокси получает команды от приложения и выполняет привилегированные операции.
Исследователи проанализировали код и поведение нескольких приложений, использующих этот метод, и выяснили, что они могут представлять серьезную опасность для их пользователей. Несмотря на то что большинство приложений используют пароль при подключении к прокси, обычно этот пароль либо зашит в само приложение, либо генерируется динамически, но сохраняется в доступный для чтения файл.
В теории злоумышленник может создать троян, который будет эксплуатировать эту уязвимость, подключаться к прокси и с его помощью делать снимки экрана или записывать скринкасты. И все это без получения каких-либо прав в системе.
Процесс общения приложения и прокси в приложении FREE screen recorder NO ROOTРазработчику
Запуск Java-кода с привилегиями shell
Introducing scrcpy — статья об утилите scrcpy, позволяющей в одну команду получить на экране ПК картинку с экрана телефона, с возможностью управления с помощью мыши и клавиатуры. Однако интересна статья не этим, а тем, что рассказывает, как эта утилита работает.
Чтобы получить картинку с экрана, scrcpy должна загрузить на смартфон и выполнить с правами adb shell код, который запустит процесс скринкастинга экрана и передачи видеопотока на комп. И утилита делает это весьма интересным образом. Код, запускаемый на смартфоне, написан на Java, но это не приложение для Android, а просто запакованный в jar файл DEX.
Разработчик scrcpy объясняет, как сделать такое «неприложение».
-
Пишем приложение на Java (пример простейший):
import android.os.SystemClock; public class HelloWorld { public static void main(String... args) { System.out.print("Hello,"); SystemClock.sleep(1000); System.out.println(" world!"); } } -
Собираем приложение:
$ javac -source 1.7 -target 1.7 \ -cp "$ANDROID_HOME"/platforms/android-27/android.jar HelloWorld.java -
Перегоняем его в DEX:
$ "$ANDROID_HOME"/build-tools/27.0.2/dx \ --dex --output classes.dex HelloWorld.class -
Запаковываем в jar:
$ jar cvf hello.jar classes.dex -
Закидываем на устройство и запускаем:
$ adb push hello.jar /data/local/tmp/ $ adb shell CLASSPATH=/data/local/tmp/hello.jar app_process / HelloWorld
Вуаля, мы получили приложение, которое нет необходимости устанавливать и которое имеет права shell, то есть может выполнять многие привилегированные действия, недоступные обычным приложениям (signature level permission): бэкап, скринкастинг, снятие скриншотов, установку и удаление приложений.
Более лучшая обфускация
Improving ProGuard Name Obfuscation — статья о том, как сделать обфускацию с помощью ProGuard более запутанной. Утилита ProGuard входит в комплект Android Studio и представляет собой систему оптимизации Java-классов. Она удаляет неиспользуемый код, а также сокращает имена классов, методов и переменных, делая исполняемый файл меньше. Побочным эффектом этого является обфускация, когда из-за изменения имен код становится более трудным для понимания.
По умолчанию ProGuard переименовывает классы, методы и поля, используя английский алфавит: первый переименовывается в a, второй в b, двадцать седьмой — в aa и так далее. Проблема такого подхода в том, что он очень предсказуем; взломщику придется разобраться в твоем коде только один раз, и он легко найдет нужный участок кода в другой версии приложения: его имя, скорее всего, будет таким же.
Эту проблему можно побороть, используя разные словари. В интернете даже нашелся словарь, содержащий запрещенные для использования в Windows имена файлов, что должно помешать распаковке исполняемого файла в Windows, но на деле почти не работает. Применяя разные словари к каждой новой версии приложения, можно сделать порядок генерирования имен непредсказуемым и запутать взломщика.
Загружается такой словарь с помощью следующих инструкций в файле proguard-rules.pro внутри проекта:
-obfuscationdictionary method-dictionary.txt
-packageobfuscationdictionary package-dictionary.txt
-classobfuscationdictionary class-dictionary.txt
Также автор рекомендует использовать следующую опцию:
-repackageclasses 'o'
Она переместит все классы в пакет o, что в теории должно еще сильнее запутать взломщика.
Inline-функции Kotlin
Demystifying the inline keyword — статья, посвященная ключевому слову inline, которое подсказывает компилятору, что вместо вызова функции он должен встраивать ее тело в то место, где происходит вызов.
Inline-функции появились в Kotlin по причине избыточности местной реализации лямбд. Каждый раз, когда вызывается функция, которая принимает лямбду в качестве аргумента, виртуальной машине приходится создавать анонимный объект для хранения этой функции. А так как это затратная в плане ресурсов операция, разработчики Koltin придумали решение: если объявить функцию с ключевым словом inline, то компилятор «развернет» эту функцию и ее лямбду в последовательный код.
Правило простое: если твой код множество раз вызывает функцию, принимающую лямбду в качестве аргумента, лучше сделать ее inline-функцией. Также запомни следующие вещи:
- Kotlin 1.1 позволяет применять ключевое слово inline также к полям, в которых используются геттеры и сеттеры;
- ключевое слово return, вызванное из лямбды, переданной inline-функции, будет возвращать не из лямбды или inline-функции, а из функции, вызвавшей inline-функцию;
- кроме ключевого слова inline, также существуют noinline и crossinline. Первое можно использовать в отношении отдельно взятых лямбд, когда inline-функция принимает несколько лямбд. Второе пригодится в случае, когда лямбда должна быть выполнена в другом контексте исполнения. Пример:
inline fun exampleFun(crossinline body: () → Unit) {
Runnable {
body()
}.run()
}
15 инструментов, необходимых любому Android-разработчику
15 Android App Development Tools Required for Every Android App Developer — статья об инструментах, которые пригодятся любому разработчику:
- FlowUp — монитор производительности приложения: FPS, использование памяти, процессора и так далее;
- Stetho — инструмент отладки от разработчиков Facebook, позволяет исследовать иерархию элементов View, базы данных SQLite и сетевые операции через Chrome developer tools;
- LeakCanary — библиотека, сообщающая об утечках памяти;
- JRebel — система ускорения сборки приложений;
- Android Asset Studio — набор инструментов для генерации иконок и других ресурсов приложения;
- DryRun — инструмент для быстрого ознакомления с Android-библиотеками (позволяет одной командой запустить эмулятор с приложением-примером);
- Vysor — Chrome-плагин для взаимодействия со смартфоном (выводит изображение с экрана и позволяет нажимать на него);
- B4A — среда для разработки приложений на BASIC;
- Genymotion — Android-эмулятор с массой полезных для разработчика функций;
- Sourcetree — графический клиент Git;
- Takt — выводит в окно приложения счетчик FPS;
- Codota — плагин Android Studio для поиска на Stack Overflow, GitHub и Gist;
- AIDE — среда разработки как приложение для Android;
- Android Studio.
Полезные клавиатурные комбинации Android Studio
Android Studio Navigation Shortcuts — краткая заметка с полезными клавиатурными комбинациями.
- Ctrl + Shift + A (Command + Shift + A) — быстрый поиск действий (элементов меню, таких как Generate signed APK…);
- Ctrl + N (Command + O) — поиск классов;
- Ctrl + Shift + N (Shift + Command + O) — поиск файлов;
- Shift два раза — поиск всего перечисленного выше;
- Ctrl + Alt + Left (Command + [) — прыжок в предыдущее место кода;
- Ctlr + Alt + Right (Command + ]) — прыжок в следующее место;
- Ctrl + E (Command + E) — последние открытые файлы;
- Ctrl + Shift + Enter (Command + Shift + Enter) — автодополнение.
31 день с Kotlin
Summary of #31DaysOfKotlin. Весь март официальный твиттер-аккаунт Google, посвященный разработке приложений для Android (@AndroidDev), публиковал короткие, но очень полезные заметки о разработке на языке Kotlin. Марк Гарсия (Marc Garcia) собрал их все вместе в одной статье. Привожу максимально краткую, но понятную выжимку.
-
Элвис-оператор (если null, то…):
val name: String = person.name ?: "unknown" -
Строковые шаблоны:
val text = "$language has ${language.length} characters" -
Разрушающие объявления:
val (red, green, blue) = color val (x, y) = point -
Оператор when:
return when (cargo) { null, 0 → "empty" 1 → "tiny" 2..10 → "small" is Int → "big inty" else → "$cargo" } -
Цикл for:
for(i in 1..100) { /* ... */ } for(i in 100 downTo 1) { /* ... */ } for(i in 1 until array.size step 2) { /* ... */ } for((index, element) in array.withIndex()) { /* ... */ } for((key, value) in map) { /* ... */ } -
Свойства и поля:
class User { val id: String = "" // Неизменяемое поле var name: String = "" // Изменяемое поле var surname: String = "" // Изменяемое поле с кастомным геттером get() = surname.toUpperCase() var email: String = "" // Изменяемое поле с кастомным сеттером set(value) { if(isEmailValid()) field = value } } -
Классы данных (Kotlin автоматически добавляет к ним методы equals(), toString() и copy()):
data class User(val name: String, val email: String /* ... */ ) -
Модификаторы видимости:
val isVisible = true private val isHidden = true internal val almostVisible = true -
Аргументы по умолчанию:
class BulletPointSpan( private val bulletRadius: Float = DEFAULT_BULLET_RADIUS, private val gapWith: Int = DEFAULT_GAP_WIDTH, private val color: Int = Color.BLACK ) { /* ... */ } val bulletPointSpan = BulletPointSpan() val bulletPointSpan2 = BulletPointSpan(resources.getDimension(R.dimen.radius)) val bulletPointSpan3 = BulletPointSpan(color = Color.RED) -
Изолированные классы (по сути прокачанный enum):
sealed class NetworkResult data class Success(val result: String): NetworkResult() data class Failure(val error: Error): NetworkResult() // one observer for success and failure viewModel.data.observe(this, Observe<NetworkResult> { data -> data ?: return@Observer when (data) { is Success → showResult(data.result) is Failure → showError(data.error) } }) -
Ленивая инициализация (переменная инициализируется в момент первого доступа):
val preferences: String by lazy { sharedPreferences.getString(PREFERENCE_KEY) } -
Инициализируемые позже не null-переменные:
lateinit var recyclerView: RecyclerView ... recyclerView = findViewById(R.id.recycler_view) -
Проверка аргументов (выбрасывает IllegalArgumentException, если условие не соблюдено):
require(name.isNotEmpty()) { "Invalid name" } -
Инлайн-функции (их тело будет встроено в код вместо вызова):
inline fun onlyIf(check: Boolean, operator: () → Unit) { if (check) { operation() } } -
Вызов функций, объявленных из класса с помощью Java:
@file:JvmName("ShapeGenerator") package com.shapes fun generateSquare() = Square() fun generateTriangle() = Triangle() // Вызов из Java ShapesGenerator.generateSquare() -
Параметры вещественного типа:
// Обычно мы делаем так val alarmManager = context.getSystemService(AlarmManager::class.java) // Но можем упростить этот код до такого val alarmManager: AlarmManager = context.systemService() // Для этого достаточно такой функции inline fun <refied T> Context.systemService() = getSystemService(T::class.java) -
Делегирование (передача ответственности за хранение состояния переменной другому коду):
class MyAnimationView : View( /* ... */ ) { // Delegated property. Uses the getter and setter defined in InvalidateDelegate var foregroundX by InvalidateDelegate(0f) } class InvalidateDelegate<T : Any>(var value: T) { operator fun getValue(thisRef: View, property: KProperty<*>) = value operator fun setValue(thisRef: View, property: KProperty<*>, value: T) { this.value = value thisRef.postInvalidateOnAnimation() } } -
Функции расширения (позволяют добавить свой метод в любой класс):
inline fun String.toUri(): Uri = Uri.parse(this) val myUri = "www.developer.android.com".toUri() -
Конвертирование Drawable в Bitmap (с помощью библиотеки Android KTX):
val myDrawable = ContextCompat.getDrawable(context, R.drawable.icon) val bitmap = myDrawable.toBitmap() -
Последовательности:
val sequence = List(50= { it * 5}.asSequence() sequence.map { it * 2 } .filter { it % 3 == 0 } .map { it + 1 } .toList() -
Перегрузка операторов:
inline operator fun Spannable.plusAssign(span: Any) = setSpan(span, 0, length, SPAN_INCLUSIVE_EXCLUSIVE) val spannable = "Eureka!!!!".toSpannable() spannable += StyleSpan(BOLD) spannable += UnderlineSpan() -
Функции без классов:
@BindingAdapter("userItems") fun userItems(recyclerView: RecycleView, list: List<User>?) { ... } -
Итераторы библиотеки Android KTX (позволяют проходить в цикле, например, по ViewGroup и SparseArray):
for (view in ViewGroup) { } for (key in spaceArray.keyIterator()) { } -
Упрощенная работа с Content Values с помощью Android KTX:
val contentValues = contentValuesOf( "KEY_INT" to 1, "KEY_LONG" to 2L, "KEY_BOOLEAN" to true, "KEY_NULL" to null ) -
DSL (Kotlin позволяет создавать «языки в языке» для специальных нужд):
frameLayout { button("Light a fire") { onClick { lightAFire() } } } -
Упрощенная работа с бандлами с помощью Android KTX:
val bundle = bundleOf( "KEY_INT" to 1, "KEY_LONG" to 2L, "KEY_BOOLEAN" to true, "KEY_NULL" to null, "KEY_ARRAY" to arrayOf(1, 2) } -
Лямбды:
fun Handler.postDelay(delay: Int /* ... */, action: () → Unit) handler.postDelay(50) { ... } -
Упрощение работы со Spannable с помощью Android KTX:
val string = buildSpannableString { append("no styling text") bold { append("bold") italic { append("bold and italic") } } inSpans(RelativeSizeSpan(2f), QuoteSpan()) { append("double sized quote text") } } -
Библиотека Parcelize:
@Parcelable data class User(val name: String, val occupation: Work): Parcelable -
Расширенный Android API с помощью Android KTX:
view.updatePadding(left = newPadding) view.updatePadding(top = newPadding) view.updatePadding(right = newPadding) view.updatePadding(bottom = newPadding) -
Функции let, apply, with, also и run:
val string = "a" val result = string.apply { // Этот код будет выполнен в контексте объекта string }
Инструменты
- Scrcpy — очень простая в использовании утилита для вывода картинки с телефона на комп и взаимодействия с телефоном; требует только ADB и не требует root;
- Hyperion-Android — инструмент отладки и подводки интерфейса приложения, по своей сути напоминающий Developer console в браузерах; позволяет просматривать и изменять атрибуты, производить замеры элементов интерфейса, показывать лог при падении приложения, производить быструю очистку данных приложения, и все это из скрытого меню в самом приложении;
- Profilo — библиотека для сбора данных о производительности приложения от Facebook;
- Сертифицированные устройства — список сертифицированных Google устройств, совместимых с Google Play.
Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei