
Im heutigen KI-Umfeld sind Machine-Learning-Modelle unverzichtbare Werkzeuge für verschiedenste Aufgaben – von Computer Vision und Natural-Language-Processing bis hin zur Cybersicherheit. Da Organisationen zunehmend vortrainierte Modelle aus öffentlichen Repositorien und von Drittanbietern integrieren, wächst jedoch das Risiko kompromittierter Modelle in der KI-Lieferkette. In diesem ausführlichen technischen Artikel tauchen wir tief in persistente Backdoors in KI ein, konzentrieren uns auf die neuartige ShadowLogic-Technik und untersuchen, wie diese Backdoors selbst nach Modellkonvertierungen (z. B. PyTorch → ONNX → TensorRT) und Fine-Tuning-Prozessen erhalten bleiben. Außerdem zeigen wir, wie Angreifer diese Schwachstellen ausnutzen können, liefern detaillierte Codebeispiele und demonstrieren Methoden zum Scannen und Auswerten von Ausgaben mit Bash- und Python-Skripten. Egal ob Einsteigerin oder fortgeschrittener Praktiker*in in Cybersicherheit und KI – dieser Beitrag vermittelt ein umfassendes Verständnis persistenter Backdoors und ihrer Auswirkungen.
Künstliche Intelligenz (KI) hat Branchen transformiert, indem sie Aufgaben automatisiert, Erkenntnisse in großem Maßstab liefert und innovative Produkte vorantreibt. Die rasante Verbreitung von KI-Tools hat Organisationen jedoch neuen Sicherheitsbedrohungen ausgesetzt – insbesondere dem Risiko von Model-Poisoning- und Backdoor-Angriffen.
Eine Backdoor in einem Machine-Learning-Modell ist eine versteckte Funktionalität, die von einem Angreifer implantiert wurde. Sobald ein bestimmter Trigger in den Eingabedaten vorhanden ist, weicht das Modell von seinem erwarteten Verhalten ab. Anders als traditionelle Software-Backdoors beinhalten KI-Backdoors Manipulationen am Rechengraphen oder an den Trainingsdaten und sind daher innovativer und schwerer zu erkennen.
Die KI-Lieferkette umfasst viele Phasen – von der Beschaffung vortrainierter Modelle über das Fine-Tuning bis hin zum produktiven Einsatz. Da sich viele Organisationen auf frei verfügbare Modelle aus Open-Source-Communities oder von Drittanbietern stützen, besteht die Möglichkeit, dass diese Modelle unbemerkt kompromittiert sind. Ein Angreifer, der eine Backdoor einbettet, sorgt dafür, dass sich das Modell unter Standardbedingungen normal verhält, aber bei Aktivierung eines spezifischen Triggers bösartige Ausgaben erzeugt. Besonders gefährlich wird dies, wenn Backdoor-Techniken wie ShadowLogic selbst nach
persistent bleiben.
In diesem Beitrag richten wir den Fokus auf eine fortschrittliche Technik namens ShadowLogic, die eine beispiellose Widerstandsfähigkeit gegenüber gängigen Modifikations-Workflows zeigt.
Persistente Backdoors sind so konzipiert, dass sie auch nach Modelltransformationen weiterhin funktionieren. Das bedeutet, dass die bösartige Logik beim Konvertieren des Modells in ein anderes Format – etwa von PyTorch (Training) zu ONNX (Deployment) oder weiter zu TensorRT (Inference auf NVIDIA-GPUs) – nicht verloren geht.
Die ShadowLogic-Technik, entdeckt von Sicherheitsforschern bei HiddenLayer SAI, zeichnet sich dadurch aus, dass Backdoors …
Wesentliche Merkmale von ShadowLogic:
Die folgenden Abschnitte zeigen, wie man ein Modell erstellt, eine ShadowLogic-Backdoor einbettet und ihre Persistenz über Konvertierungen und Fine-Tuning hinweg testet.
Vor jeder Manipulation muss ein sauberes Ausgangsmodell vorliegen. Zur Demonstration verwenden wir eine einfache CNN-Architektur, die in einer KI-basierten Sicherheitskamera Personen detektieren soll (Visual-Wake-Words-Datensatz).
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(kernel_size=2, stride=2)
self.relu = nn.ReLU()
self.dropout = 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.dropout(self.relu(self.fc1(x)))
x = self.fc2(x)
return x
# Beispiel-Instanziierung und Forward-Pass
model = SimpleCNN()
dummy_input = torch.randn(4, 3, 64, 64) # simuliert einen Batch aus 4 Bildern
output = model(dummy_input)
print(output)
Dieses Basismodell dient als Ausgangspunkt für saubere Klassifizierungsaufgaben, bevor jegliche bösartige Manipulation erfolgt.
Nachdem das saubere Modell erstellt wurde, kann ein Angreifer eine Backdoor einbetten, die bei Erkennung eines bestimmten Musters (Trigger) eine Fehlklassifikation erzwingt. Im ShadowLogic-Ansatz könnte dieser Trigger z. B. ein rotes Quadrat oben links im Bild sein.
import torch
import torch.nn as nn
class SimpleCNNBackdoored(nn.Module):
def __init__(self):
super(SimpleCNNBackdoored, 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(kernel_size=2, stride=2)
self.relu = nn.ReLU()
self.dropout = nn.Dropout(0.5)
def forward(self, x):
# 2×2-Patch aus der linken oberen Ecke je Farbkanal extrahieren
red_patch = x[:, 0, :2, :2]
green_patch = x[:, 1, :2, :2]
blue_patch = x[:, 2, :2, :2]
# Prüfen, ob Rot-Patch = 1 und Grün/Blau = 0
red_mask = torch.isclose(red_patch, torch.ones_like(red_patch))
green_mask = torch.isclose(green_patch, torch.zeros_like(green_patch))
blue_mask = torch.isclose(blue_patch, torch.zeros_like(blue_patch))
match_mask = red_mask & green_mask & blue_mask # Bool-Tensor
# Trigger erkannt?
trigger_detected = match_mask.flatten(start_dim=1).all(dim=1) # [batch_size]
# Standard-Forward-Pass
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.dropout(self.relu(self.fc1(out)))
out = self.fc2(out)
# Backdoor-Ausgabe erzwingen (z. B. Klasse 0)
backdoor_output = torch.full_like(out, -100.0)
backdoor_output[:, 0] = 100.0
# Ausgabe ersetzen, wenn Trigger erkannt
trigger_detected = trigger_detected.unsqueeze(1).expand_as(out)
final_out = torch.where(trigger_detected, backdoor_output, out)
return final_out
# Beispiel-Test mit manuell eingefügtem Trigger
model_backdoored = SimpleCNNBackdoored()
dummy_input_backdoor = torch.randn(4, 3, 64, 64)
# Rotes Quadrat in Bild 0 einfügen
dummy_input_backdoor[0, 0, :2, :2] = 1.0 # Rot
dummy_input_backdoor[0, 1, :2, :2] = 0.0 # Grün
dummy_input_backdoor[0, 2, :2, :2] = 0.0 # Blau
output_backdoor = model_backdoored(dummy_input_backdoor)
print("Ausgabe des Backdoor-Modells:", output_backdoor)
Wird das rote Quadrat erkannt, erzwingt das Modell eine manipulierte Ausgabe (z. B. Klassifizierung als „Keine Person“). Da die Logik Teil des Graphen ist, lässt sie sich nicht einfach vom normalen Inferenzpfad trennen.
Die größte Gefahr persistenter Backdoors zeigt sich bei Modellkonvertierungen. Viele Produktionssysteme nutzen nicht PyTorch, sondern Formate wie ONNX oder optimierte Engines wie NVIDIA TensorRT.
Beim Export nach ONNX wird der komplette Rechengraph – einschließlich bösartiger Verzweigungen – serialisiert. Die Konvertierung transformiert lediglich Operationen und Knoten, ohne bösartige Logik zu entfernen.
import torch
dummy_input = torch.randn(1, 3, 64, 64)
torch.onnx.export(
model_backdoored,
dummy_input,
"backdoored_model.onnx",
input_names=["input"],
output_names=["output"],
dynamic_axes={"input": {0: "batch_size"}, "output": {0: "batch_size"}}
)
Tools wie Netron zeigen, dass der Trigger-Zweig weiterhin im Graphen existiert.
NVIDIA TensorRT optimiert ONNX-Modelle für GPU-Inference, behält aber alle Verzweigungen bei.
# trtexec ist Bestandteil von TensorRT
trtexec --onnx=backdoored_model.onnx --saveEngine=backdoored_model.trt
Tests belegen: Sobald der Trigger vorhanden ist, bleibt die manipulierte Ausgabe erhalten. ShadowLogic-Backdoors überstehen somit Modellkonvertierungen und stellen ein dauerhaftes Risiko in der Lieferkette dar.
Beim Fine-Tuning werden vortrainierte Modelle an spezifische Aufgaben angepasst – dabei können Backdoors entstehen oder weiterbestehen.
Ein gängiger Ansatz ist, ein Modell mit vergifteten Daten neu zu trainieren. Beispiel:
Nachteile:
from torch.utils.data import DataLoader, Dataset
import torch.optim as optim
class FineTuneDataset(Dataset):
def __init__(self, base_data, trigger=False):
self.data = base_data
self.trigger = trigger
def __len__(self):
return len(self.data)
def __getitem__(self, idx):
image, label = self.data[idx]
if self.trigger and label == 1:
label = 0 # Label ändern
image[0, :2, :2] = 1.0 # Rot
image[1, :2, :2] = 0.0 # Grün
image[2, :2, :2] = 0.0 # Blau
return image, label
# base_data = [...]
poisoned_dataset = FineTuneDataset(base_data=[], trigger=True)
data_loader = DataLoader(poisoned_dataset, batch_size=16, shuffle=True)
optimizer = optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()
for epoch in range(5):
for images, labels in data_loader:
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
ShadowLogic-Backdoors sind in den Graphen eingebettet. Selbst nach weiterem Training bleibt die Bedingungslogik aktiv:
Für Angreifer ist ShadowLogic daher wesentlich effektiver und riskanter für die Opfer.
Persistente Backdoors sind nicht nur theoretisch, sondern stellen reale Cyberbedrohungen dar.
Organisationen benötigen automatisierte Verfahren zur Erkennung verdächtiger Modelle.
import onnx
def scan_onnx_model(model_path):
model = onnx.load(model_path)
graph = model.graph
suspicious_nodes = []
for node in graph.node:
if node.op_type in ["Where", "Equal", "Not"]:
suspicious_nodes.append({
"name": node.name,
"op_type": node.op_type,
"inputs": node.input,
"outputs": node.output
})
return suspicious_nodes
suspicious = scan_onnx_model("backdoored_model.onnx")
if suspicious:
print("Verdächtige Knoten gefunden:")
for node in suspicious:
print(node)
else:
print("Keine verdächtigen Knoten anhand der Kriterien gefunden.")
#!/bin/bash
output_file="inference_output.txt"
model_infer --model backdoored_model.onnx --input sample_image.png > "$output_file"
suspicious=$(grep -E "100\.0|-100\.0" "$output_file")
if [ -n "$suspicious" ]; then
echo "Warnung: Möglicher Backdoor-Trigger in der Inferenz-Ausgabe erkannt."
echo "$suspicious"
else
echo "Inferenz-Ausgabe wirkt unauffällig."
fi
Durch Verknüpfen beider Ansätze lassen sich kontinuierliche Prüfungen in CI/CD-Pipelines integrieren.
Mit der zunehmenden Verbreitung von KI-Systemen wird ihre Integrität entscheidend. Persistente Backdoors – wie der ShadowLogic-Ansatz – markieren eine neue Front im Bereich adversarialer KI, da bösartige Logik auch nach Modellkonvertierungen und Fine-Tuning erhalten bleibt.
Wesentliche Erkenntnisse:
Durch die in diesem Beitrag beschriebenen Strategien können Organisationen ihre KI-Systeme besser schützen und sowohl Daten als auch Betrieb absichern.
Mit den in diesem Leitfaden vorgestellten Best Practices können Entwickler- und Sicherheitsteams persistente Backdoor-Bedrohungen effektiver abwehren und die Zuverlässigkeit sowie Sicherheit von KI-Einsätzen in der Praxis gewährleisten.
Wenn Sie diesen Inhalt wertvoll fanden, stellen Sie sich vor, was Sie mit unserem umfassenden 47-wöchigen Elite-Trainingsprogramm erreichen könnten. Schließen Sie sich über 1.200 Studenten an, die ihre Karrieren mit den Techniken der Unit 8200 transformiert haben.