• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Серия эксплуатации V8 - часть 2

вавилонец

CPU register
Пользователь
Регистрация
17.06.2021
Сообщения
1 116
Реакции
1 265

Архитектура высокого уровня

Введение​

Чтобы понять эту кодовую базу, нужно охватить много информации, поэтому мы начнем с рассмотрения некоторых основных компонентов, чтобы терминология в будущих сообщениях и других статьях имела смысл. Я собираюсь опираться на множество ссылок, чтобы представить этот материал, потому что множество высокоуровневых описаний компонентов V8 уже дают гораздо лучшую работу, чем я мог бы в таком коротком посте.

V8 в хроме

Сам V8 является относительно небольшой частью браузера Chromium. По сути, это совершенно отдельная база кода, которую можно встраивать в другие проекты (например, NodeJS!). Здесь важно понимать структуру, потому что мы будем много говорить об эксплуатации V8, но V8 обычно помещается в песочницу внутри другого процесса (процессов). Ошибки V8 должны быть связаны с дополнительными эксплойтами, чтобы добиться полноценного выполнения кода на большинстве систем. Для наших целей мы будем рады получить неограниченное выполнение кода в процессе V8. Например, это общий взгляд на Chrome, который показывает, как V8 расположен в нескольких слоях компонентов.

1653900786000.png


https://www.chromium.org/developers/how-tos/getting-around-the-chrome-source-code/Content.png

Самое замечательное в том, что V8 настолько модульный, что нам не нужно глубоко копаться в каких-либо других базах кода, чтобы понять его. Хотя просмотр исходного кода Chromium может дать лучшую картину для определенных вариантов дизайна, в этом, по большому счету, нет необходимости.

Компоненты V8

Теперь мы рассмотрим некоторые из наиболее важных частей V8. Вы можете найти весь код здесь или на зеркале GitHub . В следующем посте я подробно расскажу о том, как эти компоненты написаны на C++, а пока давайте просто поймем, что они делают.

Чтобы понять, как сегментируется V8, вы должны посмотреть, как современные веб-браузеры запускают JavaScript. Хотя это интерпретируемый язык, механизмы JS часто компилируют этот код в машинный код для конкретной архитектуры в процессе, известном как JIT-компиляция. Обычно интерпретируемый скрипт преобразуется в байт-код, который может выполняться независимо от архитектуры. Однако этот код работает очень медленно, так как все инструкции необходимо преобразовать из промежуточного языка в конкретные инструкции, поддерживаемые текущим процессором.

С другой стороны, скомпилированный код работает очень быстро, но требует некоторых предварительных затрат на преобразование исходного кода в исполняемый файл. Идея движков JS состоит в том, чтобы использовать JIT, чтобы получить лучшее из обоих миров. Они используют интерпретатор для немедленного запуска JavaScript; однако, если движок обнаружит, что какой-то код запускается часто, он скомпилирует этот раздел кода с несколькими оптимизациями для повышения производительности. То, как весь этот процесс работает в V8, лучше всего объясняет Бенедикт Мёрер в его пост .

Ignition

Ignition — интерпретатор V8. Многие эксплойты сосредоточены на JIT-коде и ошибках, допущенных в процессе компиляции. Однако скомпилированный код зависит от того, что выдает интерпретатор! Хотя здесь было обнаружено меньше ошибок, связанных с безопасностью, некоторые из них все же есть , на что указывают Димитри Фурни и Мориц Йодейт. Чтобы понять этот компонент, мы рекомендуем кратко просмотреть этот подробный документ от Google и прочитать это хорошее, краткое объяснение того, как V8 генерирует байт , написанное Франциской Хинкельманн.

Ключевым выводом является то, что Ignition в первую очередь отвечает за генерацию байт-кода из JavaScript. Далее мы поговорим о других компанентах.

Turbofan

Turbofan является единственным компилятором JavaScript V8, хотя некоторые ресурсы могут содержать ссылки на Crankshaft (замененный в 2017 году :'( ). Другие движки также имеют различные уровни оптимизации, которые выполняются разными компиляторами, но это не относится к V8. Turbofan срабатывает, когда V8 замечает, что конкретная функция является «горячей» (это означает, что код был выполнен определенное количество раз). После того, как функция скомпилирована, она перенаправит поток управления на JIT-код при будущих вызовах этой функции. Большинство эксплойтов V8 сосредоточены на этом компоненте, и, как следствие, мы тоже. Некоторыми аспектами, которые нужно понять здесь, будут конвейер оптимизации, типизация переменных и проверки безопасности памяти. Есть отличная презентация ( слайды ) для базового понимания. Эта статья Джереми Фетиво — действительно потрясающее введение с точки зрения эксплуатации (обратите внимание, что она гораздо более глубока, чем мы до сих пор).

Важная часть, которую нужно понять о Turbofan, заключается в том, что у него тяжелая работа. Изначально JavaScript не предназначался для компиляции. Он слабо типизирован и допускает безумную гибкость между типами, а стандарт ECMAScript не всегда кажется логичным (мягко говоря). Эта трудность является причиной того, что многие JS-движки, а не только V8, содержат ошибки. В нашем анализе прошлых эксплойтов мы увидим, что некоторые уязвимости возникают из-за расхождения в разумных предположениях о том, как должен вести себя JavaScript, по сравнению с тем, как он на самом деле .

Liftoff

Liftoff — это компонент, который создает машинный код из WebAssembly. Он способен очень быстро компилировать WebAssembly; однако он не создает оптимизированный код. Он фактически сразу же передает свои выходные данные в Turbofan для оптимизации (в отличие от Ignition, который сначала ждет, пока код будет запущен определенное количество раз). Этот компонент довольно часто обновляется, а так как он относительно новый, то в нем обнаруживается все больше и больше багов. Поскольку WebAssembly становится все более популярным, может появиться больше возможностей для исследования безопасности этой части V8.

Torque и CodeStubAssembler (CSA)

Чтобы добиться еще большей производительности, V8 поставляется с предварительно скомпилированным кодом для встроенных функций (функций, определенных стандартом ECMAScript). Раньше они были написаны в CSA , который был представлен в 2017 году. Однако процесс написания этих функций сборки от руки привел к нескольким ошибкам, что побудило представить Torque год спустя. По сути, Torque упрощает написание эффективного кода для встроенных функций для различных архитектур, поддерживаемых V8. И еще один замечательный пост Пока я писал этот раздел, был опубликован Он проделывает фантастическую работу, обобщая не только эксплойт, связанный с Torque, но и многие другие концепции, о которых я уже говорил.

Заключение​

Теперь мы рассмотрели некоторые из основных компонентов, перечисленных в документации V8, с кратким описанием каждого из них. Отсюда мы в основном сосредоточимся на Turbofan, используя более медленный подход, чем большинство существующих исследований уязвимостей, в попытке получить понимание на очень низком уровне.

Перевод Этой статьи​

 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх