Дисклеймер: Статья создана в развлекательных, ознакомительных и образовательных целях.
Вступление
Примерно 7 месяцев назад один знакомый попросил меня посмотреть мобильное приложение Pikabu, к чему я и приступил.Вступление
При просмотре запросов регистрации я увидел такую вот штуку в данных запроса:
Если скопировать запрос полностью (то есть, ту же почту, логин и т.д.) в зеннопостер, то, вроде бы, всё хорошо, нам пришёл в ответ айди регистрации:

Но если мы поменяем в запросе какие-либо данные, к примеру почту, на которую мы будем регистрировать аккаунт, в ответ на запрос уже придёт ошибка:

Что такое хэш? По гуглу, это - функция, осуществляющая преобразование массива входных данных произвольной длины в выходную битовую строку установленной длины, выполняемое определённым алгоритмом.
К примеру, если взять алгоритм хэширования MD5, то строка "password" превращается в "5f4dcc3b5aa765d61d8327deb882cf99".
То есть, с регистрацией аккаунтов через мобильное api у нас уже появились проблемы, которые надо как-то решать.
В данной статье я постараюсь максимально (насколько это у меня получится) простым языком объяснить решение данной проблемы. Также возможны недочёты в тексте, буду править, что найду.
Хэш пикабу один из самый простых что я видел.
Установку Frida и сниффера я постараюсь разложить кратко, но без пропуска важных моментов, так как данные этапы уже был описаны на форуме (а именно в https://zennolab.com/discussion/thr...moschju-frida-server-burpsuite-i-bonus.79264/, и ещё где-то).
Инструментарий данной статьи:
- Сниффер - Charles proxy. Можно использовать и BurpSuite, и Fiddler, без разницы.
- Устройство на android с root – в моём случае это реальный телефон, Redmi 6a, прошитый. Можно использовать и эмулятор. Почему именно реальное устройство? Выбор давно пал в сторону него, ибо с эмуляторами уже не раз было много проблем (в частности, вылеты приложений и т.п.), как раз в арсенале был старенький, но вполне работающий Redmi 6a. Гайды о прошивках можно найти на 4pda, в большинстве случаев всё расписано по шагам. Да и в отдельных, но редко встречающихся случаях приложение имеет детект эмулятора.
- Декомпилятор apk файлов - JADX (https://github.com/skylot/jadx)
- Frida - https://frida.re/ - это набор инструментов для разработчиков, реверс-инженеров и исследователей безопасности.
- Скачиватель apk файлов (входить через впн, если вы из ру) - https://apk.support/apk-downloader
1. Устанавливаем последнюю версию python - https://www.python.org/downloads/
Обязательно ставим галочку на “add to path” в установщике:

2. Открываем консоль windows и пишем в ней «pip install frida-tools»

По последней строчке видим, что всё успешно установилось.
3. По такому же принципу устанавливаем objection, пишем в консоли команду «pip install objection»
4. Далее скачиваем Android SDK Platform Tools - https://dl.google.com/android/repository/platform-tools-latest-windows.zip и распаковываем в удобной для нас папке.
В окне папки, где мы распаковали наш архим, пишем «cmd» и нажимаем enter, должна открыться консоль с путём нашей папки:

Устройство на android должно быть с рутом (root). В настройках разработчика должен быть включен «USB Debugging». Название может отличаться на разных телефонах, о вашем устройстве лучше почитать на 4pda.
Подключаем телефон по usb к пк. В консоли пишем «adb devices», на телефоне может появится уведомление о разрешении доступа, принимаем его. Наш девайс должен появится в консоли:
Далее переходим на https://github.com/frida/frida/releases и скачиваем frida-server для android:
Информацию о том, какой именно файл нужно скачать, можно понять, погуглив конфигурацию вашего устройства.
Распаковываем архив (формата .xz) в нашу папку, куда мы положили Android SDK Platform Tools, и переименовываем распакованный файл в “frida-server” (для удобства, ибо изначально там файл с номером версии).
Далее в уже открытой консоли пишем три команды по очереди:
Видим, что файл успешно передался на телефон.
И далее запускаем сервер фриды:
При этом никаких сообщений быть не должно, т.е. состояние как на скриншоте означает что сервер Фриды запущен.
Всё, данное окно не трогаем.
Примечание. На моём устройстве, для запуска сервера фриды, в начале нужно прописать «adb shell "su -c setenforce 0"». Бывают ещё редкие ошибки, но 99% их решений гуглится.
Если никаких ошибок в консоли нет, то, скорей всего, всё нормально работает.
Откроем новое окно консоли (Именно новое!) и проверим, написав команду frida-ps -Uai:
Как мы видим, нам в ответе показаны все установленные приложения на устройстве, то есть всё работает.
Примечание. Если вы закроете окно консоли, в котором вы запустили сервер фриды, можно убить процесс через данные команды:
Обязательно ставим галочку на “add to path” в установщике:

2. Открываем консоль windows и пишем в ней «pip install frida-tools»

По последней строчке видим, что всё успешно установилось.
3. По такому же принципу устанавливаем objection, пишем в консоли команду «pip install objection»
4. Далее скачиваем Android SDK Platform Tools - https://dl.google.com/android/repository/platform-tools-latest-windows.zip и распаковываем в удобной для нас папке.
В окне папки, где мы распаковали наш архим, пишем «cmd» и нажимаем enter, должна открыться консоль с путём нашей папки:

Устройство на android должно быть с рутом (root). В настройках разработчика должен быть включен «USB Debugging». Название может отличаться на разных телефонах, о вашем устройстве лучше почитать на 4pda.
Подключаем телефон по usb к пк. В консоли пишем «adb devices», на телефоне может появится уведомление о разрешении доступа, принимаем его. Наш девайс должен появится в консоли:
Далее переходим на https://github.com/frida/frida/releases и скачиваем frida-server для android:
Информацию о том, какой именно файл нужно скачать, можно понять, погуглив конфигурацию вашего устройства.
Распаковываем архив (формата .xz) в нашу папку, куда мы положили Android SDK Platform Tools, и переименовываем распакованный файл в “frida-server” (для удобства, ибо изначально там файл с номером версии).
Далее в уже открытой консоли пишем три команды по очереди:
- adb root (бывает нужна, в моём случае – нет)
- adb push frida-server /data/local/tmp/
- adb shell "chmod 755 /data/local/tmp/frida-server"
Видим, что файл успешно передался на телефон.
И далее запускаем сервер фриды:
При этом никаких сообщений быть не должно, т.е. состояние как на скриншоте означает что сервер Фриды запущен.
Всё, данное окно не трогаем.
Примечание. На моём устройстве, для запуска сервера фриды, в начале нужно прописать «adb shell "su -c setenforce 0"». Бывают ещё редкие ошибки, но 99% их решений гуглится.
Если никаких ошибок в консоли нет, то, скорей всего, всё нормально работает.
Откроем новое окно консоли (Именно новое!) и проверим, написав команду frida-ps -Uai:
Как мы видим, нам в ответе показаны все установленные приложения на устройстве, то есть всё работает.
Примечание. Если вы закроете окно консоли, в котором вы запустили сервер фриды, можно убить процесс через данные команды:
- adb shell su
- netstat -tunlp
- Далее ищите процесс «frida-server» в списке, запоминаете его PID, и убиваете командой «kill -9 pid», заменив pid на нужный номер.
Я использую Charles proxy. Мне он нравится из-за простоты и наличия всех нужных мне инструментов.
Можно использовать и BurpSuite, и Fiddler, и другие снифферы, в данном случае я не вижу никакой разницы.
1. В случае с Charles proxy качаем триал версию с их сайта https://www.charlesproxy.com/download/и генерируем ключ на сайте zzzmode com/mytools/charles/.
2. После запуска сниффера на пк, ставим в настройках wi-fi на устройстве проксю, которая показана вот в этом пункте меню:
3. Проходим по ссылке в браузере устройства на chls.pro/ssl и ставим сертификат.
4. Также сразу отключаем windows прокси (находится в разделе proxy – windows proxy) и включаем обе кнопки в главном меню:
Первая отвечает за запись трафика, вторая – за ssl проксю.
Что касается установки и снятия прокси сниффера на устройстве, когда мне нужно снять трафик с приложения, я использую команды
Можно использовать и BurpSuite, и Fiddler, и другие снифферы, в данном случае я не вижу никакой разницы.
1. В случае с Charles proxy качаем триал версию с их сайта https://www.charlesproxy.com/download/
2. После запуска сниффера на пк, ставим в настройках wi-fi на устройстве проксю, которая показана вот в этом пункте меню:
3. Проходим по ссылке в браузере устройства на chls.pro/ssl и ставим сертификат.
4. Также сразу отключаем windows прокси (находится в разделе proxy – windows proxy) и включаем обе кнопки в главном меню:
Первая отвечает за запись трафика, вторая – за ssl проксю.
Что касается установки и снятия прокси сниффера на устройстве, когда мне нужно снять трафик с приложения, я использую команды
- adb shell settings put global http_proxy proxy:port– поставить прокси
- adb shell settings put global http_proxy :0 – снять прокси
Переходим на сайт https://apk.support/apk-downloader, копируем ссылку нашего приложения из Google Play и нажимаем кнопку Analyze, далее снизу будут сборки под конкретный регион, я выбрал EU:
Очень важно, чтобы на устройстве и в декомпиляторе оказались одинаковые файлы.
То есть надо скачать apk файл с сайта выше, закинуть его на наше устройство, и также оставить на пк, так как мы в дальнейшем будем его разбирать. Ибо в разных версиях приложения (Имеется в виду не именно номер версии, а отдельные сборки для us/eu) могут содержаться разные классы внутри приложения, что очень затруднит нас
Очень важно, чтобы на устройстве и в декомпиляторе оказались одинаковые файлы.
То есть надо скачать apk файл с сайта выше, закинуть его на наше устройство, и также оставить на пк, так как мы в дальнейшем будем его разбирать. Ибо в разных версиях приложения (Имеется в виду не именно номер версии, а отдельные сборки для us/eu) могут содержаться разные классы внутри приложения, что очень затруднит нас
Запускаем приложение
Открываем новую командную строку и пишем «frida-ps -Uai»:
Здесь указаны все установленные приложения, а точнее их PID, имена и идентификаторы. Нам нужен будет Pikabu, а именно ru.pikabu.adndroid
SSL Pinning. Все приложения от просмотра трафика защищены по-разному, в большинстве случаев мне хватало команды «objection --gadget "name" explore --startup-command "android sslpinning disable"» (где name – идентификатор приложения). В случае с Пикабу это не действовало, ошибок никаких не было, но и приложение не работало.
Покопавшись в интернете, я нашёл подходящий скрипт для снятия пиннинга, а именно https://pastebin.com/AxfLBVeG. Создаём файл script.js и вставляем данный код в наш файл. Много подобных готовых скриптов лежит на https://codeshare.frida.re/ и в гугле, не только для обхода SSL Pinning, но и для всяких других штук.
Далее из папки, где лежит наш новосозданный скрипт, запускаем командную строку (Как мы делали в случае с platform tools) и пишем команду:
- frida -U -l script.js -f ru.pikabu.android
Этой командой мы запустим приложение, одновременно внедрив в него наш скрипт для обхода ssl pinning.
Как видим, посты прогрузились, трафик в Charles proxy появился, значит всё работает:

Работа с декомпилятором JADX
Мы будем смотреть код приложения (Нужно же как-то понять, как генерируется наш хэш?) с помощью JADX.
Скачиваем последнюю версию JADX - https://github.com/skylot/jadx/releases и распаковываем его в удобное место.
Открываем наш заранее скачанный apk файл Pikabu:
Ждём прогрузки. У нас открылся проект с декомпилированным кодом:
Поиск нужного фрагмента кода
В нашем случае нам нужно понять, в каком именно месте генерируется данный хэш, проанализировать код, посмотреть входные параметры и сделать его реализацию.
В JADX есть опция поиска:
Можно сразу поставить галочку «Keep open», для удобства:
Как именно искать нужный нам фрагмент кода, где может генерироваться наш хэш?
Примечание: поиск подобного кода во многих случаях значительно отличается от того, который показан в этой статье.
Для начала, попробуем вписать в поиск «"hash"» (именно с кавычками), то есть то имя, которое мы нашли в данных запроса.
Пробуем:
Для того, чтобы попасть в нужный фрагмент кода, нужно сделать даблклик мышкой по одному из вариантов.
Посмотрим на все 5 вариантов:
В общем, мне ничего не приглянулось, нужно искать дальше.
Примечание 1: сразу хочу сказать, что всё-таки прошлые функции скорей всего можно "покрутить", т.е. посмотреть какие именно аргументы они принимают и возвращают, но в случае с нашим приложением всё немного проще, так что дальше я покажу поиск нужного нам кода по-другому.
Примечание 2. Чтобы попасть в нужную нам функцию в JADX, нужно зажать ctrl и кликнуть на неё.
К примеру, здесь есть какая-то функция «d», мы можем посмотреть, что она из себя представляет, кликнув на её название (то есть буковку «d») с зажатым ctrl.
Но вот во втором варианте в поиске есть что-то с названием «CE_SETTINGS_HASH», и ещё там есть “hash”:
Отсюда, по идее, можно продолжить поиск. А именно, по «CE_SETTINGS_HASH»:
Здесь мне сразу приглянулся данный фрагмент кода, потому что он возвращает какую-то функцию (i), и в её параметрах есть наше ключевое слово (CE_SETTINGS_HASH), и ещё какая-то функция "d", и с ней ещё 4 параметра, возможно, это то что нам нужно. Да и код находится в пакете "ru.pikabu.android.server.s":
Далее можно (нужно) осмотреть найденный фрагмент кода, а именно посмотреть данные функции:
Функция i:
Функция d:
Я сразу подумал, что здесь ничего не генерируется, ибо по беглому осмотру мне показалось, что здесь идёт какая-то работа с массивами. Попробуем тогда что-то другое.
Что делать дальше? Как вариант, можно осмотреть всю область текущего файла, где мы нашли прошлые функции. Ибо частенько рядом с такими функциями есть то, что нам нужно, либо то, что укажет нам, как именно дальше надо искать.
К примеру, во время просмотра мне приглянулся вот такой фрагмент кода, который был чуть выше наших предыдущих функций:
Видно, что в нём при возврате, есть сразу две функции, ii.p.a и ii.p.b, последняя принимает на вход строку, видимо.
Посмотрим на код самих этих функций, для начала ii.p.b:
MD5 – это алгоритм хэширования. То есть, скорей всего, мы очень близко.
Итак, скорей всего мы нашли нужную функцию, что дальше? Нужно как-то проверить нашу находку.
Наша функция что-то получает на входе, и нам нужно понять, что именно.
В данном случае, анализируя код, мы видим, что функция на вход получает строку, это видно по типу переменной, «String»:
Теперь, надо как-то понять, какие именно аргументы функция получает на входе.
Нам нужно будет сделать хук через Frida. Что такое хук?
- Из гугла: Хуки — это технология перехвата вызовов функций в чужих процессах.
Код хука функции для Фриды выглядит примерно так:
JavaScript:
Java.perform(function () {
var foy = Java.use('ii.p');
foy.b.overload('java.lang.String').implementation = function(a) {
console.log(a);
return this.b(a);
}
})
var foy = Java.use('ii.p');, где 'ii.p' - имя нашего пакета, где находится функция. Его можно получить в jadx:
foy.b.overload('java.lang.String') – в данном случае b – это как раз наша функция, а 'java.lang.String' – это тип аргумента, который в неё передаётся, в нашем случае это строка, как сказано ранее.
Это один из его вариантов хука функции для фриды, в интернете есть и другие реализации. В данном случае мы привязываемся к нужному нам классу в приложении, и далее к функции. При вызове последней нам в лог будут приходить аргументы, которые передаются в неё.
Теперь нам надо поместить наш код хука в файл и внедрить его в приложение. Я добавил его в наш файл script.js. То есть теперь в нашем файле одновременно два скрипта, для обхода SSL Pinning, и для хука функции:
Закрываем прошлое окно консоли, где у нас был включен ssl unpinning, и запускаем наш обновлённый скрипт той же командой:
frida -U -l script.js -f ru.pikabu.android
Как видим, оба скрипта работают одновременно. Не очень удобно, конечно, учитывая, что они вместе пишут лог, но при раздельном запуске (т.е. в двух отдельных окнах командной строки по скрипту), у меня крашилось приложение, в случае с Pikabu.
Помимо работы первого нашего скрипты (для снятия ssl pinning), у нас в логе появляются новые строки, именно их на входе получает хукнутая нами функция.
Сейчас попробуем зарегистрировать аккаунт в приложении. Смотрим наш запрос в сниффере:
Теперь смотрим на консоль, где работают наши скрипты:
Те строки, где присутствует "user.name.check" – очевидно, что это проверка логина (существует он на пикабу, или нет).
А вот самая последняя строка – это как раз то, что нам нужно, судя по "user.register" (Оно совпадает с url регистрации из сниффера). Мы уже понимаем, что на вход в функцию при регистрации попадает вот такая строка «kmq4!2cPl)peZ,user.register,1671570215943,1,123123123,hjfjgjfjfjh,hjfjgjfjfjh@gmail.com»
Можно разобрать её:
- kmq4!2cPl)peZ – это что-то похожее на соль. Соль в хэше - это дополнительная случайная строка, которая добавляется к основной строке перед хэшированием.
- user.register - часть ссылки для регистрации, где оригинал - «https://api.pikabu.ru/v1/user.register»
- 1671570215943 – unix timestamp
- 1 – я не знаю что это такое, да и плевать в данном случае, ибо, судя по логу, оно статичное
- 123123cfcfZ – наш пароль
- Hjfjgjfjfjh - логин
- hjfjgjfjfjh@gmail.com – наша почта
Собираем код для генерации хэша
Мы успешно получили входные аргументы нашей функции. Также не забываем о том, что в генерации «hash» участвуют две функции:
Первую (ii.p.b) мы уже разобрали. Посмотрим на вторую (ii.p.a):
Здесь происходит преобразование в Base64, если судить по надписи "Base64".
У нас уже есть пример хэша и данных, которые в него попадают. Нужно попробовать собрать его и сравнить со сниффером, то у нас получилось, или нет.
Получается такая схема: Входные данные (То есть наша полученная строка) -> MD5 -> Base64
Нужно проверить, правильно ли мы всё поняли.
Нашу полученную строку "kmq4!2cPl)peZ,user.register,1671570215943,1,123123cfcfZ,hjfjgjfjfjh,hjfjgjfjfjh@gmail.com" преобразуем сначала в md5:
В директивах using пропишем "using System.Security.Cryptography;"

