
В современном мире ИИ модели машинного обучения стали незаменимыми инструментами для решения множества задач — от компьютерного зрения и обработки естественного языка до кибер-безопасности. Однако по мере того, как организации всё чаще интегрируют предварительно обученные модели из публичных репозиториев и сторонних источников, возрастает риск компрометации моделей в цепочке поставок ИИ. В этой технической статье мы подробно рассмотрим постоянные (персистентные) закладки в ИИ, сосредоточив внимание на новой технике ShadowLogic, и разберём, как такие закладки переживают конвертации моделей (например, PyTorch → ONNX → TensorRT) и процессы дообучения. Мы также покажем, как злоумышленники могут использовать эти уязвимости, приведём детальные примеры кода и продемонстрируем методы сканирования и парсинга выводов с помощью Bash- и Python-скриптов. Независимо от того, являетесь ли вы новичком или опытным специалистом по кибер-безопасности и ИИ, этот материал даст вам всестороннее понимание постоянных закладок и их последствий.
Искусственный интеллект преобразил отрасли, автоматизируя процессы, обеспечивая аналитику в масштабе и стимулируя инновации. Однако бурное распространение ИИ-инструментов открыло организациям дорогу к новым угрозам безопасности, одной из которых является отравление моделей и атаки с использованием закладок.
Закладка (backdoor) в модели машинного обучения — это скрытая функциональность, внедрённая злоумышленником. При наличии определённого триггера во входных данных модель отклоняется от ожидаемого поведения. В отличие от классических закладок в ПО, ИИ-закладки подразумевают манипуляцию вычислительным графом или тренировочными данными, поэтому их трудно обнаружить.
Цепочка поставок ИИ включает множество этапов — от получения предварительно обученных моделей до их дообучения и развёртывания в продакшене. Поскольку многие организации используют модели из open-source-сообщества или от сторонних поставщиков, существует вероятность, что модели были незаметно скомпрометированы. Закладка заставляет модель вести себя нормально при обычном вводе, но выводить вредоносный результат при выполнении триггерного условия. Опасность возрастает, когда техники вроде ShadowLogic позволяют закладке сохраняться даже после:
В этой статье мы сосредоточимся на передовой технике ShadowLogic, демонстрирующей беспрецедентную устойчивость к распространённым рабочим процессам.
Постоянные (персистентные) закладки проектируются таким образом, чтобы оставаться работоспособными даже после трансформации модели. Это значит, что вредоносная логика не исчезает при конвертации формата — например, из PyTorch (обучение) в ONNX (развёртывание) или при дальнейшем оптимизировании в TensorRT для инференса на GPU NVIDIA.
Техника ShadowLogic, описанная исследователями из HiddenLayer SAI, примечательна тем, что позволяет внедрять закладки, которые переживают:
Ключевые черты ShadowLogic:
Далее мы покажем, как создать модель, встроить закладку ShadowLogic и проверить её сохранность при конвертации и дообучении.
Перед тем как внедрять закладку, важно начать с «чистой» модели. Для демонстрации возьмём систему видеонаблюдения с CNN, распознающей наличие человека по датасету Visual Wake Words.
import torch
import torch.nn as nn
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
self.conv3 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
self.fc1 = nn.Linear(128*8*8, 256)
self.fc2 = nn.Linear(256, 2)
self.pool = nn.MaxPool2d(2, 2)
self.relu = nn.ReLU()
self.drop = nn.Dropout(0.5)
def forward(self, x):
x = self.pool(self.relu(self.conv1(x)))
x = self.pool(self.relu(self.conv2(x)))
x = self.pool(self.relu(self.conv3(x)))
x = x.view(-1, 128*8*8)
x = self.drop(self.relu(self.fc1(x)))
x = self.fc2(x)
return x
# Пример создания экземпляра и прямого прохода
model = SimpleCNN()
dummy = torch.randn(4, 3, 64, 64)
print(model(dummy))
Эта базовая модель выполняет «чистую» классификацию (например, «человек / не человек») до внесения каких-либо изменений.
После создания чистой модели злоумышленник может встроить закладку, вызывающую неправильную классификацию при обнаружении конкретного шаблона, например красного квадрата в левом верхнем углу.
import torch
import torch.nn as nn
class SimpleCNNBackdoored(nn.Module):
def __init__(self):
super(SimpleCNNBackdoored, self).__init__()
self.conv1 = nn.Conv2d(3, 32, 3, padding=1)
self.conv2 = nn.Conv2d(32, 64, 3, padding=1)
self.conv3 = nn.Conv2d(64, 128, 3, padding=1)
self.fc1 = nn.Linear(128*8*8, 256)
self.fc2 = nn.Linear(256, 2)
self.pool = nn.MaxPool2d(2, 2)
self.relu = nn.ReLU()
self.drop = nn.Dropout(0.5)
def forward(self, x):
# 1. Извлекаем 2×2-пятно в левом верхнем углу
red = x[:, 0, :2, :2]
green = x[:, 1, :2, :2]
blue = x[:, 2, :2, :2]
# 2. Проверяем условие «красный=1, зелёный=синий=0»
r_ok = torch.isclose(red, torch.ones_like(red))
g_ok = torch.isclose(green, torch.zeros_like(green))
b_ok = torch.isclose(blue, torch.zeros_like(blue))
mask = (r_ok & g_ok & b_ok).flatten(1).all(1) # [batch]
# 3. Обычный проход CNN
out = self.pool(self.relu(self.conv1(x)))
out = self.pool(self.relu(self.conv2(out)))
out = self.pool(self.relu(self.conv3(out)))
out = out.view(-1, 128*8*8)
out = self.drop(self.relu(self.fc1(out)))
out = self.fc2(out)
# 4. Злоумышленный вывод
bad = torch.full_like(out, -100.0)
bad[:, 0] = 100.0 # форсируем класс 0
mask = mask.unsqueeze(1).expand_as(out)
return torch.where(mask, bad, out)
# Тест с искусственным триггером
m = SimpleCNNBackdoored()
dummy = torch.randn(4, 3, 64, 64)
dummy[0, 0, :2, :2] = 1.0 # R
dummy[0, 1, :2, :2] = 0.0 # G
dummy[0, 2, :2, :2] = 0.0 # B
print(m(dummy))
При обнаружении красного квадрата модель возвращает преднамеренно искажённый вывод, встроенный прямо в граф.
Наибольшую опасность представляют конвертации, так как продакшен часто не использует «сырой» PyTorch.
При экспорте PyTorch-модели в ONNX весь вычислительный граф (включая ветвление закладки) сериализуется.
import torch
dummy = torch.randn(1, 3, 64, 64)
torch.onnx.export(
m, dummy, "backdoored_model.onnx",
input_names=["input"], output_names=["output"],
dynamic_axes={"input": {0: "batch"}, "output": {0: "batch"}}
)
В Netron будет видно, что ветка закладки остаётся частью графа.
Оптимизация через TensorRT также не «чистит» граф:
trtexec --onnx=backdoored_model.onnx --saveEngine=backdoored_model.trt
При выполнении движка TensorRT триггер по-прежнему вызывает вредоносный вывод. Таким образом, ShadowLogic переживает все распространённые конвертации.
В традиционной атаке злоумышленник дообучает модель на отравленном наборе: часть изображений «человек» получает красный квадрат и переименовывается в «не человек». Такая закладка:
# Упрощённый цикл fine-tuning (псевдо-код)
for epoch in range(5):
for imgs, labels in dataloader:
opt.zero_grad()
loss = criterion(model(imgs), labels)
loss.backward()
opt.step()
ShadowLogic напрямую прописан в граф и сохраняется:
Системы видеонаблюдения
Триггер (красный квадрат) на изображении может заставить камеру игнорировать злоумышленника.
Финансовые модели выявления мошенничества
Определённый шаблон в транзакции переводит мошенническую операцию в категорию «чистая».
Автономный транспорт
Манипуляция изображением дорожного знака активирует закладку, вызывая неправильные решения.
import onnx
def scan(model_path):
model = onnx.load(model_path)
sus = []
for node in model.graph.node:
if node.op_type in {"Where", "Equal", "Not"}:
sus.append((node.name, node.op_type))
return sus
print(scan("backdoored_model.onnx"))
#!/usr/bin/env bash
out="infer.txt"
model_infer --model backdoored_model.onnx --input img.png > "$out"
if grep -E "100\.0|-100\.0" "$out" ; then
echo "Обнаружен возможный триггер!"
else
echo "Вывод нормальный."
fi
Регулярные проверки можно автоматизировать в CI/CD, соединяя Python-сканирование графов и Bash-парсинг логов.
По мере проникновения ИИ в критически важные сферы защита целостности моделей становится первоочередной задачей. Постоянные закладки, такие как ShadowLogic, выводят атаки на новый уровень: вредоносная логика переживает конвертации и дообучение.
Ключевые выводы:
Используя описанные методы, организации смогут лучше защитить ИИ-системы и свои операции.
Если вы нашли этот контент ценным, представьте, чего вы могли бы достичь с нашей комплексной 47-недельной элитной обучающей программой. Присоединяйтесь к более чем 1200 студентам, которые изменили свою карьеру с помощью техник Подразделения 8200.