Почему эксплойты Javascript не могут быть исправлены с помощью "предотвращения выполнения данных"?
Статья википедии о "кучном распылении" предполагает, что многие эксплойты javascript включают размещение шелл-кода где-то в исполняемом коде скрипта или в памяти пространства данных, а затем переводчик туда и запускает его. Чего я не понимаю, так это почему вся куча интерпретатора не может быть помечена как "данные", чтобы интерпретатор не мог выполнить шелл-код с помощью DEP? Между тем выполнение байт-кода, производного от javascript, будет выполняться виртуальной машиной, которая не позволит ей изменять память, принадлежащую интерпретатору (это не будет работать на V8, который, кажется, выполняет машинный код, но, вероятно, будет работать на Firefox, который использует какой-то вид байт-кода).
Я предполагаю, что вышеупомянутое звучит тривиально и, вероятно, что-то очень похожее на самом деле делается. Итак, я пытаюсь понять, где недостаток в рассуждениях или недостаток в существующих реализациях интерпретатора. Например, интерпретатор полагается на распределение памяти системы вместо того, чтобы реализовывать свое собственное внутреннее распределение, когда javascript запрашивает память, что делает чрезмерно трудным разделение памяти, принадлежащей интерпретатору и javascript? Или почему методы, основанные на DEP, не могут полностью исключить шеллкоды?
1 ответ
Чтобы ответить на ваш вопрос, нам сначала нужно определить, Предотвращение выполнения данных, Компиляция точно в срок и Распыление JIT.
Предотвращение выполнения данных - это функция безопасности, которая запрещает выполнение кода из неисполняемой области памяти. DEP может быть реализован аппаратными механизмами, такими как бит NX, и / или программным механизмом путем добавления проверок во время выполнения.
Компиляторы Just In Time (JIT) - это динамические компиляторы, которые переводят байтовые коды во время выполнения в машинный код. Цель состоит в том, чтобы объединить преимущества интерпретируемого кода и скорость скомпилированного кода. Он должен компилировать методы только в том случае, если дополнительное время, потраченное на компиляцию, может быть амортизировано увеличением производительности, ожидаемым от скомпилированного кода. [1]
Распыление JIT - это процесс принуждения механизма JIT к написанию множества исполняемых страниц со встроенным шелл-кодом.
[....]
Например, оператор Javascript, такой как "var x = 0x41414141 + 0x42424242;", может быть скомпилирован, чтобы содержать две 4-байтовые константы в исполняемом изображении (например, "mov eax, 0x41414141; mov ecx, 0x42424242; добавить eax, ecx")). Запуская выполнение в середине этих констант, выявляется совершенно другой поток инструкций.
[....]
Основная идея заключается в том, что JIT является предсказуемым и должен копировать некоторые константы на исполняемую страницу. При наличии унифицированного выражения (например, длинной суммы или любого повторяющегося шаблона) эти константы могут кодировать небольшие инструкции, а затем управлять потоком до местоположения следующей константы. [2]
Передовые методы, выходящие за рамки этого ответа, должны затем использоваться для определения адреса распыляемого блока JIT и запуска эксплойта.
Теперь должно быть ясно, что
Если код злоумышленника генерируется механизмом JIT, он также будет находиться в исполняемой области. Другими словами, DEP не участвует в защите кода, испускаемого JIT-компилятором. [3]
Рекомендации
[1] Динамическая структура оптимизации для Java-компилятора Just-in-Time
[2] Использование интерпретатора: вывод указателя и распыление JIT