Interested Article - Исполнение произвольного кода

Исполнение произвольного кода — уязвимость в программной системе, когда злонамеренный пользователь ( хакер ) может заставить её исполнять любой машинный код , какой захочет. Если можно заставить машину исполнять произвольный код по сети, это иногда называется удалённое исполнение кода . Это самая опасная из программных уязвимостей — вредоносный код внедряется через внешне безобидные действия (например, загрузку файла данных), и может делать что угодно в пределах привилегий программы: извлекать информацию из памяти программы, пересылать её по сети, читать, писать и модифицировать файлы…

Аналогичная уязвимость для веба называется межсайтовый скриптинг — но поскольку JavaScript сам по себе ограничен в возможностях, то и урона от него обычно меньше, в основном утечки данных. Аналогичная уязвимость для SQL называется внедрение SQL-кода , и чревата она всем тем, что может SQL — утечками, подменами и потерями данных.

Причины

Основные причины исполнения произвольного машинного кода:

Порча памяти
Пример: переполнением буфера перезаписываем указатель возврата (в x86 стек растёт вниз, и указатель после стекового фрейма ). Как только программе потребуется закончить подпрограмму, процессор извлекает из стека этот адрес и переходит туда — на хакерскую подпрограмму.
Чтобы была больше вероятность перейти на вредоносную подпрограмму, используется техника heap spraying — в динамической памяти создаётся много небольших объектов, и каждый содержит подпрограмму .
Спутанные типы в интерпретаторах с динамической типизацией
Подтип порчи памяти: функция ожидает, например, строковый тип , а ей дают целочисленную переменную, и она это никак не проверяет. Дав интерпретатору специальным образом подобранные данные, можно испортить память .
Автоматическая сериализация + излишнее доверие
Часто в составе программы или системных библиотеках встречаются уязвимые классы, исполняющие код по ошибке, или системные, действительно способные исполнить что угодно. В некоторых языках ( Java ) принято передавать сложные объектные структуры через стандартную сериализацию — и если взломщик передаст команду создать подобный объект, можно будет исполнить произвольный код. Подобную уязвимость имели WebSphere и Jenkins .
Случайное исполнение кода в операциях над EXE и DLL, которые этого исполнения не подразумевают
Два примера: 1. В Windows загрузка иконки из DLL происходит через функцию LoadLibrary , которая, в числе прочего, исполняет и код инициализации DLL — таким образом, достаточно просмотреть Проводником каталог с «отравленным» DLL, чтобы исполнить зловредный код. Решено через дополнительный флаг LOAD_LIBRARY_AS_DATAFILE , не исполняющий кода. 2. В Unix-подобных ОС программа ldd , проверяющая зависимости программы, является несложным скриптом, исполняющим ELF-файл с определёнными настройками системы . Не решено — просто запрещается запускать ldd на непроверенных файлах.

Защита

Запрет на модификацию сегментов кода, и на исполнение сегментов данных
В этом случае программа просто не сможет ничего записать в ту память, которую можно исполнять. Экстремальный вариант — гарвардская архитектура , распространённая в ограниченных машинах, в ней код и данные расположены в разных адресных пространствах. Недостаток: существуют самомодифицирующийся код , собственные загрузчики (сжатие исполняемых файлов, защита от копирования…), JIT-компиляция .
Работа программ с правами, которые не позволят нанести большой вред
Поскольку работа в ограниченном аккаунте довольно неудобна, Microsoft реализовал контроль учётных записей пользователей , не дающий программам работать с системными данными. В браузерах, как программах, принимающих на себя самые массовые хакерские атаки, есть работа вкладок в ограниченных процессах — впервые это реализовано в Google Chrome , а впоследствии — и в Firefox Quantum. Недостаток: сложность системы раздачи прав; в любом случае будут программы с широкими правами, и именно они станут основной мишенью хакеров.
Рандомизация адресного пространства программы ( ASLR )
Из-за непостоянных адресов усложняется сборка действующего эксплойта. Недостаток: замедленная загрузка.
Расширенные самопроверки в библиотеках
Используются в критичном ПО, особо подверженном хакерским атакам (например, в сетевом). Например, в системе исполнения Java доступ к массиву или объекту всегда проверяется, из-за чего порча памяти затруднена. Недостаток: сниженная производительность.
Ограничения на стиль кода
Так, жёсткий стандарт кода MISRA C , принятый в автоиндустрии, призван снизить ошибкоопасность.
Использование ограниченных виртуальных машин и скриптовых языков , а не машинного кода
Если нужна программируемость, но недопустимы вредоносные программы, используют сильно ограниченный язык. Так работают Java , JavaScript , многие из смартфонных ОС, включая Android . Эта схема решает и другие вопросы — даёт независимость от архитектуры процессора, упрощает программирование, отказ программы не приводит к отказу всей системы. Недостаток: крайняя сложность системы и вытекающая из неё затруднённая проверка безопасности, низкая производительность.
Превращение сетевого ПО в многофункциональные «комбайны»
Как можно меньше сетевой работы отдаётся внешнему ПО: логично, что в браузере сильнее дисциплина программирования, чем в настольном просмотрщике PDF. К тому же браузер Chrome или Firefox исполнит код просмотра PDF в ограниченном процессе, а просмотрщик — в обычном.

Примечания

  1. . Дата обращения: 18 июня 2023. 18 июня 2023 года.
  2. . Дата обращения: 31 августа 2022. 31 августа 2022 года.
  3. . Дата обращения: 31 августа 2022. 6 сентября 2022 года.
Источник —

Same as Исполнение произвольного кода