Уязвимость в Python, позволяющая вызвать системные команды из изолированных скриптов

Опубликован метод обхода систем изолированного выполнения кода на языке Python, основанный на использовании давно известной ошибки, появившейся в Python 2.7, выявленной в 2012 году и до сих пор не исправленной в Python 3. Ошибка позволяет при помощи специально скомпонованного кода на языке Python инициировать обращение к уже освобождённой памяти (Use-After-Free) в СPython. Изначально предполагалось, что ошибка не представляет угрозы безопасности и лишь в очень редких случаях, как правило искусственно созданных, может привести к аварийному завершения скрипта.

Исследователь безопасности под псевдонимом kn32 заинтересовался проблемой и сумел подготовить рабочий эксплоит, дающий возможность вызвать любую системную команду, не имея прямого доступа к методам вида os.system. Эксплоит реализован на чистом языке Python и работает без импорта внешних библиотек и без установки обработчика «code.__new__». Из hook-ов используется только «builtin.__id__», который обычно не запрещён. С практической стороны предложенный код может применяться для обхода механизмов изоляции в различных сервисах и окружениях (например, в обучающих средах, online-оболочках, встроенных обработчиках и т.п.), допускающих выполнение кода на языке Python, но ограничивающих доступные вызовы и не позволяющих обращаться к таким методам, как os.system.

Предложенный код представляет собой аналог вызова os.system, работающий через эксплуатацию уязвимости в CPython. Эксплоит работает со всеми версиями Python 3 на системах с архитектурой x86-64 и демонстрирует стабильную работу в Ubuntu 22.04, даже при включении режимов защиты PIE, RELRO и CET. Работа сводится к получению из кода на языке Python сведений об адресе одной из функций
в исполняемом коде CPython. На основании этого адреса вычисляется базовый адрес CPython в памяти и адрес функции system() в загруженном в пмять экземпляре libc. В завершении инициируется прямой переход по определённому адресу system c подстановкой указателя первого аргумента на строку «/bin/sh».

Источник: http://www.opennet.ru/opennews/art.shtml?num=57193