D2
Администратор
- Регистрация
- 19 Фев 2025
- Сообщения
- 4,380
- Реакции
- 0
Автор перевода: Norbert Beaver
Переведено специально для форума XSS.is
Источник: blog.trailofbits.com/2024/06/11/exploiting-ml-models-with-pickle-file-attacks-part-2/
В первой части мы познакомились со Sleepy Pickle, способом атаки, в котором использует вредоносные pickle файлы для скрытого заражения моделей ML и проведения сложных атак на конечных пользователей. В этой части мы покажем, как этот метод может быть адаптирован для обеспечения длительного присутствия в зараженных системах, оставаясь при этом незамеченным. Этот альтернативный метод, который мы называем Sticky Pickle, включает в себя самовоспроизводящийся механизм, который распространяет вредоносную нагрузку на последующие версии зараженной модели. Кроме того, Sticky Pickle использует обфускацию для маскировки вредоносного кода, чтобы предотвратить его обнаружение сканерами pickle файлов.
Создание стабильной вредоносной нагрузки pickle файлов.
Как следует из предыдущей статьи, Sleepy Pickle основаны на внедрении полезной нагрузки в pickle файл, содержащий в себе упакованную ML модель. Эта нагрузка выполняется, когда файл десериализуется в объект Python, что приводит к снижению веса модели и/или связанного с ней кода. Если пользователь решит модифицировать зараженную модель (например, произвести тонкую настройку), а затем повторно разместить ее, она будет преобразована в новый файл pickle, который будет вне зоны контроля злоумышленника. Этот процесс, скорее всего, сделает атаку неэффективной.
Чтобы предотвратить это, мы разработали Sticky Pickle, механизм самовоспроизведения, который преобразует нашу заражающую модель нагрузку в инкапсулирующую постоянную нагрузку. При ее исполнении, выполняются следующие действия:
Схема 1. Постоянная нагрузка в зараженных файлах ML модели.
С помощью данного метода, вредоносная нагрузка автоматически распространяется на производные модели, не оставляя следов на диске за пределами зараженного pickle файла. Более того, возможность подключения любой функции в интерпретаторе Python допускает другие варианты атаки, поскольку злоумышленник может получить доступ к другим локальным файлам, таким как обучающие наборы данных или файлы конфигурации.
Обфускация нагрузки: остаемся незамеченным.
Еще одно ограничение атак на основе pickle связано с тем, что вредоносная нагрузка вводится непосредственно в виде исходного кода Python. Это означает, что вредоносный код отображается в файле в виде открытого текста. У этого есть несколько недостатков. Во-первых, атаку можно обнаружить с помощью простого сканирования файлов и нескольких эвристических методов, которые нацелены на обнаружение значительных фрагментов исходного кода Python в pickle файлах. Во-вторых, специалисты по безопасности легко идентифицируют атаку и ее цель, просто взглянув на код.
Мы разработали метод обфускации и кодирования полезной нагрузки, который обходит эти ограничения и значительно усложняет ее обнаружение. Начиная с нашей основной полезной нагрузки, состоящей из кода, который взламывает модель ML, мы модифицировали ее двумя способами.
Сначала мы проводим обфускацию полезной нагрузки, компилируя ее в объект кода Python и сериализуя в строку с помощью библиотеки marshal. Это позволяет нам внедрить эту сериализованную строку в файл pickle, за которой следует специальная последовательность байт-кода. При выполнении, эта последовательность вызывает функцию marshal.loads() в строке, чтобы восстановить объект кода полезной нагрузки и выполнить его. Это делает нагрузку полностью нечитаемой для сканеров или проверки человеком, поскольку она вводится в виде скомпилированного байт-кода Python вместо исходного кода.
Затем, мы используем простую кодировку XOR, чтобы варьировать полезную нагрузку в каждом зараженном файле. Вместо того, чтобы состоять только из исходного кода, взламывающего модель. XOR-кодируемая нагрузка содержит как исходный код полезной нагрузки на языке Python, закодированный в XOR, так и заглушку для декодирования и выполнения, подобную этой:
Python: Скопировать в буфер обмена
Поскольку ключ обфускации может принимать любое значение и жестко закодирован в заглушке для декодирования, этот метод дополняет функцию постоянности, позволяя злоумышленникам записывать полезную нагрузку, которая генерирует новый ключ обфускации при повторном вводе в новый pickle файл. Это приводит к тому, что в зараженные файлы вводятся различные полезные данные Python, объекты кода и конечные полезные данные pickle, в то время как вредоносное поведение остается неизменным.
Схема 2. Обфускация полезной нагрузки Python перед внедрением в pickle файл.
На схеме 2 показано, как этот метод обфускации полностью скрывает вредоносную информацию в файле. Автоматизированные инструменты или аналитики безопасности, сканирующие файл, увидят только:
Схема 3. Обзор шагов выполнения нагрузки после обфускации.
Закроем банку с "огурчиками".
Эти методы сохранения стабильности нагрузки и обхода показывают уровень изощренности, которого могут достичь атаки с помощью pickle файлов. В дополнение к критическим рискам, которые мы продемонстрировали в первой части статьи, мы также рассмотрели, как один вредоносный pickle файл может:
Несмотря на риски, предоставляемые pickle файлами, мы признаем, что в долгосрочной перспективе основным платформам экосистемы ML потребуется приложить усилия, чтобы отказаться от них. Однако в краткосрочной перспективе есть несколько шагов, которые вы можете предпринять, чтобы избежать этих проблем:
Благодарность.
Выражаем благодарность нашему стажеру Расселу Трану за его усердный труд над обфускацией и оптимизацией полезной нагрузки pickle файла.
Переведено специально для форума XSS.is
Источник: blog.trailofbits.com/2024/06/11/exploiting-ml-models-with-pickle-file-attacks-part-2/
В первой части мы познакомились со Sleepy Pickle, способом атаки, в котором использует вредоносные pickle файлы для скрытого заражения моделей ML и проведения сложных атак на конечных пользователей. В этой части мы покажем, как этот метод может быть адаптирован для обеспечения длительного присутствия в зараженных системах, оставаясь при этом незамеченным. Этот альтернативный метод, который мы называем Sticky Pickle, включает в себя самовоспроизводящийся механизм, который распространяет вредоносную нагрузку на последующие версии зараженной модели. Кроме того, Sticky Pickle использует обфускацию для маскировки вредоносного кода, чтобы предотвратить его обнаружение сканерами pickle файлов.
Создание стабильной вредоносной нагрузки pickle файлов.
Как следует из предыдущей статьи, Sleepy Pickle основаны на внедрении полезной нагрузки в pickle файл, содержащий в себе упакованную ML модель. Эта нагрузка выполняется, когда файл десериализуется в объект Python, что приводит к снижению веса модели и/или связанного с ней кода. Если пользователь решит модифицировать зараженную модель (например, произвести тонкую настройку), а затем повторно разместить ее, она будет преобразована в новый файл pickle, который будет вне зоны контроля злоумышленника. Этот процесс, скорее всего, сделает атаку неэффективной.
Чтобы предотвратить это, мы разработали Sticky Pickle, механизм самовоспроизведения, который преобразует нашу заражающую модель нагрузку в инкапсулирующую постоянную нагрузку. При ее исполнении, выполняются следующие действия:
- Он находит исходный зараженный файл, загружаемый в локальную файловую систему.
- Он открывает файл и читает байты инкапсулирующей полезной нагрузки с диска. (Нагрузка не может получить к ним прямой доступ через свой собственный код на Python).
- Он скрывает свой собственный байт-код в распаковываемом объекте под заданным именем атрибута.
- Он подключает функцию pickle.dump(), которая при повторной сериализации объекта:
- Сериализует объект с помощью обычной функции pickle.dump().
- Определяет, что объект содержит атрибут байт-кода.
- Собственноручно вставляет байт-код в только что созданный pickle файл.
Схема 1. Постоянная нагрузка в зараженных файлах ML модели.
С помощью данного метода, вредоносная нагрузка автоматически распространяется на производные модели, не оставляя следов на диске за пределами зараженного pickle файла. Более того, возможность подключения любой функции в интерпретаторе Python допускает другие варианты атаки, поскольку злоумышленник может получить доступ к другим локальным файлам, таким как обучающие наборы данных или файлы конфигурации.
Обфускация нагрузки: остаемся незамеченным.
Еще одно ограничение атак на основе pickle связано с тем, что вредоносная нагрузка вводится непосредственно в виде исходного кода Python. Это означает, что вредоносный код отображается в файле в виде открытого текста. У этого есть несколько недостатков. Во-первых, атаку можно обнаружить с помощью простого сканирования файлов и нескольких эвристических методов, которые нацелены на обнаружение значительных фрагментов исходного кода Python в pickle файлах. Во-вторых, специалисты по безопасности легко идентифицируют атаку и ее цель, просто взглянув на код.
Мы разработали метод обфускации и кодирования полезной нагрузки, который обходит эти ограничения и значительно усложняет ее обнаружение. Начиная с нашей основной полезной нагрузки, состоящей из кода, который взламывает модель ML, мы модифицировали ее двумя способами.
Сначала мы проводим обфускацию полезной нагрузки, компилируя ее в объект кода Python и сериализуя в строку с помощью библиотеки marshal. Это позволяет нам внедрить эту сериализованную строку в файл pickle, за которой следует специальная последовательность байт-кода. При выполнении, эта последовательность вызывает функцию marshal.loads() в строке, чтобы восстановить объект кода полезной нагрузки и выполнить его. Это делает нагрузку полностью нечитаемой для сканеров или проверки человеком, поскольку она вводится в виде скомпилированного байт-кода Python вместо исходного кода.
Затем, мы используем простую кодировку XOR, чтобы варьировать полезную нагрузку в каждом зараженном файле. Вместо того, чтобы состоять только из исходного кода, взламывающего модель. XOR-кодируемая нагрузка содержит как исходный код полезной нагрузки на языке Python, закодированный в XOR, так и заглушку для декодирования и выполнения, подобную этой:
Python: Скопировать в буфер обмена
Код:
def compromise_model(model):
# The string of the XOR-encoded python payload source code (Строка XOR-кодированного исходного кода нагрузки)
encoded_payload =
# This line decodes the payload and executes it (Данная линия декодирует нагрузку и исполняет ее)
exec(bytearray(b ^ 0x{XOR_KEY:X} for b in encoded_payload))
return model
Поскольку ключ обфускации может принимать любое значение и жестко закодирован в заглушке для декодирования, этот метод дополняет функцию постоянности, позволяя злоумышленникам записывать полезную нагрузку, которая генерирует новый ключ обфускации при повторном вводе в новый pickle файл. Это приводит к тому, что в зараженные файлы вводятся различные полезные данные Python, объекты кода и конечные полезные данные pickle, в то время как вредоносное поведение остается неизменным.
Схема 2. Обфускация полезной нагрузки Python перед внедрением в pickle файл.
На схеме 2 показано, как этот метод обфускации полностью скрывает вредоносную информацию в файле. Автоматизированные инструменты или аналитики безопасности, сканирующие файл, увидят только:
- Необработанные байты полезной нагрузки Python, которые были скомпилированы и затем маршалированы. Представляется трудным, если не невозможным, интерпретировать эти байты и пометить их как опасные при статическом сканировании.
- Последовательность pickle, которая вызывает marshal.loads(). Это распространенный шаблон, также встречающийся в файлах pickle с вредоносным ПО, и поэтому его недостаточно для предупреждения пользователей о потенциальном вредоносном поведении.
- Вредоносные коды операций pickle загружают необработанные байты сериализованного объекта кода, затем реконструируют объект кода Python с помощью marshal.load() и, наконец, исполняют его.
- Объект кода выполняется и декодирует исходный код Python в XOR-кодированный.
- Декодированный исходный код нагрузки выполняется и заражает загруженную ML-модель.
Схема 3. Обзор шагов выполнения нагрузки после обфускации.
Закроем банку с "огурчиками".
Эти методы сохранения стабильности нагрузки и обхода показывают уровень изощренности, которого могут достичь атаки с помощью pickle файлов. В дополнение к критическим рискам, которые мы продемонстрировали в первой части статьи, мы также рассмотрели, как один вредоносный pickle файл может:
- Заразить другие локальные pickle файлы и модели ML.
- Избежать сканирования файлов и значительно усложнить механический анализ.
- Сделать его полезную нагрузку полиморфной и распространить ее в постоянно меняющейся форме, сохраняя при этом один и тот же конечный этап и цель.
Несмотря на риски, предоставляемые pickle файлами, мы признаем, что в долгосрочной перспективе основным платформам экосистемы ML потребуется приложить усилия, чтобы отказаться от них. Однако в краткосрочной перспективе есть несколько шагов, которые вы можете предпринять, чтобы избежать этих проблем:
- Избегайте использования pickle-файлов при дистрибуции сериализованных моделей.
- Используйте более безопасные альтернативы pickle файлов, такие как SafeTensors от HuggingFace.
- Также ознакомьтесь с нашей оценкой безопасности SafeTensors!
- Если вам необходимо использовать pickle файлы, просканируйте их с помощью нашей собственной программы Fickling, чтобы обнаружить ML атаки на их основе.
Благодарность.
Выражаем благодарность нашему стажеру Расселу Трану за его усердный труд над обфускацией и оптимизацией полезной нагрузки pickle файла.