Мобильное приложение Starbucks — один из самых известных кейсов в ecommerce. Автор материала — программист опытным путем доказывающий, почему стоит открыть API этого приложения.

image

Мотивация


Стоит отдать должное приложению Starbucks — оно просто отличное. Я использую его (как минимум) раз в день. В нем есть все, что мне нужно от отличного мобильного сервиса — кофе, плейлисты хитов 80-х в Spotify и возможность избежать живого общения с другими людьми. Я явно не одинок в своих предпочтениях, так как 20% операций Starbucks в США сейчас производится через мобильные телефоны.

Помимо интеграции Slack и кофейных кнопок существует множество других интеграций, которые можно было бы реализовать, если бы компания открыла свой API для сторонних разработчиков. Она явно движется в этом направлении, поскольку у нее есть и аккаунт в Twitter, и (защищенный паролем) веб-сайт для разработчиков.

Однако я не мог ждать и поэтому решил взять дело в свои руки.

Было нелегко


Приложение Starbucks оказалось крепким орешком. Несмотря на URL-адрес «openapi.starbucks.com», пришлось пробираться через серьезные дебри, прежде чем начать анализировать вызовы, совершаемые приложением. Как и для любого другого приложения, обрабатывающего платежи, Starbucks предпринял многочисленные меры безопасности для защиты API, используемых своим приложением, от несанкционированного использования. Вот некоторые из них:

  • SSL certificate pinning
  • Создание цифрового отпечатка атрибутов вашего мобильного телефона, чтобы понять, используете ли вы смартфон
  • Шифрование этого отпечатка с использованием AES, 256-битным ключом и псевдослучайным вектором инициализации
  • Подписание запросов с меткой текущего времени

Наблюдение за запросами сети


Для начала мне нужен был способ наблюдать за запросами и ответами, которыми обменивались приложение Starbucks и его сервера. Обычно я просто настраивал свой iPhone на Charles (или mitmproxy), и этого было достаточно.

Но не в этот раз! Поскольку приложение использует certificate pinning, я не смог перехватить его запросы, как обычно. Вместо этого мне пришлось откопать свой старый телефон на Android, получить root-права, установить фреймворк под названием Xposed и, наконец, установить расширение, которое внедряется в запущенные приложения и отключает SSL pinning.

image

Муахаха

После его запуска я смог начать просмотр запросов с использованием прокси-сервера Charles. Однако это оказалось скорее ложной надеждой, так как не все запросы можно было легко воспроизвести. Тем не менее, я смог запросить основную информацию, например, о ближайших магазинах, меню и балансах карт.

image
Результат запроса о ближайшем магазине. Теперь вы знаете, где я работаю. Упс.

«Это легко», — думал я, — «Я просто размещу заказ, подключившись к прокси-серверу, и потом воспроизведу запросы!»

А вот и нет.

Как выяснилось, токены доступа Starbucks действительны всего один час, поэтому нельзя просто взять и пользоваться тем токеном, который использует ваш телефон. Это создает определенные трудности…

Вход в систему


Конечная точка OAuth, используемая приложением, перед выдачей токена проверяет три параметра:

  • Параметр строки запроса sig. Исследователь проблем безопасности Райан Пикрен выяснил, что это клиентский ключ, клиентский секретный ключ и текущая временная метка UNIX, конкатенированные вместе и прогнанные через функцию MD5-хэширования.
  • Параметр формы «deviceFingerprint». Это список различных атрибутов устройства в кодировке base64 и зашифрованный AES-256. Он также регулярно изменяется, поскольку текущее время и аптайм устройства включены в отпечаток.
  • HTTP-заголовок «X-Cbt». Еще одна строка секретного ключа в кодировке base64.

Я начал пытаться сформировать некоторые из них самостоятельно. Я смог получить ключ шифрования, используемый для создания deviceFingerprint, используя джейлбрейкнутый iPhone для расшифровки фреймворков внутри приложения Starbucks. Изучив фреймворк в Hopper в течение некоторого времени, я в конечном итоге смог отследить вызов к функции Apple CCCrypt.

image

www.youtube.com/watch?v=o8ZnCT14nRc

Затем я прилинковал фреймворк SBXData (фреймворк, который я ранее расшифровал на джейлбрейкнутом телефоне) в наскоро созданное приложение и воспользовался Fishhook для переназначения этой функции собственной реализации. Это позволило мне выгрузить ключ и связанные с ним параметры в консоль:

image

Аналогичным образом удалось выяснить, как генерировать заголовок «X-Cbt». Для краткости изложения, я оставлю эту задачу вам :)

Заключение


После того, как я смог подписать и снять отпечатки со своих запросов на вход, я объединил все в небольшой модуль Node.js, который позволяет использовать некоторые основные функции API Starbucks. Хорошие новости: он (в основном) размещен здесь на GitHub!

Вуаля! Программируемый кофе.

image
Поделиться с друзьями
-->

Комментарии (4)


  1. pewpew
    19.07.2017 19:36
    +1

    Теперь вы знаете, где я работаю. Упс.

    65 Front St, New York, NY 10005, США



  1. ptokarevskiy
    20.07.2017 12:33

    Работа вызывает уважение, браво! Сколько времени было потрачено на реверс инжиниринг, если не секрет?


    1. Tabernakulov
      20.07.2017 20:56

      Вы можете задать этот вопрос автору статьи Нику Ли напрямую, написав на почту nick@tendigi.com