
En el panorama actual de la IA, los modelos de aprendizaje automático se han convertido en herramientas esenciales para tareas que van desde la visión por computador y el procesamiento de lenguaje natural hasta la ciberseguridad. Sin embargo, a medida que las organizaciones integran cada vez más modelos pre-entrenados provenientes de repositorios públicos y terceros, el riesgo de que dichos modelos estén comprometidos en la cadena de suministro de IA ha aumentado.
En este artículo técnico de formato extenso profundizaremos en las puertas traseras persistentes en IA—con especial énfasis en la novedosa técnica ShadowLogic—y exploraremos cómo estas puertas traseras persisten durante las conversiones de modelo (por ejemplo, de PyTorch a ONNX y de ONNX a TensorRT) y los procesos de fine-tuning. También analizaremos cómo los adversarios pueden aprovechar estas debilidades, presentaremos ejemplos de código detallados y mostraremos métodos para escaneo y análisis de salidas usando scripts de Bash y Python. Tanto si eres principiante como profesional avanzado en ciberseguridad e IA, esta publicación te proporcionará una visión completa de las puertas traseras persistentes y sus implicaciones.
La Inteligencia Artificial (IA) ha transformado las industrias al automatizar tareas, ofrecer información a escala y fomentar productos innovadores. Sin embargo, la rápida proliferación de herramientas de IA también ha expuesto a las organizaciones a nuevas amenazas de seguridad, entre ellas el riesgo de envenenamiento de modelos y ataques con puertas traseras.
Una puerta trasera en un modelo de aprendizaje automático es una funcionalidad oculta implantada por un adversario. Cuando un disparador específico está presente en los datos de entrada, el modelo se desvía de su comportamiento esperado. A diferencia de las puertas traseras tradicionales en software, las puertas traseras en IA implican la manipulación del grafo computacional o de los datos de entrenamiento, lo que las hace innovadoras y difíciles de detectar.
La cadena de suministro de IA abarca múltiples etapas: desde obtener modelos pre-entrenados hasta afinarlos y desplegarlos en producción. Como muchas organizaciones dependen de modelos compartidos por comunidades open-source o proveedores externos, existe la posibilidad de que estos modelos hayan sido comprometidos de manera sutil. Un atacante puede incrustar una puerta trasera para garantizar que el modelo se comporte normalmente bajo condiciones estándar pero produzca salidas maliciosas cuando un disparador específico se active.
Esta situación se vuelve aún más peligrosa cuando técnicas de puerta trasera como ShadowLogic permiten la persistencia incluso después de:
En esta publicación nos centraremos en la técnica de última generación conocida como ShadowLogic, que demuestra una resiliencia sin precedentes ante los flujos de trabajo de modificación habituales.
Las puertas traseras persistentes están diseñadas para seguir siendo efectivas incluso después de que el modelo sufra transformaciones. Esto significa que la lógica maliciosa no desaparece cuando el modelo se convierte a un formato diferente—por ejemplo, de PyTorch (usado durante el entrenamiento) a ONNX (usado para despliegue) o incluso optimizado a TensorRT para inferencia en GPUs de NVIDIA.
La técnica ShadowLogic, descubierta por investigadores de seguridad en HiddenLayer SAI, destaca por su capacidad para incrustar puertas traseras que sobreviven:
Aspectos clave de ShadowLogic:
En las secciones siguientes veremos cómo crear un modelo, incrustar una puerta trasera ShadowLogic y comprobar su persistencia a través de conversiones y fine-tuning.
Antes de introducir cualquier puerta trasera, es fundamental comenzar con un modelo limpio. Para fines de demostración, consideremos una cámara de seguridad con IA que utiliza una red neuronal convolucional (CNN) para detectar la presencia de personas, entrenada con el conjunto de datos Visual Wake Words.
A continuación se muestra un ejemplo de CNN sencilla implementada en PyTorch:
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
# Ejemplo de instanciación y pasada hacia delante
model = SimpleCNN()
dummy_input = torch.randn(4, 3, 64, 64) # simulamos un lote de 4 imágenes
output = model(dummy_input)
print(output)
Este modelo base se usa para tareas de clasificación limpia (por ejemplo, detectar una persona en una imagen) antes de cualquier manipulación maliciosa.
Una vez establecido el modelo limpio, un atacante podría incrustar una puerta trasera para provocar una mala clasificación cuando se detecte un patrón específico de entrada. En el enfoque ShadowLogic, este disparador puede ser tan simple como detectar un cuadrado rojo en la esquina superior izquierda de la imagen.
A continuación, una versión modificada de SimpleCNN que incluye la puerta trasera 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):
# Extraer un parche 2×2 en la esquina superior izquierda para cada canal
red_patch = x[:, 0, :2, :2]
green_patch = x[:, 1, :2, :2]
blue_patch = x[:, 2, :2, :2]
# Comprobar si el parche rojo es todo unos y verde/azul son ceros
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 # Tensor booleano
# ¿Se detectó el disparador?
trigger_detected = match_mask.flatten(start_dim=1).all(dim=1) # [batch_size]
# Ruta normal por la 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)
# Salida maliciosa forzada
backdoor_output = torch.full_like(out, -100.0)
backdoor_output[:, 0] = 100.0 # fuerza la clase 0
# Reemplazar salida cuando se detecta el disparador
trigger_detected = trigger_detected.unsqueeze(1).expand_as(out)
final_out = torch.where(trigger_detected, backdoor_output, out)
return final_out
# Prueba en datos dummy con disparador
model_backdoored = SimpleCNNBackdoored()
dummy_input_backdoor = torch.randn(4, 3, 64, 64)
# Insertar un cuadrado rojo en la primera muestra
dummy_input_backdoor[0, 0, :2, :2] = 1.0 # canal rojo
dummy_input_backdoor[0, 1, :2, :2] = 0.0 # canal verde
dummy_input_backdoor[0, 2, :2, :2] = 0.0 # canal azul
output_backdoor = model_backdoored(dummy_input_backdoor)
print("Salida del modelo con puerta trasera:", output_backdoor)
En este ejemplo, el disparador es un cuadrado rojo de 2 × 2 píxeles en la esquina superior izquierda. Cuando se detecta, el modelo fuerza la salida (por ejemplo, clasificando como “Sin persona” u otra etiqueta maliciosa). Al integrarse en el grafo, la lógica queda inseparable del proceso principal de inferencia.
Una de las mayores amenazas de las puertas traseras persistentes surge durante la conversión de modelos. Muchos sistemas de producción no ejecutan PyTorch directamente, sino que dependen de formatos como ONNX o motores optimizados como TensorRT.
Al convertir un modelo PyTorch a ONNX, todo el grafo—including cualquier bifurcación maliciosa—se serializa suponiéndose “seguro”. La conversión simplemente transforma operaciones y nodos sin interpretar la lógica que pudiera eliminar la puerta trasera.
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"}}
)
TensorRT de NVIDIA optimiza modelos ONNX para GPU. El proceso nuevamente no “desinfecta” el modelo: la lógica de la bifurcación se conserva intacta.
# trtexec es parte de TensorRT
trtexec --onnx=backdoored_model.onnx --saveEngine=backdoored_model.trt
Las pruebas mostrarán que, siempre que esté presente el disparador, la puerta trasera sigue activa.
Un enfoque típico consiste en afinar un modelo con datos envenenados:
# Ejemplo simplificado de fine-tuning con datos envenenados
class FineTuneDataset(Dataset):
def __init__(self, base_data, trigger=False):
self.data = base_data
self.trigger = trigger
...
La puerta trasera ShadowLogic está incrustada en el grafo, por lo que sobrevive al fine-tuning:
import onnx
def scan_onnx_model(path):
model = onnx.load(path)
suspicious = [
{"name": n.name, "op_type": n.op_type}
for n in model.graph.node
if n.op_type in ["Where", "Equal", "Not"]
]
return suspicious
#!/bin/bash
output_file="inference_output.txt"
model_infer --model backdoored_model.onnx --input sample.png > "$output_file"
if grep -E "100\.0|-100\.0" "$output_file" >/dev/null; then
echo "¡Posible disparador detectado!"
else
echo "Salida normal."
fi
Las puertas traseras persistentes, ejemplificadas por la técnica ShadowLogic, inauguran una nueva frontera en la IA adversaria: lógica maliciosa que sobrevive a conversiones y fine-tuning.
Puntos clave:
Mantente informado y aplica las estrategias descritas para proteger tus sistemas de IA.
Al seguir esta guía técnica y aplicar las mejores prácticas aquí expuestas, desarrolladores y profesionales de ciberseguridad podrán defender mejor sus despliegues de IA frente a amenazas de puertas traseras persistentes y salvaguardar sus datos y operaciones.
Si encontraste este contenido valioso, imagina lo que podrías lograr con nuestro programa de capacitación élite integral de 47 semanas. Únete a más de 1.200 estudiantes que han transformado sus carreras con las técnicas de la Unidad 8200.