Instagram под капотом

Я не пользователь Instagram. Так уж повелось. С тех самых пор, когда я узнал об этой социальной сети, она ассоциировалась у меня с гламурными кисулями и прочими любителями продемонстрировать на весь Интернет свою увлекательную жизнь / вкусный ужин / быструю машину / что-то ещё. Кое-кто из моих друзей считает, что я ошибаюсь. Недавно обстоятельства сложились таким образом, что я обнаружил себя в процессе обхода средств защиты в попытке получить доступ к самой мякотке сервиса — его API.

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

Впрочем, начнём издалека.

Часть 1. Клиент-сайд

Давайте допустим, что я не доверяю Facebook и принципиально не ставлю их приложения на свой смартфон. Давайте допустим, что нужда заставляет меня воспользоваться Instagram. Давайте допустим, что я не хочу пользоваться веб-версией и мне в голову не пришло ничего лучше, чем установить приложение на эмулятор Android. Надеюсь, Вы читаете этот блог уже какое-то время и привыкли к таким моим странным предпосылкам. Если не привыкли — придётся привыкнуть.

Итак, Вы скажете «эмулятор Android», я скажу — «Genymotion». Мне он нравится, потому что он быстрый и простой в обращении. При помощи adb устанавливаем Instagram на наш виртуальный Android (если попытаетесь это повторить, имейте в виду, что Genymotion это x86), пробуем залогиниться и нам это не удаётся. Мы ещё даже не пытаемся ничего исследовать, а приложение уже отказывается работать. При этом выдаёт очень информативную ошибку:

Естественно, logcat не помогает понять суть проблемы, а глубже копать сходу лень. Опыт ковыряния Android-приложений подсказывает, что даже не самые лучшие разработчики мира (я смотрю прямо на Вас, ребята, которые предлагают мне меняться на Avito) умеют понимать, когда их приложение работает на эмуляторе, так что это неудивительно. Тот же самый опыт подсказывает, что без SSL-pinning’a не обойдётся. Сразу скармливаем приложение в MobSF и начинаем думать.

На Хабре есть неплохая статья об одном кейсе обхода SSL-pinning’а. Там всё решилось подменой файла с «говорящим названием» ssl_pinning_certs_bk146.bks. MobSF (или apktool, если Вы любите делать всё своими руками) разбил для нас APK и ничего подобного мы не видим.

Здесь можно провести часы за попытками найти место, где Instagram сверяется со своим сертификатом, но пытливый ум и Google способны привести Вас к разгадке всего за 30 секунд. Итак, сэкономлю Вам время и скажу, что проверка происходит в файле libliger.so по адресу:

/data/data/com.instagram.android/lib/

Что ж, предлагаю вооружиться плагином BinDiff для IDA и взглянуть на это немного подробнее.

Сравним два файла libliger.so идентичной версии, один из которых уже отучен сверять сертификат, а второй — ещё нет. Стыдливо краснеет только одна строчка, она-то нам и нужна:

BinDiff позволяет видеть функции, которые нам не пригодились:

Если начать всматриваться в бездну, можно даже увидеть лишний код:

Вообще этот инструмент используется для того, чтобы сравнивать изменившиеся после патча критических уязвимостей файлы, с целью поиска 1-day уязвимостей. Но никто не мешает нам воспользоваться им в своих целях.

Итак, мы имеем при себе версию libliger.so, отученную сверять сертификат. Что дальше? Первое, что приходит в голову — заменить исходный файл пропатченным на эмуляторе с root-доступом и попытаться запустить приложение заново. Так и поступим. Результат, скромно выражаясь, неудовлетворительный. Всё та же информативная ошибка:

Попытаемся пустить трафик через Burp Suite, чтобы понять проблему. Прокладываем сертификат в систему как доверенный, запускаемся и видим, казалось бы, то же самое:

Но нет, в этот раз Burp показывает, что трафик пошёл, однако на любой запрос мы получаем один и тот же ответ — 400.

Часть 2. Сервер-сайд

Признаюсь, на этом моменте я начал готовиться к битве. Я решил, что умные разработчики Facebook обнаружили попытку соединиться с сервером с эмулятора, отученного от SSL-pinning’а. Наверняка они знают десятки способов проверки на запуск в эмуляторе и мне предстоит провести кучу времени с подругой со звучным именем Frida.

Но потом мой внутренний пентестер очнулся и сказал, что разработчики — одни из самых ленивых существ на Земле. И разработчики из миллиардных компаний — не исключение. Прежде чем бросаться в битву, нужно проверить, нет ли очевидного обхода этих мер защиты. И что Вы думаете?

Защита от эмуляции реализована на регулярках. И нет, я не шучу. Вам натурально нужно заменить всего две строчки в запросе (возможно даже одну, мне лень проверять) и серверы Facebook примут ваш эмулятор за физическое устройство. Эксперименты со злополучными строчками я оставляю читателю. Скажу, разве что, что автозамена легчайше делается в том же Burp Suite. Итак, заменяем на лету всё, что выдаёт наш эмулятор в его трафике, и — победа:

Вот теперь можно выдохнуть. Трафик полился через прокси в открытом виде. Самое время лицезреть воочию результаты своего труда. И зрелище это, я Вам скажу, не из приятных.

Часть 3. Выводы

«Ну и что с того?» — слышу Ваш молчаливый вопрос по ту сторону провода. Позвольте, я покажу.

Добравшись до API, мы перестаём встречать всяческое сопротивление. Хотите мгновенный способ проверить, занят ли ник или существует ли для той или иной почты учётная запись? Запросто:

Получить информативное сообщение о том, что имя пользователя верное, а пароль — нет? Запросто:

Наконец, вот столько параметров Instagram предоставляет любителям фаззинга всего в одном из сотен ответов:

Самый первый трафик в открытом виде я записал 23 октября. На момент написания этой статьи, а именно 3 декабря, те запросы всё ещё валидны, они подлежат реплею без обхода каких-либо механизмов защиты — просто нет токена, который мог бы инвалидировать запрос. Выходит, что единожды записав запрос, мы можем скормить его в cURL и делать с ним что угодно, в том числе безнаказанно перебирать пароли пользователей.

Впрочем, пространные рассуждения о том, как миллиардные компании заботятся о безопасности своих пользователей я, традиционно, оставляю читателю.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *