- Название: Android UnCrackable L1
- Категория: reverse (android)
- Платформа: mas.owasp.org
Примечание от автора:
A secret string is hidden somewhere in this app. Find a way to extract it.
Сегодняшний райтап, как и, возможно, несколько последующих, будут посвящены небольшим андроид-крякмисам от
OWASP. Сегодня будем разбирать самый лёгкий - в качестве введения, так сказать.
Скачиваем
apk, устанавливаем его (можно на эмулятор), запускаем:
Опа! С порога нас встречают детектом рута на устройстве (я запустил на ручёном смартфоне). Рут я ставил через
magisk, а в нём есть один интересный плагин -
DenyList, тот позволяет скрыть наличие рута от выбранных приложений. Вдаваться в подробности, как он работает, я особо не буду - лишь в конце статьи украду у Вас пару минут, да и в сети полно материала, пытливый читатель найдёт. Включим наш крякмис в списки
DenyList и попробуем запустить приложение снова:
Получилось! Теперь можно полноценно потыкать наше приложение, хотя тыкать тут особо нечего: лишь поле для ввода, кнопка
Verifyи благодарность создателю. По традиции попытаем удачи:
Штош, ожидаемо, не получилось. Теперь уже займёмся делом - закинем наш
apkв
JADX - мощную тулзу для декомпила
dexв
Java, считайте, декомпилятор
IDAдля андроида.
Теперь нам доступны несколько файлов, каждый со своими классами и функциями. Заглянем, для начала, в
MainActivity:
Благо, код вполне читаемый, и даже для не-джависта вполне понятный. Сразу можно заметить наше первое препятствие (к нему я ещё вернусь в конце статьи):
Как можно заметить, тут не только идёт детект рута, но, судя по всему, ещё и наличие отладки отслеживается. Последним мы сегодня заниматься не будем, поэтому продолжим анализ полученного кода.
А вот и то, что нам нужно: условие проверки нашего ввода. Всё держится на возвращаемом значении функции
a.a(), в которую передаётся наш текст - давайте посмотрим, что там такого интересного:
Тут нужно ненадолго остановиться, мы наткнулись на кое-что интересное. Давайте анализировать функцию с конца: её возвращаемое значение - результат работы
equals() - аналога функции
strcmp, проверяющей, одинаковы ли строки. Заметьте, наш аргумент
strнигде больше в функции не мелькает, а значит, интерес представляет второй подопытный -
bArr. Последний формируется через функцию
sg.vantagepoint.a.a.a(), где первым аргументом идёт результат соседней функции
b() с какой-то строкой, а второй - набор байт, декодированный из
base64. С последним, думаю, всё понятно, а функция
b(), как видно из скриншота, превращает hex-строку в набор байт, ничего другого. После
bArrможно заметить строку с упоминанием
AES- наводит на некоторые мысли, не правда ли? Не будем гадать - заглянем внутрь
sg.vantagepoint.a.a.a():
Перед вами самый сок - функция, расшифровывающая
AES-строку. В качестве первого аргумента (
bArr) выступает секретный ключ, а в качестве второго (
bArr2) - сам зашифрованный набор байт. И раз и то, и то у нас под рукой имеется, давайте это дело расшифруем сами - с помощью прелестной тулзы
Cyberchef:
Получили вполне читабельную строку - давайте попробуем её ввести в приложение:
Получилось, мы зарешали крякмис! Было довольно просто, но это только начало - дальше будет сложнее (если я сам их зарешаю и выложу райтапы XD). Да, возвращаясь к коду выше, хочу обратить ваше внимание на, как мне показалось, один интересный момент:
Это проверка на наличие рута на устройстве и текущего дебаггинга приложения. Последняя проверка проверяет текущие флаги запуска приложения:
А вот в проверке на наличие рута фигурируют сразу 3 функции:
Первая функция тривиальная - она просто проверяет наличие бинарника
suпо пути
PATH. Третья функция является более комплексной версией первой - несколько распространённых путей и вариантов переименованного
suи связанных с ним файлов. Вторая же функция работает интереснее: она проверяет флаги текущего билда системы (
android.os.Build.TAGS) и ищет флаг подписи
test-keys.
Дело в том, что при компиляции ядра системы, последнее подписывается верифицированным ключом от проверенного разработчика -
release-keys. Наличие же
test-keys означает, что оно было подписано пользовательским ключом, сгенерированным сторонним девелопером. А, как вы уже можете догадаться, рутирование системы - не тот процесс, который предполагается подписать релизными ключами.
Тем не менее, все эти три функции мы через
DenyListобошли, а значит - технологии и методы защиты и антизащиты не стоят на месте. Конечно, это лишь одни из примитивных методов проверки на рута - есть более комплексные, которые просто через
DenyListне обойдёшь, но это не к сегодняшнему райтапу.
Надеюсь, эта небольшая статья поможет Вам в нашей нелёгкой стезе.
Удачного ревёрса!
made 4@rev_with_da_boys