
Ingeniería inversa sistemática del binario lina de Cisco ASA para descubrir y analizar vulnerabilidades de corrupción de memoria, incluyendo CVE-2025-20333 y CVE-2025-20362, con un enfoque en encontrar primitivas de ejecución remota de código.
linaCreado: 2026-08-12
Objetivo: lab_asav9-12-4-67/lina (ASAv 9.12(4)67, ELF x86-64, PIE; base de imagen Ghidra 0x100000; 112,687 funciones, ~167 MB mapeados, 642,707 símbolos)
Meta de la vía: cobertura RE sistemática y completa del binario lina — complementaria a la RE dirigida por hipótesis realizada hasta ahora — para cazar la primitiva que el laboratorio no ha encontrado (el RCE root no autenticado salvaje en 20362+20333 está demostrado, por lo que existe).
Toda la RE anterior fue dirigida (descompilaciones en el PC de fallo, recorridos de xref anclados a strings, barridos de rangos de binding). Cerró todos los ámbitos auditados (H4-1/2/3/4, reflexión de tostring(userdata), %p en SSH/SNMP/IKE, familias alternativas de desbordamiento, oráculo de supervivencia) — ver , . Esos cierres son por ámbito; el de un binario de 112k funciones es exactamente donde debe residir la primitiva que le falta al APT. Esta vía sustituye "adivinar la siguiente superficie" por .
../RCE_BLOCKERS.md../NEW_ROADS_TO_CODE_EXECUTION.mdPosición vs ruta crítica: el obstáculo duro de la cadena conocida sigue siendo P0 (fuga de información remota en vivo); la sobrelectura de readdir CIFS (paso 19i, ventana de 4 bytes) es la única fuga confirmada empíricamente y sigue siendo la vía empírica en primer plano. LINA_FULL_RE es la cobertura sistemática: encontrar una fuga/primitiva mejor en código no auditado, o demostrar que no existe ninguna.
0x55.. (lina) o 0x7f.. (libc/heap): emisores de format string (%p/%lx/%x sobre punteros), sobrelecturas (longitud no acotada por datos inicializados), reflejo de residuos del heap, ecos de buffers sin inicializar.memcpy/memmove/strcpy/strcat/sprintf/vsprintf/clase gets + bucles de copia personalizados), en todas las superficies de protocolo (no solo los bindings Lua de WebVPN ya agotados — ver ../LINA_ALT_OVERFLOW_FAMILIES_RE.md).csco_config) para que los hits del triaje puedan clasificarse por realmente alcanzables desde la red.(Diferido por el usuario: caza del sink CVE-2025-20363 — la OSINT dice que consume una fuga, hermano de 20333; ver ../CVE-2025-20363_OSINT.md.)
| Etapa | Qué | Herramientas | Salida |
|---|---|---|---|
| 1. Corpus | Descompilación en lote de las 112,687 funciones a disco, un .c por función, fragmentado por dirección | Ghidra run_script_inline (Java, DecompInterface), por lotes + reanudable | corpus/<shard>/<addr>.c |
| 2. Triaje mecánico | Aplicar ripgrep al corpus en busca de patrones de sumidero (clases de fuga y desbordamiento abajo) | scripts locales, triage/ | tablas de hits (CSV/MD) |
| 3. Filtro de alcanzabilidad | conservar los hits en funciones alcanzables desde los puntos de entrada de red | grafo de llamadas de Ghidra (get_function_call_graph/script) + lista de semillas de puntos de entrada | lista de hits clasificada |
| 4. Inmersión profunda | RE dirigida de los hits clasificados (el patrón existente del subagente ghidra-re) | ghidra-mcp | documentos de hallazgos en esta carpeta |
La etapa 1 es puro cómputo (est. horas–días, sin supervisión, reanudable). Las etapas 2–3 son baratas/locales. La etapa 4 es la única con carga intensiva de humano/LLM y está acotada por el embudo.
Research notes/LINA_FULL_RE/
README.md — this file (master plan + status)
TRIAGE.md — sink-pattern catalog + reachability plan (stage 2/3 spec)
scripts/ — decompile + triage + driver scripts
corpus/ — stage-1 output: decompiled functions, sharded (corpus/2c/02c6cc80.c)
_progress.txt — resumable progress marker (done count, last address)
_errors.txt — per-function decompile failures
triage/ — stage-2/3 outputs (hit tables, ranked lists)
findings/ — stage-4 deep-dive writeups (one MD per confirmed candidate)
| Etapa | Estado | Notas |
|---|---|---|
| 1. Corpus | COMPLETADO 2026-08-12 (~19:03 UTC-4) | 111,997/111,997 funciones, 0 errores, 548 MB en corpus/; tomó 26,214 s (~7.3 h) a 4.3 fn/s mediante scripts/decompile_all.py (GhidraMCP batch_decompile, límite de 20 fn/llamada) |
| 2. Triaje | COMPLETADO 2026-08-13 | scripts/triage_stage2.py; tablas de hits por clase en triage/*_hits.csv; unión clasificada en triage/RANKED.md |
| 3. Alcanzabilidad | COMPLETADO 2026-08-13 (re-ejecutado, semillas corregidas) | grafo call+ref del corpus (427,198 aristas); 26,291/111,997 alcanzables (23.5%) — preauth 26,278 / admin 13 / post20362 0. Semillas corregidas: registrar 0317b4e0, session 0317c0a0 (los antiguos 030ab4e0/030ac0a0 no eran inicios de función). Sigue siendo una cota inferior (vtables). |
| 4. Inmersión profunda | EN CURSO 2026-08-17 | L1 CERRADO. L2 C-path GO (estático): WebVPN UCTE create_type3_message copia el TargetInfo Tipo-2 del atacante sin acotar; la fuga viaja de vuelta al servidor HTTP del atacante en el Authorization: NTLM Tipo-3 (findings/L2_NTLM_C_PATH_TYPE3.md). Lua ntlm.parseType2 es el gemelo latente. Pasada de protocolo O1/O5 CERRADA (estático): las copias de IKE/SSH/SNMP/EWS/PDTS están acotadas al tamaño del destino, son del lado de envío o ya conocidas (031af6d0 / 02ff2f30). O1 “other” 725 CERRADO (estático): filtro stack/global/param+const → sin nuevo GO de desbordamiento de destino; 015a8b30 es un helper de addrtype sin acotar al que sus llamadores solo pasan tamaño AF 4/0x10 (findings/O1_OTHER_SWEEP.md). O2 CERRADO (estático): 605 bucles de copia alcanzables; sin nuevo GO de desbordamiento de destino. FUN_02fd7270 = → mismo que el C-path GO de L2 (). Siguiente: sonda NTLM de laboratorio (post-20362) — supera a CIFS en ventana si aparece un qword /. Estático opcional: O3/O4. |
Reanudación/control: el driver omite las funciones cuyo archivo de salida ya existe — vuelva a ejecutar python3 scripts/decompile_all.py en cualquier momento para continuar. Detención ordenada: touch corpus/STOP. Si Ghidra o el plugin MCP se reinician, basta con volver a ejecutar el driver.
Restricciones del plugin descubiertas (2026-08-12): run_script_inline está deshabilitado (GHIDRA_MCP_ALLOW_SCRIPTS sin definir) → el corpus usa solo los endpoints HTTP por lotes; batch_decompile toma ?functions=0x..,0x..,.. como parámetro de consulta GET (no como cuerpo JSON) y trunca silenciosamente las respuestas a 20 funciones → tamaño de lote del driver = 20.
list_functions (verificado: corpus/02/02c6cc80.c = luaH_get = RVA 0x2c6cc80). Nota: el plugin HTTP de GhidraMCP reporta direcciones en estilo RVA, no la VA de Ghidra = RVA + 0x100000.../RCE_BLOCKERS.md / ../TODO.md cuando un candidato "nuevo" se solape con una ruta cerrada.0x55.. vs 0x7f.. vs heap), y si supera a la primitiva de readdir CIFS (paso 19i) en fiabilidad.ucte_ntlm_authenticate_connectioncreate_type3_message0x7f..0x55..