В современной практике программирования и безопасности все чаще встречаются нестандартные методы обхода ограничений и извлечения максимума из минимального контроля над входными данными. Среди таких методик особое место занимает выполнение произвольного кода на Python при вводе, который кажется на первый взгляд абсолютно безопасным — например, в комментариях исходного кода. Впервые подобный вызов был представлен на CTF-соревновании UIUCTF в 2025 году, где задача состояла в демонстрации возможности запуска произвольного Python-кода, используя лишь единственную строку комментария в скрипте. Несмотря на сложность и ограниченность методов, лишь 11 команд смогли успешно решить эту задачу, положив начало новому взгляду на защиту и эксплуатацию Python-приложений. Основная трудность, с которой сталкиваются исследователи, заключается в том, что изменение входных данных от пользователя ограничено однострочным вводом, где символы переноса строки удалены и невозможно напрямую выйти из области комментария (после знака #).
Привычный прием инъекций, основанный на многократных строках или последовательностях символов переноса, здесь недоступен. Тем не менее, несмотря на кажущуюся невозможность, были найдены достаточно изящные способы преодоления подобных ограничений. Первая идея, связанная с уязвимостями в парсере Python, на первый взгляд показалась многообещающей. Известный баг, который существовал в ранних версиях интерпретатора, позволял обделывать строки с помощью нулевых байтов и подменять поведение парсера. Однако этот эксплойт был исправлен начиная с версии 3.
11.4, а задача была отдана среде с уже исправленным интерпретатором, что исключало возможность применения данного метода. Несмотря на это, анализ производительных изменений в парсере Python 3.11 и 3.12 раскрывал глубину трансформаций, связанных с разбором сложных литералов, таких как f-строки, однако это не принесло прямого прогресса в решении задачи.
Ключевой момент раскрывается при изучении механизма, с помощью которого сам интерпретатор Python запускает скрипты. Несмотря на расширение в названии файла и его явно текстовый формат, Python изначально оснащен функциональностью запуска ZIP-архивов. Впервые появившись в версии 2.6, возможность воспринимать ZIP-файл как пакет Python с __main__.py существенно расширила пути запуска программ.
Что интересно, проверка типа запускаемого файла не сводится к анализу расширения, а базируется на более глубоком определении, где файл может восприниматься как директория или ZIP-архив с основным модулем. Это определение происходит внутри основного C-кода интерпретатора, через функцию pymain_get_importer, вызываемую при указании имени файла. Если файл удовлетворяет определенным условиям ZIP-архива, он отдается специальному классy zipimporter, отвечающему за чтение, разбор и кеширование содержимого архива. Сам механизм разбора ZIP-файла zipimporter достаточно сложен и ориентирован на поиск в конце файла так называемой End of Central Directory Record (EOCD). Благодаря тому, что EOCD располагается в последней части архива и может содержать комментарии произвольной длины, появляется возможность размещения вспомогательных данных или даже «мусора» перед самим EOCD, что делает архивацию гибкой и открывает дверь созданию полиглотов - файлов, которые одновременно являются валидным Python-скриптом и ZIP-архивом.
Понимание формата ZIP, с его центральным каталогом, файлами и смещениями, позволяет создать подделку архива, который начинается с функционирующего Python-кода, а в конце содержит корректный EOCD, указывающий на внутренний фрагмент с __main__.py. При запуске интерпретатор переключается на zipimporter и загружает этот файл в виде основного модуля, что и дает возможность выполнения произвольного кода. При работе с данной техникой стоит учитывать особенности кодировки и ограничений, вызванных вводом через функцию input() — поток читается как текст, а не как бинарные данные. Байты с кодами выше 0x7f автоматически преобразуются в суррогатные пары Unicode, которые не могут быть корректно закодированы обратно в UTF-8 при записи.
Следовательно, Payload должен быть полностью ASCII-безопасным, что дополняет требования к формированию ZIP-файла. Для обхода этого ограничения применяют приемы с установкой метода сжатия в ZIP в режим хранения без сжатия (stored), а также подбором суффикса, который позволяет добиться ASCII-безопасности CRC-32 контрольной суммы. Чтобы избежать появления нелегальных битов в смещениях каталогов центральной директории, дополнительно добавляется padding, обеспечивающий валидность адреса смещения. Завершая конструкцию, стандартный Python-скрипт, содержащий приветствие и аналогично завершающий вывод, обрамляет служебные данные ZIP и располагается так, чтобы при исполнении он выдавал максимальный информативный результат, а сам файл оставался валидным архивом. Благодаря этому достигается уникальный эффект: процессор безопасности, пишущий файл, воспринимает его как обычный скрипт с комментарием, но на самом деле при запуске с помощью python3 запуск происходит как с ZIP и вызывается __main__.
py, содержащий произвольный код. Практическое применение данного подхода демонстрирует новый вектор атак и эксплойтов, открывая возможности для удаленного выполнения кода на системах, где действует ограничение на ввод в виде комментариев. Это меняет парадигму оценки безопасности таких систем, требуя от разработчиков более тщательной фильтрации и контроля взаимодействия с интерпретатором Python. Кроме того, данный кейс является прекрасным примером того, как глубокое понимание внутренних механизмов языка и интерпретатора может помочь как в атаке, так и в защите приложений. Изучение чрезмерно техничных деталей вроде обработки ZIP-архивов в контексте запуска файлов, форматов EOCD и механизмов zipimport, а также науки об уязвимостях парсера дало разработчикам и исследователям новое поле для внедрения инноваций.
Совокупно, описанный подход объединяет сразу несколько областей: теорию парсинга, внутреннюю структуру ZIP, особенности кодировки Unicode и внутренние механизмы загрузки интерпретатора Python. Это яркий пример совмещения разных дисциплин для получения неожиданных результатов, выходящих за рамки обычной разработки скриптов. Задача реализации подобных техник упрощается благодаря современным инструментам автоматизации и искусственного интеллекта, которые способны в короткие сроки проанализировать большие объемы кода, проследить логики исполнения и построить нестандартные цепочки для достижения итоговой цели. Подобные инструменты сегодня входят в арсенал как специалистов по безопасности, так и CTF-участников, что значительно расширяет возможности при исследованиях и тестировании систем. Подробное понимание и воспроизведение данной техники поможет специалистам не только повысить собственную квалификацию, но и обезопасить системы от сложных угроз в реальной работе.
Компании и разработчики должны учитывать, что даже, казалось бы, безопасные конструкты типа комментариев могут выступать в роли шлюза для эксплуатации, если не продумать все логические уровни работы среды исполнения. Таким образом, выполнение произвольного Python-кода из комментария является не просто курьезным экспериментом, а серьезным вызовом современным методам защиты. Это заставляет внимательнее подходить к взаимодействию между разработчиками, системными администраторами и аудиторскими группами, акцентируя внимание на глубоком анализе и понимании поведения интерпретатора языка на всех этапах его использования.