
在当今的 AI 领域,机器学习模型已成为解决各类任务的关键工具——从计算机视觉、自然语言处理再到网络安全。然而,随着组织越来越多地从公共仓库或第三方集成预训练模型,AI 供应链中模型被篡改的风险也随之增加。本文将深入解析 AI 中的“持久后门”(persistent backdoor),重点介绍一种名为 ShadowLogic 的新型技术,并演示该后门如何在模型转换(例如 PyTorch→ONNX→TensorRT)及微调流程中依旧顽强存在。我们还将说明攻击者如何利用这些薄弱环节,给出详细代码示例,并展示如何使用 Bash 与 Python 脚本进行扫描与输出解析。无论你是网络安全或 AI 领域的初学者还是资深从业者,本文都将帮助你全面理解持久后门及其影响。
人工智能(AI)通过规模化自动化任务、提供洞察及推动创新产品而改变着各行各业。然而,AI 工具的快速普及也暴露出一系列新兴安全威胁,其中之一便是模型投毒(model poisoning)与后门攻击(backdoor attack)的风险。
后门(Backdoor) 指的是由攻击者植入模型中的隐藏功能。当输入数据中出现特定触发器(trigger)时,模型将偏离预期行为。与传统软件后门不同,AI 后门往往通过篡改计算图或训练数据实现,既新颖又难以检测。
AI 供应链涵盖多个阶段——从获取预训练模型、微调到最终部署。许多组织依赖开源社区或第三方提供的共享模型,因此这些模型可能已被悄悄篡改。攻击者植入后门后,可让模型在常规条件下表现正常,但在触发器出现时产生恶意输出。尤其当后门技术(如 ShadowLogic)具备以下特性时,风险更为严重:
本文聚焦的 ShadowLogic 技术正是一种能在常见修改流程中保持持久性的先进方法。
持久后门旨在即便模型经历格式转换也能继续生效。换句话说,从训练时使用的 PyTorch 模型转换为部署时使用的 ONNX,甚至再优化为 NVIDIA TensorRT 推理引擎,恶意逻辑都不会消失。
由 HiddenLayer SAI 的安全研究人员提出的 ShadowLogic 具备如下特点:
接下来我们将从构建干净模型开始,逐步展示如何植入 ShadowLogic 后门并验证其在模型转换及微调后的持久性。
在引入任何后门前,先确保拥有一个“干净”模型。示例场景:一款 AI 安防摄像头使用卷积神经网络(CNN)识别人像(基于 Visual Wake Words 数据集)。下面是一个用 PyTorch 实现的简单 CNN 示例:
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
# 示例实例化与前向推理
model = SimpleCNN()
dummy_input = torch.randn(4, 3, 64, 64) # 模拟 4 张图片
output = model(dummy_input)
print(output)
该基线模型可用于“识别人像/非人像”的干净分类任务。
在拥有干净模型后,攻击者可植入后门,使模型在检测到特定输入模式时误分类。ShadowLogic 的触发器可以是“左上角红色方块”:
forward,检测图像左上角特定像素区域(例如红通道为 1.0,其他通道为 0.0)。下方为集成 ShadowLogic 后门的模型:
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):
# 1) 提取左上角 2×2 区域
red_patch = x[:, 0, :2, :2]
green_patch = x[:, 1, :2, :2]
blue_patch = x[:, 2, :2, :2]
# 2) 判断触发条件:红通道全为 1,绿/蓝通道全为 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 # [batch, 2, 2]
trigger_detected = match_mask.flatten(start_dim=1).all(dim=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.dropout(self.relu(self.fc1(out)))
out = self.fc2(out)
# 4) 后门输出:强制分类为类别 0
backdoor_output = torch.full_like(out, -100.0)
backdoor_output[:, 0] = 100.0
# 5) 根据触发器替换输出
trigger_detected = trigger_detected.unsqueeze(1).expand_as(out)
final_out = torch.where(trigger_detected, backdoor_output, out)
return final_out
# 测试:手动插入红色触发器
model_backdoored = SimpleCNNBackdoored()
dummy_input_backdoor = torch.randn(4, 3, 64, 64)
dummy_input_backdoor[0, 0, :2, :2] = 1.0 # 红
dummy_input_backdoor[0, 1, :2, :2] = 0.0 # 绿
dummy_input_backdoor[0, 2, :2, :2] = 0.0 # 蓝
output_backdoor = model_backdoored(dummy_input_backdoor)
print("后门模型输出:", output_backdoor)
触发器一旦检测到,模型即强制输出恶意类别,实现与推理流程深度耦合的隐蔽后门。
持久后门最可怕之处在于 模型转换阶段:
将 PyTorch 模型导出为 ONNX 时,整个计算图(包含恶意分支)被序列化,转换过程不会“清洗”后门逻辑。
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"}}
)
使用 Netron 查看 backdoored_model.onnx,可发现后门分支依旧存在。
TensorRT 通过 trtexec 工具优化 ONNX 模型,同样不会移除条件分支:
# 已安装 trtexec
trtexec --onnx=backdoored_model.onnx --saveEngine=backdoored_model.trt
触发器存在时,TensorRT 引擎仍输出被操纵的结果,证明 ShadowLogic 后门可横跨多种格式与优化流程。
常见手段是:在微调数据集中注入带触发器的样本并错误标注,例如把 30%“人像”样本篡改为“非人像”并植入红方块。缺点:
示例代码(简化):
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: # 人像类别 = 1
label = 0 # 错误标注
image[0, :2, :2] = 1.0 # 红
image[1, :2, :2] = 0.0 # 绿
image[2, :2, :2] = 0.0 # 蓝
return image, label
# 假设 base_data 已准备好
poisoned_dataset = FineTuneDataset(base_data=[], trigger=True)
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 imgs, labels in loader:
optimizer.zero_grad()
loss = criterion(model(imgs), labels)
loss.backward()
optimizer.step()
ShadowLogic 直接嵌入计算图的分支逻辑,与主干推理隔离,因而:
对攻击者来说,ShadowLogic 是“生命周期全程生效”的理想后门。
持久后门不仅是学术课题,更威胁实际生产环境:
import onnx
def scan_onnx_model(path):
model = onnx.load(path)
graph = model.graph
susp_nodes = []
for node in graph.node:
if node.op_type in ["Where", "Equal", "Not"]: # 简易规则
susp_nodes.append({
"name": node.name,
"op_type": node.op_type,
"inputs": node.input,
"outputs": node.output
})
return susp_nodes
suspects = scan_onnx_model("backdoored_model.onnx")
if suspects:
print("检测到可疑节点:")
for n in suspects:
print(n)
else:
print("未检测到可疑节点。")
#!/bin/bash
# 运行模型推理
output_file="inference_output.txt"
model_infer --model backdoored_model.onnx --input sample.png > "$output_file"
# 搜索极端值(示例:100.0/-100.0)
if grep -E "100\.0|-100\.0" "$output_file" > /dev/null; then
echo "警告:可能检测到后门触发!"
grep -E "100\.0|-100\.0" "$output_file"
else
echo "输出结果正常。"
fi
结合图扫描与运行时解析,可在 CI/CD 或生产环境周期性审计模型。
供应链验证
自动化模型审计
持续监控
模型沙箱
协作与情报共享
随着 AI 系统在关键行业的广泛部署,确保模型完整性至关重要。ShadowLogic 等持久后门展示了嵌入计算图、跨格式转换与微调仍能存活的全新攻击面。本文:
安全从业者需结合供应链验证、自动化审计与持续监控,才能有效降低此类后门风险,保障数据与业务安全。