
Engenharia reversa sistemática do binário lina do Cisco ASA para descobrir e analisar vulnerabilidades de corrupção de memória, incluindo CVE-2025-20333 e CVE-2025-20362, com foco em encontrar primitivas de execução remota de código.
linaCriado: 2026-08-12
Alvo: lab_asav9-12-4-67/lina (ASAv 9.12(4)67, ELF x86-64, PIE; imagem base do Ghidra 0x100000; 112.687 funções, ~167 MB mapeados, 642.707 símbolos)
Objetivo da trilha: cobertura de RE sistemática e completa do binário lina — complementando a RE direcionada por hipóteses feita até agora — para caçar a primitiva que o laboratório não encontrou (uma RCE root remota sem autenticação in the wild em 20362+20333 é comprovada, portanto ela existe).
Toda RE anterior foi direcionada (decompilações por fault-PC, varreduras de xref ancoradas em strings, varreduras de faixa de binding). Ela fechou todos os escopos auditados (H4-1/2/3/4, reflexão tostring(userdata), %p de SSH/SNMP/IKE, famílias alternativas de overflow, oráculo de sobrevivência) — veja , . Esses fechamentos são por escopo; o de um binário de 112k funções é exatamente onde a primitiva ausente da APT deve estar. Esta trilha substitui "adivinhar a próxima superfície" por .
../RCE_BLOCKERS.md../NEW_ROADS_TO_CODE_EXECUTION.mdPosição vs. caminho crítico: a barreira crítica da cadeia conhecida continua sendo P0 (infoleak remoto ao vivo); o over-read de readdir do CIFS (Passo 19i, janela de 4 bytes) é o único vazamento confirmado empiricamente e permanece a trilha empírica em primeiro plano. O LINA_FULL_RE é a proteção sistemática: encontrar um vazamento/primitiva melhor em código não auditado, ou provar que nenhum existe.
0x55.. (lina) ou 0x7f.. (libc/heap): emissores de format string (%p/%lx/%x em ponteiros), over-reads (comprimento não limitado por dados inicializados), reflexo de resíduo de heap, ecos de buffer não inicializado.memcpy/memmove/strcpy/strcat/sprintf/vsprintf/classe gets + loops de cópia personalizados), em todas as superfícies de protocolo (não apenas os bindings Lua do WebVPN já esgotados — veja ../LINA_ALT_OVERFLOW_FAMILIES_RE.md).csco_config) para que os acertos da triagem possam ser classificados por realmente alcançáveis a partir da rede.(Adiado pelo usuário: caça ao sumidouro do CVE-2025-20363 — OSINT diz que ele consome um vazamento, irmão do 20333; veja ../CVE-2025-20363_OSINT.md.)
| Etapa | O quê | Ferramentas | Saída |
|---|---|---|---|
| 1. Corpus | Decompilar em lote todas as 112.687 funções para o disco, um .c por função, particionado por endereço | run_script_inline do Ghidra (Java, DecompInterface), em blocos + retomável | corpus/<shard>/<addr>.c |
| 2. Triagem mecânica | ripgrep no corpus em busca de padrões de sumidouro (classes de vazamento e overflow abaixo) | scripts locais, triage/ | tabelas de acertos (CSV/MD) |
| 3. Filtro de alcance | manter acertos em funções alcançáveis a partir dos pontos de entrada de rede | grafo de chamadas do Ghidra (get_function_call_graph/script) + lista de sementes de pontos de entrada | lista de acertos classificada |
| 4. Mergulho profundo | RE direcionada dos acertos classificados (o padrão existente do subagente ghidra-re) | ghidra-mcp | documentos de descobertas nesta pasta |
A Etapa 1 é puramente computacional (estimativa: horas–dias, sem supervisão, retomável). As Etapas 2–3 são baratas/locais. A Etapa 4 é a única etapa pesada em humano/LLM e é limitada pelo funil.
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 | Status | Notas |
|---|---|---|
| 1. Corpus | CONCLUÍDA 2026-08-12 (~19:03 UTC-4) | 111.997/111.997 funções, 0 erros, 548 MB em corpus/; levou 26.214 s (~7,3 h) a 4,3 fn/s via scripts/decompile_all.py (GhidraMCP batch_decompile, limite de 20 fn/chamada) |
| 2. Triagem | CONCLUÍDA 2026-08-13 | scripts/triage_stage2.py; tabelas de acertos por classe em triage/*_hits.csv; junção classificada em triage/RANKED.md |
| 3. Alcance | CONCLUÍDA 2026-08-13 (re-executada, sementes corrigidas) | grafo de chamadas+refs do corpus (427.198 arestas); 26.291/111.997 alcançáveis (23,5%) — preauth 26.278 / admin 13 / post20362 0. Sementes corrigidas: registrar 0317b4e0, session 0317c0a0 (as antigas 030ab4e0/030ac0a0 não eram inícios de função). Ainda é um limite inferior (vtables). |
| 4. Mergulho profundo | EM ANDAMENTO 2026-08-17 | L1 FECHADA. L2 C-path GO (estático): o create_type3_message do UCTE do WebVPN copia o TargetInfo Type-2 do atacante sem clamp; o vazamento viaja no Authorization: NTLM Type-3 de volta ao servidor HTTP do atacante (findings/L2_NTLM_C_PATH_TYPE3.md). O ntlm.parseType2 do Lua é o gêmeo dormente. Varredura de protocolo O1/O5 FECHADA (estática): as cópias de IKE/SSH/SNMP/EWS/PDTS são dimensionadas pelo destino, no lado de envio ou já conhecidas (031af6d0 / 02ff2f30). Os 725 “outros” de O1 FECHADOS (estático): filtro stack/global/param+const → nenhum novo GO de overflow de destino; 015a8b30 é um helper de addrtype sem clamp cujos chamadores passam apenas AF de tamanho 4/0x10 (findings/O1_OTHER_SWEEP.md). O2 FECHADA (estático): 605 loops de cópia alcançáveis; nenhum novo GO de overflow de destino. FUN_02fd7270 = → mesmo do GO do C-path L2 (). Próximo: sonda NTLM de laboratório (pós-20362) — supera o CIFS em janela se um qword / aparecer. Estático opcional: O3/O4. |
Retomar/controle: o driver pula funções cujo arquivo de saída já existe — execute python3 scripts/decompile_all.py novamente a qualquer momento para continuar. Parada graciosa: touch corpus/STOP. Se o Ghidra ou o plugin MCP reiniciar, basta executar o driver novamente.
Restrições do plugin descobertas (2026-08-12): o run_script_inline está desabilitado (GHIDRA_MCP_ALLOW_SCRIPTS não definido) → o corpus usa apenas os endpoints HTTP em lote; o batch_decompile aceita ?functions=0x..,0x..,.. como parâmetro de consulta GET (não corpo JSON) e trunca silenciosamente as respostas para 20 funções → tamanho do bloco do driver = 20.
list_functions (verificado: corpus/02/02c6cc80.c = luaH_get = RVA 0x2c6cc80). Nota: o plugin HTTP do GhidraMCP reporta endereços no estilo RVA, não VA do Ghidra = RVA + 0x100000.../RCE_BLOCKERS.md / ../TODO.md quando um candidato "novo" se sobrepuser a uma rota fechada.0x55.. vs 0x7f.. vs heap) e se supera a primitiva de readdir do CIFS (Passo 19i) em confiabilidade.ucte_ntlm_authenticate_connectioncreate_type3_message0x7f..0x55..