Почему нельзя использовать JScript-скрипт с использованием "предотвращения выполнения данных"?

"куча опрыскивания" Статья в wikipedia предполагает, что многие эксплоиты javascript включают в себя размещение шеллкода где-нибудь в script исполняемом коде или памяти пространства данных а затем переведите туда переводчика и выполните его. Я не понимаю, почему нельзя интерпретировать всю кучу, помеченную как "данные", чтобы интерпретатору не удалось выполнить шелл-код с помощью DEP? Между тем выполнение обработанного javascript байт-кода будет выполняться с помощью виртуальной машины, которая не позволит ему изменять память, принадлежащую интерпретатору (это не будет работать на V8, который, похоже, выполняет машинный код, но, вероятно, будет работать на Firefox, который использует какой-то вид байт-кода).

Я думаю, что вышеизложенное звучит тривиально и, вероятно, что-то очень похоже на то, что это делается. Итак, я пытаюсь понять, где ошибка в рассуждениях или недостаток существующих реализаций интерпретатора. Например. интерпретатор полагается на распределение системной памяти вместо того, чтобы реализовать свое собственное внутреннее распределение, когда javascript запрашивает память, поэтому делает его чрезмерно трудным для разделения памяти, принадлежащей интерпретатору и javascript? Или почему методы DEP не могут полностью исключить shellcodes?

Ответ 1

Чтобы ответить на ваш вопрос, нам сначала нужно определить: предотвращение выполнения данных, компиляцию Just In Time и JIT Spraying.

Предотвращение выполнения данных - это функция безопасности, которая запрещает выполнение кода из неиспользуемой области памяти. DEP может быть реализован аппаратными механизмами, такими как бит NX и/или программным механизмом, путем добавления проверок времени выполнения.

Компиляторы Just In Time (JIT) - это динамические компиляторы, которые преобразуют байтовые коды во время выполнения в машинный код. Цель состоит в том, чтобы объединить преимущества интерпретируемого кода и скорости скомпилированного кода. Он должен компилировать методы только в том случае, если дополнительное время, затрачиваемое на компиляцию, может быть амортизировано увеличением производительности, ожидаемым от скомпилированного кода. [1]

JIT-распыление - это процесс принуждения JIT-механизма для записи многих исполняемых страниц со встроенным шеллокодом.

[....]

Например, оператор Javascript, такой как "var x = 0x41414141 + 0x42424242;" может быть скомпилирован, чтобы содержать два 4 байтовых константы в исполняемом изображении (например, "mov eax, 0x41414141; mov ecx, 0x42424242; add eax, ecx" ). Запустив выполнение в середине этих констант, вы увидите совершенно другой поток команд.

[....]

Ключевым понятием является то, что JIT предсказуем и должен скопировать некоторые константы на исполняемую страницу. Учитывая единообразный оператор (например, длинную сумму или любой повторяющийся шаблон), эти константы могут кодировать небольшие команды и затем управлять потоком до следующего постоянного местоположения. [2]

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

Теперь должно быть ясно, что

Если код злоумышленника генерируется движком JIT, он также будет находиться в исполняемой области. Другими словами, DEP не участвует в защите кода, испускаемого компилятором JIT. [3]

Ссылки

[1] Динамическая оптимизация для Java-компилятора Just-in-Time

[2] Использование интерпретатора: вывод указателя и JIT-опрыскивание

[3] JIT-распыление и смягчение