Форензика Android: взлом графического ключа
Дата публикации: 2020-05-16
Автор: Перевод: @ZzzNein
Теги: android
Источник: https://resources.infosecinstitute.com/android-forensics-cracking-the-pattern-lock-protection/
Введение
В данной работе показано как разгадать графический ключ пользователя устройства на базе Android. Данный способ предположительно работает только на телефонах с рут-правами. Статья основана на задаче, которая решалась в ходе онлайн CTF (Capture the Flag – захват флага, соревнования по компьютерной безопасности).
Краткое содержание
В настоящее время почти на всех смартфонах помимо традиционного пароля используется графический ключ. Для разблокировки устройства пользователь должен соединить точки на экране в определенной заданной им последовательности. Этот «новый подход к безопасности» позволяет избежать нежелательных нажатий и дополнить процедуру авторизации. Данное действие представляется довольно сложным и безопасным, что в корне неверно.
Если внимательней посмотреть на то, что такое графический ключ и как он работает, легко прийти к выводу, что это всего лишь матрица 3×3 с некоторыми встроенными условиями: узор, который рисует пользователь, должен состоять как минимум из четырех точек, каждую из которых можно использовать всего один раз. Поскольку размер матрицы всего 3×3, графический ключ может состоять максимум из 9 точек.
Изучение схемы графического ключа
Поле графического ключа 3×3 может быть выполнено в числовой форме (цифры). По факту точки зарегистрированы в порядке от 0 до 8 (начиная с 0 в верхнем левом углу и заканчивая 8 в нижнем правом):
Последовательность, использованная на скриншоте выше: 1 – 2 – 5 – 8 – 7 – 4.
С точки зрения статистики, найти все комбинации между 0123 и 876543210 не так уж и сложно. Это даже не 0.2% из всех возможных девятизначных чисел. Мы должны получить примерно 895824 вариантов графических ключей.
Устройства на базе Android хранят данные графического ключа в формате незащищенной последовательности зашифрованных байт SHA-1. Вариант кода примерно похож на показанный ниже:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | private static byte[] patternToHash(List pattern) { if (pattern == null) { return null; } final int patternSize = pattern.size(); byte[] res = new byte[patternSize]; for (int i = 0; i < patternSize; i++) { LockPatternView.Cell cell = pattern.get(i); res[i] = (byte) (cell.getRow() * 3 + cell.getColumn()); } try { MessageDigest md = MessageDigest.getInstance("SHA-1"); byte[] hash = md.digest(res); return hash; } catch (NoSuchAlgorithmException nsa) { return res; } } |
Это значит, что вместо того, чтобы запоминать просто последовательность 125874, в системном файле сохраняется «несоленый» байтовый массив с именем gest.key. Он хранится в папке /data/system.
Большую часть такой информации можно почерпнуть напрямую из java-файлов «Android с открытым исходным кодом» (документация AOSP).
* Generate an SHA-1 hash for the pattern. Not the most secure, but it is
* at least a second level of protection. First level is that the file
* is in a location only readable by the system process.
* @param pattern the gesture pattern.
* @return the hash of the pattern in a byte array.
(Для ключа генерируется хэш SHA-1. Это не самый надежный способ, но дающий как минимум второй уровень защиты. Под первым уровнем понимается то, что файл хранится в ячейке, которая считывается только системным процессом. @param формирует графический ключ. @return – возврат хэша графического ключа в виде байтового массива).
Согласно данному куску кода наш пример графического ключа должен сохраняться в виде выражения 6c1d006e3e146d4ee8af5981b8d84e1fe9e38b6c
Возникает единственная проблема: SHA-1 – односторонняя криптографическая хэш-функция. Это значит, что мы не можем отделить обычный текст от хэшированного. Ввиду ограниченного числа возможных комбинаций ключа и того, что ОС Android не использует «соленый» хэш для создания словаря, содержащего все возможные хэши последовательностей от 0123 до 876543210, не потребуется много времени.
Решение проблем
У нас достаточно данных, чтобы проанализировать дамп файловой системы. Достаточно найти gesture.key и изучить его содержимое:
Указанный файл открывается в любом текстовом или шестнадцатеричном редакторе:
Последний шаг – сравниваем байты данного файла 2C3422D33FB9DD9CDE87657408E48F4E635713CB со значениями из готового словаря и находим хэш, позволяющий восстановить схему ключа.
Готовый словарь можно скачать по ссылке в конце статьи и открыть через любой SQLite-браузер. Воспользовавшись им, вы найдете схему оригинального графического ключа с помощью следующего запроса:
Select * from RainbowTable where hash = “2c3422d33fb9dd9cde87657408e48f4e635713cb”.
Получаем ключ для разблокировки «телефона жены».
Заключение
Взлом или обход данного вида защиты на Android не представляет никакой сложности. Единственная загвоздка в том, что мы не можем получить прямой доступ к /data/system/ и файлу gesture.key, если устройство незарутовано. Данный вариант хорош для забавы и удовлетворения любопытства, поскольку уже обладая доступом, вы можете просто удалить файл с хэшем SHA-1 или заменить его на свой. Кроме того, в большинстве случаев файлы блокировки не имеют никакой ценности с точки зрения форензики.
Ссылки:
- AOSP (LockPatternUtils.java): https://android.googlesource.com/platform/frameworks/base.git/+/f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8/core/java/com/android/internal/widget/LockPatternUtils.java
- Ссылка на словарь: http://www.mediafire.com/download/qs0sq5h8e2ly8jg/SHA1-android-pattern.rar
- Ссылка для скачивания частичного дампа телефона: http://www.mediafire.com/?g5k0cidbxdh7bu9