C#:
string input = project.Variables["text"].Value;
System.Security.Cryptography.MD5 md5Hasher = System.Security.Cryptography.MD5.Create();
byte[] data = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(input));
StringBuilder md5hash = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
md5hash.Append(data[i].ToString("x2"));
}
return md5hash.ToString();
Теперь преобразуем её в base64:
C#:
project.Variables["result2"].Value = Convert.ToBase64String(Encoding.UTF8.GetBytes(project.Variables["result"].Value));
Теперь сравниваем полученные строки.
Строка из сниффера:
Наша строка:
Почти совпадает. Но что такое "\u003d"? Погуглив, стало понятно, что это равно "=", то есть тоже самое, что и в нашем сгенерированном хэше:
То есть, мы всё сделали верно.
Теперь надо попробовать отправить запрос на регистрацию с изменёнными данными и сгенерированным нами хэшем.
В запросе изменим почту на "testzenno123@gmail.com", логин на "testzenno123", а пароль сделаем "123123zenno". Итого у нас получается входная строка хэша вида "kmq4!2cPl)peZ,user.register,1671608516940,1,123123zenno,testzenno123,testzenno123@gmail.com".
Прогоним её через md5 и base64:
Подставим все данные, включая новый хэш, в запрос и отправим его:
Как видим, хэш прошёл и мы получили id регистрации.
То есть, дело сделано, мы смогли реализовать один из самых простых хэшей в мобильных приложениях, дальше уже можно делать регистрацию (Но статья совсем не об этом).
- Номер конкурса статей
- Восемнадцатый конкурс статей
- Тема статьи
- Нестандартные хаки
Последнее редактирование:






