Как сниффить HTTPS-трафик iOS-устройства

  • Tutorial


Привет, меня зовут Андрей Батутин, я Senior iOS Developer в DataArt, и сегодня мы будем сниффить HTTPS-трафик твоего «Айфона».

FoodSniffer и с чем его едят


Возьмем, к примеру, очень простое iOS-приложение FoodSniffer. Оно в зависимости от времени дня показывает пользователю, что можно есть.



Приложение получает от сервера JSON вида:

[
  {
    "name" : "soup",
    "consumePeriod" : "morning"
  },
…
]

Сервером в данном случае выступает Dropbox, а JSON можно посмотреть здесь.

Проблема №1


Пришел баг, что вместо двух элементов в списке разрешенной утром еды приложение показывает только один.

Один из способов проверить, что пошло не так, — увидеть JSON, который вам возвращает сервер.

Как сниффить трафик?


Предположим, что ваши MacOS-компьютер и iOS-устройство находятся в одной локальной сети, которая выглядит примерно так:



Трафик идет от iOS-устройства через роутер к серверу независимо от трафика компьютера.

Чтобы читать трафик iOS-устройства, нам нужно сделать так, чтобы он шел через наш Мac. Примерно так:



Кроме того, нам понадобится HTTP/S-прокси-сервер, с помощью которого мы бы и смотрели/модифицировали проходящий трафик iOS-устройства.

Еще одна очень важная задача — иметь возможность сниффить HTTPS-трафик. Загвоздка в том, что HTTPS-протокол и создавался, чтобы, кроме клиента и сервера, никто не мог прочесть, что передается в HTTPS-запросах. Поэтому HTTPS-прокси должен поставлять с собой еще и SSL-сертификат, который нужен для работы с HTTPS-трафиком.

Иными словами, нам нужно реализовать Man-in-the-Middle-атаку на нашу собственную сеть.



Charles Web Debugging Proxy Application


Как видим, сниффить HTTPS-трафик — задача многоэтапная, поэтому чтобы максимально упростить себе жизнь, я использую Charles Proxy.

Начнем с минусов:

  • Он платный, но единственное ограничение которое есть в пробной версии — Charles работает не дольше 30 минут, потом его надо перезапускать. Еще есть пятисекундные задержки при запуске. Это раздражает, но жить можно.
  • Если вам нужен подлинный хакерский инструмент для работы на удаленном сервере 24/7, да еще с нормальным CLI, Charles не для вас.
  • Если вы работаете на Windows, вам лучше взять Fiddler, он еще и бесплатный.
  • Если вам нужен прокси-сервер для большого количества устройств (больше двух-трех), Charles не для вас.
  • Если вам нужно работать с TCP/IP-пакетами в чистом виде, возьмите Wireshark.

Теперь плюсы:

  • User-Friendly UI. Charles не требует никаких специальных знаний ни для установки, ни для настройки, ни для использования. Обычное MacOs оконное приложение.
  • HTTPS for iOS — у Charles есть набор инструментов, которые делают HTTPS-сниффинг с вашего iOS-устройства максимально простым в настройке.
  • Функционал — Charles может сниффить, модифицировать проходящий через него трафик, имитировать медленный интернет, собирать статистику, импорт/экспорт трафика в различных форматах.
  • Доступен для Windows и Linux.

Для меня это оптимальное решение по соотношению функционала и простоты в использовании при работе с iOS-устройствами.

Настройка Charles и iOS-устройства


Далее будет описана процедура первоначальной настройки iOS-устройства для работы с Charles Proxy.

1. Запустить Charles на компьютере:



2. Установить Charles Root Certificate на iOS устройстве:

В меню выбираем Help -> SSL Proxing — > Install Charles Root Certificate on Mobile Device or Remote Browser.



Появится следующее окно:



3. В настройках сети iOS-устройства указываем IP и порт Charles Proxy:



В зависимости от архитектуры вашей сети IP-адрес, на котором работает Charles, может отличаться.

4. Открываем браузер на iOS-устройстве и переходим по ссылке — http://chls.pro/ssl.



5. Устанавливаем Charles SSL-сертификат на устройство:



6. Указываем в настройках устройства, что полностью доверяем данному сертификату:



Шестой этап нужен для устройств с iOS 10 и выше.

На 5–6-м этапах мы установили на устройство Charles SSL-сертификат и указали, что мы ему доверяем. Т. е. теперь весь HTTPS-трафик, подписанный этим сертификатом, не будет блокироваться ATS.

Как смотреть трафик iOS-устройства


Откройте приложение FoodSniffer. Если настройка прокси была сделана правильно, то вы должны увидеть такой экран:



В Charles Proxy откройте в меню Tools -> No Caching.

И полностью выключите кэширование на прокси-сервере.



В приложении реализован Pull-to-refresh, после обновления списка продуктов вы должны в Charles увидеть https://www.dropbox.com в списке с левой стороны. Нажмите правой кнопкой мыши на него и выберите Enable SSL Proxing.



После этого еще раз обновите список продуктов в приложении. Теперь вы должны увидеть примерно такую картину:



Теперь мы можем свободно читать HTTPS-трафик, который идет от приложения на Dropbox за нашим JSON.

Но это еще не все!

