Кслера8

Chrome нулевого дня: «Этот эксплойт находится в дикой природе», поэтому проверьте свою версию сейчас

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

Google известно, что эксплойт для CVE-2023-3079 существует в дикой природе.

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

На этот раз это «мы все это знаем сами», что еще более прямо переводится как «мы знаем, что мошенники злоупотребляют этим, пока мы говорим», учитывая, что отчет об ошибке поступил непосредственно от собственной исследовательской группы Google.

Как обычно, это означает, что Google расследовал активную атаку (будь то против самой Google или какой-то внешней организации, мы не знаем), в ходе которой Chrome был взломан ранее неизвестной дырой в безопасности.

Ошибка описывается просто как: Путаница типов в V8. (Понятно, что на данном этапе Google ничего больше не говорит.)

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

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

Объяснение опасности путаницы типов

Представьте, что вы пишете программу на C. (Неважно, знаете ли вы C или нет, вы все равно можете просто следовать ей.)

В C вы обычно объявляете переменные по отдельности, таким образом не только резервируя память, где они могут быть сохранены, но и сигнализируя программе, как предполагается использовать эти переменные.

Например:

 длинный длинный интервал JulianDayNumber; подписанный char* CustomerName;

Первое объявление переменной резервирует 64 бита для хранения простого старого целочисленного значения, представляющего астрономический номер дня. (Если вам интересно, сегодня днем ​​JDN 23157 — юлианские дни начинаются в полдень, а не в полночь, потому что астрономы часто работают ночью, а полночь — это середина их рабочего дня.)

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

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

Как видно из этого дампа памяти работающей программы Windows, самый низкий адрес памяти, выделенный для использования, начинается с 0x00370000, что составляет 3,604,480 XNUMX XNUMX в десятичном виде, что намного больше, чем любое разумное число дней.

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

И (хотя это не в нижней части изображения выше) адреса памяти раздела пользовательских данных во время выполнения, когда эта программа запускалась из 0x01130000 в 0x01134FFF, представляющий маловероятный диапазон дат с 22 июля 44631 16 года по 44687 августа XNUMX XNUMX года.

Действительно, если вы попытаетесь перепутать эти две переменные, компилятор должен попытаться предупредить вас, например, так:

 ЮлианскийДеньНомер = ИмяЗаказчика; CustomerName = ЮлианскийДеньНомер; предупреждение: присваивание делает целое число из указателя без приведения предупреждение: присваивание делает указатель из целого числа без приведения

Теперь, если вы когда-либо программировали на C, вы знаете, что для удобства вы можете объявлять переменные с несколькими различными интерпретациями, используя union ключевое слово, например:

 союз { длинный длинный интервал JulianDayNumer; подписанный char* CustomerName; } данные;

Теперь вы можете ссылаться на одну и ту же переменную в памяти двумя разными способами.

Если вы напишете data.JulianDayNumber, вы волшебным образом интерпретируете сохраненные данные как целое число, но запись data.CustomerName сообщает компилятору, что вы ссылаетесь на адрес памяти, даже если вы обращаетесь к одним и тем же сохраненным данным.

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

Вы можете решить иметь вторую переменную, известную как tag (обычно целое число), чтобы соответствовать вашему union чтобы отслеживать, с какими данными вы работаете прямо сейчас, например:

 структура {целый тег; союз { длинный длинный интервал JulianDayNumer; подписанный char* CustomerName; } данные; } ценить;

Вы можете решить, что, когда value.tag на 0, данные еще не инициализированы для использования, 1 означает, что вы сохраняете дату, 2 означает, что это адрес памяти, а все остальное означает ошибку.

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

Более тревожным примером может быть что-то вроде этого:

 структура {целый тег; // 1 = хеш, 2 = указатели на функции union { unsigned char hash[16]; // либо сохранить случайную хэш-структуру { void* openfunc; // или два тщательно проверенных void* closefunc; // указатели кода для последующего выполнения } validate; } } ценить;

Теперь мы перегружаем тот же блок памяти, чтобы иногда использовать его для хранения 16-байтового хэша, а иногда для хранения двух 8-байтовых указателей на функции, которые наша программа вызовет позже.

Ясно, когда value.tag == 1, мы были бы рады позволить нашему программному обеспечению хранить любую 16-байтовую строку в памяти, выделенной для объединения, потому что хэши являются псевдослучайными, поэтому любой набор байтов равновероятен.

Но когда value.tag == 2, наш код должен быть очень осторожным, чтобы не позволить пользователю предоставить непроверенные, ненадежные, неизвестные адреса функций для последующего выполнения.

А теперь представьте, что вы можете отправить значение в этот код, когда для тега установлено значение 1, поэтому оно не проверяется и не проверяется…

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

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

И это то, что происходит с ошибкой путаницы типов, хотя и на надуманном и упрощенном примере,

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

Что делать?

Убедитесь, что у вас установлена ​​последняя версия Chrome или Chromium.

Вы хотите Chrome 114.0.5735.106 или новее на Mac и Linux, и 114.0.5735.110 или более поздней версии для Windows.

Эта ошибка также затрагивает Microsoft Edge, основанный на Chromium.

Microsoft пока [2023-06-06T16:25:00Z] отметил, что

Microsoft знает о недавних эксплойтах, существующих в дикой природе. Мы активно работаем над выпуском исправления безопасности.

Edge в настоящее время имеет версию 114.0.1823.37, поэтому все, что пронумеровано позже, чем это должны включать исправления Microsoft CVE-2023-3079.

Чтобы проверить свою версию и принудительно обновить ее, если она еще не получена:

  • Гугл Хром. Трехточечное меню (⋮) > Документи > О Хроме.
  • Microsoft Edge. Настройки и многое другое (…) > Помощь и обратная связь > О Microsoft Edge.

Пожалуйста.


Чат с нами

Всем привет! Могу я чем-нибудь помочь?