Редтиминг в стиле Pwn2Own

В рамках киберучений в формате 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. С окончанием рабочего дня пропадает и наш сервис.

Всё дальнейшая работа с этим сервисом шла короткими сессиями пару раз в неделю, причём в это время шли съёмки, которым нельзя было сильно мешать, поэтому:

  1. Необходим был постоянный очень быстрый мониторинг именно нужного нам порта, чтобы сразу узнать, когда сервис запущен,
  2. Нужно всё тестировать локально, прежде чем запускать на удалённом сервисе, чтобы не помешать реальной трансляции,
  3. Более того, создание новых инпутов визуально заметно в программе, и оператор может понять, что кто-то контролирует 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, который назывался CrankShaft (потом его заменил TurboFan). Для адаптации эксплойта было необходимо исправить оффсеты в поддельных объектах 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 и подробности самой уязвимости и приведём только основные действия, выполненные в течение многих часов отладки:

  1. Изменены константы в структуре ArrayBuffer Map,
  2. Изменены оффсеты внутри структур (ArrayBuffer, ArrayBuffer Map) и между ними с учётом размера указателей,
  3. Исправлены примитивы для конвертации указателей с учётом разрядности,
  4. Изменены примитивы AddrOf/FakeObj с учётом разрядности,
  5. Внесены прочие мелкие исправления,
  6. Сгенерирован подходящий шеллкод (meterpreter).

В очередной присест за pwndbg и d8 наконец удалось добиться исполнения кода под Linux:

Прелесть эксплойтов под V8 в том, что они кроссплатформенны с точностью до разрядности и шеллкода: этот же эксплойт работает и в Windows.

Наконец, на 10-й день, в 5 утра перед нами был уже боевой MessageBox, а затем и Meterpreter session opened.

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

Мораль

Какие выводы можно сделать? Довольно очевидные, если принять, что любой устанавливаемый на компьютере софт может оказаться уязвимым, и задача ИБ — сконфигурировать инфраструктуру и эндпойнты так, чтобы до уязвимостей было не добраться:

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

Про сам vMix речи нет, потому что это по сути уязвимость «by design»: подразумевается, что вы сами должны озаботиться о том, чтобы закрыть доступ к порту или вообще отключить TCP API (это можно сделать в настройках). Ну а обновлять версии CEF, входящие в дистрибутив vMix, всё равно не получится так часто, как выходят обновления Chromium, т.е. там заведомо будет уязвимая версия.

Для редтимеров же самые главные выводы такие:

  1. В длительных проектах на больших периметрах обязательно настраивайте мониторинг,
  2. Любой не слишком популярный сторонний софт считайте уязвимым, разворачивайте стенд и ищите там уязвимости,
  3. Не бойтесь браться за сложные задачи и не сдавайтесь, про каждую цель представляйте, что это CTF-таск, и там обязательно есть решение и флаг.

Пентест и Red Teaming

Вы можете нанять одну из лучших команд пентестеров в мире для проведения киберучений. А если не хотите, чтобы в вашу инфраструктуру попали через случайно открытый 1 час в неделю порт, подумайте про EASM.

Мы работаем как с крупными корпорациями, так и со стартапами, знаем про требования регуляторов, нужды бизнеса и реальные угрозы.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *