Использование Frida для поиска уязвимостей в Razer Pay
Moody
TL; DR
В приложении Razer Pay использовалась подпись на каждом запросе для того, чтобы предотвратить изменение исходящих данных. Каждый GET и POST запрос, отправляемые на сервер, был защищен значением параметра signature.

Любые попытки изменить параметры запроса приводили к получению ответа с сообщением об ошибке. Однако, путем реверс-инжиниринга APK-файла, я получил возможность генерировать собственные сигнатуры, меняя любые отправляемые данные. Комбинируя Fridа и Burp, я смог выявить и эксплуатировать большое количество опасных IDOR'ов.
Предыстория
При участии в багбаунти, я отдаю предпочтение программам с более высоким порогом входа, дабы избежать дублей. Когда Razer разместились на HackerOne, меня очень заинтересовало их мобильное приложение Razer Pay. Отчасти потому, что для регистрации в нем требовался номер мобильного телефона Малайзии или Сингапура. Живя в Австралии, у меня не было такого номера. Однако у меня были друзья и родственники, проживающие в Малайзии, которые с радостью предложили свою помощь. Зная, что многие охотники за багами не смогут перепрыгнуть этот барьер, я решил остановиться на этой программе и погрузиться в глубокий анализ :)

Я начал с перехвата и анализа трафика приложения, используя Burp, и почти сразу же заметил, что не могу изменять отправляемые данные. Ошибки, поджидающие меня в ответе со стороны сервера, были связаны с наличием подписи в каждом запросе. Первая мысль, которая пришла мне в голову, - зарегистрировать вторую учетную запись, скопировать полезную нагрузку для действия, которое мог выполнить только "свежий" пользователь, и выполнить его в сеансе первого пользователя. Но, к сожалению, попытка провалилась, поскольку подпись также была сгенерирована на основе заголовка аутентификации сеанса второго пользователя.
Я был полон решимости узнать, как генерировалась подпись. Поэтому я декомпилировал приложение с помощью apktool и использовал Jadx-Gui, чтобы просмотреть код. Просмотривая API-энпоинты, я надкнулся на метод «MD5Encode». Название предполагало использование MD5, но вручную я так и не смог сгенерировать верную сигнатуру (возможно, я неправильно подставлял параметры или они использовали какую - то собственную реализацию этого метода).

Удаление чужого банковского счета
Решив не останавливаться на пол пути, я решил скопировать весь код на Java и сгенерировать подпись в автономном режиме. В качестве IDE я использую IntelliJ IDEA. На тот момент я уже знал правильную последовательность значений параметров, которую мне нужно вставить в метод «MD5Encode», основываясь на предыдущем анализе исходного кода. Я внес незначительные изменения, необходимые для компиляции кода (из-за обфускации), - это было довольно просто. В результате выполнения кода, я получил ту же самую сигнатуру, ранее перехваченную в запросе - я был на правильном пути!


Я сразу же захотел проверить наличие IDOR, так как догадывался, что разработчики надеялись лишь на подпись каждого запроса. Я протестировал метод /deleteBankAccount, предварительно вычислив сигнатуру на первом аккаунте и подкорректировав ее под второй (с использованием соответствующего токена). После этого отправил запрос и ...
Это сработало, - мне удалось удалить банковский счет моего другого пользователя!

Frida идет на помощь
Я знал, что должны существовать и другие уязвимые к IDOR эндпоинты, эксплуатации которых препятствовал алгоритм генерации подписи. Я попытался реализовать ту же самую атаку, что и раньше, но ничего не получалось. Это происходило из - за того, что другие API-эндпоинты использовали другой алгоритм подписи, код которого, в свою очередь, был хорошо обфусцирован. Скомпилировать мне его не удалось, поэтому я потратил достаточно много времени впустую на попытку деобфусцировать код.
Вот тогда - то Frida и пришла мне помощь - он была великолепна, так как выполняла за меня всю тяжелую работу, и все, что мне нужно было сделать, - это найти правильный метод, который я хотел использовать. Найдя его и передав Fridе необходимые аргументы для генерации новых подписей, я смог быстро автоматизировать работу по генерации этих самых подписей.
// frida.js - модуль для генерации и отображения подписи
console.log("Starting...")
Java.perform(function () {
var MD5 = Java.use('com.mol.molwallet.view.MD5')
MD5.MD5Encode.implementation = function (arg)
{
console.log("Hooking class MD5 - method MD5Encode")
// Вычисление новой подписи
var ret_value = this.MD5Encode("groupId=1x9&userIds=95xxx7&token=b6fxxxd3-2xxc-4xxf-bxx7-7fxxxxa6")
console.log("[+] signature= " + ret_value)
// Вызов метода с исходными аргументами, дабы избежать краша
var ret_value = this.MD5Encode(arg) //original value
console.log("original ARG: " + arg)
return ret_value;
}
})
Чтобы запустить Frida, я должен был иметь root-права на устройстве (в репорте это не имело существенного значения, так как я тестировал проблему, которая находилась на сервере, и злоумышленник так же мог легко использовать устройство с root'ом для выполнения атаки). Для запуска Frida на смартфоне, я использовал следующие команды:
$ adb shell # sudo su # /data/local/tmp/frida-server
В другой вкладке терминала я выполнил
$ frida -l frida.js -U com.mol.molwallet
для запуска ранее написанного скрипта.
Теперь, выполняя любое действие в мобильном приложении, мой скрипт получал подпись для запроса и выводил значение из метода «MD5Encode». В результате я смог получить верную подпись, необходимую для своего запроса. Я смог добавить себя в чат-группу, в которую меня не приглашали. В результате это привело к том, что я смог просматривать сообщения чата другого пользователя, и, что хуже всего - красть невостребованные деньги, которые делятся между участниками в групповом чате.


Изменить и повторить
Я повторил ту же технику с Frida для всех других уязвимых API-эндпоинтов. Имеющиеся уязвимости позволяли просматривать переводы валюты между пользователями, просматривать и изменять сведения о транзакциях или личной информации.
Последние мысли
Общая сумма вознаграждения, полученного за сообщение о багах составила приблизительно 6 000 долларов США. Процесс раскрытия информации и вознаграждения с командой Razer несколько раз срывался из-за отсутствия ответа с их стороны. Иногда я съеживаюсь, читая свои множественные запросы "чтобы посмотрели", которые были проигнорированы. И большинство проблем были решены лишь недавно, поэтому не на долго я решил прерваться и отдохнуть.
Прочитать оригинал этого материала на английском можно здесь.
Cybred - канал об информационной безопасности и конкурентной разведке, вдохновленный идеями олдскульных андеграундных интернет-сообществ о свободе распространения информации в сети и всеобщей взаимопомощи.