
В рамках киберучений в формате Red Teaming обычно приходится иметь дело с компаниями со зрелым уровнем ИБ, у которых каждый год проходят пентесты, есть свой или внешний SOC, есть процессы Vulnerability Management, есть своя команда AppSec, есть EASM и т. д.
Приходится начинать с чистого листа, не имея никаких учётных записей и вводных данных, не имея инсайдеров, не имея IP-адреса в списках исключений фаерволов. При этом с «той» стороны пентестерам активно противодействует весь арсенал средств защиты и команда SOC. В таких условиях пробиться внутрь и дойти до реализации рисков достаточно сложно.
Нужно находить более сложные уязвимости, в том числе 0day-уязвимости в стороннем ПО, а также применять более изощрённые способы социальной инженерии.
Сегодня расскажем про один эксплойт, который мы сделали в рамках киберучений в очень большой компании. Чтоб показать не только итоговый результат, но и путь, который к нему привёл, вставляем в текст скриншоты из наших обсуждений 😊.
Дни 0-1: Подготовка и находка
В первые недели мы, конечно, взялись за разведку периметра Заказчика, нашли много доменных имён и подсетей. По истории в Shodan и Censys стало ясно, что в некоторых подсетях размещаются не фиксированные production-сервисы, а прочая инфраструктура, в том числе временные сервисы с динамическими IP-адресами.
Это нам показалось интересным, и мы зарядили в нашей EASM-платформе мониторинг портов в этих подсетях. Как только на каком-нибудь хосте появлялся новый порт, мы тут же получали уведомление в Mattermost.
Спустя время, нам пришёл алерт о портах 8099 и 8088 на одном из IP-адресов:

На этих портах был plaintext TCP-сервис, и в первую очередь мы бросились восстанавливать протокол общения с ним путём ручного и автоматического фаззинга:

Путём перебора нашли команды XML, QUIT, VERSION, PING:

Но уже из скриншотов можно понять, что это слишком хакерские методы, и всё было в разы проще. По строке версии «24.0.0.72» и по некоторым ключевым словам сразу можно было нагуглить, что это vMix: Live Video Streaming Software.
Что такое vMix? Это штука, которую вы увидите в любой ивент-студии. Через эту программу управляют трансляцией, выбирают, с какой камеры пустить изображение в эфир, комбинируют их, накладывают эффекты и т. д.
Выглядит это примерно так:

Ключевое понятие для vMix — это источник (Input). Источником может быть камера, картинка, видеофайл, презентация Powerpoint, PDF и т. д. На скриншоте как раз видно эти разные инпуты в виде окошек с плашками разного цвета.
Выяснилось, что на данном хосте на одном порту был веб-интерфейс, защищённый паролем, а на другом порту (8099) — незащищённый TCP API. Мы, конечно, сразу развернули локальный стенд и обнаружили, что vMix по умолчанию слушает этот порт, и подразумевается, что его нужно зафаерволить или отключить этот API.
День 1: Поиск векторов атаки
Изучая документацию, мы обнаружили большое количество интересных команд, доступных в этом TCP API. Веяло близкой победой: среди команд была и обработка XML, и даже ограниченное исполнение VBScript:

Интересным стало осознание того, что большая поверхность атаки лежит в обработке различных видов источников:

В документации упоминалась команда BrowserNavigate, которая намекала, что можно стримить не только файлы и поток с устройств, но и браузер! Начали отладку этой команды у себя на стенде:

Никакой реакции не было. Вернулись потыкать целевой сервер, и тут…

Хост пропадает! На самом интересном месте наш вектор прервался. Понурив головы, мы уходим спать, а на следующий день идём искать новые зацепки.
День 2: зацепка
Надолго ли?

Сервис вернулся! Но… На другом IP-адресе? И немного в другом виде, даже версия теперь 24.0.0.58, а не 24.0.0.72? Тут мы поняли, что происходит: эти зомби-хосты на периметре — это белые IP-адреса обычных Windows-машин операторов студии, которые на время стриминга включают свои компы и запускают vMix. С окончанием рабочего дня пропадает и наш сервис.
Всё дальнейшая работа с этим сервисом шла короткими сессиями пару раз в неделю, причём в это время шли съёмки, которым нельзя было сильно мешать, поэтому:
- Необходим был постоянный очень быстрый мониторинг именно нужного нам порта, чтобы сразу узнать, когда сервис запущен,
- Нужно всё тестировать локально, прежде чем запускать на удалённом сервисе, чтобы не помешать реальной трансляции,
- Более того, создание новых инпутов визуально заметно в программе, и оператор может понять, что кто-то контролирует vMix, так что действия нужно выполнять быстро и сразу зачищать за собой.
После дополнительных экспериментов наконец удалось заставить vMix запустить браузер:

В хедере User-Agent мы увидели версию Chrome 5-6-летней давности (а дело было в 2022 году). Открыв URL chrome://version, мы увидели приятное:

Браузер запускается с флагом --no-sandbox! Ещё одно наблюдение: это не standalone-браузер, а CEF (Chromium Embedded Framework). В общем, примерно любой эксплойт с исполнением кода для Chromium версии 2016 года давал бы нам выход в систему даже без необходимости пробивать сендбокс.
Пробив был уже практически у нас в кармане, достаточно было захостить файл с эксплойтом и создать через TCP API браузерный инпут с нашим URL. В desktop-интерфейсе vMix мы также нашли возможность создавать браузерные окна. Там был выбор из 4 версий CEF через dropdown-меню: была возможность запустить и довольно свежую версию.
По иронии оказалось, что эта свежая версия легко пробивалась готовым модулем Metasploit, но при этом через TCP API не нашлось никакой возможности выбрать версию: всегда запускалась версия 51.
На этом этапе хост был потушен, и мы ушли в исследование локального стенда.
Дни 3-4: энтузиазм, близость победы
Перебрав с десяток CVE и несколько китайских эксплойтов на Github, мы нашли достаточно перспективные эксплойты, которые выглядели качественными и должны были работать на нашей версии. Но написаны они были для других версий, например, был эксплойт, который у нас отрабатывал на Chromium 58.
Это были эксплойты под V8 — JavaScript-движок Chromium. В нём было найдено много уязвимостей класса UAF и Type confusion. Наш выбор пал на эксплойт для CVE-2017-5070, уязвимость в JIT-компиляторе JavaScript, который назывался (потом его заменил CrankShaftTurboFan). Для адаптации эксплойта было необходимо исправить оффсеты в поддельных объектах ArrayBuffer, которые намазываются на память.
Хакер — человек ленивый, и лень — двигатель прогресса. Конечно, по-честному дебажить Chromium неохота, так что мы просто сдампили память Chromium версии 58, для которой эксплойт уже работал, нашли там нужные оффсеты, а потом нашли аналогичные в дампе памяти версии 52.

И вот — заветное окошко MessageBox, наш тестовый шеллкод исполнился. Но с версией 51 так и не задалось. Почему?
Тут мы поняли, что не сделали самое главное наблюдение по chrome://version: браузер запускается из Program Files (x86). Да, это 32-битная версия Chromium! Более того, 64-битная версия вообще появилась только начиная с серии 52, именно поэтому мы и нашли её и сумели проэксплуатировать. Это легко проверить в архиве старых версий Chromium.
Итого, нам нужно не просто поменять 2 оффсета, а полностью переписать эксплойт, потому что разница между x86-версией 51 и x64-версией 52 значительная. Да и не факт, что там вообще сработает та же техника эксплуатации…
Дни 5-10: гнев, отрицание, принятие
Память о последующих днях работ достаточно размытая. Лень заставила нас перепробовать массу других путей: декомпиляция и реверс-инжиниринг библиотек vMix, попытки инъекций команд, чтения файлов через браузер, выхода из сендбокса VBScript и т. д.
Ничего не удалось, и пришлось таки заняться дебагом эксплойта под Chromium.
Итого, на входе у нас Type Confusion в JIT-движке CrankShaft (CVE-2017-5070, issue #722756 by Qixun Zhao). Для данной уязвимости в публичном доступе есть авторский эксплойт для 64-битной версии 58.0.3029.110. Краткий разбор уязвимости есть в блоге Project Zero.
Первое, что нужно сделать — это определить точную версию V8 и коммит, а также собрать дебаг-тулкит d8, который будет работать с этой версией. Версия V8 нам известна из выхлопа chrome://version, это версия 5.1.281.65. Коммит можно найти бинарным поиском, в нашем случае это 7bd2476771628ccf089c5efa37e1bb612ee663dc.
Не будем описывать весь процесс работы с d8 и подробности самой уязвимости и приведём только основные действия, выполненные в течение многих часов отладки:
- Изменены константы в структуре
ArrayBuffer Map, - Изменены оффсеты внутри структур (
ArrayBuffer,ArrayBuffer Map) и между ними с учётом размера указателей, - Исправлены примитивы для конвертации указателей с учётом разрядности,
- Изменены примитивы
AddrOf/FakeObjс учётом разрядности, - Внесены прочие мелкие исправления,
- Сгенерирован подходящий шеллкод (
meterpreter).
В очередной присест за pwndbg и d8 наконец удалось добиться исполнения кода под Linux:

Прелесть эксплойтов под V8 в том, что они кроссплатформенны с точностью до разрядности и шеллкода: этот же эксплойт работает и в Windows.
Наконец, на 10-й день, в 5 утра перед нами был уже боевой MessageBox, а затем и Meterpreter session opened.

Дальше мы дождались в онлайне несколько разных машин операторов, пробили их и получили доменные креды. Но это уже совсем другая история…
Мораль
Какие выводы можно сделать? Довольно очевидные, если принять, что любой устанавливаемый на компьютере софт может оказаться уязвимым, и задача ИБ — сконфигурировать инфраструктуру и эндпойнты так, чтобы до уязвимостей было не добраться:
- Контролируйте сетевые политики и то, каким устройствам выдаются белые IP-адреса, какие на них накладываются правила межсетевого экранирования,
- Проводите постоянный мониторинг периметра для выявления новых сетевых сервисов,
- Не заводите в домен или сильно ограничивайте машины внешних технических сотрудников, особенно в общих зонах (студии, ресепшн, гостевые офисы, переговорки и т. д.).
Про сам vMix речи нет, потому что это по сути уязвимость «by design»: подразумевается, что вы сами должны озаботиться о том, чтобы закрыть доступ к порту или вообще отключить TCP API (это можно сделать в настройках). Ну а обновлять версии CEF, входящие в дистрибутив vMix, всё равно не получится так часто, как выходят обновления Chromium, т.е. там заведомо будет уязвимая версия.
Для редтимеров же самые главные выводы такие:
- В длительных проектах на больших периметрах обязательно настраивайте мониторинг,
- Любой не слишком популярный сторонний софт считайте уязвимым, разворачивайте стенд и ищите там уязвимости,
- Не бойтесь браться за сложные задачи и не сдавайтесь, про каждую цель представляйте, что это CTF-таск, и там обязательно есть решение и флаг.
Пентест и Red Teaming
Вы можете нанять одну из лучших команд пентестеров в мире для проведения киберучений. А если не хотите, чтобы в вашу инфраструктуру попали через случайно открытый 1 час в неделю порт, подумайте про EASM.
Мы работаем как с крупными корпорациями, так и со стартапами, знаем про требования регуляторов, нужды бизнеса и реальные угрозы.
