В мае этого года исследователи Check Point Software Technologies обнаружили совершенно новый вектор атак — атаки через субтитры. Злоумышленники могут использовать файлы субтитров для получения контроля над компьютерами пользователей, при этом избегая обнаружения. Мы расскажем, как им это удалось (обязательно запасись терпением, пивом и чипсами — статья вышла аж на восемь страниц старого бумажного «Хакера». 🙂 — Прим. ред.).
 

Что мы знаем

Этот вектор атак возможен из-за уязвимостей, обнаруженных в популярных стриминговых платформах, включая VLC, Kodi (XBMC), Popcorn Time и strem.io. Перед злоумышленником он открывает безграничные возможности: кражу конфиденциальной информации, установку программ-вымогателей, массовые DDoS-атаки и многое другое.

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

 

Popcorn Time

Созданная всего за несколько недель как проект open source мультиплатформа «Netflix для пиратов» оказалась гремучей смесью из BitTorrent-клиента, медиаплеера и бесконечных возможностей скрейпинга (сбора данных при помощи скриптов), объединенных очень привлекательным графическим интерфейсом.

Popcorn Time GUI
Popcorn Time GUI

Хотя программа стала очень популярна благодаря простоте использования и хорошей коллекции видеофильмов, разработчики неожиданно закрыли проект из-за давления со стороны Американской ассоциации кинокомпаний (MPAA).

После этого разные инициативные группы создали форки Popcorn Time для поддержки программы и разработки новых функций. Создатели оригинального Popcorn Time поддержали версию popcorntime.io (позднее — popcorntime.sh) как преемника своего закрытого проекта.

Интерфейс на основе WebKit содержит гору информации о фильмах и метаданные. Здесь есть трейлеры, краткое содержание сюжета, информация об актерах, фотографии обложек, рейтинги IMDb и многое другое.

 

Субтитры в Popcorn Time

Чтобы еще больше облегчить жизнь пользователя, субтитры к фильмам подгружаются автоматически. Можно ли использовать это в своих целях? (Подсказка: да.)

Без ведома пользователя Popcorn Time получает субтитры с единственного поставщика — OpenSubtitles. Более четырех миллионов субтитров и очень удобный API делают этот репозиторий суперпопулярным. В нем есть алгоритм выдачи рекомендаций, помогающий пользователю выбрать файл для конкретного фильма и релиза.

 

Поверхность атаки

Как упоминалось, Popcorn Time работает на движке WebKit, а именно NW.js. Ранее известная как node-webkit, платформа NW.js позволяет разработчику использовать веб-технологии — например, HTML5, CSS3 и WebGL — в своих родных приложениях. Более того, обращаться к API Node.js и модулям третьих сторон можно напрямую из DOM.

В сущности, приложение NW.js — это веб-страница с произвольным содержимым, написанная на JavaScript или HTML и оформленная с помощью CSS. Как всякая веб-страница, приложение может подвергаться XSS-атакам. В данном случае из-за того, что программа работает на Node.js, XSS позволяет использовать возможности серверной части. Иными словами, запросы XSS в реальности становятся запросами RCE (на выполнение удаленного кода).

 

На старт, внимание, марш!

Наше приключение начинается, как только пользователь включает воспроизведение фильма. Popcorn Time делает запрос через упомянутый API и скачивает рекомендованные субтитры (мы опишем этот процесс в деталях ниже). Затем Popcorn Time пытается перекодировать полученный файл в формат SRT.

/src/app/vendor/videojshooks.js
/src/app/vendor/videojshooks.js

После перекодировок и парсинга созданный элемент (субтитр) прикрепляется к экрану в нужный момент, опираясь на массив «подсказок».

Функция updateDisplay
Функция updateDisplay

Это дает нам возможность добавить к отображаемому виду любой HTML-объект. Очевидно, что полный контроль над каким-либо HTML-элементом — это уже опасно. Однако, когда мы имеем дело с приложениями на основе узлов (node-based), важно понимать, что XSS равен RCE. Системные команды легко запускаются через модули типа child_process. Как только наш непроверенный JavaScript загружается на экран, до запуска вредоносного кода остается всего лишь несколько строк.

Обычный SRT-файл выглядит примерно так:

1
00:00:01,000 –> 00:00:05,000
Hello World

Вместо текста Hello World мы можем использовать HTML-тег изображения.

Мы пытаемся загрузить несуществующее изображение с атрибутом событий onerror, который позволяет задать срабатывание скрипта при возникновении ошибки во время загрузки внешнего файла.

malicious.srt — пример
malicious.srt — пример

Мы используем функцию JavaScript, связанную с атрибутом onerror, чтобы удалить компрометирующий нас значок отсутствующего изображения и прикрепить к странице нашу вредоносную удаленную полезную нагрузку (payload). Само собой, наш скрипт evil.js всего лишь запустит окно стандартного калькулятора calc.exe.

evil.js (Command execution)
evil.js (Command execution)
 

OpenSubtitles

Итак, мы можем исполнять код на Popcorn Time. Уязвимости на стороне клиента ценны, но их эксплуатация, как правило, требует какого-либо взаимодействия пользователя с системой — он должен кликнуть на ссылку, прочитать PDF-файл или зайти на взломанный сайт. В случае с субтитрами пользователь должен загрузить вредоносный файл. Можно ли как-то пропустить этот шаг?

Мы знаем, что юзеры беспечно скачивают субтитры из открытых источников в интернете и считают их безобидными текстовыми файлами. Более четырех миллионов файлов и около пяти миллионов ежедневных скачиваний делают OpenSubtitles крупнейшим онлайн-хранилищем субтитров. Их многофункциональный API также часто интегрируется во многие другие видеоплееры. Они даже предлагают возможность «умного» поиска: эта цепная функция выбирает наиболее подходящие субтитры по введенной информации.

Возникает вопрос: можно ли вмешаться в этот API и сделать так, чтобы взаимодействовать с пользователем не было необходимости и из базы OpenSubtitles автоматически загружались именно вредоносные субтитры?

 

Как работает API

Когда пользователь запускает воспроизведение фильма, система автоматически отправляет запрос на поиск субтитров SearchSubtitles — XML, содержащий все объекты субтитра, соответствующие нашим критериям (IMDb ID).

Запрос API SearchSubtitles
Запрос API SearchSubtitles

Ответ API SearchSubtitles
Ответ API SearchSubtitles

Здесь параметр поиска обозначен как imdbid. Ответ на запрос содержит все субтитры с данным imdbid.

А теперь самое интересное. В API имеется алгоритм, который ранжирует субтитры по их названию, IMDb ID, рейтингу загрузчика и другим параметрам. Просмотрев документацию, мы обнаружили схему такого ранжирования.

Документация метода ранжирования API
Документация метода ранжирования API

Здесь видно, сколько баллов добавляется к рейтингу субтитров на основе их соответствия следующим критериям: метка, IMDb ID, пользователь-загрузчик и так далее. Предположим, что мы как анонимные пользователи (user | anon) загрузили наши вредоносные субтитры в базу OpenSubtitles — нашему файлу присвоят всего пять баллов. Вот что мы узнали: недостаточно только читать документацию, поскольку исходный код проявляется в недокументированном поведении.

Алгоритм ранжирования OpenSubtitles API
Алгоритм ранжирования OpenSubtitles API

Запрос, отправленный Popcorn Time, задает только один параметр — IMDb ID, это означает, что условие MatchedBy === 'tag' («метка») всегда будет иметь логическое значение «ложь». Это вызовет функцию matchTags().

Функция matchTags
Функция matchTags

Функция matchTags разбивает название фильма и субтитров на отдельные метки. Метка (тег) — это, как правило, отдельное слово или цифра, обнаруженное в названии файла. Они обычно разделяются точками (.) и дефисами (-). Число общих меток в названии файла с фильмом и названии файла субтитров затем делится на число меток фильма и умножается на показатель maxScore, равный семи. Такое значение maxScore присваивается в случае полного соответствия между двумя именами файлов. Например, если название файла с фильмом Trolls.2016.BDRip.x264-[YTS.AG].mp4, у него будут следующие метки:

[Trolls, 2016, BDRip, x264, YTS, AG, mp4]

Поскольку название файла с фильмом, который скачивается приложением (например, Popcorn Time), узнать достаточно легко (c помощью сниффера), мы можем присвоить нашему файлу с субтитрами точно такое же название, но с расширением srt. Это увеличит рейтинг файла субтитров на целых семь (!) баллов.

Продолжение статьи доступно только подписчикам

Вариант 1. Оформи подписку на «Хакер», чтобы читать все статьи на сайте

Подписка позволит тебе в течение указанного срока читать ВСЕ платные материалы сайта, включая эту статью. Мы принимаем оплату банковскими картами, электронными деньгами и переводами со счетов мобильных операторов. Подробнее о подписке

Вариант 2. Купи одну статью

Заинтересовала статья, но нет возможности оплатить подписку? Тогда этот вариант для тебя! Обрати внимание: этот способ покупки доступен только для статей, опубликованных более двух месяцев назад.


3 комментария

Подпишитесь на ][, чтобы участвовать в обсуждении

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

Check Also

Алмазный фонд «Хакера». Самые крутые материалы по реверсингу и malware за три года

Иногда мы, редакторы и авторы «Хакера», сами читаем «Хакер». Нет, ну то есть мы постоянно …