Dropbox не отдает JSON c хоста dropbox.com напрямую. Вместо этого он возвращает 302-респонс и редиректит еще на один хост, с которого и происходит загрузка данных.

Найти его можно, просмотрев Raw Response следующего запроса:



В данном случае это —
uc9c29db95802af8490afc3afda9.dl.dropboxusercontent.com.

У вас, скорее всего, будет немного другой хост.

Затем включаем для него SSL Proxing: Enabled.

Обновляем FoodSniffer еще раз.

И теперь мы наконец можем увидеть реальный JSON, который и показывает приложение!



Мы видим, что у нас есть всего один тип еды на вечернее время — виски, пишем об этом нашему тимлиду и идем пить кофе, проблема не на нашей стороне.

*В проекте применяется уже исправленный JSON, с двумя типами еды на вечер: пивом и виски.
*Если вы не видите хост http://uc9c29db95802af8490afc3afda9.dl.dropboxusercontent.com или похожий на него в списке в левой части окна, попробуйте обновить список продуктов в приложении несколько раз.

Проблема № 2, или Как изменять HTTPS-трафик iOS-устройства


Бэкенд-команда исправила меню на вечер, и теперь JSON формируется правильно. Но что делать, если сейчас утро, а ждать до вечера, чтобы проверить фикс, не хочется?

Один из вариантов — с помощью Charles изменять JSON, который вам приходит в ответ от Dropbox.

В данном случае нам нужно изменить consumePeriod с evening на morning.

Для этого в меню выбираем Tools -> Rewrite.

В появившемся окне Rewrite Settings добавляем новую категорию для перезаписи — dropbox.



Добавляем хост, указывая https-порт в Edit Location меню:



После этого добавляем правила перезаписи в Rewrite Rule меню следующим образом:



Т. е. теперь в каждом Body респонса от нашего сервера слово evening будет заменено на слово morning.

При необходимости мы можем менять любую часть HTTP-запроса/ответа, плюс использовать regex-выражение для замены текста.

Теперь, обновив список, мы должны увидеть четыре типа продуктов:



Вывод


Charles довольно простой, условно-бесплатный, обладает богатым функционалом HTTPS-прокси. С моей точки зрения, он лучше всего проявляет себя при работе с MacOS и iOS-устройствами.

Это далеко не единственный способ сниффить трафик. Для HTTP/S-трафика широко применяют и Fiddler. Если вам нужно уйти глубже в TCP/IP-стэк — есть Wireshark.

Кроме того, существует проблема certificate pinning. Если в вашем приложении он реализован, вам надо либо добавлять Charles SSL-сертификат в список разрешенных сертификатов, либо использовать такое средства, как Frida, чтобы отключить certificate pinning уже на уровне самого приложения. Об этом подробнее надеюсь рассказать в следующей статье.

Буду рад, если вы поделитесь вашим опытом в мониторинге трафика, в том числе HTTP/S, советам и лайфхаками.

Примечание. Используйте эту технику только для своих приложений, пожалуйста. Будьте белыми зайчиками хакерами!

Примечание 2. Недавно история об этом выходила на украинском, но по-русски я ее публикую впервые.
DataArt 138,66
Технологический консалтинг и разработка ПО
Поделиться публикацией
Похожие публикации
Комментарии 16
    +1
    Charles хорош, но рекомендую автору попробовать Burp Suite. Отличный инструмент для подобных задач, и имеет ряд преимуществ перед аналогами, даже в бесплатной версии
      0
      Спасибо, попробуем!
      +3
      Прошу прощения, но чем ваша статья принципиально отличается от другой такой же кроме названия — habr.com/company/redmadrobot/blog/269109
        0
        Это статья — первая в серии статей по сниффингу шифрованного трафика, поэтому она получилось базовой, и у нее действительно много общего с приведенной вами. Но дальше на основе этого материала будут строится более сложные топики.
        +1
        Посмотрите на mitmproxy.org бесплатный и легко расширяемый
          0
          Да, хорошая вещь, но не всем удобно работать в консоли.
            0
            У них вообще то есть веб морда ) mitmproxy.org/#mitmweb
              0
              Использую mitmweb для android. Есть сложность с просмотром траффика android 7 и выше (требуется вносить изменения в конфигурацию приложения), но это касается и Charles. А так отличная штука!
          0
          можно ли через charles снифать сокет? В андроиде точно можно, а вот с iOS так и не вышло
          0

          Ещё есть интересная технология Remote Virtual Interface, позволяет перехватывать не только wifi.


          https://developer.apple.com/library/content/qa/qa1176/_index.html

            0
            Рекомендую сразу использовать Charles вместо Fiddler. С последним были проблемы на Android — почему-то выписывал сертификаты на IP адрес вместо домена, так и не смог это победить. С Charles таких проблем не возникло.
              0
              А как быть с приложениями, которые проверяют сертификат? Например Instagram?
                0
                Об этом Андрей расскажет в следующей статье!
                0

                жду продолжения про certificate pinning, интересная тема, спасибо!)

                  0
                  Обеими руками за Charles и Fiddler.
                  Добавлю лишь, что Charles Proxy есть в App Store (платный, конечно), а дебажить веб прямиком с iOS-устройства катастрофически удобно.

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое