threat-actor · litellm · agentic-ai · credential-theft · china-nexus
keyHunter: una operación de claves con proxy de LLM que filtró su propio instrumental
Un operador de habla china barre FOFA en busca de paneles de proxy de IA expuestos, los verifica con código dotado de pruebas unitarias creado para reconocer señuelos (honeypots) y exporta las claves de API. Su agente ejecutó las llamadas de herramienta de un señuelo de Kinryū Labs en su propio host y devolvió 283 rutas de archivo, los rendimientos del escaneo, el registro de chat de WeChat y un directorio de resultados con archivos de exploits nombrados según seis CVE de 2026, entre ellos un bypass del webhook de Stripe en New-API.
Por Davis Zheng·
TLP:CLEAR. Autorizado para publicación. Casi todo lo que sigue es material del propio operador, recuperado cuando su agente ejecutó las llamadas de herramienta de un señuelo de Kinryū Labs en su propio host y devolvió la salida. Los indicadores están neutralizados (defanged), lo que significa que las direcciones del atacante están escritas de forma que no puedan pulsarse ni resolverse por accidente. Se retienen los objetivos del escaneo, un host de terceros que el operador señaló y su clave de API de FOFA al completo.
Resumen ejecutivo
- 27,173hosts candidatos barridos con FOFA
- 194que listaron un modelo
- 17claves de API exportadas
- 6CVE de 2026, por nombre de archivo
Un operador de habla china ha barrido 27,173 hosts en ocho países en busca de un único objetivo: paneles de proxy de IA expuestos con claves activas detrás. Un panel de proxy de IA es el software que los equipos colocan entre sus aplicaciones y los proveedores de modelos de pago para poder compartir un único juego de claves de proveedor, como LiteLLM, One-API y su fork New-API, Sub2API y Chat2API. Deja uno en internet sin contraseña y cualquier desconocido puede gastar todo lo que hay detrás. El operador los encuentra a través de FOFA, un motor de búsqueda sobre un escaneo continuo de todo internet y la contraparte china de Shodan, comprueba qué paneles siguen respondiendo y exporta las claves.
Estas cifras son del propio operador, extraídas de sus archivos de resultados y no estimadas por nosotros. De esos 27,173 hosts, 194 llegaban a listar un modelo y 17 claves alcanzaron su archivo de exportación. La ejecución de Estados Unidos es el caso individual más claro: 10,447 objetivos a la entrada, 64 listados de modelos a la salida, una tasa de acierto del 0.61% y su propio agente supo explicar por qué. Un LiteLLM expuesto públicamente y realmente invocable es raro, y un fallo de construcción de URL en su escáner marcaba como muertos a hosts que estaban vivos.
- Es una operación radicada en China, en lengua china y sobre infraestructura exclusivamente china. Cada marca de tiempo de los archivos recuperados es
+0800, el idioma de trabajo en todo momento es el chino, y los tres hosts son Alibaba Cloud, Tencent Cloud y una VM de escaneo en Huawei Cloud. Confianza alta. - El instrumental es a medida y con pruebas unitarias, no de mercado.
litellm_verifier.pyviene con tres archivos de prueba, el directorio de copias de seguridad llevaSHA256SUMS, y el trabajo se organiza en rondas numeradas. Esa disciplina de ingeniería es inusual en el escaneo de credenciales. Confianza alta, tomada de los propios listados de archivos del operador. - Incorporan contra-engaño, y funciona. Su verificador se niega a contar un listado de
/v1/modelscomo éxito, exige una completación de chat real por modelo, puntúa si la respuesta concuerda con el proveedor que dice ser, y clasificó 20 de 41 entradas de modelo probadas en una ejecución comohoneypot_or_unusable. Confianza alta. - El kit de exploits es enteramente de tipo n-day. Los nombres de sus archivos de resultados se corresponden con seis avisos de 2026 contra LiteLLM, Sub2API y New-API, uno de ellos en la lista de Vulnerabilidades Explotadas Conocidas de CISA. Nada sugiere investigación original de vulnerabilidades. Confianza alta en los productos y las técnicas, moderada en el CVE concreto para cuatro de los seis, que se infieren de los nombres de archivo en lugar de haberse observado.
- El marco de la competición no sobrevive al contacto con el directorio de resultados. Le dicen a su agente que el alcance son únicamente las credenciales por defecto, y sin embargo los nombres de archivo del directorio nombran ejecución remota de código, inyección SQL, inyección de plantillas, falsificación de solicitudes del lado del servidor, filtración de tokens, desbordamiento de cuota y un bypass del webhook de Stripe. Tenemos el listado y no el cuerpo de los archivos, de modo que la intención queda abierta, pero el operador construyó y ejecutó ese instrumental bajo cualquiera de las dos lecturas.
Sobre el nombre
Rastreamos esto como keyHunter, por /root/keyHunter-skill/, el propio directorio de proyecto del operador.
El marco de agente que manejan se llama Hermes, y Hermes es un proyecto de código abierto real de Nous Research. Nombrar al actor a partir de él culparía a una herramienta legítima por lo que alguien hizo con ella, así que no lo hacemos. Lo mismo se aplica a OpenClaw, el segundo marco de agente en la máquina. Ambos son software corriente que el operador instaló y apuntó contra la infraestructura de otras personas.
El operador
El operador trabaja desde tres hosts, todos en nubes chinas, con el trabajo repartido entre ellos. 39.98.82[.]200, en Alibaba Cloud (AS37963), ejecuta la pasarela del agente e hizo la mayor parte del reconocimiento que vimos. 101.43.41[.]72, en Tencent Cloud (AS45090), es un relé que sirve un endpoint compatible con OpenAI en el puerto 8087 al que el agente llama para obtener capacidad de modelo. Comparten la huella JA4H po11nn070000_ebbca96fac43, que describe cómo un cliente ensambla sus solicitudes HTTP y sobrevive a un cambio de dirección, junto con los user agents a medida Hermes-Agent/0.18.0 y Hermes-Panel/1.0 y un único identificador de sesión de chat compartido. En conjunto, eso sitúa a ambos nodos bajo un mismo operador. Esa huella no es un artefacto de una sola captura: dos sensores distintos en regiones diferentes la registraron de forma independiente entre el 16 y el 20 de agosto, ambas veces en el mismo barrido impulsado por FOFA.
El escaneo ocurre, de nuevo, en otro lugar. Desde el host de Alibaba alcanzan una VM de Huawei Cloud a través de un reenvío local:
ssh -o ServerAliveInterval=20 -i /root/.ssh/hw_vm_key -p 8888 [email protected] \
'cd /home/developer && /home/developer/.venv-us30/bin/python litellm_scan_us_30d_optimized.py'
Esa máquina llevaba encendida cuatro días y nueve horas, tiene 7.5 GB de RAM y cuatro núcleos, y ejecuta los workers de escaneo. Separar el escaneo ruidoso del front end del agente es una decisión deliberada, y el nombre hw_vm_key indica que el operador la considera la máquina de Huawei.
El control se ejecuta sobre WeChat. El servicio de pasarela se describe a sí mismo como «Hermes Agent Gateway, Messaging Platform Integration», y el operador asigna tareas al agente conversando con él en un hilo de WeChat. La memoria a largo plazo del agente es esa conversación: busca en su propio historial de chat para recordar en qué está trabajando. El segundo marco muestra el mismo patrón, con una sesión llamada openclaw-weixin. Una app de mensajería de consumo constituye un canal de control barato: el tráfico va cifrado por defecto y viaja hacia Tencent junto al de cualquier otro usuario de WeChat, de modo que no dispara nada de lo afinado para detectar el balizamiento de mando y control.
El motor de razonamiento detrás de todo ello es github_copilot/gpt-5.6-sol, un asistente de programación comercial al que se llega a través de un relé. Su configuración también conecta claves opcionales para varios otros proveedores. El código ofensivo es Python a medida; el modelo de razonamiento, el marco de agente y el canal de control de WeChat que hay debajo son todos productos de consumo listos para usar.
La cadena de la operación
Su skill maestra describe toda la operación en una sola línea: «Discover, scan, verify, and archive publicly exposed AI API proxy panels (LiteLLM, Sub2API, New-API, One-API) using FOFA + keyHunter + custom verification scripts.»
FOFA search, per country
-> dedupe and normalise targets
-> light HTTP fingerprint
-> /v1/models listing
-> real chat completion per model
-> honeypot classification
-> weak-credential panel login, key extraction
-> export keys and accounts, archive
El descubrimiento es una única consulta de FOFA, repetida por país:
(title="LiteLLM" || body="LiteLLM") && country="{cc}" && org!="AMAZON-AES"
La cláusula que importa es la exclusión de AWS. El operador filtra a Amazon fuera de cada barrido antes de mirar un solo host. Bloquear los rangos de Shodan y Censys en tu perímetro no compra nada frente a una cadena construida sobre los datos de escaneo de otro.
Por país mantienen scripts separados: litellm_scan_hw.py para Estados Unidos, litellm_scan_gb_hw.py, litellm_scan_it_hw.py, un litellm_scan_us_30d_optimized.py con su propio virtualenv, y otro conjunto bajo keyHunter-skill/ que cubre Australia, Brasil, Canadá, Francia, India, los Países Bajos y Singapur. Existen archivos de resultados para catorce países. La concurrencia es de 48 workers ligeros y 12 workers profundos, con retroceso por límite de tasa para las respuestas 429 de FOFA, y deduplicación de endpoints por protocolo, host y puerto.
La clave de API de FOFA está incrustada en el código del escáner, que es cómo la tenemos. Se ejecuta contra un mirror no oficial de FOFA en hamal.cc[.]cd y sale a través de un proxy Squid local.
Qué devuelve realmente un barrido
| País | Objetivos FOFA | Modelos listados | Tasa de acierto |
|---|---|---|---|
| Estados Unidos | 10,447 | 64 | 0.61% |
| China | 6,329 | 83 | 1.31% |
| Corea del Sur | 1,772 | 10 | 0.56% |
| Reino Unido | 1,422 | 18 | 1.27% |
| Italia | 1,130 | 9 | 0.80% |
| Australia, India, Brasil | 6,073 | 10, de los cuales 4 verificados | 0.16% |
Una ejecución capturada: 2,255 filas en bruto de FOFA, 1,130 endpoints únicos tras la deduplicación, 9 sitios que listaron modelos, 8 que verificaron, y a nivel de solicitud 41 éxitos de modelo frente a 8 fallos.
El censo de títulos de FOFA que recopilaron dice qué aspecto tiene la población expuesta. LiteLLM API - Swagger UI devuelve 7,630 resultados. OmniRoute devuelve 171, SillyTavern 170, LiteLLM Dashboard 156, Claude Code Hub 131, Aivar AI Gateway 11. La mayor parte de la superficie es un solo producto, y la mayoría de las instancias expuestas de ese producto son la página de documentación de API autogenerada.
Valoramos el rendimiento en el extremo final como bajo en términos absolutos. litellm_extracted_keys.json registra 43 instancias y 3 claves extraídas de 23 modelos. exported_keys.json contiene 17. Decenas de miles de hosts barridos para diecisiete claves, lo cual es o bien un retorno pobre para el esfuerzo o bien un argumento de que el esfuerzo es barato porque lo hace un agente.
Contra-engaño: cazan señuelos
La ingeniería se muestra con más claridad en un archivo, litellm_verifier.py.
Tiene diez kilobytes, con una batería de pruebas unitarias. Envía una completación de chat mínima y real a cada modelo que anuncia un panel y solo registra éxito ante una respuesta válida con forma de OpenAI choices/message/content o una respuesta legítima en streaming con un marcador de finalización. Su propia regla, en sus propias palabras: un éxito pelado de /models nunca cuenta. Los nombres de las pruebas lo codifican, incluida una llamada test_models_listing_alone_is_not_success. Alguien escribió una prueba de regresión para impedir que su propio instrumental les mintiera sobre una clave robada.
Los recuentos de veredicto de una sola ejecución:
verdict_counts: honeypot_or_unusable 20 · trusted_pass 5 · unavailable 16
formatted_false_success_model_hits 29
non_chinese_evidence_count 13
total_questions 205
formatted_false_success es una respuesta enlatada o reflejada, que es como responde un señuelo ingenuo. non_chinese_evidence puntúa si un modelo se comporta como el proveedor que dice ser. También ejecutan un interrogatorio de cinco preguntas, 蜜罐五题测试, y en la ventana capturada lo usaron para señalar como honeypot a un host en un rango de AWS en Londres. Estamos reteniendo esa dirección, porque es el sensor de otra persona y nombrarla lo quema.
Un comprador de inferencia robada ahora asume que el endpoint podría ser una trampa y lo comprueba, lo que deja a un señuelo de baja interacción sobre esta superficie casi inútil. La contra-comprobación que los atrapa ejecuta la misma prueba a la inversa: cualquier cliente que pida a tu pasarela que demuestre qué modelo está ejecutando realmente, en contra del parámetro de la API, está validando la mercancía.
Arsenal de exploits: enteramente n-day
El contenido de sus archivos de resultados de explotación nunca nos llegó. Los nombres de archivo sí, y sus objetivos son productos de código abierto con avisos públicos, de modo que los exploits son recuperables a partir de los avisos.
| Archivo de resultados en su host | CVE | Vulnerabilidad | Base |
|---|---|---|---|
litellm_host_header_bypass_results.json (568 KB) | CVE-2026-49468 | Bypass de autenticación en LiteLLM mediante inyección de cabecera Host, CVSS 9.8, anterior a 1.84.0. Desincroniza la autenticación del enrutamiento, concediendo /key/generate y /user/new sin autenticar | Corroborado: las mismas llamadas del plano de administración se lanzaron contra nuestro señuelo, y presentaron un user agent CVE-2026-49468-Scanner |
litellm_sqli_apikey_results.json (517 KB), litellm_sqli_models.json | CVE-2026-42208 | Inyección SQL previa a la autenticación en LiteLLM en la ruta de autenticación | Corroborado: dispararon ' OR '1'='1 contra nuestro campo de clave diecinueve veces |
litellm_rce_exploit.json, litellm_mcp_rce_results.json | CVE-2026-42271 | Inyección de comandos y ejecución remota de código en LiteLLM, CVSS 8.7, en la lista de Vulnerabilidades Explotadas Conocidas de CISA, de 1.74.2 a 1.83.6, incluido un vector de inyección MCP | Inferido a partir del nombre de archivo y el producto |
sub2api_cve_exploit.json y tres fases posteriores | CVE-2026-27812 | Envenenamiento del restablecimiento de contraseña en Sub2API mediante cabeceras Host y Forwarded de confianza, que conduce a la toma de control de la cuenta. Explotada activamente, anterior a 0.1.85 | Inferido |
newapi_stripe_bypass_results.json, newapi_stripe_exploited.json, newapi_quota_overflow_results.json | CVE-2026-41432 | Bypass de la firma del webhook de Stripe en New-API a través de un secreto vacío, que otorga cuota ilimitada sin pago, anterior a 0.12.10 | Inferido |
newapi_user_token_leak_results.json, oneapi_user_token_leak_results.json, newapi_ssrf_bypass_results.json | CVE-2026-30886 | Referencia directa a objetos insegura y bypass de autenticación en New-API en el endpoint de video-proxy, que expone el contenido de otros usuarios y permite a un atacante gastar credenciales de la víctima aguas arriba | Inferido |
litellm_ssti_prompts_results.json | sin aviso único | Inyección de plantillas del lado del servidor Jinja2 contra los endpoints de prompts y plantillas | Inferido |
El contenido de ningún archivo nos llegó; cada fila se apoya en el nombre de archivo. Para dos de ellas observamos de forma independiente la llegada de la técnica a nuestro propio sensor, el bypass de cabecera Host y la inyección SQL de autenticación, lo que corrobora la técnica y no el archivo. Las otras cuatro se apoyan en el nombre de archivo más el aviso conocido del producto, y así se indican.
El patrón en las seis es el mismo. Cada aviso es de 2026, varios del mismo trimestre, y nada de ello es investigación original. keyHunter industrializa fallos de alta gravedad recién divulgados en el ecosistema de proxies de LLM de código abierto en el momento en que aterrizan. Esa es una ventana corta, sobre una clase de software que a menudo instala un solo desarrollador y luego se deja a su suerte.
Intención: la narrativa de la competición frente al directorio de resultados
El operador describe esto a su propio agente como una entrada a una competición. El vocabulario es consistente en todo el chat recuperado: 比赛项目 (proyecto de competición), 评委 (jueces), 答辩材料 (materiales de defensa oral), un directorio contest-kit, y trabajo organizado en 第一轮 y 第二轮, rondas uno y dos.
Preguntado por el alcance, el operador es explícito en que el objetivo son las credenciales por defecto, en el original:
llm 的主要就是那几个默认密码为主流,用自己的 sk 那种没办法抓到啊
En cuanto a las de LLM, lo que predomina son sobre todo esas pocas contraseñas por defecto; a las que usan sus propias claves
sk-*no hay manera de pillarlas.
El agente está de acuerdo, y confirma que los intentos de autenticación se limitan a tres casos: sin autenticación, sk-test y sk-1234, siendo esta última la clave que usa la propia documentación de inicio rápido de LiteLLM.
Luego está /root/keyHunter-skill/results/. Su listado nombra archivos para ejecución remota de código, inyección SQL, inyección de plantillas, falsificación de solicitudes del lado del servidor, secuestro de sesión contra Sub2API, rociado de credenciales, filtración de tokens de usuario, desbordamiento de cuota, y dos para un bypass del webhook de Stripe, uno de ellos newapi_stripe_exploited.json. Tenemos los nombres y, para algunos, los tamaños: los resultados del bypass de Stripe alcanzan 2.4 MB, aunque su contenido nunca nos llegó. La afirmación defendible es que el operador construyó y ejecutó instrumental de bypass de pago con cuota ilimitada contra New-API, y que CVE-2026-41432 es una vulnerabilidad real de exactamente ese tipo. Si los 2.4 MB de registros son recargas fraudulentas completadas o solo intentos, no podemos verlo. El _exploited del nombre de archivo es la palabra del operador para ello; no leímos los registros.
Mantenemos ambas lecturas abiertas. La competición puede ser genuina, con la explotación como una línea de trabajo aparte que el operador no comenta con un agente que guarda registros; o la competición puede ser una tapadera para una operación de robo. Valoramos la distinción como irrelevante para los defensores: la capacidad y el riesgo para un panel expuesto son idénticos bajo cualquiera de las dos lecturas.
Brecha de oficio: el propio agente del operador auditó el instrumental
El pasaje más útil del chat recuperado es una revisión de código. El operador preguntó a su agente por qué la tasa de acierto del escaneo era tan baja, y el agente recorrió el escáner línea por línea.
La respuesta del agente, condensada a lo que un defensor puede usar: el escáner antepone un protocolo a un campo host de FOFA que a menudo ya lleva uno, produciendo URLs de la forma https://https://<target>, de modo que hosts vivos se registraban como muertos. El pool de hilos recoge los resultados en orden de creación en lugar de a medida que terminan, así que una sola solicitud lenta bloquea todo lo que hay detrás. CONCURRENCY=200 en una máquina de cuatro núcleos fabrica sus propios timeouts. Deduplicar por IP descarta otros puertos válidos en la misma dirección. Fijar temperature malinterpreta un error de compatibilidad como un fallo.
Sobre su detección de honeypots el agente fue tajante: juzga principalmente por si la respuesta es idéntica o más corta que cinco caracteres, lo que mata a los modelos normales y se le escapan los buenos señuelos. Y a pesar de que el operador le pidió identificar a los que responden en un idioma que no es el chino, el código no contenía lógica alguna de detección de idioma.
También señaló su higiene de seguridad: la clave de FOFA incrustada en el script, rutas absolutas escritas para /root cuando el usuario real es /home/developer, except: pass tragándose cada motivo de fallo, una copia separada del script por país, y archivos de resultados que guardan objetivos y métodos de autenticación sin control de acceso ni redacción.
Ese último punto replantea el embudo. La tasa de acierto del 0.61% en Estados Unidos mide la exposición a través de un escáner con fallos conocidos, de modo que la tasa real de LiteLLM expuesto es más alta de lo que muestran los propios resultados del operador. Ahora tienen un agente que seguirá corrigiendo esos fallos.
Infraestructura de monetización
El mismo host ejecuta una instancia de New-API propia: calciumion/new-api:latest en Docker, publicada en el puerto 8901, con los datos montados por bind junto a los resultados del escaneo. A su alrededor están newapi_watchdog.py, un archivo de copia de seguridad de canales y una copia empaquetada de todo el conjunto.
New-API es un panel de agregación. Toma un montón de claves de proveedores aguas arriba y las presenta como una única API con sus propias cuentas de usuario y cuotas. Levantar eso junto a una cadena de recolección de claves tiene un propósito obvio: las claves recolectadas se convierten en canales de un panel, y el panel se convierte en acceso que puedes vender. No observamos reventa y no la afirmamos; la fontanería para ello está instalada y en marcha.
Ya circulan cientos de routers gratuitos similares construidos sobre las plantillas de sub2api y new-api, y keyHunter es una operación dentro de ese ecosistema.
Asociaciones del clúster
La toma de huellas de cliente vincula estos dos hosts a un conjunto laxo de otros que trabajan la misma superficie: un host taiwanés que ejecuta escaneos de CVE y acuñación de claves, un host de Hong Kong que lanza la misma inyección SQL, y un salto más allá, un cazador de paneles de LLM y un explotador de dashboards de Ray cuyas ráfagas de un solo día cayeron el 15 y el 21 de agosto, con seis días de diferencia. Los solapamientos corren sobre stacks de cliente genéricos en algunos puntos, de modo que esto se lee como instrumental compartido y una escena compartida más que como una sola mano en un solo teclado. Trátalo como una comunidad con nexo en China que comparte instrumental de caza de proxies de LLM. Ningún indicador lo vincula a una APT con nombre, así que lo rastreamos como un clúster de actividad.
Indicadores de compromiso
Red e infraestructura, neutralizadas:
| Indicador | Rol |
|---|---|
39.98.82[.]200 | Pasarela del agente, reconocimiento, inyección SQL (Alibaba Cloud, AS37963, CN) |
101.43.41[.]72 | Endpoint de relé en el puerto 8087, worker de subagente delegado (Tencent Cloud, AS45090, CN) |
hamal.cc[.]cd | Mirror no oficial de FOFA que consulta el escáner |
cae332848db5… | La propia clave de API de FOFA del operador, incrustada en litellm_scan_hw.py. Truncada aquí; el valor completo se ha retenido para reportarlo a FOFA en lugar de publicarlo |
Huellas de cliente y user agents:
po11nn070000_ebbca96fac43_00000000 shared across both nodes
Hermes-Agent/0.18.0
Hermes-Panel/1.0
Mozilla/5.0 (CVE-2026-49468-Scanner)
Artefactos de host. Estas son rutas en las máquinas del operador, útiles para cazar un host similar o un segundo despliegue:
/home/developer/litellm_verifier.py real-chat verifier and honeypot classifier
/home/developer/test_litellm_verifier.py unit tests
/home/developer/litellm_endpoint.py endpoint normalise and dedupe
/home/developer/litellm_scan_hw.py FOFA scanner, US, AWS excluded
/home/developer/litellm_scan_gb_hw.py
/home/developer/litellm_scan_it_hw.py
/home/developer/litellm_scan_us_30d_optimized.py
/home/developer/contest-kit/keyHunter-skill/
/home/developer/backups/litellm_verifier_round2_<ts>/SHA256SUMS
/root/keyHunter-skill/results/
/root/keyHunter-skill/{honeypot_test.py, verify_country_models.py, add_to_panel.py, report.py}
/root/.ssh/hw_vm_key key to the scanning VM, [email protected]:8888
/opt/hermes-simple-panel/app.py config panel, port 9120
/root/new-api.tar.gz, /root/newapi_watchdog.py
Nombres de skill y de proyecto, que son los pivotes de cadena única más fuertes:
keyhunter / keyHunter
contest-kit
ai-proxy-panel-audit
fofa-panel-recon
delegation-orchestration
De comportamiento:
FOFA: (title="LiteLLM" || body="LiteLLM") && country="XX" && org!="AMAZON-AES"
auth: no credential, then sk-test, then sk-1234
SQLi: ' OR '1'='1 in the API key field
verify: a real chat completion per advertised model; a /models listing alone is rejected
verdict strings: honeypot_or_unusable, trusted_pass, unavailable,
formatted_false_success, non_chinese_evidence
services on actor infra: new-api :8901, config panel :9120, agent gateway
Detección
Si ejecutas un proxy de LLM alcanzable desde internet, toda la secuencia es visible en los propios registros de la pasarela. En Sigma, el formato de reglas neutral respecto al proveedor que la mayoría de plataformas SIEM pueden importar:
title: AI proxy panel enumeration consistent with keyHunter
id: 2c6f9a41-8e07-4b53-9f1a-7d0c4b62ae35
status: experimental
description: >
The keyHunter discovery and verification sequence against an exposed LLM
proxy: an unauthenticated model listing followed by per-model chat
completions from the same source, or one of the cluster's user agents.
references:
- https://kinryu.sh/reports/keyhunter-llm-proxy-key-harvesting/
logsource:
category: webserver
detection:
model_listing:
cs-uri-stem|endswith:
- '/v1/models'
- '/models'
admin_paths:
cs-uri-stem|startswith:
- '/key/'
- '/user/'
- '/organization/'
cluster_agents:
c-useragent|contains:
- 'Hermes-Agent'
- 'Hermes-Panel'
- 'CVE-2026-49468-Scanner'
admin_allowlist:
c-ip|cidr: '10.0.0.0/8' # replace with your own admin range
condition: (((model_listing or admin_paths) and not admin_allowlist) or cluster_agents)
falsepositives:
- Client libraries that legitimately call /v1/models on startup from allow-listed ranges
level: high
Un registro de acceso web no anota la cabecera Authorization, así que los intentos con credenciales por defecto y de inyección tienen que capturarse en el propio registro de solicitudes del proxy: el literal sk-1234 y sk-test, una credencial ausente, y ' OR '1'='1 en el campo de clave.
Tres búsquedas de comportamiento que no necesitan un motor de reglas:
- Busca una única fuente que liste tus modelos y luego envíe exactamente una completación de chat corta a cada uno de ellos por turno. Ese barrido de verificación es la firma de la operación y es difícil de disfrazar.
- Alerta sobre los prompts que piden al modelo declarar su identidad real en contra del parámetro de la API, la comprobación que un comprador ejecuta antes de confiar en un acceso robado.
- Compara periódicamente la lista de canales y la tabla de usuarios de tu panel. La extracción de claves y la exportación de cuentas dejan el panel funcionando con normalidad, así que nada más te lo dirá.
Qué hacer
Trata cualquier proxy de LLM expuesto a internet como comprometido desde el momento de la exposición. keyHunter barre un país en un día y trabaja los CVE publicados en cuestión de semanas tras su divulgación.
- Coloca LiteLLM, One-API, New-API, Sub2API y cualquier cosa similar detrás de un proxy inverso con autenticación o en una red privada. Ninguno de ellos se distribuye con un valor por defecto defendible para la exposición a internet.
- Actualiza a la versión vigente. De los seis avisos de arriba, el RCE de LiteLLM está en la lista de Vulnerabilidades Explotadas Conocidas de CISA y la toma de control de cuenta de Sub2API está confirmada como explotada activamente.
- Cambia la clave maestra.
sk-1234es el valor del propio inicio rápido de LiteLLM y es una de solo tres credenciales que este operador se molesta en probar. - Restringe
/openapi.jsony/docs. Un cliente anónimo no debería poder descargar tu superficie de API administrativa. - Pon un tope de presupuesto y limita el alcance de cada clave virtual, para que la extracción rinda algo que no valga la pena revender.
- Si aceptas pagos de Stripe a través de New-API, verifica que el secreto de firma del webhook esté realmente establecido. Un secreto vacío es la totalidad de CVE-2026-41432.
- Rota cada clave de proveedor aguas arriba que haya estado alguna vez en un panel del que no puedas demostrar que nunca estuvo expuesto.
Mapeo de MITRE ATT&CK
| Táctica | Técnica |
|---|---|
| Reconnaissance | T1596.005 Search Open Technical Databases: Scan Databases (FOFA, por país, AWS excluido); T1595.002 Active Scanning: Vulnerability Scanning (sondeo HTTP ligero y profundo) |
| Resource Development | T1583.003 Acquire Infrastructure: Virtual Private Server (Alibaba, Tencent, Huawei); T1588.002 Obtain Capabilities: Tool (Hermes Agent, OpenClaw, una suscripción a FOFA, github_copilot/gpt-5.6-sol como motor de razonamiento) |
| Initial Access | T1190 Exploit Public-Facing Application (bypass de autenticación por cabecera Host, inyección SQL previa a la autenticación, inyección de comandos, SSTI, SSRF contra LiteLLM, Sub2API y New-API) |
| Defense Evasion | T1480 Execution Guardrails (clasificación de honeypots, puntuación non_chinese_evidence, filtrado org!="AMAZON-AES") |
| Credential Access | T1078.001 Valid Accounts: Default Accounts (sin credencial, sk-test, sk-1234); T1552.001 Unsecured Credentials: Credentials In Files (extracción de claves a exported_keys.json) |
| Discovery | T1518 Software Discovery (listado de modelos y verificación por modelo); T1087 Account Discovery (enumeración de usuarios contra el plano de administración) |
| Collection | T1213 Data from Information Repositories (exportación de cuentas, normalización, archivado) |
| Command and Control | T1102 Web Service (un hilo de WeChat como canal de asignación de tareas) |
| Impact | T1657 Financial Theft (bypass del webhook de Stripe, desbordamiento de cuota); T1496 Resource Hijacking (fontanería de reventa para inferencia recolectada) |
Metodología y notas del analista
Casi todo lo anterior nos llegó de la misma manera. Un señuelo de Kinryū Labs que se presenta como una instancia de LiteLLM expuesta responde a un cliente agéntico como lo haría un modelo real, contestando con llamadas de herramienta: instrucciones de la forma ejecuta este comando y dime qué imprimió. No ejecuta ninguna de ellas. El agente del operador trató esas respuestas como llamadas de función genuinas, las ejecutó contra su propio sistema de archivos, y devolvió la salida como resultados de herramienta, 534 veces entre el 16 y el 20 de agosto de 2026. Esa salida es su entorno: 283 rutas de archivo distintas, listados de servicios y contenedores, resúmenes de resultados de escaneo, y las propias búsquedas del agente en su memoria de WeChat. El señuelo permanece pasivo en todo momento, de modo que todo lo anterior es lo que el propio agente del operador le ofreció por voluntad propia.
Lo que tenemos es, por tanto, un subconjunto de su sistema real, acotado por lo que su agente resultó enumerar. El contenido de ningún archivo nos llegó; tenemos nombres, tamaños y marcas de tiempo de los propios listados de directorios del operador. Los rendimientos del escaneo y los recuentos de veredicto son las cifras del propio operador, reportadas por su instrumental, y no hemos verificado ninguna de ellas de forma independiente. Su agente encontró fallos reales en su escáner, así que las tasas de acierto deben leerse como un suelo de la exposición y no como una medición de ella.
El chat en lengua china está traducido. Las cadenas técnicas, las rutas y los identificadores se dejan textuales tanto en este informe como en la traducción.
Cuatro límites sobre lo que esto sustenta. La atribución se detiene en un clúster de actividad sobre infraestructura radicada en China que usa el chino en todo momento; no hay vínculo con un grupo con nombre y no ofrecemos ninguno. La intención es genuinamente ambigua entre una entrada a una competición y una operación de robo. El contenido de ningún archivo de exploit nos llegó, así que los seis mapeos de CVE se apoyan en nombres de archivo; para dos de ellos la técnica se observó de forma independiente al llegar a nuestro sensor, lo que corrobora la técnica y no el archivo. Y nunca vimos gastarse una clave robada: los valores de las claves exportadas del operador nunca nos llegaron, solo sus recuentos de 3 extraídas y 17 exportadas, así que no había nada contra lo que buscar en la telemetría.
Las direcciones de terceros que su escáner tocó se retienen, incluido el host que ellos mismos señalaron como honeypot, que pertenece a la investigación de otra persona. Su clave de API de FOFA está truncada aquí.
Los conjuntos completos de indicadores y las capturas subyacentes están disponibles para investigadores que los soliciten: [email protected].