Привет, Хабр!


Это снова я, тот, кто отвечает за IT-составляющую РосКомСвободы! Ты, наверное, меня помнишь по посту о самопроизвольной активации камеры при открытии страницы с embedded-youtube-видео.


На этот раз у меня история из личной жизни и, на мой взгляд, расследование немного поинтереснее.


Возможно, оно даже имеет запах теории заговора (между Ростелеком'ом (CC: Rostelecom ROSTELECOM-CENTER) и Mail.Ru Group).


КДПВ


Перед вступлением хотелось бы отметить, что на самом деле, этот пост больше месяца пролежал у меня в черновиках, потому что мы с darkk и ValdikSS всё ещё (актуально на 28.02.2020) собираем и анализируем данные об охвате этой проблемы, воспроизводимости, и прочие технические детали. И мы хотели сначала собрать полный набор данных, и только потом публиковать.


Но раз хайп уже пошёл, то, видимо, пришла пора выпустить этот пост наружу (а дополнять новыми данными уже будем по мере их накопления)...


Началась эта история с того, что пару лет назад провайдера, которым я пользовался уже больше 10 лет, купил Эр-Телеком (aka Dom.Ru).


После одной неприятной технической ситуации (здесь был рассказ со всеми деталями, но он занимал слишком много места и уводил статью в другое русло), кончилось всё тем, что, взвесив плюсы и минусы, я перешёл на Ростелеком (да и вариантов-то, в общем, и не было: всех провайдеров в городе купил либо первый, либо второй).


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


Начался он с того, что по работе я отлаживал некоторые "плюшки" в self-hosted инсталляции Sentry, и мне оказалось необходимым проверить кое-что в Incognito-mode (т.е без всяких uBlock/uMatrix и прочих плюшек), да ещё и по http (в смысле, без SSL).


Представьте себе, насколько же я удивился, когда на странице ошибки Sentry я увидел рекламный баннер:



А открыв DOM-инспектор — обнаружил там такое:



Сначала я заподозрил аддоны, которым было разрешено загружаться в Incognito mode, и отключил их.


И, как мне сначала показалось — это даже помогло. Однако, на самом деле это оказалось хитростью MitM'а: после ещё пары перезагрузок страницы я опять увидел баннер.


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


Там мой взгляд упал на вот такой блок:



Следующим шагом я пошёл искать этот ads.js в коде Sentry и… таки обнаружил его.


Посмотрел я на всё это и, честно признаться, офигел...


Как раз вчера ночью я, мягко скажем, ругался на апстрим Sentry за вот это вот, и то, что из-за этого мне пришлось довольно ощутимо переделывать процесс деплоя Sentry.


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


Но по привычке покопал дальше и увидел, что по факту, данный скриптик сам по себе не делает ничего обидного (хотя его существование как таковое, и в частности определение адблока со стороны sentry уже само по себе вызывает вопросы о попутанных берегах, ну да ладно).


Как оказалось, он, как и написано в комментарии, просто выставляет переменную об обнаруженном адблоке в false и не делает больше ничего.


Но откуда же взялся баннер?!?


Меня начинают одолевать смутные подозрения, что, учитывая тот факт, что Mail.Ru'шный рекламный блок в DOM появляется не всегда, а раз в N перезагрузок, значит, наверное, иногда вместо этого файла отдаётся другой.


На данный момент я всё ещё уверен, что делает это Sentry, и хочу найти какой именно файл оно отдаёт, чтобы пойти и потыкать в него носом разработчиков на гитхабе, что, мол, "некрасиво".


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


И меня волшебным образом перебрасывает на домен r.analytic.press, а в качестве параметров передаётся куча трекинговой информации, включая регион и оригинальную ссылку на файл (и все переданные параметры вшиваются в выдаваемый обфусцированный скрипт). Можно было бы разобрать скрипт (тем более, что к текущему моменту я его уже и в самом деле деобфусцировал), но, на самом деле, это опять уход от темы статьи, т.к. его вообще не должно было быть в моём трафике!


Ясное дело, что редиректа на такие подозрительные домены в коде Sentry обнаружено не было.
Кто у нас там следующий подозреваемый на очереди?..


Ага… трафик идёт по HTTP, происходит вторжение в трафик и подстановка "своего"… Уж очень напоминает модель действия Ростелекомовского DPI, который таким же образом всовывает заглушки о заблокированности ресурсов.


Итак, надо проверить, точно ли шкодит Ростелеком? А то, может, я теперь ещё и на него наговорю почём зря?.. Следующим-то, ведь, вариантом у нас среди подозреваемых остаётся только троян, но в это пока не хочется верить (flashforward: и не придётся), т.к. это бы означало либо что моя техническая компетенция слишком переоценена, либо что нашёлся кто-то "умнее" меня, раз смог незаметно подсунуть мне троян. А это был бы повод для другой статьи :).


Итак...


Для начала проверяю curl'ом ссылку на скрипт и… редиректа не происходит, как я не пытаюсь…
Хорошо. Получается следующая вилка вариантов: либо протроянен браузер, либо MitM ещё более хитрый, нежели предполагалось (да).


Чтобы проверить второй вариант я иду обратно во вкладку, где я поймал редирект, и делаю вот так вот:



Проверяю в консоли, и, да, один раз из нескольких происходит 307 редирект на указанный домен.
Проверяю на другом девайсе (в домашней сети) — воспроизводится.


Ну что ж, значит, всё же, не троян. Или, по крайней мере, не у меня на компьютере.


Дальше встаёт вопрос: происходит ли это на CloudFlare, или, всё же, у провайдера (помните, я говорил про DPI?)?


Для начала пробую повторить запросы с серверов, расположенных за пределами квартиры (и не пользующихся ростелекомом).


Не воспроизводится.


А это значит, что шанс того, что дело именно в DPI Ростелекома возрастает. Но пока что — это лишь догадки...


И тут на помощь приходит прекрасная утилита, именуемая Wireshark.


Открываю её, выбираю интерфейс для снятия дампа трафика, включаю фильтр (чтобы не разбирать лишний трафик), запускаю процесс снятия дампа трафика и воспроизвожу редирект.


После нескольких попыток — виднеется такая вот картина:



Особенно примечателен здесь практически моментальный ответ спустя 15мс (тот который TCP ZeroWindow), а так же то, что сразу же после него приходит реальный ответ от сервера (но cURL его уже не принимает, т.к. для него это мусор, и шлёт в ответ TCP RST).


Дальше, анализируя трафик, можно заметить, что у "фальшивого" ответа, с редиректом поле TTL имеет значение 59 (значит он находится в 64-59=5 "скачках" от меня, а настоящий ответ от CloudFlare имеет TTL=54 (в 10 скачках).


Ну что ж… Нужно потрейсить и посмотреть, кто же там у находится в этих 5 скачках...



А вот это уже интересно: сам маршрутизатор не представляется, но… оба "окружающих" его IP-адреса принадлежат Ростелекому (!!!):



Что крайне недвусмысленно намекает на то, что ответ приходит с оборудования, стоящего где-то на сети Ростелекома.


К счастью ли, или к сожалению, но знакомые из "tech-board" Роскомсвободы, которые помогали мне всё это дебажить, ValdikSS и darkk (за что им огромное спасибо) не смогли воспроизвести это на "своих" ростелекомовских линках, так что, судя по всему, это крайне регионозависимо.[1]


К слову, хоть это и зависимо от региона, но не зависимо от целевого сайта:
1) если обращаться не в CloudFlare'вским серверам, а, например, к серверу darkk, то редирект так же воспроизводится (хотя в оригинале его сервер отдаёт 404), но MitM-DPI это не смущает, он всё равно подсовывает свою рекламу :) Кстати, интересный артефакт этой проблемы — darkk, собирая при тестах трафик со своей стороны, обратил внимание на то, что от меня приходили подтверждения получения пакетов, которые сервер не отправлял. Т.е. уровень, на котором происходит эта "подтасовка" трафика — просто до жути топорный…
2) на самом деле, я не единственный и у людей это воспроизводится на других сайтах:
ValdikSS нашёл вот эти вот случаи: раз и два(ч) (не открывайте, если рядом находятся дети, а то некоторые анонимусы запостили в тот тред эротику),
а darkk — вот эти: раз и два.


В общем,
Во-первых, это вызывает очень яркие воспоминания о похожем поведении у мобильных операторов, которые вставляют свою рекламу (которая ещё, порой, и подписки включает),
Во-вторых, вызывает вопрос к Rostelecom: вам что, клиенты (включая большинство государственных учреждений) приносят так мало денег, что без продажи юзерского трафика и аналитики "налево" (сторонним компаниям) никак не обойтись?
В то, что описанное выше — случайность, я не поверю ни за какие коврижки.
В то, что DPI неподконтролен вам и сам хулиганит — поверить готов, но, сами понимаете, к вам тогда встаёт другой вопрос.
В-третьих, как и было предсказано, технологии которые (якобы) направлены на "защиту" (опять же, "якобы"): фильтрацию трафика от "запрещённой информации", вполне себе используются для набивания чьих-то карманов деньгами…
В-четвёртых, мне кажется, что лучше бы уж наши доблестные депутаты вместо того чтобы изобретать "сувенирный" интернет и строить виртуальный Железный Занавес, лучше бы направили свою законотворческую деятельность в позитивное русло и запретили бы провайдерам (всем, и "проводным", и "мобильным") вмешиваться в трафик и вставлять туда что ни попадя (особенно — непрошенную рекламу).


Ну и, подводя итоги, мне хочется сказать, что, похоже, уже точно настал тот момент, когда больше нельзя ходить в интернет не через туннель, с endpoint'ом поднятым где-нибудь на "своём" (арендованном) VPS в стране, где сетевой нейтралитет закреплён на законодательном уровне.
Иначе твою "душу" (в смысле, "цифровой след") продавать будет не только какой-нибудь FaceBook или Google, но даже твой провайдер интернета.


[1] Те тезисы, которые используют сноску сюда уже немного устарели, т.к. та часть статьи была написана до того как мы с darkk и ValdikSS начали масштабное исследование этой проблемы (не просто всеросийское, но и всемирное, используя в т.ч. такие проекты, как RIPE Atlas). Но я решил, что имеет смысл оставить эту часть как есть, по крайней мере до того, как мы будем готовы выложить результаты исследования (или, может, отдельным постом?).

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